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