Log -> SecureLog
[apps/native/sample/QrCodeRecognizer.git] / project / src / Renderer.cpp
1 //
2 // Tizen C++ SDK
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Flora License, Version 1.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.tizenopensource.org/license
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an AS IS BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 #include "Renderer.h"
19
20 #include "CameraTools.h"
21 #include "GLtools.h"
22 #include "Cubes.h"
23
24 using namespace Tizen::Graphics::Opengl;
25
26 Renderer::Renderer()
27 {
28 }
29
30 Renderer::~Renderer()
31 {
32 }
33
34 void
35 Renderer::SetTextureData(int width, int height, void* data)
36 {
37     glBindTexture   (GL_TEXTURE_2D, __textureColorId);
38     glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, width >> 1, height >> 1, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, ((unsigned char*) data) + width * height);
39     glBindTexture   (GL_TEXTURE_2D, __textureId);
40     glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
41 }
42
43 void
44 Renderer::SetModelViewMatrix(int i, const Tizen::Graphics::FloatMatrix4* mat)
45 {
46     if (mat)
47         memcpy(__modelView[i], mat->matrix, 16 * sizeof(float));
48
49     float matrix[16] = {0.f};
50     multiplyMatrix(leftTransform, __modelView[i], matrix);
51     multiplyMatrix(matrix, rightTransform, __modelView[i]);
52 }
53
54 void
55 Renderer::SetCameraAngle(float angle)
56 {
57     __cameraAngle = angle;
58 }
59
60 void
61 Renderer::Init(int width, int height)
62 {
63     GLbyte vShaderStr[] =
64         "attribute vec4 a_Position;           \n"
65         "attribute vec2 a_TexCoord;           \n"
66         "attribute vec3 a_Colour;             \n"
67         "                                     \n"
68         "uniform mat4 u_Mvp;                  \n"
69         "                                     \n"
70         "varying vec2 v_TexCoord;             \n"
71         "varying vec3 v_Colour;               \n"
72         "                                     \n"
73         "void main()                          \n"
74         "{                                    \n"
75         "   gl_Position = u_Mvp * a_Position; \n"
76         "   v_TexCoord  = a_TexCoord;         \n"
77         "   v_Colour    = a_Colour;           \n"
78         "}                                    \n";
79
80     GLbyte fShaderStr[] =
81         "precision mediump float;                                                                             \n"
82         "uniform sampler2D s_Texture;                                                                         \n"
83         "uniform sampler2D s_TextureColor;                                                                    \n"
84         "varying vec2 v_TexCoord;                                                                             \n"
85         "varying vec3 v_Colour;                                                                               \n"
86         "                                                                                                     \n"
87         "void main()                                                                                          \n"
88         "{                                                                                                    \n"
89         "    float y = texture2D(s_Texture, v_TexCoord).r + v_Colour.r;                                       \n"
90         "    float v = texture2D(s_TextureColor, vec2(v_TexCoord.x, v_TexCoord.y) * 0.5).r + v_Colour.b - 0.5;\n"
91         "    float u = texture2D(s_TextureColor, vec2(v_TexCoord.x, v_TexCoord.y + 1.0) * 0.5).a + v_Colour.g - 0.5;\n"
92         "    float r = y + 1.772 * u;                                                                         \n"
93         "    float g = y - 0.34414 * u - 0.71414 * v;                                                         \n"
94         "    float b = y + 1.402 * v;                                                                         \n"
95         "    gl_FragColor = vec4(r, g, b, 1.0);                                                               \n"
96         "}                                                                                                    \n";
97
98     // Load the shaders and get a linked program object
99     __programObject = loadProgram ((char *)vShaderStr, (char *)fShaderStr);
100
101     // Get the attribute locations
102     __positionLoc   = glGetAttribLocation (__programObject, "a_Position");
103     __texCoordLoc   = glGetAttribLocation (__programObject, "a_TexCoord");
104     __colorLoc  = glGetAttribLocation (__programObject, "a_Colour");
105
106     // Get the sampler location
107     __samplerLoc = glGetUniformLocation (__programObject, "s_Texture");
108     __samplerColorLoc = glGetUniformLocation (__programObject, "s_TextureColor");
109     __mvpPLoc    = glGetUniformLocation (__programObject, "u_Mvp");
110
111     // Load the texture
112     __textureId = createSimpleTexture2D (GL_LUMINANCE, width, height);
113     __textureColorId = createSimpleTexture2D (GL_LUMINANCE_ALPHA, width >> 1, height >> 1);
114
115     __mvp2[0]  = 1; __mvp2[1]  = 0; __mvp2[2]  = 0; __mvp2[3]  = 0;
116     __mvp2[4]  = 0; __mvp2[5]  = 1; __mvp2[6]  = 0; __mvp2[7]  = 0;
117     __mvp2[8]  = 0; __mvp2[9]  = 0; __mvp2[10] = 1; __mvp2[11] = 0;
118     __mvp2[12] = 0; __mvp2[13] = 0; __mvp2[14] = 0; __mvp2[15] = 1;
119
120     for(int i = 0; i < CUBE_COUNT; ++i)
121     {
122         memset(__modelView[i], 0, 16 * sizeof(float));
123     }
124
125     float u[] = {0.f, 0.25f, 0.f};
126     float v[] = {0.f, 0.f, 0.25f};
127     for(int j = 0; j < 3; ++j)
128     {
129         for(int i = 0; i < 36; ++i)
130         {
131             colorList[j][i * 3] = aColours[i * 3];
132             colorList[j][i * 3 + 1] = aColours[i * 3 + 1] + u[j];
133             colorList[j][i * 3 + 2] = aColours[i * 3 + 2] + v[j];
134         }
135     }
136 }
137
138 void
139 Renderer::Draw(void)
140 {
141
142 #ifdef PORTRAIT
143     float glScale = (float)GLtools::getHeight() / GLtools::getWidth();
144 #else
145     float glScale = (float)GLtools::getWidth() / GLtools::getHeight();
146 #endif
147     float cScale  = (float)CameraTools::GetWidth() / CameraTools::GetHeight();
148
149     float scaleWidth  = 1.0f;
150     float scaleHeight = 1.0f;
151
152
153
154
155     if (cScale < glScale)
156     {
157         scaleHeight = cScale / glScale;
158     }
159     else
160     {
161         scaleWidth = cScale / glScale;
162     }
163
164
165     float widthShift  = (1.f - scaleWidth) / 2.f;
166     float heightShift = (1.f - scaleHeight) / 2.f ;
167
168
169     GLfloat vVertices[] = {
170 #ifdef PORTRAIT
171              1.0f                   ,  1.0f                     , 0.0f,       // Position 3
172 #else
173             -1.0f                   ,  1.0f                     , 0.0f,       // Position 0
174 #endif
175              0.0f                   ,  heightShift              ,                              // TexCoord 0
176              0.f                    ,  0.0f                     , 0.0f,       // Color
177
178 #ifdef PORTRAIT
179             -1.0f                   ,  1.0f                     , 0.0f,       // Position 0
180 #else
181             -1.0f                   , -1.0f                     , 0.0f,       // Position 1
182 #endif
183              0.0f                   ,  scaleHeight + heightShift,                              // TexCoord 1
184              0.0f                   ,  0.f                      , 0.0f,       // Color
185
186 #ifdef PORTRAIT
187             -1.0f                   , -1.0f                     , 0.0f,       // Position 1
188 #else
189              1.0f                   , -1.0f, 0.0f,                            // Position 2
190 #endif
191              scaleWidth + widthShift,  scaleHeight + heightShift,                               // TexCoord 2
192              0.0f                   ,  0.0f                     , 0.0f,       // Color
193
194 #ifdef PORTRAIT
195              1.0f                   , -1.0f, 0.0f,                            // Position 2
196 #else
197              1.0f                   ,  1.0f                     , 0.0f,       // Position 3
198 #endif
199              scaleWidth + widthShift,  heightShift              ,                              // TexCoord 3
200              0.0f                   ,  0.0f                     , 0.0f        // Color
201     };
202
203
204
205     GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
206
207     perspectiveMatrix   (__cameraAngle, (double)GLtools::getWidth()/(double)GLtools::getHeight(), 0.01, 100.0, __perspectiveMatrix);
208
209     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
210
211     glUseProgram                (__programObject);
212
213     glVertexAttribPointer       (__positionLoc, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), vVertices);
214     glVertexAttribPointer       (__texCoordLoc, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), &vVertices[3]);
215     glVertexAttribPointer       (__colorLoc, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), &vVertices[5]);
216
217     glEnableVertexAttribArray   (__positionLoc);
218     glEnableVertexAttribArray   (__texCoordLoc);
219     glEnableVertexAttribArray   (__colorLoc);
220
221     glUniformMatrix4fv          (__mvpPLoc, 1, GL_FALSE, __mvp2);     // GL_CHECK
222
223     glActiveTexture             (GL_TEXTURE1);
224     glBindTexture               (GL_TEXTURE_2D, __textureColorId);
225     glUniform1i                 (__samplerColorLoc, 1);
226
227     glActiveTexture             (GL_TEXTURE0);
228     glBindTexture               (GL_TEXTURE_2D, __textureId);
229     glUniform1i                 (__samplerLoc, 0);
230
231     glDisable                    (GL_DEPTH_TEST);
232     glDrawElements              (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
233
234     glVertexAttribPointer       (__positionLoc, 3, GL_FLOAT, GL_FALSE, 0, aVertices);
235     glVertexAttribPointer       (__texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, aTexCoords);
236
237     glEnable                    (GL_CULL_FACE);
238     glEnable                    (GL_DEPTH_TEST);
239
240     glActiveTexture             (GL_TEXTURE1);
241     glBindTexture               (GL_TEXTURE_2D, 0);
242     glActiveTexture             (GL_TEXTURE0);
243     glBindTexture               (GL_TEXTURE_2D, 0);
244
245     float mvp[16];
246     for(int i = 0; i < CUBE_COUNT; ++i)
247     {
248         multiplyMatrix(__perspectiveMatrix, __modelView[i], mvp);
249         glUniformMatrix4fv          (__mvpPLoc, 1, GL_FALSE, mvp);        // GL_CHECK
250         glVertexAttribPointer       (__colorLoc, 3, GL_FLOAT, GL_FALSE, 0, colorList[i % 3]);
251         glDrawArrays                (GL_TRIANGLES, 0, 36);
252     }
253 }
254
255 GLuint
256 Renderer::loadShader(GLenum type, const char *shaderSrc)
257 {
258     GLuint shader;
259     GLint compiled;
260
261     shader = glCreateShader (type);
262
263     if (shader == 0)
264     {
265         return 0;
266     }
267
268     // Load the shader source
269     glShaderSource (shader, 1, &shaderSrc, NULL);
270
271     // Compile the shader
272     glCompileShader (shader);
273
274     // Check the compile status
275     glGetShaderiv (shader, GL_COMPILE_STATUS, &compiled);
276
277     if (!compiled)
278     {
279         GLint infoLen = 0;
280
281         glGetShaderiv (shader, GL_INFO_LOG_LENGTH, &infoLen);
282
283         if (infoLen > 1)
284         {
285             char* infoLog = (char*)malloc (sizeof(char) * infoLen);
286
287             glGetShaderInfoLog (shader, infoLen, NULL, infoLog);
288             AppSecureLogExceptionTag ("QrCodeRecognizer", "Error compiling shader:\n%s\n", infoLog);
289
290             free (infoLog);
291         }
292
293         glDeleteShader (shader);
294         return 0;
295     }
296
297     return shader;
298
299 }
300
301 GLuint
302 Renderer::loadProgram(const char *vertShaderSrc, const char *fragShaderSrc)
303 {
304     GLuint vertexShader;
305     GLuint fragmentShader;
306     GLuint programObject;
307     GLint linked;
308
309     // Load the vertex/fragment shaders
310     vertexShader = loadShader (GL_VERTEX_SHADER, vertShaderSrc);
311     if (vertexShader == 0)
312     {
313         return 0;
314     }
315
316     fragmentShader = loadShader (GL_FRAGMENT_SHADER, fragShaderSrc);
317     if (fragmentShader == 0)
318     {
319         glDeleteShader(vertexShader);
320         return 0;
321     }
322
323     // Create the program object
324     programObject = glCreateProgram ();
325
326     if (programObject == 0)
327     {
328         return 0;
329     }
330
331     glAttachShader (programObject, vertexShader);
332     glAttachShader (programObject, fragmentShader);
333
334     // Link the program
335     glLinkProgram (programObject);
336
337     // Check the link status
338     glGetProgramiv (programObject, GL_LINK_STATUS, &linked);
339
340     if (!linked)
341     {
342         GLint infoLen = 0;
343
344         glGetProgramiv (programObject, GL_INFO_LOG_LENGTH, &infoLen);
345
346         if (infoLen > 1)
347         {
348             char* infoLog = (char*)malloc (sizeof(char) * infoLen);
349
350             glGetProgramInfoLog (programObject, infoLen, NULL, infoLog);
351             AppSecureLogExceptionTag("ImageRecognizer", "Error linking program: %s", infoLog);
352
353             free (infoLog);
354         }
355
356         glDeleteProgram (programObject);
357         return 0;
358     }
359
360     // Free up no longer needed shader resources
361     glDeleteShader (vertexShader);
362     glDeleteShader (fragmentShader);
363
364     return programObject;
365 }
366
367 GLuint
368 Renderer::createSimpleTexture2D(GLenum type, int width, int height)
369 {
370     // Create a simple 2x2 texture image with four different colors
371     // Texture object handle
372     GLuint textureId;
373
374     GLubyte* pixels = new GLubyte[width * height * 4];
375
376     // Generate a texture object
377     glGenTextures (1, &textureId);
378
379     // Bind the texture object
380     glBindTexture (GL_TEXTURE_2D, textureId);
381
382     // Load the texture
383     glTexImage2D (GL_TEXTURE_2D, 0, type, width, height, 0, type, GL_UNSIGNED_BYTE, pixels);
384
385     // Set the filtering mode
386     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
387     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
388
389     delete[] pixels;
390
391     return textureId;
392 }
393
394 void
395 Renderer::rotateMatrix(double angle, double x, double y, double z, float *R)
396 {
397     double radians, c, s, c1, u[3], length;
398     int i, j;
399
400     radians = (angle * M_PI) / 180.0;
401
402     c = cos(radians);
403     s = sin(radians);
404
405     c1 = 1.0 - cos(radians);
406
407     length = sqrt(x * x + y * y + z * z);
408
409     u[0] = x / length;
410     u[1] = y / length;
411     u[2] = z / length;
412
413     for (i = 0; i < 16; i++)
414     {
415         R[i] = 0.0;
416     }
417
418     R[15] = 1.0;
419
420     for (i = 0; i < 3; i++)
421     {
422         R[i * 4 + (i + 1) % 3] = float(u[(i + 2) % 3] * s);
423         R[i * 4 + (i + 2) % 3] = float(-u[(i + 1) % 3] * s);
424     }
425
426     for (i = 0; i < 3; i++)
427     {
428         for (j = 0; j < 3; j++)
429         {
430             R[i * 4 + j] += float(c1 * u[i] * u[j] + (i == j ? c : 0.0));
431         }
432     }
433 }
434
435 void
436 Renderer::perspectiveMatrix(double fovy, double aspect, double znear, double zfar, float *P)
437 {
438     int i;
439     double f;
440
441     f = 1.0/tan(fovy * 0.5);
442
443     for (i = 0; i < 16; i++)
444     {
445         P[i] = 0.0f;
446     }
447
448 #ifdef PORTRAIT
449     P[0]  = float(f / aspect);
450     P[5]  = float(f);
451 #else
452     P[0]  = float(f);
453     P[5]  = float(f * aspect);
454 #endif
455
456     P[10] = float((znear + zfar) / (znear - zfar));
457     P[11] = -1.0f;
458     P[14] = float((2.0 * znear * zfar) / (znear - zfar));
459     P[15] = 0.0f;
460 }
461
462 void
463 Renderer::multiplyMatrix(const float *A, const float *B, float *C)
464 {
465     int i, j, k;
466     float aTmp[16];
467
468     for (i = 0; i < 4; i++)
469     {
470         for (j = 0; j < 4; j++)
471         {
472             aTmp[j * 4 + i] = 0.0f;
473
474             for (k = 0; k < 4; k++)
475             {
476                 aTmp[j * 4 + i] += A[k * 4 + i] * B[j * 4 + k];
477             }
478         }
479     }
480
481     for (i = 0; i < 16; i++)
482     {
483         C[i] = aTmp[i];
484     }
485 }