1 #include "OpenGLUtils.h"
2 #include <map>
3 
4 namespace touchcontrols
5 {
6 float GLScaleWidth = 400;
7 float GLScaleHeight = -300;
8 
9 
10 #ifdef USE_GLES2
11 extern "C"
12 {
13 
14 float glTranslateX,glTranslateY,glTranslateZ;
15 
16 float glColorR, glColorG, glColorB, glColorA;
glColor4f(GLfloat r,GLfloat g,GLfloat b,GLfloat a)17 void glColor4f(GLfloat r,GLfloat g,GLfloat b,GLfloat a)
18 {
19 	glColorR = r;
20 	glColorG = g;
21 	glColorB = b;
22 	glColorA = a;
23 }
24 
glLoadIdentity()25 void glLoadIdentity()
26 {
27 	glTranslateX = glTranslateY = glTranslateZ = 0;
28 }
29 
glScalef(GLfloat x,GLfloat y,GLfloat z)30 void glScalef(GLfloat x,GLfloat y,GLfloat z)
31 {
32 
33 }
34 
glTranslatef(GLfloat x,GLfloat y,GLfloat z)35 void glTranslatef(GLfloat x,GLfloat y,GLfloat z)
36 {
37 	glTranslateX+=x;
38 	glTranslateY-=y;
39 	glTranslateZ+=z;
40 }
41 }
42 
translateX(float X)43 float translateX(float X)
44 {
45 	return -(1-X*2);
46 }
translateY(float Y)47 float translateY(float Y)
48 {
49 	return (-Y*2+1);
50 }
GLES2scaleX(float X)51 float GLES2scaleX(float X)
52 {
53 	return X*2;
54 }
GLES2scaleY(float Y)55 float GLES2scaleY(float Y)
56 {
57 	return Y*2;
58 }
59 const char vShaderStr [] =
60 		"attribute vec4 a_position;  \
61 			attribute vec2 a_texCoord;   \
62 			varying vec2 v_texCoord;     \
63 			uniform vec4 u_translate;    \
64 			void main()                 \
65 			{                           \
66 			   gl_Position = a_position + u_translate; \
67 			   v_texCoord = a_texCoord;  \
68 			}                            \
69 			";
70 
71 const char  fShaderStr [] =
72 		"precision mediump float;                            \
73 			varying vec2 v_texCoord;                            \
74 			uniform sampler2D s_texture;                        \
75 		    uniform vec4 u_color;    \
76 			void main()                                         \
77 			{                                                   \
78 				vec4 alpha = texture2D( s_texture, v_texCoord ); \
79 				gl_FragColor = alpha*u_color;  \
80 			}                                                   \
81 			";
82 
83 const char  fShaderColorStr [] =
84 		"precision mediump float;                            \
85 		    uniform vec4 u_color;    \
86 			void main()                                         \
87 			{                                                   \
88 				gl_FragColor = u_color;  \
89 			}                                                   \
90 			";
91 
loadShader(int shaderType,const char * source)92 int loadShader(int shaderType,const char * source) {
93 	int shader = glCreateShader(shaderType);
94 	if (shader != 0) {
95 		glShaderSource(shader,1, &source,NULL);
96 		glCompileShader(shader);
97 
98 
99 		GLint  length;
100 
101 		glGetShaderiv ( shader , GL_INFO_LOG_LENGTH , &length );
102 
103 		if ( length ) {
104 			char* buffer  =  new char [ length ];
105 			glGetShaderInfoLog ( shader , length , NULL , buffer );
106 			LOGTOUCH("shader = %s", buffer);
107 			delete [] buffer;
108 
109 			GLint success;
110 			glGetShaderiv( shader, GL_COMPILE_STATUS, &success );
111 			if ( success != GL_TRUE )  LOGTOUCH("ERROR compiling shader");
112 		}
113 
114 
115 	}
116 	return shader;
117 }
118 
createProgram(const char * vertexSource,const char * fragmentSource)119 int createProgram(const char * vertexSource, const char *  fragmentSource) {
120 	int vertexShader = loadShader(GL_VERTEX_SHADER, vertexSource);
121 	int pixelShader = loadShader(GL_FRAGMENT_SHADER, fragmentSource);
122 
123 	int program = glCreateProgram();
124 	if (program != 0) {
125 		glAttachShader(program, vertexShader);
126 		// checkGlError("glAttachShader");
127 		glAttachShader(program, pixelShader);
128 		// checkGlError("glAttachShader");
129 		glLinkProgram(program);
130 		/*
131 		int[] linkStatus = new int[1];
132 		glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
133 		if (linkStatus[0] != GLES20.GL_TRUE) {
134 			LOGE("Could not link program: ");
135 			LOGE(glGetProgramInfoLog(program));
136 			glDeleteProgram(program);
137 			program = 0;
138 		}
139 		 */
140 
141 	}
142 	return program;
143 }
144 
145 GLfloat mTexVertices[] =
146 {
147 		0.0f, 0.0f, // TexCoord 0
148 		0.0f, -1.0f, // TexCoord 1
149 		1.0f, -1.0f, // TexCoord 2
150 		1.0f, 0.0f // TexCoord 3
151 };
152 /*
153 GLfloat mTexVertices[] =
154 {
155 		0.0f, 0.0f, // TexCoord 0
156 		0.0f, 1.0f, // TexCoord 1
157 		1.0f, 1.0f, // TexCoord 2
158 		1.0f, 0.0f // TexCoord 3
159 };
160  */
161 // Handle to a program object
162 static int mProgramObject;
163 static int mProgramObjectColor;
164 
165 // Attribute locations
166 static int mPositionLoc;
167 static int mTexCoordLoc;
168 
169 // Sampler location
170 static int mSamplerLoc;
171 static int mColorLoc;
172 
173 static int mPositionTranslateLoc;
174 
175 
176 static int mPositionLocColor;
177 static int mColorLocColor;
178 static int mPositionTranslateLocColor;
179 
180 
181 static int gles2InitDone = 0;
182 
initGLES2()183 void initGLES2()
184 {
185 
186 	// Load the shaders and get a linked program object
187 	mProgramObject = createProgram(vShaderStr, fShaderStr);
188 	mProgramObjectColor = createProgram(vShaderStr, fShaderColorStr);
189 
190 	// Get the attribute locations
191 	mPositionLoc = glGetAttribLocation(mProgramObject, "a_position");
192 	mTexCoordLoc = glGetAttribLocation(mProgramObject, "a_texCoord" );
193 
194 	// Get the sampler location
195 	mSamplerLoc = glGetUniformLocation ( mProgramObject, "s_texture" );
196 	mPositionTranslateLoc =glGetUniformLocation ( mProgramObject, "u_translate" );
197 	mColorLoc  = glGetUniformLocation ( mProgramObject, "u_color" );
198 
199 
200 	//COLOR
201 	mPositionLocColor            = glGetAttribLocation(mProgramObjectColor, "a_position");
202 	mColorLocColor               = glGetUniformLocation ( mProgramObjectColor, "u_color" );
203 	mPositionTranslateLocColor   =glGetUniformLocation ( mProgramObjectColor, "u_translate" );
204 }
205 #endif
206 
207 
208 #ifdef USE_GLES2
drawRect(GLuint texture,float x,float y,GLRect & rect)209 void drawRect(GLuint texture, float x, float y, GLRect &rect)
210 {
211 	//LOGTOUCH("drawRect");
212 	glUseProgram(mProgramObject);
213 
214 	glVertexAttribPointer ( mPositionLoc, 3, GL_FLOAT,
215 			false,
216 			3 * 4, rect.vertices);
217 
218 	glVertexAttribPointer ( mTexCoordLoc, 2, GL_FLOAT,
219 			false,
220 			2 * 4,
221 			mTexVertices );
222 
223 	glEnableVertexAttribArray ( mPositionLoc );
224 	glEnableVertexAttribArray ( mTexCoordLoc );
225 
226 	// Bind the texture
227 	glActiveTexture ( GL_TEXTURE0 );
228 	glBindTexture ( GL_TEXTURE_2D, texture );
229 
230 	// Set the sampler texture unit to 0
231 	glUniform1i ( mSamplerLoc, 0 );
232 
233 	glUniform4f(mPositionTranslateLoc,  translateX(x + glTranslateX), translateY(y + glTranslateY), 0, 0);
234 	glUniform4f(mColorLoc,glColorR,glColorG,glColorB,glColorA);
235 
236 	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
237 }
238 
239 #else
drawRect(GLuint texture,float x,float y,GLRect & rect)240 void drawRect(GLuint texture, float x, float y, GLRect &rect)
241 {
242 
243     if (texture == -1)
244         return;
245 
246 	//LOGTOUCH("drawRect %d",texture);
247 	glBindTexture(GL_TEXTURE_2D, texture);
248 
249 	glVertexPointer(3, GL_FLOAT, 0, rect.vertices);
250 	glTexCoordPointer(2, GL_FLOAT, 0, rect.texture);
251 
252 	glTranslatef(x, -y, 0);
253 	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
254 	//Move back to original pos in case other rects to draw
255 	glTranslatef(-x, y, 0);
256 
257 }
258 #endif
259 
260 #ifdef USE_GLES2
drawRect(GLfloat r,GLfloat g,GLfloat b,GLfloat a,float x,float y,GLRect & rect)261 void drawRect(GLfloat r,GLfloat g,GLfloat b,GLfloat a, float x, float y, GLRect &rect)
262 {
263 	glUseProgram(mProgramObjectColor);
264 
265 	glColor4f(r, g, b, a );
266 
267 
268 	glVertexAttribPointer ( mPositionLocColor, 3, GL_FLOAT,
269 			false,
270 			3 * 4, rect.vertices);
271 
272 
273 	glEnableVertexAttribArray ( mPositionLocColor );
274 
275 	// Bind the texture
276 	//glDeactiveTexture ( GL_TEXTURE0 );
277 
278 
279 	glUniform4f(mPositionTranslateLocColor,  translateX(x + glTranslateX), translateY(y + glTranslateY), 0, 0);
280 	glUniform4f(mColorLocColor,glColorR,glColorG,glColorB,glColorA);
281 
282 	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
283 
284 	glColor4f(1, 1, 1, 1 );
285 }
286 
287 #else
drawRect(GLfloat r,GLfloat g,GLfloat b,GLfloat a,float x,float y,GLRect & rect)288 void drawRect(GLfloat r,GLfloat g,GLfloat b,GLfloat a, float x, float y, GLRect &rect)
289 {
290 	glDisable(GL_TEXTURE_2D);
291 	glColor4f(r, g, b, a );
292 
293 	glVertexPointer(3, GL_FLOAT, 0, rect.vertices);
294 	glTranslatef(x, -y, 0);
295 	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
296 
297 	glColor4f(1, 1, 1, 1 );
298 	glEnable(GL_TEXTURE_2D);
299 }
300 #endif
301 
302 
303 #ifdef USE_GLES2
drawLines(float x,float y,GLLines & lines)304 void drawLines(float x, float y, GLLines &lines)
305 {
306 	glUseProgram(mProgramObjectColor);
307 
308 	glVertexAttribPointer ( mPositionLocColor, 3, GL_FLOAT,
309 			false,
310 			3 * 4, lines.vertices);
311 
312 
313 
314 	glEnableVertexAttribArray ( mPositionLocColor );
315 
316 	// Bind the texture
317 	glActiveTexture ( GL_TEXTURE0 );
318 	glBindTexture ( GL_TEXTURE_2D, 0 );
319 
320 	glUniform4f(mPositionTranslateLocColor,  translateX(x + glTranslateX), translateY(y + glTranslateY), 0, 0);
321 	glUniform4f(mColorLocColor,glColorR,glColorG,glColorB,glColorA);
322 
323 	glDrawArrays(GL_LINES, 0,  lines.len);
324 }
325 
326 #else
drawLines(float x,float y,GLLines & lines)327 void drawLines(float x, float y, GLLines &lines)
328 {
329 
330 	glDisable(GL_TEXTURE_2D);
331 
332 	glVertexPointer(3, GL_FLOAT, 0, lines.vertices);
333 
334 	glTranslatef(x, -y, 0);
335 
336 	glDrawArrays(GL_LINES, 0, lines.len);
337 
338 	glEnable(GL_TEXTURE_2D);
339 }
340 #endif
341 
342 
343 
344 FILE* file;
345 
png_read(png_structp png_ptr,png_bytep data,png_size_t length)346 void png_read(png_structp png_ptr, png_bytep data, png_size_t length) {
347 	fread(data,1,length,file);
348 }
349 //This need to be set
350 std::string graphicsBasePath;
setGraphicsBasePath(std::string path)351 void setGraphicsBasePath(std::string path)
352 {
353 	graphicsBasePath = path;
354 }
355 
356 //in case same texture is wanted
357 std::map <std::string, GLuint> tc_gl_textures;
358 
359 static int texNumber = 20000;
loadTextureFromPNG(std::string filename,int & width,int & height)360 GLuint loadTextureFromPNG(std::string filename, int &width, int &height)
361 {
362 	LOGTOUCH("loadTextureFromPNG %s", filename.c_str());
363 
364     if (filename == "")
365     {
366         LOGTOUCH("Blank texture name");
367         return -1;
368     }
369 
370 #ifdef USE_GLES2
371 	if (!gles2InitDone)
372 		initGLES2();
373 
374 	gles2InitDone = 1;
375 #endif
376 
377 	//Check if already loaded
378 	std::map<std::string, GLuint>::iterator it = tc_gl_textures.find(filename);
379 	if(it != tc_gl_textures.end())
380 	{
381 	   //element found;
382 	   LOGTOUCH("PNG %s is already loaded", filename.c_str());
383 	   return it->second;
384 	}
385 
386 	std::string full_file = graphicsBasePath + filename + ".png";
387 	file = fopen(full_file.c_str(), "r");
388 	if (!file) {
389 		LOGTOUCH_E("Error opening %s from APK", full_file.c_str());
390 		return TEXTURE_LOAD_ERROR;
391 	}
392 
393 	//header for testing if it is a png
394 	png_byte header[8];
395 
396 	//read the header
397 	fread( header, 1,8,file);
398 
399 	//test if png
400 	int is_png = !png_sig_cmp(header, 0, 8);
401 	if (!is_png) {
402 		fclose(file);
403 		LOGTOUCH_E("Not a png file : %s", full_file.c_str());
404 		return TEXTURE_LOAD_ERROR;
405 	}
406 
407 	//create png struct
408 	png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,
409 			NULL, NULL);
410 	if (!png_ptr) {
411 		fclose(file);
412 		LOGTOUCH_E("Unable to create png struct : %s", full_file.c_str());
413 		return (TEXTURE_LOAD_ERROR);
414 	}
415 
416 	//create png info struct
417 	png_infop info_ptr = png_create_info_struct(png_ptr);
418 	if (!info_ptr) {
419 		png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL);
420 		LOGTOUCH_E("Unable to create png info : %s", full_file.c_str());
421 		fclose(file);
422 		return (TEXTURE_LOAD_ERROR);
423 	}
424 
425 	//create png info struct
426 	png_infop end_info = png_create_info_struct(png_ptr);
427 	if (!end_info) {
428 		png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
429 		LOGTOUCH_E("Unable to create png end info : %s", full_file.c_str());
430 		fclose(file);
431 		return (TEXTURE_LOAD_ERROR);
432 	}
433 
434 	//png error stuff, not sure libpng man suggests this.
435 	if (setjmp(png_jmpbuf(png_ptr))) {
436 		fclose(file);
437 		LOGTOUCH_E("Error during setjmp : %s", full_file.c_str());
438 		png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
439 		return (TEXTURE_LOAD_ERROR);
440 	}
441 
442 	//init png reading
443 	//png_init_io(png_ptr, fp);
444 	png_set_read_fn(png_ptr, NULL, png_read);
445 
446 	//let libpng know you already read the first 8 bytes
447 	png_set_sig_bytes(png_ptr, 8);
448 
449 	// read all the info up to the image data
450 	png_read_info(png_ptr, info_ptr);
451 
452 	//variables to pass to get info
453 	int bit_depth, color_type;
454 	png_uint_32 twidth, theight;
455 
456 	// get info about png
457 	png_get_IHDR(png_ptr, info_ptr, &twidth, &theight, &bit_depth, &color_type,
458 			NULL, NULL, NULL);
459 
460 	//update width and height based on png info
461 	width = twidth;
462 	height = theight;
463 
464 	// Update the png info struct.
465 	png_read_update_info(png_ptr, info_ptr);
466 
467 	// Row size in bytes.
468 	int rowbytes = png_get_rowbytes(png_ptr, info_ptr);
469 
470 	// Allocate the image_data as a big block, to be given to opengl
471 	png_byte *image_data = new png_byte[rowbytes * height];
472 	if (!image_data) {
473 		//clean up memory and close stuff
474 		png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
475 		LOGTOUCH_E("Unable to allocate image_data while loading %s ", full_file.c_str());
476 		fclose(file);
477 		return TEXTURE_LOAD_ERROR;
478 	}
479 
480 	//row_pointers is for pointing to image_data for reading the png with libpng
481 	png_bytep *row_pointers = new png_bytep[height];
482 	if (!row_pointers) {
483 		//clean up memory and close stuff
484 		png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
485 		delete[] image_data;
486 		LOGTOUCH_E("Unable to allocate row_pointer while loading %s ", full_file.c_str());
487 		fclose(file);
488 		return TEXTURE_LOAD_ERROR;
489 	}
490 	// set the individual row_pointers to point at the correct offsets of image_data
491 	for (int i = 0; i < height; ++i)
492 		row_pointers[height - 1 - i] = image_data + i * rowbytes;
493 
494 	//read the png into image_data through row_pointers
495 	png_read_image(png_ptr, row_pointers);
496 
497 	//Now generate the OpenGL texture object
498 	GLuint texture = texNumber++;
499 
500 	glBindTexture(GL_TEXTURE_2D, texture);
501 	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
502 			GL_UNSIGNED_BYTE, (GLvoid*) image_data);
503 
504 	//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
505 	//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
506 
507 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
508 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
509 
510 
511 	//clean up memory and close stuff
512 	png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
513 	delete[] image_data;
514 	delete[] row_pointers;
515 	fclose(file);
516 
517 	//Add to cache
518 	tc_gl_textures[filename] = texture;
519 
520 	return texture;
521 
522 }
523 
524 
525 
526 }
527