Logo
  • Main Page
  • Related Pages
  • Modules
  • Classes
  • Files

mmsfbgl.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2005-2007 Stefan Schwarzer, Jens Schneider,             *
00003  *                           Matthias Hardt, Guido Madaus                  *
00004  *                                                                         *
00005  *   Copyright (C) 2007-2008 BerLinux Solutions GbR                        *
00006  *                           Stefan Schwarzer & Guido Madaus               *
00007  *                                                                         *
00008  *   Copyright (C) 2009-2013 BerLinux Solutions GmbH                       *
00009  *                                                                         *
00010  *   Authors:                                                              *
00011  *      Stefan Schwarzer   <stefan.schwarzer@diskohq.org>,                 *
00012  *      Matthias Hardt     <matthias.hardt@diskohq.org>,                   *
00013  *      Jens Schneider     <jens.schneider@diskohq.org>,                   *
00014  *      Guido Madaus       <guido.madaus@diskohq.org>,                     *
00015  *      Patrick Helterhoff <patrick.helterhoff@diskohq.org>,               *
00016  *      René Bählkow       <rene.baehlkow@diskohq.org>                     *
00017  *                                                                         *
00018  *   This library is free software; you can redistribute it and/or         *
00019  *   modify it under the terms of the GNU Lesser General Public            *
00020  *   License version 2.1 as published by the Free Software Foundation.     *
00021  *                                                                         *
00022  *   This library is distributed in the hope that it will be useful,       *
00023  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00024  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00025  *   Lesser General Public License for more details.                       *
00026  *                                                                         *
00027  *   You should have received a copy of the GNU Lesser General Public      *
00028  *   License along with this library; if not, write to the                 *
00029  *   Free Software Foundation, Inc.,                                       *
00030  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
00031  **************************************************************************/
00032 
00033 #include "mmsgui/fb/mmsfbgl.h"
00034 #include "mmsgui/fb/mmsfb.h"
00035 #include <stdio.h>
00036 #include <math.h>
00037 #include <stdlib.h>
00038 
00039 #ifdef __HAVE_OPENGL__
00040 
00041 #define INITCHECK if (!this->initialized) return false;
00042 
00043 #define GET_ATTR(name,str) \
00044     eglGetConfigAttrib(eglDisplay, eglConfig[i], name, &value); \
00045     printf("  %s = %x\n", str, value);
00046 
00047 
00048 #define OGL_CALC_COORD_MIDDLE(v1, v2) (((v1)<=(v2)) ? (float)(v1) + 0.49f : (float)(v1) + 0.51f)
00049 
00050 #define OGL_CALC_COORD_F(v1, v2) (((v1)<(v2)) ? (float)(v1) : ((v1)>(v2)) ? (float)(v1) + 0.99f : (float)(v1))
00051 #define OGL_CALC_COORD_S(v1, v2) (((v1)<(v2)) ? (float)(v1) : ((v1)>(v2)) ? (float)(v1) + 0.99f : (float)(v1) + 0.99f)
00052 
00053 #define OGL_CALC_TEXCOORD_F(v1, v2, size)   (((v1)>(v2)&&(v1==size)) ? 1.0f : OGL_CALC_COORD_F(v1, v2) / (size))
00054 #define OGL_CALC_TEXCOORD_S(v1, v2, size)   (((v1)>(v2)&&(v1==size)) ? 1.0f : OGL_CALC_COORD_S(v1, v2) / (size))
00055 
00056 
00057 MMSFBGL::MMSFBGL() {
00058     // init vars...
00059     this->initialized = false;
00060     this->VSMatrixLoc_initialized = false;
00061     this->FSColorLoc_initialized = false;
00062     this->FSTextureLoc_initialized = false;
00063     this->VSTexCoordLoc_initialized = false;
00064 
00065     // default framebuffer object is always 0, so set bound_fbo to 0
00066     this->bound_fbo = 0;
00067 
00068     // no vertex/index buffer object is currently bound
00069     this->bound_vbo = 0;
00070     this->bound_ibo = 0;
00071 
00072     this->useKMS = false;
00073 
00074 #ifdef __HAVE_KMS__
00075     this->drm = NULL;
00076     this->drm_fb = NULL;
00077 #endif
00078 
00079 }
00080 
00081 MMSFBGL::~MMSFBGL() {
00082     terminate();
00083 }
00084 
00085 
00086 //////////////////////////////
00087 
00088 //#define ERROR_CHECK_EXIT
00089 //#define ERROR_CHECK_RETURN
00090 #define ERROR_CHECK_PRINT
00091 
00092 #ifdef ERROR_CHECK_EXIT
00093 #define ERROR_CHECK_VOID(where) if (!getError(where, __LINE__)) exit(1);
00094 #define ERROR_CHECK_BOOL(where) if (!getError(where, __LINE__)) exit(1);
00095 #endif
00096 
00097 #ifdef ERROR_CHECK_RETURN
00098 #define ERROR_CHECK_VOID(where) if (!getError(where, __LINE__)) return;
00099 #define ERROR_CHECK_BOOL(where) if (!getError(where, __LINE__)) return false;
00100 #endif
00101 
00102 #ifdef ERROR_CHECK_PRINT
00103 #define ERROR_CHECK_VOID(where) getError(where, __LINE__);
00104 #define ERROR_CHECK_BOOL(where) getError(where, __LINE__);
00105 #endif
00106 
00107 #ifndef ERROR_CHECK_VOID
00108 #define ERROR_CHECK_VOID(where)
00109 #endif
00110 
00111 #ifndef ERROR_CHECK_BOOL
00112 #define ERROR_CHECK_BOOL(where)
00113 #endif
00114 
00115 //////////////////////////////
00116 
00117 void MMSFBGL::printImplementationInformation() {
00118     GLint int_params[32];
00119 
00120     printf("\nOpenGL Implementation Information:\n");
00121     printf("----------------------------------------------------------------------\n");
00122     printf("Vendor..............................: %s\n", glGetString(GL_VENDOR));
00123     printf("Renderer............................: %s\n", glGetString(GL_RENDERER));
00124     printf("Version.............................: %s\n", glGetString(GL_VERSION));
00125     printf("Version of Shading Language.........: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
00126     glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, int_params);
00127     printf("GL_NUM_COMPRESSED_TEXTURE_FORMATS...: %d\n", int_params[0]);
00128     glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, int_params);
00129     printf("GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS.: %d\n", int_params[0]);
00130     glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, int_params);
00131     printf("GL_MAX_CUBE_MAP_TEXTURE_SIZE........: %d\n", int_params[0]);
00132     glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, int_params);
00133     printf("GL_MAX_TEXTURE_IMAGE_UNITS..........: %d\n", int_params[0]);
00134     glGetIntegerv(GL_MAX_TEXTURE_SIZE, int_params);
00135     printf("GL_MAX_TEXTURE_SIZE.................: %d\n", int_params[0]);
00136     glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, int_params);
00137     printf("GL_MAX_VERTEX_ATTRIBS...............: %d\n", int_params[0]);
00138     glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, int_params);
00139     printf("GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS...: %d\n", int_params[0]);
00140     glGetIntegerv(GL_MAX_VIEWPORT_DIMS, int_params);
00141     printf("GL_MAX_VIEWPORT_DIMS................: %dx%d\n", int_params[0], int_params[1]);
00142 
00143     // prepare extension string and print it
00144     printf("Extensions..........................: ");
00145     unsigned int linelen = 38;
00146     char buffer[32768];
00147     char *bufptr = buffer;
00148     char *extstr = (char*)glGetString(GL_EXTENSIONS);
00149     while (*extstr) {
00150         // get next value
00151         char *start = extstr;
00152         while (*extstr && *extstr != ' ') extstr++;
00153         unsigned int vlen = extstr - start;
00154         while (*extstr == ' ') extstr++;
00155 
00156         if (bufptr != buffer) {
00157             if (linelen + vlen + 2 < 79) {
00158                 memcpy(bufptr, ", ", 2);
00159                 bufptr+= 2;
00160                 linelen+= 2;
00161             }
00162             else {
00163                 memcpy(bufptr, ",\n", 2);
00164                 bufptr+= 2;
00165                 linelen = 0;
00166             }
00167         }
00168 
00169         memcpy(bufptr, start, vlen);
00170         bufptr+= vlen;
00171         linelen+= vlen;
00172     }
00173     *bufptr = 0;
00174     printf(buffer);
00175     printf("\n");
00176     printf("----------------------------------------------------------------------\n\n");
00177 }
00178 
00179 bool MMSFBGL::getError(const char* where, int line) {
00180 #ifdef __HAVE_OPENGL__
00181     int err = glGetError();
00182     if (err != GL_NO_ERROR) {
00183         // try to get description
00184         const char *desc = "unknown";
00185         switch (err) {
00186         case GL_INVALID_ENUM:
00187             desc = "GL_INVALID_ENUM";
00188             break;
00189         case GL_INVALID_VALUE:
00190             desc = "GL_INVALID_VALUE";
00191             break;
00192         case GL_INVALID_OPERATION:
00193             desc = "GL_INVALID_OPERATION";
00194             break;
00195         case GL_OUT_OF_MEMORY:
00196             desc = "GL_OUT_OF_MEMORY";
00197             break;
00198 #ifdef GL_STACK_OVERFLOW
00199         case GL_STACK_OVERFLOW:
00200             desc = "GL_STACK_OVERFLOW";
00201             break;
00202 #endif
00203 #ifdef GL_STACK_UNDERFLOW
00204         case GL_STACK_UNDERFLOW:
00205             desc = "GL_STACK_UNDERFLOW";
00206             break;
00207 #endif
00208 #ifdef GL_TABLE_TOO_LARGE
00209         case GL_TABLE_TOO_LARGE:
00210             desc = "GL_TABLE_TOO_LARGE";
00211             break;
00212 #endif
00213 #ifdef GL_INVALID_FRAMEBUFFER_OPERATION
00214         case GL_INVALID_FRAMEBUFFER_OPERATION:
00215             desc = "GL_INVALID_FRAMEBUFFER_OPERATION";
00216             break;
00217 #endif
00218         }
00219 
00220         // print error to stdout
00221         printf("MMSFBGL: ERR 0x%x (%s) AT LINE %d, %s\n", err, desc, line, where);
00222         return false;
00223     }
00224 #endif
00225 
00226 #ifdef __HAVE_EGL__
00227     EGLint iErr = eglGetError();
00228     if (iErr != EGL_SUCCESS) {
00229         printf("MMSFBGL: ERR 0x%x AT LINE %d, %s\n", iErr, line, where);
00230         return false;
00231     }
00232 #endif
00233 
00234     return true;
00235 }
00236 
00237 
00238 bool MMSFBGL::buildShader(MMSFBGL_SHADER_TYPE shader_type, const char *shader_code, GLuint *shader) {
00239 
00240 #ifdef __HAVE_GLES2__
00241 
00242     // create the shader object
00243     *shader = glCreateShader((shader_type==MMSFBGL_SHADER_TYPE_FRAGMENT_SHADER)?GL_FRAGMENT_SHADER:GL_VERTEX_SHADER);
00244     ERROR_CHECK_BOOL("glCreateShader()");
00245 
00246     // load the source code into it
00247     glShaderSource(*shader, 1, (const char**)&shader_code, NULL);
00248     ERROR_CHECK_BOOL("glShaderSource()");
00249 
00250     // compile the source code
00251     glCompileShader(*shader);
00252     ERROR_CHECK_BOOL("glCompileShader()");
00253 
00254     // check if compilation succeeded
00255     GLint compiled;
00256     glGetShaderiv(*shader, GL_COMPILE_STATUS, &compiled);
00257     ERROR_CHECK_BOOL("glGetShaderiv()");
00258 
00259     if (!compiled) {
00260         // an error happened, first retrieve the length of the log message
00261         int i32InfoLogLength, i32CharsWritten;
00262         glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &i32InfoLogLength);
00263         ERROR_CHECK_BOOL("glGetShaderiv()");
00264 
00265         // allocate enough space for the message and retrieve it
00266         char* pszInfoLog = new char[i32InfoLogLength];
00267         glGetShaderInfoLog(*shader, i32InfoLogLength, &i32CharsWritten, pszInfoLog);
00268         ERROR_CHECK_BOOL("glGetShaderInfoLog()");
00269 
00270         // displays the error
00271         printf("Failed to compile %s shader: %s\n",
00272                 (shader_type==MMSFBGL_SHADER_TYPE_FRAGMENT_SHADER)?"fragment":"vertex",
00273                 pszInfoLog);
00274 
00275         // freeing memory
00276         delete [] pszInfoLog;
00277         glDeleteShader(*shader);
00278         ERROR_CHECK_BOOL("glDeleteShader()");
00279         *shader = 0;
00280         return false;
00281     }
00282 
00283     return true;
00284 
00285 #else
00286 
00287     return false;
00288 
00289 #endif
00290 }
00291 
00292 bool MMSFBGL::linkProgram(GLuint fragment_shader, GLuint vertex_shader, GLuint *program) {
00293 
00294 #ifdef __HAVE_GLES2__
00295 
00296     // create the shader program
00297     *program = glCreateProgram();
00298     ERROR_CHECK_BOOL("glCreateProgram()");
00299 
00300     // attach the fragment and vertex shaders to it
00301     glAttachShader(*program, fragment_shader);
00302     ERROR_CHECK_BOOL("glAttachShader(*program, fragment_shader)");
00303     glAttachShader(*program, vertex_shader);
00304     ERROR_CHECK_BOOL("glAttachShader(*program, vertex_shader)");
00305 
00306     // bind the vertex attribute to specified location
00307     glBindAttribLocation(*program, MMSFBGL_VSV_LOC, "VSVertex");
00308     ERROR_CHECK_BOOL("glBindAttribLocation(*program, MMSFBGL_VSV_LOC, \"VSVertex\")");
00309 
00310     // link the program
00311     glLinkProgram(*program);
00312     ERROR_CHECK_BOOL("glLinkProgram()");
00313 
00314     // check if linking succeeded in the same way we checked for compilation success
00315     GLint linked;
00316     glGetProgramiv(*program, GL_LINK_STATUS, &linked);
00317     ERROR_CHECK_BOOL("glGetProgramiv()");
00318 
00319     if (!linked) {
00320         // an error happened, first retrieve the length of the log message
00321         int ui32InfoLogLength, ui32CharsWritten;
00322         glGetProgramiv(*program, GL_INFO_LOG_LENGTH, &ui32InfoLogLength);
00323         ERROR_CHECK_BOOL("glGetProgramiv()");
00324 
00325         // allocate enough space for the message and retrieve it
00326         char* pszInfoLog = new char[ui32InfoLogLength];
00327         glGetProgramInfoLog(*program, ui32InfoLogLength, &ui32CharsWritten, pszInfoLog);
00328         ERROR_CHECK_BOOL("glGetProgramInfoLog()");
00329 
00330         // displays the error
00331         printf("Failed to link program: %s\n", pszInfoLog);
00332 
00333         // freeing memory
00334         delete [] pszInfoLog;
00335         glDeleteProgram(*program);
00336         ERROR_CHECK_BOOL("glDeleteProgram()");
00337         *program = 0;
00338         return false;
00339     }
00340 
00341     return true;
00342 
00343 #else
00344 
00345     return false;
00346 
00347 #endif
00348 }
00349 
00350 bool MMSFBGL::buildShaderProgram(const char *fragment_shader_code, const char *vertex_shader_code, GLuint *program) {
00351 
00352 #ifdef __HAVE_GLES2__
00353 
00354     // create new fragment and vertex shader and attach it to a program
00355     GLuint fshader;
00356     GLuint vshader;
00357 
00358     if (buildShader(MMSFBGL_SHADER_TYPE_FRAGMENT_SHADER, fragment_shader_code, &fshader)) {
00359         if (buildShader(MMSFBGL_SHADER_TYPE_VERTEX_SHADER, vertex_shader_code, &vshader)) {
00360             if (linkProgram(fshader, vshader, program)) {
00361                 glDeleteShader(fshader);
00362                 ERROR_CHECK_BOOL("glDeleteShader(fshader)");
00363                 glDeleteShader(vshader);
00364                 ERROR_CHECK_BOOL("glDeleteShader(vshader)");
00365                 return true;
00366             }
00367             else {
00368                 glDeleteShader(fshader);
00369                 ERROR_CHECK_BOOL("glDeleteShader(fshader)");
00370                 glDeleteShader(vshader);
00371                 ERROR_CHECK_BOOL("glDeleteShader(vshader)");
00372             }
00373         }
00374         else {
00375             glDeleteShader(fshader);
00376             ERROR_CHECK_BOOL("glDeleteShader(fshader)");
00377         }
00378     }
00379 
00380 #endif
00381 
00382     return false;
00383 }
00384 
00385 bool MMSFBGL::buildShaderProgram4Drawing(GLuint *program) {
00386     // fragment and vertex shaders code
00387     const char* fragment_shader =
00388         "uniform mediump vec4 FSColor;  \n"
00389         "void main (void)               \n"
00390         "{                              \n"
00391         "   gl_FragColor = FSColor;     \n"
00392         "}                              \n";
00393 
00394     const char* vertex_shader =
00395         "attribute highp vec4   VSVertex;       \n"
00396         "uniform mediump mat4   VSMatrix;       \n"
00397         "void main(void)                        \n"
00398         "{                                      \n"
00399         "   gl_Position = VSMatrix * VSVertex;  \n"
00400         "}                                      \n";
00401 
00402     return buildShaderProgram(fragment_shader, vertex_shader, program);
00403 }
00404 
00405 bool MMSFBGL::buildShaderProgram4Blitting(GLuint *program) {
00406     // fragment and vertex shaders code
00407     const char* fragment_shader =
00408         "precision mediump float;                               \n"
00409         "varying vec2 v_texCoord;                               \n"
00410         "uniform sampler2D FSTexture;                           \n"
00411         "void main()                                            \n"
00412         "{                                                      \n"
00413         "   gl_FragColor = texture2D(FSTexture, v_texCoord);    \n"
00414         "}                                                      \n";
00415 
00416     const char* vertex_shader =
00417         "attribute vec4 VSVertex;               \n"
00418         "attribute vec2 VSTexCoord;             \n"
00419         "varying vec2 v_texCoord;               \n"
00420         "uniform mediump mat4 VSMatrix;         \n"
00421         "void main()                            \n"
00422         "{                                      \n"
00423         "   gl_Position = VSMatrix * VSVertex;  \n"
00424         "   v_texCoord = VSTexCoord;            \n"
00425         "}                                      \n";
00426 
00427     return buildShaderProgram(fragment_shader, vertex_shader, program);
00428 }
00429 
00430 
00431 bool MMSFBGL::buildShaderProgram4ModulateBlitting(GLuint *program) {
00432     // fragment and vertex shaders code
00433     const char* fragment_shader =
00434         "precision mediump float;                                       \n"
00435         "varying vec2 v_texCoord;                                       \n"
00436         "uniform sampler2D FSTexture;                                   \n"
00437         "uniform mediump vec4 FSColor;                                  \n"
00438         "void main()                                                    \n"
00439         "{                                                              \n"
00440         "   gl_FragColor = FSColor * texture2D(FSTexture, v_texCoord);  \n"
00441         "}                                                              \n";
00442 
00443     const char* vertex_shader =
00444         "attribute vec4 VSVertex;               \n"
00445         "attribute vec2 VSTexCoord;             \n"
00446         "varying vec2 v_texCoord;               \n"
00447         "uniform mediump mat4 VSMatrix;         \n"
00448         "void main()                            \n"
00449         "{                                      \n"
00450         "   gl_Position = VSMatrix * VSVertex;  \n"
00451         "   v_texCoord = VSTexCoord;            \n"
00452         "}                                      \n";
00453 
00454     return buildShaderProgram(fragment_shader, vertex_shader, program);
00455 }
00456 
00457 
00458 bool MMSFBGL::buildShaderProgram4BlittingFromAlpha(GLuint *program) {
00459     // fragment and vertex shaders code
00460     const char* fragment_shader =
00461         "precision mediump float;                                               \n"
00462         "varying vec2 v_texCoord;                                               \n"
00463         "uniform sampler2D FSTexture;                                           \n"
00464         "uniform mediump vec4 FSColor;                                          \n"
00465         "void main()                                                            \n"
00466         "{                                                                      \n"
00467         "   vec4 baseColor = texture2D(FSTexture, v_texCoord);                  \n"
00468         "   gl_FragColor = vec4(FSColor.r, FSColor.g, FSColor.b, baseColor.a);  \n"
00469         "}                                                                      \n";
00470 
00471     const char* vertex_shader =
00472         "attribute vec4 VSVertex;               \n"
00473         "attribute vec2 VSTexCoord;             \n"
00474         "varying vec2 v_texCoord;               \n"
00475         "uniform mediump mat4 VSMatrix;         \n"
00476         "void main()                            \n"
00477         "{                                      \n"
00478         "   gl_Position = VSMatrix * VSVertex;  \n"
00479         "   v_texCoord = VSTexCoord;            \n"
00480         "}                                      \n";
00481 
00482     return buildShaderProgram(fragment_shader, vertex_shader, program);
00483 }
00484 
00485 
00486 bool MMSFBGL::buildShaderProgram4ModulateBlittingFromAlpha(GLuint *program) {
00487     // fragment and vertex shaders code
00488     const char* fragment_shader =
00489         "precision mediump float;                                                           \n"
00490         "varying vec2 v_texCoord;                                                           \n"
00491         "uniform sampler2D FSTexture;                                                       \n"
00492         "uniform mediump vec4 FSColor;                                                      \n"
00493         "void main()                                                                        \n"
00494         "{                                                                                  \n"
00495         "   vec4 baseColor = texture2D(FSTexture, v_texCoord);                              \n"
00496         "   gl_FragColor = vec4(FSColor.r, FSColor.g, FSColor.b, FSColor.a * baseColor.a);  \n"
00497         "}                                                                                  \n";
00498 
00499     const char* vertex_shader =
00500         "attribute vec4 VSVertex;               \n"
00501         "attribute vec2 VSTexCoord;             \n"
00502         "varying vec2 v_texCoord;               \n"
00503         "uniform mediump mat4 VSMatrix;         \n"
00504         "void main()                            \n"
00505         "{                                      \n"
00506         "   gl_Position = VSMatrix * VSVertex;  \n"
00507         "   v_texCoord = VSTexCoord;            \n"
00508         "}                                      \n";
00509 
00510     return buildShaderProgram(fragment_shader, vertex_shader, program);
00511 }
00512 
00513 
00514 bool MMSFBGL::initShaders() {
00515 
00516 #ifdef __HAVE_GLES2__
00517 
00518     printf("initializing shaders...\n");
00519 
00520     // current program object not set
00521     this->po_current = 0;
00522 
00523     // build all available shaders...
00524     buildShaderProgram4Drawing(&this->po_draw);
00525     buildShaderProgram4Blitting(&this->po_blit);
00526     buildShaderProgram4ModulateBlitting(&this->po_modulateblit);
00527     buildShaderProgram4BlittingFromAlpha(&this->po_blit_fromalpha);
00528     buildShaderProgram4ModulateBlittingFromAlpha(&this->po_modulateblit_fromalpha);
00529 
00530     return true;
00531 
00532 #else
00533 
00534     return false;
00535 
00536 #endif
00537 }
00538 
00539 void MMSFBGL::deleteShaders() {
00540 
00541 #ifdef __HAVE_GLES2__
00542 
00543     if (this->po_draw) {
00544         glDeleteProgram(this->po_draw);
00545         ERROR_CHECK_VOID("glDeleteProgram(this->po_draw)");
00546         this->po_draw = 0;
00547     }
00548 
00549     if (this->po_blit) {
00550         glDeleteProgram(this->po_blit);
00551         ERROR_CHECK_VOID("glDeleteProgram(this->po_blit)");
00552         this->po_blit = 0;
00553     }
00554 
00555     if (this->po_modulateblit) {
00556         glDeleteProgram(this->po_modulateblit);
00557         ERROR_CHECK_VOID("glDeleteProgram(this->po_modulateblit)");
00558         this->po_modulateblit = 0;
00559     }
00560 
00561     if (this->po_blit_fromalpha) {
00562         glDeleteProgram(this->po_blit_fromalpha);
00563         ERROR_CHECK_VOID("glDeleteProgram(this->po_blit_fromalpha)");
00564         this->po_blit_fromalpha = 0;
00565     }
00566 
00567     if (this->po_modulateblit_fromalpha) {
00568         glDeleteProgram(this->po_modulateblit_fromalpha);
00569         ERROR_CHECK_VOID("glDeleteProgram(this->po_modulateblit_fromalpha)");
00570         this->po_modulateblit_fromalpha = 0;
00571     }
00572 
00573     this->po_current = 0;
00574 
00575 #endif
00576 }
00577 
00578 #ifdef __HAVE_XLIB__
00579 bool MMSFBGL::init(Display *x_display, int x_screen, Window x_window, int w, int h) {
00580 
00581     if (this->initialized) {
00582         // already initialized
00583         return false;
00584     }
00585 
00586 #ifdef __HAVE_EGL__
00587     //TODO: implement EGL for XLIB
00588     printf("\nInitializing EGL:\n");
00589     printf("----------------------------------------------------------------------\n");
00590 
00591     this->x_display = x_display;
00592     this->x_window = x_window;
00593 
00594     eglDisplay = eglGetDisplay((EGLNativeDisplayType) x_display);
00595 
00596     if (eglDisplay == EGL_NO_DISPLAY) {
00597         printf("Error: eglGetDisplay() returned EGL_NO_DISPLAY.\n");
00598         terminate();
00599         return false;
00600     }
00601 
00602     /*
00603         Step 2 - Initialize EGL.
00604         EGL has to be initialized with the display obtained in the
00605         previous step. We cannot use other EGL functions except
00606         eglGetDisplay and eglGetError before eglInitialize has been
00607         called.
00608         If we're not interested in the EGL version number we can just
00609         pass NULL for the second and third parameters.
00610     */
00611     EGLint iMajorVersion, iMinorVersion;
00612     if (!eglInitialize(eglDisplay, &iMajorVersion, &iMinorVersion))
00613     {
00614         printf("Error: eglInitialize() failed.\n");
00615         terminate();
00616         return false;
00617     }
00618 
00619     /*
00620         Step 3 - Make OpenGL ES the current API.
00621         EGL provides ways to set up OpenGL ES and OpenVG contexts
00622         (and possibly other graphics APIs in the future), so we need
00623         to specify the "current API".
00624     */
00625     eglBindAPI(EGL_OPENGL_ES_API);
00626 
00627     if (eglGetError() != EGL_SUCCESS)
00628     if (!getError("eglBindAPI"))
00629     {
00630         terminate();
00631         return false;
00632     }
00633 
00634     /*
00635         Step 4 - Specify the required configuration attributes.
00636         An EGL "configuration" describes the pixel format and type of
00637         surfaces that can be used for drawing.
00638         For now we just want to use a 16 bit RGB surface that is a
00639         Window surface, i.e. it will be visible on screen. The list
00640         has to contain key/value pairs, terminated with EGL_NONE.
00641      */
00642 
00643     EGLint pi32ConfigAttribs[11];
00644     pi32ConfigAttribs[0] = EGL_SURFACE_TYPE;
00645     pi32ConfigAttribs[1] = EGL_WINDOW_BIT;
00646     pi32ConfigAttribs[2] = EGL_RENDERABLE_TYPE;
00647     pi32ConfigAttribs[3] = EGL_OPENGL_ES2_BIT;
00648     pi32ConfigAttribs[4] = EGL_RED_SIZE;
00649     pi32ConfigAttribs[5] = 8;
00650     pi32ConfigAttribs[6] = EGL_GREEN_SIZE;
00651     pi32ConfigAttribs[7] = 8;
00652     pi32ConfigAttribs[8] = EGL_BLUE_SIZE;
00653     pi32ConfigAttribs[9] = 8;
00654     pi32ConfigAttribs[10] = EGL_NONE;
00655 
00656 
00657     /*
00658         Step 5 - Find a config that matches all requirements.
00659         eglChooseConfig provides a list of all available configurations
00660         that meet or exceed the requirements given as the second
00661         argument. In most cases we just want the first config that meets
00662         all criteria, so we can limit the number of configs returned to 1.
00663     */
00664     int iConfigs;
00665     int config_size=10;
00666 
00667     if (!eglChooseConfig(eglDisplay, pi32ConfigAttribs, eglConfig, config_size, &iConfigs) || (iConfigs < 1))
00668     {
00669         printf("Error: eglChooseConfig() failed.\n");
00670         terminate();
00671         return false;
00672     }
00673     else {
00674         for (int i = 0; i < iConfigs; i++) {
00675            EGLint value;
00676            printf("config #%d ***\n", i);
00677            GET_ATTR(EGL_BUFFER_SIZE, "EGL_BUFFER_SIZE");
00678            GET_ATTR(EGL_ALPHA_SIZE, "EGL_ALPHA_SIZE");
00679            GET_ATTR(EGL_BLUE_SIZE, "EGL_BLUE_SIZE");
00680            GET_ATTR(EGL_GREEN_SIZE, "EGL_GREEN_SIZE");
00681            GET_ATTR(EGL_RED_SIZE, "EGL_RED_SIZE");
00682            GET_ATTR(EGL_DEPTH_SIZE, "EGL_DEPTH_SIZE");
00683            GET_ATTR(EGL_STENCIL_SIZE, "EGL_STENCIL_SIZE");
00684            GET_ATTR(EGL_CONFIG_CAVEAT, "EGL_CONFIG_CAVEAT");
00685            GET_ATTR(EGL_CONFIG_ID, "EGL_CONFIG_ID");
00686            GET_ATTR(EGL_LEVEL, "EGL_LEVEL");
00687            GET_ATTR(EGL_MAX_PBUFFER_HEIGHT, "EGL_MAX_PBUFFER_HEIGHT");
00688            GET_ATTR(EGL_MAX_PBUFFER_PIXELS, "EGL_MAX_PBUFFER_PIXELS");
00689            GET_ATTR(EGL_MAX_PBUFFER_WIDTH, "EGL_MAX_PBUFFER_WIDTH");
00690            GET_ATTR(EGL_NATIVE_RENDERABLE, "EGL_NATIVE_RENDERABLE");
00691            GET_ATTR(EGL_NATIVE_VISUAL_ID, "EGL_NATIVE_VISUAL_ID");
00692            GET_ATTR(EGL_NATIVE_VISUAL_TYPE, "EGL_NATIVE_VISUAL_TYPE");
00693            //GET_ATTR(EGL_PRESERVED_RESOURCES, "EGL_PRESERVED_RESOURCES"); not all gles2 implementations have this
00694            GET_ATTR(EGL_SAMPLES, "EGL_SAMPLES");
00695            GET_ATTR(EGL_SAMPLE_BUFFERS, "EGL_SAMPLE_BUFFERS");
00696            GET_ATTR(EGL_SURFACE_TYPE, "EGL_SURFACE_TYPE");
00697            GET_ATTR(EGL_TRANSPARENT_TYPE, "EGL_TRANSPARENT_TYPE");
00698            GET_ATTR(EGL_TRANSPARENT_BLUE_VALUE, "EGL_TRANSPARENT_BLUE_VALUE");
00699            GET_ATTR(EGL_TRANSPARENT_GREEN_VALUE, "EGL_TRANSPARENT_GREEN_VALUE");
00700            GET_ATTR(EGL_TRANSPARENT_RED_VALUE, "EGL_TRANSPARENT_RED_VALUE");
00701            GET_ATTR(EGL_NONE, "EGL_NONE");
00702            GET_ATTR(EGL_BIND_TO_TEXTURE_RGB, "EGL_BIND_TO_TEXTURE_RGB");
00703            GET_ATTR(EGL_BIND_TO_TEXTURE_RGBA, "EGL_BIND_TO_TEXTURE_RGBA");
00704            GET_ATTR(EGL_MIN_SWAP_INTERVAL, "EGL_MIN_SWAP_INTERVAL");
00705            GET_ATTR(EGL_MAX_SWAP_INTERVAL, "EGL_MAX_SWAP_INTERVAL");
00706            GET_ATTR(EGL_LUMINANCE_SIZE, "EGL_LUMINANCE_SIZE");
00707            GET_ATTR(EGL_ALPHA_MASK_SIZE, "EGL_ALPHA_MASK_SIZE");
00708            GET_ATTR(EGL_COLOR_BUFFER_TYPE, "EGL_COLOR_BUFFER_TYPE");
00709            GET_ATTR(EGL_RENDERABLE_TYPE, "EGL_RENDERABLE_TYPE");
00710            GET_ATTR(EGL_MATCH_NATIVE_PIXMAP, "EGL_MATCH_NATIVE_PIXMAP");
00711            GET_ATTR(EGL_CONFORMANT, "EGL_CONFORMANT");
00712         }
00713     }
00714 
00715     /*
00716         Step 6 - Create a surface to draw to.
00717         Use the config picked in the previous step and the native window
00718         handle when available to create a window surface. A window surface
00719         is one that will be visible on screen inside the native display (or
00720         fullscreen if there is no windowing system).
00721         Pixmaps and pbuffers are surfaces which only exist in off-screen
00722         memory.
00723     */
00724     eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig[0], (EGLNativeWindowType) x_window, NULL);
00725 
00726     if (!getError("eglCreateWindowSurface"))
00727     {
00728         terminate();
00729         return false;
00730     }
00731 
00732     /*
00733         Step 7 - Create a context.
00734         EGL has to create a context for OpenGL ES. Our OpenGL ES resources
00735         like textures will only be valid inside this context
00736         (or shared contexts).
00737     */
00738     EGLint ai32ContextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
00739     eglContext = eglCreateContext(eglDisplay, eglConfig[0], EGL_NO_CONTEXT, ai32ContextAttribs);
00740     if (!getError("eglCreateContext"))
00741     {
00742         terminate();
00743         return false;
00744     }
00745 
00746     /*
00747         Step 8 - Bind the context to the current thread and use our
00748         window surface for drawing and reading.
00749         Contexts are bound to a thread. This means you don't have to
00750         worry about other threads and processes interfering with your
00751         OpenGL ES application.
00752         We need to specify a surface that will be the target of all
00753         subsequent drawing operations, and one that will be the source
00754         of read operations. They can be the same surface.
00755     */
00756     eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
00757     if (!getError("eglMakeCurrent"))
00758     {
00759         terminate();
00760         return false;
00761     }
00762 
00763     /*
00764         Step 9 - Draw something with OpenGL ES.
00765         At this point everything is initialized and we're ready to use
00766         OpenGL ES to draw something on the screen.
00767     */
00768 
00769 
00770 
00771     // get the dimension of the screen
00772     int wh[4];
00773     glGetIntegerv(GL_VIEWPORT, wh);
00774     this->screen_width = wh[2];
00775     this->screen_height = wh[3];
00776     printf("SCREEN WIDTH = %d, HEIGHT = %d\n", this->screen_width, this->screen_height);
00777     printf("----------------------------------------------------------------------\n");
00778 
00779     printImplementationInformation();
00780 
00781     // init fragment and vertex shaders
00782     if (initShaders()) {
00783 
00784         // prepare current matrix for shaders
00785         loadIdentityMatrix(this->current_matrix);
00786 
00787         // prepare current color for shaders
00788         this->current_color_r = 0;
00789         this->current_color_g = 0;
00790         this->current_color_b = 0;
00791         this->current_color_a = 0;
00792 
00793         // wrapper successfully initialized
00794         this->initialized = true;
00795     }
00796 
00797     return true;
00798 
00799 #endif
00800 
00801 #ifdef __HAVE_GLX__
00802 
00803     printf("\nInitializing GLX:\n");
00804     printf("----------------------------------------------------------------------\n");
00805 
00806     this->x_display = x_display;
00807     this->x_window = x_window;
00808 
00809     int glxMajor, glxMinor;
00810     glXQueryVersion(x_display, &glxMajor, &glxMinor);
00811     printf("GLX-Version %d.%d\n", glxMajor, glxMinor);
00812     int attribList[] =
00813         {GLX_RGBA,
00814         GLX_RED_SIZE, 8,
00815         GLX_GREEN_SIZE, 8,
00816         GLX_BLUE_SIZE, 8,
00817         GLX_DEPTH_SIZE, 16,
00818         GLX_DOUBLEBUFFER,
00819         None};
00820     this->xvi = glXChooseVisual(x_display, x_screen, attribList);
00821     if (this->xvi == NULL) {
00822         int attribList[] =
00823                 {GLX_RGBA,
00824                 GLX_RED_SIZE, 8,
00825                 GLX_GREEN_SIZE, 8,
00826                 GLX_BLUE_SIZE, 8,
00827                 None};
00828         this->xvi = glXChooseVisual(x_display, x_screen, attribList);
00829         printf("singlebuffered rendering will be used, no doublebuffering available\n");
00830         if(this->xvi == NULL) {
00831             printf("shit happens.... \n");
00832             return false;
00833         }
00834     }
00835     else {
00836         printf("doublebuffered rendering available\n");
00837     }
00838 
00839     // create a GLX context
00840     this->glx_context = glXCreateContext(x_display, this->xvi, 0, GL_TRUE);
00841     if (!this->glx_context) {
00842         printf("context generation failed...\n");
00843         return false;
00844     }
00845 
00846     if(glXMakeCurrent(x_display, x_window, this->glx_context) != True) {
00847         printf("make current failed\n");
00848         return false;
00849     }
00850 
00851     if (glXIsDirect(x_display, this->glx_context))
00852         printf("DRI enabled\n");
00853     else
00854         printf("no DRI available\n");
00855 
00856     XMapRaised(x_display, x_window);
00857     XFlush(x_display);
00858 
00859     // init extension pointers
00860     GLenum err=glewInit();
00861     if(err!=GLEW_OK) {
00862         //problem: glewInit failed, something is seriously wrong
00863         printf("Error: %s\n", glewGetErrorString(err));
00864         return false;
00865     }
00866 
00867     // wrapper successfully initialized
00868     this->initialized = true;
00869     this->screen_width = w;
00870     this->screen_height = h;
00871     printf("SCREEN WIDTH = %d, HEIGHT = %d\n", this->screen_width, this->screen_height);
00872     printf("----------------------------------------------------------------------\n");
00873 
00874     printImplementationInformation();
00875 
00876     return true;
00877 
00878 #else
00879     return false;
00880 #endif
00881 }
00882 
00883 #else
00884 
00885 bool MMSFBGL::init() {
00886 
00887     if (this->initialized) {
00888         // already initialized
00889         return false;
00890     }
00891 
00892 #ifdef __HAVE_KMS__
00893     if (mmsfb->getKmsInterface()->isInitialized()) {
00894         this->useKMS = true;
00895         this->drm = mmsfb->getKmsInterface()->getDrm();
00896         this->drm_fb = NULL;
00897     }
00898 #endif
00899 
00900 
00901 #ifdef __HAVE_EGL__
00902 
00903     printf("\nInitializing EGL:\n");
00904     printf("----------------------------------------------------------------------\n");
00905 
00906     /*
00907         Step 1 - Get the default display.
00908         EGL uses the concept of a "display" which in most environments
00909         corresponds to a single physical screen. Since we usually want
00910         to draw to the main screen or only have a single screen to begin
00911         with, we let EGL pick the default display.
00912         Querying other displays is platform specific.
00913     */
00914     if (this->useKMS) {
00915 #ifdef __HAVE_KMS__
00916         eglDisplay = eglGetDisplay((EGLNativeDisplayType)this->drm->dev);
00917 #endif
00918     } else {
00919         eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
00920     }
00921     if (eglDisplay == EGL_NO_DISPLAY) {
00922         printf("Error: eglGetDisplay() returned EGL_NO_DISPLAY.\n");
00923         terminate();
00924         return false;
00925     }
00926 
00927     /*
00928         Step 2 - Initialize EGL.
00929         EGL has to be initialized with the display obtained in the
00930         previous step. We cannot use other EGL functions except
00931         eglGetDisplay and eglGetError before eglInitialize has been
00932         called.
00933         If we're not interested in the EGL version number we can just
00934         pass NULL for the second and third parameters.
00935     */
00936     EGLint iMajorVersion, iMinorVersion;
00937     if (!eglInitialize(eglDisplay, &iMajorVersion, &iMinorVersion))
00938     {
00939         printf("Error: eglInitialize() failed.\n");
00940         terminate();
00941         return false;
00942     }
00943 
00944     /*
00945         Step 3 - Make OpenGL ES the current API.
00946         EGL provides ways to set up OpenGL ES and OpenVG contexts
00947         (and possibly other graphics APIs in the future), so we need
00948         to specify the "current API".
00949     */
00950     eglBindAPI(EGL_OPENGL_ES_API);
00951 
00952     if (eglGetError() != EGL_SUCCESS)
00953     if (!getError("eglBindAPI"))
00954     {
00955         terminate();
00956         return false;
00957     }
00958 
00959     /*
00960         Step 4 - Specify the required configuration attributes.
00961         An EGL "configuration" describes the pixel format and type of
00962         surfaces that can be used for drawing.
00963         For now we just want to use a 16 bit RGB surface that is a
00964         Window surface, i.e. it will be visible on screen. The list
00965         has to contain key/value pairs, terminated with EGL_NONE.
00966      */
00967 
00968 //  EGLint pi32ConfigAttribs[13];
00969 //  if (this->useKMS) {
00970 ////        EGLint pi32ConfigAttribs[13];
00971 //      pi32ConfigAttribs[0] = EGL_SURFACE_TYPE;
00972 //      pi32ConfigAttribs[1] = EGL_WINDOW_BIT;
00973 //      pi32ConfigAttribs[2] = EGL_RENDERABLE_TYPE;
00974 //      pi32ConfigAttribs[3] = EGL_OPENGL_ES2_BIT;
00975 //      pi32ConfigAttribs[4] = EGL_RED_SIZE;
00976 //      pi32ConfigAttribs[5] = 1;
00977 //      pi32ConfigAttribs[6] = EGL_GREEN_SIZE;
00978 //      pi32ConfigAttribs[7] = 1;
00979 //      pi32ConfigAttribs[8] = EGL_BLUE_SIZE;
00980 //      pi32ConfigAttribs[9] = 1;
00981 //      pi32ConfigAttribs[10] = EGL_ALPHA_SIZE;
00982 //      pi32ConfigAttribs[11] = 0;
00983 //      pi32ConfigAttribs[12] = EGL_NONE;
00984 //
00985 //  } else {
00986         EGLint pi32ConfigAttribs[11];
00987         pi32ConfigAttribs[0] = EGL_SURFACE_TYPE;
00988         pi32ConfigAttribs[1] = EGL_WINDOW_BIT;
00989         pi32ConfigAttribs[2] = EGL_RENDERABLE_TYPE;
00990         pi32ConfigAttribs[3] = EGL_OPENGL_ES2_BIT;
00991         pi32ConfigAttribs[4] = EGL_RED_SIZE;
00992         pi32ConfigAttribs[5] = 8;
00993         pi32ConfigAttribs[6] = EGL_GREEN_SIZE;
00994         pi32ConfigAttribs[7] = 8;
00995         pi32ConfigAttribs[8] = EGL_BLUE_SIZE;
00996         pi32ConfigAttribs[9] = 8;
00997         pi32ConfigAttribs[10] = EGL_NONE;
00998 //      pi32ConfigAttribs[11] = EGL_NONE;
00999 //      pi32ConfigAttribs[12] = EGL_NONE;
01000 //  }
01001 
01002 
01003     /*
01004         Step 5 - Find a config that matches all requirements.
01005         eglChooseConfig provides a list of all available configurations
01006         that meet or exceed the requirements given as the second
01007         argument. In most cases we just want the first config that meets
01008         all criteria, so we can limit the number of configs returned to 1.
01009     */
01010     int iConfigs;
01011     int config_size=0;
01012     if (this->useKMS)
01013         config_size=1;
01014     else
01015         config_size=10;
01016 
01017     if (!eglChooseConfig(eglDisplay, pi32ConfigAttribs, eglConfig, config_size, &iConfigs) || (iConfigs < 1))
01018     {
01019         printf("Error: eglChooseConfig() failed.\n");
01020         terminate();
01021         return false;
01022     }
01023     else {
01024         for (int i = 0; i < iConfigs; i++) {
01025            EGLint value;
01026            printf("config #%d ***\n", i);
01027            GET_ATTR(EGL_BUFFER_SIZE, "EGL_BUFFER_SIZE");
01028            GET_ATTR(EGL_ALPHA_SIZE, "EGL_ALPHA_SIZE");
01029            GET_ATTR(EGL_BLUE_SIZE, "EGL_BLUE_SIZE");
01030            GET_ATTR(EGL_GREEN_SIZE, "EGL_GREEN_SIZE");
01031            GET_ATTR(EGL_RED_SIZE, "EGL_RED_SIZE");
01032            GET_ATTR(EGL_DEPTH_SIZE, "EGL_DEPTH_SIZE");
01033            GET_ATTR(EGL_STENCIL_SIZE, "EGL_STENCIL_SIZE");
01034            GET_ATTR(EGL_CONFIG_CAVEAT, "EGL_CONFIG_CAVEAT");
01035            GET_ATTR(EGL_CONFIG_ID, "EGL_CONFIG_ID");
01036            GET_ATTR(EGL_LEVEL, "EGL_LEVEL");
01037            GET_ATTR(EGL_MAX_PBUFFER_HEIGHT, "EGL_MAX_PBUFFER_HEIGHT");
01038            GET_ATTR(EGL_MAX_PBUFFER_PIXELS, "EGL_MAX_PBUFFER_PIXELS");
01039            GET_ATTR(EGL_MAX_PBUFFER_WIDTH, "EGL_MAX_PBUFFER_WIDTH");
01040            GET_ATTR(EGL_NATIVE_RENDERABLE, "EGL_NATIVE_RENDERABLE");
01041            GET_ATTR(EGL_NATIVE_VISUAL_ID, "EGL_NATIVE_VISUAL_ID");
01042            GET_ATTR(EGL_NATIVE_VISUAL_TYPE, "EGL_NATIVE_VISUAL_TYPE");
01043            //GET_ATTR(EGL_PRESERVED_RESOURCES, "EGL_PRESERVED_RESOURCES"); not all gles2 implementations have this
01044            GET_ATTR(EGL_SAMPLES, "EGL_SAMPLES");
01045            GET_ATTR(EGL_SAMPLE_BUFFERS, "EGL_SAMPLE_BUFFERS");
01046            GET_ATTR(EGL_SURFACE_TYPE, "EGL_SURFACE_TYPE");
01047            GET_ATTR(EGL_TRANSPARENT_TYPE, "EGL_TRANSPARENT_TYPE");
01048            GET_ATTR(EGL_TRANSPARENT_BLUE_VALUE, "EGL_TRANSPARENT_BLUE_VALUE");
01049            GET_ATTR(EGL_TRANSPARENT_GREEN_VALUE, "EGL_TRANSPARENT_GREEN_VALUE");
01050            GET_ATTR(EGL_TRANSPARENT_RED_VALUE, "EGL_TRANSPARENT_RED_VALUE");
01051            GET_ATTR(EGL_NONE, "EGL_NONE");
01052            GET_ATTR(EGL_BIND_TO_TEXTURE_RGB, "EGL_BIND_TO_TEXTURE_RGB");
01053            GET_ATTR(EGL_BIND_TO_TEXTURE_RGBA, "EGL_BIND_TO_TEXTURE_RGBA");
01054            GET_ATTR(EGL_MIN_SWAP_INTERVAL, "EGL_MIN_SWAP_INTERVAL");
01055            GET_ATTR(EGL_MAX_SWAP_INTERVAL, "EGL_MAX_SWAP_INTERVAL");
01056            GET_ATTR(EGL_LUMINANCE_SIZE, "EGL_LUMINANCE_SIZE");
01057            GET_ATTR(EGL_ALPHA_MASK_SIZE, "EGL_ALPHA_MASK_SIZE");
01058            GET_ATTR(EGL_COLOR_BUFFER_TYPE, "EGL_COLOR_BUFFER_TYPE");
01059            GET_ATTR(EGL_RENDERABLE_TYPE, "EGL_RENDERABLE_TYPE");
01060            GET_ATTR(EGL_MATCH_NATIVE_PIXMAP, "EGL_MATCH_NATIVE_PIXMAP");
01061            GET_ATTR(EGL_CONFORMANT, "EGL_CONFORMANT");
01062         }
01063     }
01064 
01065 
01066     /*
01067         Step 6 - Create a surface to draw to.
01068         Use the config picked in the previous step and the native window
01069         handle when available to create a window surface. A window surface
01070         is one that will be visible on screen inside the native display (or
01071         fullscreen if there is no windowing system).
01072         Pixmaps and pbuffers are surfaces which only exist in off-screen
01073         memory.
01074     */
01075     if (this->useKMS) {
01076 #ifdef __HAVE_KMS__
01077         eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig[0], (EGLNativeWindowType) this->drm->surface, NULL);
01078 //      eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig[0], (EGLNativeWindowType) mmsfb->getKmsInterface()->getOmapBo(), NULL);
01079 #endif
01080     } else {
01081         eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig[0], (EGLNativeWindowType) NULL, NULL);
01082     }
01083 
01084     if (!getError("eglCreateWindowSurface"))
01085     {
01086         terminate();
01087         return false;
01088     }
01089 
01090     /*
01091         Step 7 - Create a context.
01092         EGL has to create a context for OpenGL ES. Our OpenGL ES resources
01093         like textures will only be valid inside this context
01094         (or shared contexts).
01095     */
01096     EGLint ai32ContextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
01097     if (this->useKMS)
01098         eglContext = eglCreateContext(eglDisplay, eglConfig[0], EGL_NO_CONTEXT, ai32ContextAttribs);
01099     else
01100         eglContext = eglCreateContext(eglDisplay, eglConfig[0], NULL, ai32ContextAttribs);
01101     if (!getError("eglCreateContext"))
01102     {
01103         terminate();
01104         return false;
01105     }
01106 
01107     /*
01108         Step 8 - Bind the context to the current thread and use our
01109         window surface for drawing and reading.
01110         Contexts are bound to a thread. This means you don't have to
01111         worry about other threads and processes interfering with your
01112         OpenGL ES application.
01113         We need to specify a surface that will be the target of all
01114         subsequent drawing operations, and one that will be the source
01115         of read operations. They can be the same surface.
01116     */
01117     eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
01118     if (!getError("eglMakeCurrent"))
01119     {
01120         terminate();
01121         return false;
01122     }
01123 
01124     /*
01125         Step 9 - Draw something with OpenGL ES.
01126         At this point everything is initialized and we're ready to use
01127         OpenGL ES to draw something on the screen.
01128     */
01129 
01130 
01131 
01132     // get the dimension of the screen
01133     int wh[4];
01134     glGetIntegerv(GL_VIEWPORT, wh);
01135     this->screen_width = wh[2];
01136     this->screen_height = wh[3];
01137     printf("SCREEN WIDTH = %d, HEIGHT = %d\n", this->screen_width, this->screen_height);
01138     printf("----------------------------------------------------------------------\n");
01139 
01140     printImplementationInformation();
01141 
01142     // init fragment and vertex shaders
01143     if (initShaders()) {
01144 
01145         // prepare current matrix for shaders
01146         loadIdentityMatrix(this->current_matrix);
01147 
01148         // prepare current color for shaders
01149         this->current_color_r = 0;
01150         this->current_color_g = 0;
01151         this->current_color_b = 0;
01152         this->current_color_a = 0;
01153 
01154         // wrapper successfully initialized
01155         this->initialized = true;
01156     }
01157 
01158     return true;
01159 
01160 #else
01161 
01162     return false;
01163 
01164 #endif
01165 }
01166 #endif
01167 
01168 
01169 
01170 bool MMSFBGL::terminate() {
01171 
01172     INITCHECK;
01173 
01174     deleteShaders();
01175 
01176 #ifdef __HAVE_EGL__
01177 
01178     /*
01179         Step 10 - Terminate OpenGL ES and destroy the window (if present).
01180         eglTerminate takes care of destroying any context or surface created
01181         with this display, so we don't need to call eglDestroySurface or
01182         eglDestroyContext here.
01183     */
01184     eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
01185     eglTerminate(eglDisplay);
01186 
01187 #endif
01188 
01189     return true;
01190 }
01191 
01192 bool MMSFBGL::getResolution(int *w, int *h) {
01193 
01194     INITCHECK;
01195 
01196     *w = this->screen_width;
01197     *h = this->screen_height;
01198 
01199     return true;
01200 }
01201 
01202 bool MMSFBGL::swap() {
01203 
01204     INITCHECK;
01205 
01206 #ifdef __HAVE_GLX__
01207 
01208     glXSwapBuffers(this->x_display, this->x_window);
01209 
01210     return true;
01211 
01212 #endif
01213 
01214 #ifdef __HAVE_EGL__
01215 
01216 /*glFlush();
01217 glFinish();
01218 eglWaitClient();
01219 eglWaitNative(EGL_CORE_NATIVE_ENGINE);
01220 sleep(1);
01221 glFlush();
01222 glFinish();
01223 eglWaitClient();
01224 eglWaitNative(EGL_CORE_NATIVE_ENGINE);
01225 sleep(1);*/
01226 
01227     eglWaitClient();
01228 
01229     eglSwapBuffers(this->eglDisplay, this->eglSurface);
01230     ERROR_CHECK_BOOL("eglSwapBuffers()");
01231 
01232 #ifdef __HAVE_KMS__
01233     if (this->useKMS) {
01234 
01235         mmsfb->getKmsInterface()->pageFlip();
01236 //      fd_set fds;
01237 //      FD_ZERO(&fds);
01238 //      FD_SET(0, &fds);
01239 //      FD_SET(this->drm->fd, &fds);
01240 //
01241 //      struct gbm_bo *bo;
01242 //      DRM_FB *fb;
01243 //      struct gbm_bo *next_bo;
01244 //      int waiting_for_flip = 1;
01245 //
01246 ////        bo = gbm_surface_lock_front_buffer(this->gbm->surface);
01247 //      next_bo = gbm_surface_lock_front_buffer(this->gbm->surface);
01248 //      fb = (DRM_FB*)drm_fb_get_from_bo(next_bo);
01249 //
01250 //      int ret =0;
01251 //      ret = drmModeSetPlane(this->drm->fd, this->drm->plane_id, this->drm->crtc_id,
01252 //              fb->fb_id, 0, 0, 0, this->drm->mode->hdisplay, this->drm->mode->vdisplay,
01253 //              0, (this->drm->mode->vdisplay-576) << 16, 1024 << 16, 576 << 16);
01254 //
01255 //      if (ret)
01256 //          printf("drmModeSetPlane failed\n");
01257 //
01258 //      ret = 0;
01259 //      ret = drmModePageFlip(this->drm->fd, this->drm->crtc_id, fb->fb_id, DRM_MODE_PAGE_FLIP_EVENT, &waiting_for_flip);
01260 //      if (ret) {
01261 //          printf("OPENGL_SWAP: failed to queue page flip\n");
01262 //          return false;
01263 //      }
01264 //
01265 //      while (waiting_for_flip) {
01266 //          ret = select(this->drm->fd + 1, &fds, NULL, NULL, NULL);
01267 //          if (ret < 0) {
01268 //              printf("OPENGL_SWAP: select err\n");
01269 //              return false;
01270 //          } else if (ret == 0) {
01271 //              printf("OPENGL_SWAP: select timeout!\n");
01272 //              return false;
01273 //          } else if (FD_ISSET(0, &fds)) {
01274 //              printf("OPENGL_SWAP: user interrupted!\n");
01275 //              break;
01276 //          }
01277 //          drmHandleEvent(this->drm->fd, &this->evctx);
01278 //      }
01279 //
01280 //      gbm_surface_release_buffer(this->gbm->surface, next_bo);
01281 ////        bo = next_bo;
01282     }
01283 #endif
01284 
01285     return true;
01286 
01287 #else
01288 
01289     return false;
01290 
01291 #endif
01292 }
01293 
01294 
01295 bool MMSFBGL::genBuffer(GLuint *bo) {
01296 
01297     INITCHECK;
01298 
01299     // generate a unique buffer id
01300     glGenBuffers(1, bo);
01301     ERROR_CHECK_BOOL("glGenBuffers()");
01302 
01303     return true;
01304 }
01305 
01306 bool MMSFBGL::deleteBuffer(GLuint bo) {
01307 
01308     INITCHECK;
01309 
01310     if (bo) {
01311         // finishing all operations
01312         glFinish();
01313         ERROR_CHECK_BOOL("glFinish()");
01314 
01315         // detach buffers
01316         bindBuffer(GL_ARRAY_BUFFER, 0);
01317         bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
01318 
01319         // now it's safe to delete the buffer
01320         glDeleteBuffers(1, &bo);
01321         ERROR_CHECK_BOOL("glDeleteBuffers()");
01322 
01323         return true;
01324     }
01325 
01326     return false;
01327 }
01328 
01329 bool MMSFBGL::bindBuffer(GLenum target, GLuint bo) {
01330 
01331     INITCHECK;
01332 
01333     switch (target) {
01334     case GL_ARRAY_BUFFER:
01335         if (this->bound_vbo != bo) {
01336             // going to change the vertex buffer object
01337             this->bound_vbo = bo;
01338 
01339             // flush all queued commands to the OpenGL server
01340             // but do NOT wait until all queued commands are finished by the OpenGL server
01341 //bad performance on MALI           glFlush();
01342 //bad performance on MALI           ERROR_CHECK_BOOL("glFlush()");
01343 //printf("this->bound_vbo = %d\n",this->bound_vbo);
01344 
01345             // activate buffer
01346             glBindBuffer(target, this->bound_vbo);
01347             ERROR_CHECK_BOOL("glBindBuffer(GL_ARRAY_BUFFER...)");
01348         }
01349         return true;
01350     case GL_ELEMENT_ARRAY_BUFFER:
01351         if (this->bound_ibo != bo) {
01352             // going to change the index buffer object
01353             this->bound_ibo = bo;
01354 
01355             // flush all queued commands to the OpenGL server
01356             // but do NOT wait until all queued commands are finished by the OpenGL server
01357 //bad performance on MALI           glFlush();
01358 //bad performance on MALI           ERROR_CHECK_BOOL("glFlush()");
01359 
01360             // activate buffer
01361             glBindBuffer(target, this->bound_ibo);
01362             ERROR_CHECK_BOOL("glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,...)");
01363         }
01364         return true;
01365     default:
01366         return false;
01367     }
01368 }
01369 
01370 
01371 bool MMSFBGL::initVertexBuffer(GLuint vbo, unsigned int size, const GLvoid *data) {
01372 
01373     INITCHECK;
01374 
01375     if (vbo) {
01376         // activate buffer
01377         bindBuffer(GL_ARRAY_BUFFER, vbo);
01378 
01379         // initializing buffer
01380         glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);
01381         ERROR_CHECK_BOOL("glBufferData(GL_ARRAY_BUFFER,...)");
01382 
01383         return true;
01384     }
01385 
01386     return false;
01387 }
01388 
01389 bool MMSFBGL::initVertexSubBuffer(GLuint vbo, unsigned int offset, unsigned int size, const GLvoid *data) {
01390 
01391     INITCHECK;
01392 
01393     if (vbo) {
01394         // activate buffer
01395         bindBuffer(GL_ARRAY_BUFFER, vbo);
01396 
01397         // initializing a part of buffer
01398         glBufferSubData(GL_ARRAY_BUFFER, offset, size, data);
01399         ERROR_CHECK_BOOL("glBufferSubData(GL_ARRAY_BUFFER,...)");
01400 
01401         return true;
01402     }
01403 
01404     return false;
01405 }
01406 
01407 bool MMSFBGL::enableVertexBuffer(GLuint vbo) {
01408 
01409     if (vbo) {
01410         // activate buffer
01411         bindBuffer(GL_ARRAY_BUFFER, vbo);
01412         return true;
01413     }
01414 
01415     return false;
01416 }
01417 
01418 void MMSFBGL::disableVertexBuffer() {
01419     // detach current buffer
01420     bindBuffer(GL_ARRAY_BUFFER, 0);
01421 }
01422 
01423 bool MMSFBGL::initIndexBuffer(GLuint ibo, unsigned int size, const GLvoid *data) {
01424 
01425     INITCHECK;
01426 
01427     if (ibo) {
01428         // activate buffer
01429         bindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
01430 
01431         // initializing buffer
01432         glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);
01433         ERROR_CHECK_BOOL("glBufferData(GL_ELEMENT_BUFFER,...)");
01434 
01435         return true;
01436     }
01437 
01438     return false;
01439 }
01440 
01441 bool MMSFBGL::initIndexSubBuffer(GLuint ibo, unsigned int offset, unsigned int size, const GLvoid *data) {
01442 
01443     INITCHECK;
01444 
01445     if (ibo) {
01446         // activate buffer
01447         bindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
01448 
01449         // initializing a part of buffer
01450         glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, size, data);
01451         ERROR_CHECK_BOOL("glBufferSubData(GL_ELEMENT_BUFFER,...)");
01452 
01453         return true;
01454     }
01455 
01456     return false;
01457 }
01458 
01459 bool MMSFBGL::enableIndexBuffer(GLuint ibo) {
01460 
01461     if (ibo) {
01462         // activate buffer
01463         bindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
01464         return true;
01465     }
01466 
01467     return false;
01468 }
01469 
01470 void MMSFBGL::disableIndexBuffer() {
01471     // detach current buffer
01472     bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
01473 }
01474 
01475 bool MMSFBGL::genTexture(GLuint *tex) {
01476 
01477     INITCHECK;
01478 
01479     // generate a unique texture id
01480     glGenTextures(1, tex);
01481     ERROR_CHECK_BOOL("glGenTextures()");
01482 
01483     return true;
01484 }
01485 
01486 bool MMSFBGL::deleteTexture(GLuint tex) {
01487 
01488     INITCHECK;
01489 
01490     if (tex) {
01491         // finishing all operations
01492         glFinish();
01493         ERROR_CHECK_BOOL("glFinish()");
01494 
01495         // switch to the primary frame buffer
01496         // so OpenGL have to finish tasks which are not finished during glFinish()
01497         GLuint fbo = this->bound_fbo;
01498         bindFrameBuffer(0);
01499 
01500 #ifdef __HAVE_GL2__
01501         // disabling GL_TEXTURE_2D only useful for the fixed-function pipeline (not for own shaders)
01502         glDisable(GL_TEXTURE_2D);
01503         ERROR_CHECK_BOOL("glDisable(GL_TEXTURE_2D)");
01504 #endif
01505 
01506         // detach texture
01507         glBindTexture(GL_TEXTURE_2D, 0);
01508         ERROR_CHECK_BOOL("glBindTexture(GL_TEXTURE_2D, 0)");
01509 
01510         // now it's safe to delete the texture
01511         glDeleteTextures(1, &tex);
01512         ERROR_CHECK_BOOL("glDeleteTextures()");
01513 
01514         // switch back to the saved fbo
01515         bindFrameBuffer(fbo);
01516 
01517         return true;
01518     }
01519 
01520     return false;
01521 }
01522 
01523 bool MMSFBGL::bindTexture2D(GLuint tex) {
01524 
01525     INITCHECK;
01526 
01527     if (tex) {
01528         // flush all queued commands to the OpenGL server
01529         // but do NOT wait until all queued commands are finished by the OpenGL server
01530 //bad performance on MALI       glFlush();
01531 //bad performance on MALI       ERROR_CHECK_BOOL("glFlush()");
01532 
01533         // activate texture
01534         glBindTexture(GL_TEXTURE_2D, tex);
01535         ERROR_CHECK_BOOL("glBindTexture(GL_TEXTURE_2D, tex)");
01536 
01537         // set min and max filter
01538         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
01539         ERROR_CHECK_BOOL("glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)");
01540         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
01541         ERROR_CHECK_BOOL("glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)");
01542 
01543         // the texture wraps over at the edges (repeat)
01544         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
01545         ERROR_CHECK_BOOL("glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)");
01546         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
01547         ERROR_CHECK_BOOL("glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)");
01548 
01549         return true;
01550     }
01551 
01552     return false;
01553 }
01554 
01555 bool MMSFBGL::initTexture2D(GLuint tex, GLenum texture_format, void *buffer, GLenum buffer_format, int sw, int sh) {
01556 
01557     INITCHECK;
01558 
01559     if (tex) {
01560         // activate texture
01561         bindTexture2D(tex);
01562 
01563         // initializing texture from buffer
01564         glTexImage2D(GL_TEXTURE_2D,
01565             0,
01566             texture_format,
01567             sw,
01568             sh,
01569             0,
01570             buffer_format,
01571             GL_UNSIGNED_BYTE,
01572             buffer);
01573         ERROR_CHECK_BOOL("glTexImage2D(GL_TEXTURE_2D,...)");
01574 
01575         return true;
01576     }
01577 
01578     return false;
01579 }
01580 
01581 
01582 bool MMSFBGL::initSubTexture2D(GLuint tex, void *buffer, GLenum buffer_format, int sw, int sh, int dx, int dy) {
01583 
01584     INITCHECK;
01585 
01586     if (tex) {
01587         // activate texture
01588         bindTexture2D(tex);
01589 
01590         // overwrite existing texture memory
01591         glTexSubImage2D(GL_TEXTURE_2D,
01592                         0,
01593                         dx,
01594                         dy,
01595                         sw,
01596                         sh,
01597                         buffer_format,
01598                         GL_UNSIGNED_BYTE,
01599                         buffer);
01600         ERROR_CHECK_BOOL("glTexSubImage2D(GL_TEXTURE_2D,...)");
01601 
01602         return true;
01603     }
01604 
01605     return false;
01606 }
01607 
01608 bool MMSFBGL::enableTexture2D(GLuint tex) {
01609 
01610 #ifdef __HAVE_GL2__
01611     // enabling GL_TEXTURE_2D only useful for the fixed-function pipeline (not for own shaders)
01612     glEnable(GL_TEXTURE_2D);
01613     ERROR_CHECK_BOOL("glEnable(GL_TEXTURE_2D)");
01614 #endif
01615 
01616     // bind source texture
01617     bindTexture2D(tex);
01618 
01619 #ifdef __HAVE_GLES2__
01620 
01621     if (!this->FSTextureLoc_initialized) {
01622         // get the location of source texture uniform variable within the fragment shader
01623         this->FSTextureLoc = -1;
01624         if (this->po_current) {
01625             this->FSTextureLoc = glGetUniformLocation(this->po_current, "FSTexture");
01626             ERROR_CHECK_BOOL("glGetUniformLocation(this->po_current, \"FSTexture\")");
01627 
01628             this->FSTextureLoc_initialized = true;
01629         }
01630     }
01631 
01632     if (!this->VSTexCoordLoc_initialized) {
01633         // get the location of texture coordinates attribute variable within the vertex shader
01634         this->VSTexCoordLoc = -1;
01635         if (this->po_current) {
01636             this->VSTexCoordLoc = glGetAttribLocation(this->po_current, "VSTexCoord");
01637             ERROR_CHECK_BOOL("glGetAttribLocation(this->po_current, \"VSTexCoord\")");
01638 
01639             this->VSTexCoordLoc_initialized = true;
01640         }
01641     }
01642 
01643 #endif
01644 
01645     return true;
01646 }
01647 
01648 
01649 void MMSFBGL::disableTexture2D() {
01650 #ifdef __HAVE_GL2__
01651     // disabling GL_TEXTURE_2D only useful for the fixed-function pipeline (not for own shaders)
01652     glDisable(GL_TEXTURE_2D);
01653     ERROR_CHECK_VOID("glDisable(GL_TEXTURE_2D)");
01654 #endif
01655 }
01656 
01657 
01658 bool MMSFBGL::genFrameBuffer(GLuint *fbo) {
01659 
01660     INITCHECK;
01661 
01662     // generate a unique FBO id
01663 #ifdef __HAVE_GL2__
01664     glGenFramebuffersEXT(1, fbo);
01665     ERROR_CHECK_BOOL("glGenFramebuffersEXT(1, fbo)");
01666 #endif
01667 
01668 #ifdef __HAVE_GLES2__
01669     glGenFramebuffers(1, fbo);
01670     ERROR_CHECK_BOOL("glGenFramebuffers(1, fbo)");
01671 #endif
01672 
01673     return true;
01674 }
01675 
01676 
01677 bool MMSFBGL::deleteFrameBuffer(GLuint fbo) {
01678 
01679     INITCHECK;
01680 
01681     // finishing all operations
01682     glFinish();
01683     ERROR_CHECK_BOOL("glFinish()");
01684 
01685     // switch to the primary frame buffer
01686     // so OpenGL have to finish tasks which are not finished during glFinish()
01687     bindFrameBuffer(0);
01688 
01689 #ifdef  __HAVE_GL2__
01690     if (fbo) {
01691         glDeleteFramebuffersEXT(1, &fbo);
01692         ERROR_CHECK_BOOL("glDeleteFramebuffersEXT()");
01693     }
01694 #endif
01695 
01696 #ifdef __HAVE_GLES2__
01697     if (fbo) {
01698         glDeleteFramebuffers(1, &fbo);
01699         ERROR_CHECK_BOOL("glDeleteFramebuffers()");
01700     }
01701 #endif
01702 
01703     return true;
01704 }
01705 
01706 
01707 bool MMSFBGL::genRenderBuffer(GLuint *rbo) {
01708 
01709     INITCHECK;
01710 
01711     // generate a unique RBO id
01712 #ifdef __HAVE_GL2__
01713     glGenRenderbuffersEXT(1, rbo);
01714     ERROR_CHECK_BOOL("glGenRenderbuffersEXT()");
01715 #endif
01716 
01717 #ifdef __HAVE_GLES2__
01718     glGenRenderbuffers(1, rbo);
01719     ERROR_CHECK_BOOL("glGenRenderbuffers()");
01720 #endif
01721 
01722     return true;
01723 }
01724 
01725 
01726 bool MMSFBGL::deleteRenderBuffer(GLuint rbo) {
01727 
01728     INITCHECK;
01729 
01730     // finishing all operations
01731     glFinish();
01732     ERROR_CHECK_BOOL("glFinish()");
01733 
01734     // switch to the primary frame buffer
01735     // so OpenGL have to finish tasks which are not finished during glFinish()
01736     bindFrameBuffer(0);
01737 
01738 #ifdef  __HAVE_GL2__
01739     if (rbo) {
01740         glDeleteRenderbuffersEXT(1, &rbo);
01741         ERROR_CHECK_BOOL("glDeleteRenderbuffersEXT()");
01742     }
01743 #endif
01744 
01745 #ifdef __HAVE_GLES2__
01746     if (rbo) {
01747         glDeleteRenderbuffers(1, &rbo);
01748         ERROR_CHECK_BOOL("glDeleteRenderbuffers()");
01749     }
01750 #endif
01751 
01752     return true;
01753 }
01754 
01755 
01756 bool MMSFBGL::attachTexture2FrameBuffer(GLuint fbo, GLuint tex) {
01757 
01758     INITCHECK;
01759 
01760 #ifdef  __HAVE_GL2__
01761     bindFrameBuffer(fbo);
01762     glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0);
01763     ERROR_CHECK_BOOL("glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0)");
01764 
01765     if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) {
01766         // the GPU does not support current FBO configuration
01767         printf("MMSFBGL: fatal error while attaching texture to framebuffer failed (GL2)\n");
01768         return false;
01769     }
01770 #endif
01771 
01772 #ifdef __HAVE_GLES2__
01773     bindFrameBuffer(fbo);
01774     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
01775     ERROR_CHECK_BOOL("glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0)");
01776 
01777     if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
01778         // the GPU does not support current FBO configuration
01779         printf("MMSFBGL: fatal error while attaching texture to framebuffer failed (GLES2)\n");
01780         return false;
01781     }
01782 #endif
01783 
01784     return true;
01785 }
01786 
01787 
01788 bool MMSFBGL::attachRenderBuffer2FrameBuffer(GLuint fbo, GLuint rbo, int width, int height) {
01789 
01790     INITCHECK;
01791 
01792 #ifdef  __HAVE_GL2__
01793     glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rbo);
01794     ERROR_CHECK_BOOL("glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rbo)");
01795 
01796     glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, width, height);
01797     ERROR_CHECK_BOOL("glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, width, height)");
01798 
01799     bindFrameBuffer(fbo);
01800     glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rbo);
01801     ERROR_CHECK_BOOL("glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rbo)");
01802 
01803     if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) {
01804         // the GPU does not support current FBO configuration
01805         printf("MMSFBGL: fatal error while attaching renderbuffer to framebuffer failed (GL2)\n");
01806         return false;
01807     }
01808 #endif
01809 
01810 #ifdef __HAVE_GLES2__
01811     glBindRenderbuffer(GL_RENDERBUFFER, rbo);
01812     ERROR_CHECK_BOOL("glBindRenderbuffer(GL_RENDERBUFFER, rbo)");
01813 
01814     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
01815     ERROR_CHECK_BOOL("glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height)");
01816 
01817     bindFrameBuffer(fbo);
01818     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo);
01819     ERROR_CHECK_BOOL("glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo)");
01820 
01821     if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
01822         // the GPU does not support current FBO configuration
01823         printf("MMSFBGL: fatal error while attaching renderbuffer to framebuffer failed (GLES2)\n");
01824         return false;
01825     }
01826 #endif
01827 
01828     return true;
01829 }
01830 
01831 
01832 bool MMSFBGL::allocTexture(GLuint tex, int width, int height) {
01833 
01834     INITCHECK;
01835 
01836     if (!initTexture2D(tex, GL_RGBA, NULL, GL_RGBA, width, height))
01837         return false;
01838 
01839     return true;
01840 }
01841 
01842 
01843 bool MMSFBGL::allocFBO(GLuint fbo, GLuint tex, int width, int height) {
01844 
01845     INITCHECK;
01846 
01847     if (!allocTexture(tex, width, height))
01848         return false;
01849 
01850     if (!attachTexture2FrameBuffer(fbo, tex))
01851         return false;
01852 
01853     return true;
01854 }
01855 
01856 
01857 bool MMSFBGL::allocFBOandRBO(GLuint fbo, GLuint tex, GLuint rbo, int width, int height) {
01858 
01859     INITCHECK;
01860 
01861     if (!allocTexture(tex, width, height))
01862         return false;
01863 
01864     if (!attachTexture2FrameBuffer(fbo, tex))
01865         return false;
01866 
01867     if (!attachRenderBuffer2FrameBuffer(fbo, rbo, width, height))
01868         return false;
01869 
01870     return true;
01871 }
01872 
01873 
01874 
01875 bool MMSFBGL::freeFBO(GLuint fbo, GLuint tex, GLuint rbo) {
01876 
01877     INITCHECK;
01878 
01879     bindFrameBuffer(0);
01880     deleteRenderBuffer(rbo);
01881     deleteTexture(tex);
01882     deleteFrameBuffer(fbo);
01883 
01884     return true;
01885 }
01886 
01887 
01888 bool MMSFBGL::bindFrameBuffer(GLuint fbo) {
01889 
01890     INITCHECK;
01891 
01892     if (this->bound_fbo != fbo) {
01893         // going to change the framebuffer object
01894         this->bound_fbo = fbo;
01895 
01896 #ifdef  __HAVE_GL2__
01897         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
01898         ERROR_CHECK_BOOL("glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo)");
01899 #endif
01900 
01901 #ifdef __HAVE_GLES2__
01902         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
01903         ERROR_CHECK_BOOL("glBindFramebuffer(GL_FRAMEBUFFER, fbo)");
01904 #endif
01905     }
01906 
01907     disableScissor();
01908     disableDepthTest();
01909     disableTexture2D();
01910     disableArrays();
01911 
01912     return true;
01913 }
01914 
01915 
01916 bool MMSFBGL::setScissor(GLint x, GLint y, GLsizei width, GLsizei height) {
01917 
01918     INITCHECK;
01919 
01920     glScissor(x, y, width, height);
01921     ERROR_CHECK_BOOL("glScissor()");
01922     glEnable(GL_SCISSOR_TEST);
01923     ERROR_CHECK_BOOL("glEnable(GL_SCISSOR_TEST)");
01924 
01925     return true;
01926 }
01927 
01928 
01929 bool MMSFBGL::disableScissor() {
01930 
01931     INITCHECK;
01932 
01933     glDisable(GL_SCISSOR_TEST);
01934     ERROR_CHECK_BOOL("glDisable(GL_SCISSOR_TEST)");
01935 
01936     return true;
01937 }
01938 
01939 
01940 void MMSFBGL::enableBlend(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) {
01941     glEnable(GL_BLEND);
01942     ERROR_CHECK_VOID("glEnable(GL_BLEND)");
01943     glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
01944     ERROR_CHECK_VOID("glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha)");
01945 }
01946 
01947 
01948 void MMSFBGL::disableBlend() {
01949     glDisable(GL_BLEND);
01950     ERROR_CHECK_VOID("glDisable(GL_BLEND)");
01951 }
01952 
01953 
01954 void MMSFBGL::enableDepthTest(bool readonly) {
01955     glEnable(GL_DEPTH_TEST);
01956     ERROR_CHECK_VOID("glEnable(GL_DEPTH_TEST)");
01957 
01958     if (!readonly) {
01959         // enable opengl to write into the depth buffer
01960         glDepthMask(GL_TRUE);
01961         ERROR_CHECK_VOID("glDepthMask(GL_TRUE)");
01962     }
01963     else {
01964         // write operations to depth buffer are not allowed
01965         glDepthMask(GL_FALSE);
01966         ERROR_CHECK_VOID("glDepthMask(GL_FALSE)");
01967     }
01968 
01969 #ifdef __HAVE_GL2__
01970     glDepthRange(0, 1);
01971     ERROR_CHECK_VOID("glDepthRange(0, 1)");
01972 #endif
01973 #ifdef __HAVE_GLES2__
01974     glDepthRangef(0, 1);
01975     ERROR_CHECK_VOID("glDepthRangef(0, 1)");
01976 #endif
01977 }
01978 
01979 void MMSFBGL::disableDepthTest() {
01980     glDisable(GL_DEPTH_TEST);
01981     ERROR_CHECK_VOID("glDisable(GL_DEPTH_TEST)");
01982 
01983     glDepthMask(GL_FALSE);
01984     ERROR_CHECK_VOID("glDepthMask(GL_FALSE)");
01985 }
01986 
01987 void MMSFBGL::setDrawingMode() {
01988 #ifdef __HAVE_GLES2__
01989     useShaderProgram4Drawing();
01990 #endif
01991 }
01992 
01993 void MMSFBGL::setTexEnvReplace(GLenum format) {
01994 #ifdef __HAVE_GL2__
01995     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
01996     ERROR_CHECK_VOID("glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE)");
01997 #endif
01998 
01999 #ifdef __HAVE_GLES2__
02000     if (format != GL_ALPHA) {
02001         useShaderProgram4Blitting();
02002     }
02003     else {
02004         useShaderProgram4BlittingFromAlpha();
02005     }
02006 #endif
02007 }
02008 
02009 void MMSFBGL::setTexEnvModulate(GLenum format) {
02010 #ifdef __HAVE_GL2__
02011     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
02012     ERROR_CHECK_VOID("glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)");
02013 #endif
02014 
02015 #ifdef __HAVE_GLES2__
02016     if (format != GL_ALPHA) {
02017         useShaderProgram4ModulateBlitting();
02018     }
02019     else {
02020         useShaderProgram4ModulateBlittingFromAlpha();
02021     }
02022 #endif
02023 }
02024 
02025 
02026 void MMSFBGL::disableArrays() {
02027 #ifdef  __HAVE_GL2__
02028     glDisableClientState(GL_VERTEX_ARRAY);
02029     ERROR_CHECK_VOID("glDisableClientState(GL_VERTEX_ARRAY)");
02030 
02031     glDisableClientState(GL_NORMAL_ARRAY);
02032     ERROR_CHECK_VOID("glDisableClientState(GL_NORMAL_ARRAY)");
02033 
02034     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
02035     ERROR_CHECK_VOID("glDisableClientState(GL_TEXTURE_COORD_ARRAY)");
02036 
02037     glDisableClientState(GL_INDEX_ARRAY);
02038     ERROR_CHECK_VOID("glDisableClientState(GL_INDEX_ARRAY)");
02039 #endif
02040 }
02041 
02042 
02043 bool MMSFBGL::useShaderProgram4Drawing() {
02044     if (!this->po_draw)
02045         return false;
02046 
02047     if (this->po_current != this->po_draw) {
02048         this->po_current = this->po_draw;
02049 
02050         glUseProgram(this->po_current);
02051         ERROR_CHECK_BOOL("glUseProgram()");
02052 
02053         this->VSMatrixLoc_initialized = false;
02054         this->FSColorLoc_initialized = false;
02055         this->FSTextureLoc_initialized = false;
02056         this->VSTexCoordLoc_initialized = false;
02057     }
02058 
02059     setCurrentMatrix(this->current_matrix);
02060     setColor(this->current_color_r, this->current_color_g, this->current_color_b, this->current_color_a);
02061 
02062     return true;
02063 }
02064 
02065 bool MMSFBGL::useShaderProgram4Blitting() {
02066     if (!this->po_blit)
02067         return false;
02068 
02069     if (this->po_current != this->po_blit) {
02070         this->po_current = this->po_blit;
02071 
02072         glUseProgram(this->po_current);
02073         ERROR_CHECK_BOOL("glUseProgram()");
02074 
02075         this->VSMatrixLoc_initialized = false;
02076         this->FSColorLoc_initialized = false;
02077         this->FSTextureLoc_initialized = false;
02078         this->VSTexCoordLoc_initialized = false;
02079     }
02080 
02081     setCurrentMatrix(this->current_matrix);
02082     setColor(this->current_color_r, this->current_color_g, this->current_color_b, this->current_color_a);
02083 
02084     return true;
02085 }
02086 
02087 bool MMSFBGL::useShaderProgram4ModulateBlitting() {
02088     if (!this->po_modulateblit)
02089         return false;
02090 
02091     if (this->po_current != this->po_modulateblit) {
02092         this->po_current = this->po_modulateblit;
02093 
02094         glUseProgram(this->po_current);
02095         ERROR_CHECK_BOOL("glUseProgram()");
02096 
02097         this->VSMatrixLoc_initialized = false;
02098         this->FSColorLoc_initialized = false;
02099         this->FSTextureLoc_initialized = false;
02100         this->VSTexCoordLoc_initialized = false;
02101     }
02102 
02103     setCurrentMatrix(this->current_matrix);
02104     setColor(this->current_color_r, this->current_color_g, this->current_color_b, this->current_color_a);
02105 
02106     return true;
02107 }
02108 
02109 
02110 bool MMSFBGL::useShaderProgram4BlittingFromAlpha() {
02111     if (!this->po_blit_fromalpha)
02112         return false;
02113 
02114     if (this->po_current != this->po_blit_fromalpha) {
02115         this->po_current = this->po_blit_fromalpha;
02116 
02117         glUseProgram(this->po_current);
02118         ERROR_CHECK_BOOL("glUseProgram()");
02119 
02120         this->VSMatrixLoc_initialized = false;
02121         this->FSColorLoc_initialized = false;
02122         this->FSTextureLoc_initialized = false;
02123         this->VSTexCoordLoc_initialized = false;
02124     }
02125 
02126     setCurrentMatrix(this->current_matrix);
02127     setColor(this->current_color_r, this->current_color_g, this->current_color_b, this->current_color_a);
02128 
02129     return true;
02130 }
02131 
02132 
02133 bool MMSFBGL::useShaderProgram4ModulateBlittingFromAlpha() {
02134     if (!this->po_modulateblit_fromalpha)
02135         return false;
02136 
02137     if (this->po_current != this->po_modulateblit_fromalpha) {
02138         this->po_current = this->po_modulateblit_fromalpha;
02139 
02140         glUseProgram(this->po_current);
02141         ERROR_CHECK_BOOL("glUseProgram()");
02142 
02143         this->VSMatrixLoc_initialized = false;
02144         this->FSColorLoc_initialized = false;
02145         this->FSTextureLoc_initialized = false;
02146         this->VSTexCoordLoc_initialized = false;
02147     }
02148 
02149     setCurrentMatrix(this->current_matrix);
02150     setColor(this->current_color_r, this->current_color_g, this->current_color_b, this->current_color_a);
02151 
02152     return true;
02153 }
02154 
02155 
02156 bool MMSFBGL::setCurrentMatrix(MMSMatrix matrix) {
02157 
02158     INITCHECK;
02159 
02160 #ifdef __HAVE_GL2__
02161 
02162     glLoadMatrixf((GLfloat*)matrix);
02163 
02164 #endif
02165 
02166 #ifdef __HAVE_GLES2__
02167 
02168     if (!this->VSMatrixLoc_initialized) {
02169         // get the location of matrix uniform variable within the vertex shader
02170         this->VSMatrixLoc = -1;
02171         if (this->po_current) {
02172             this->VSMatrixLoc = glGetUniformLocation(this->po_current, "VSMatrix");
02173             ERROR_CHECK_BOOL("glGetUniformLocation(this->po_current, \"VSMatrix\")");
02174 
02175             this->VSMatrixLoc_initialized = true;
02176         }
02177     }
02178 
02179     if (this->VSMatrixLoc >= 0) {
02180         // store the new matrix for the vertex shader
02181         glUniformMatrix4fv(this->VSMatrixLoc, 1, GL_FALSE, (GLfloat*)matrix);
02182         ERROR_CHECK_BOOL("glUniformMatrix4fv(this->VSMatrixLoc, 1, GL_FALSE, (GLfloat*)matrix)");
02183     }
02184 
02185 #endif
02186 
02187     // change the current matrix
02188     copyMatrix(this->current_matrix, matrix);
02189 
02190     return true;
02191 }
02192 
02193 
02194 bool MMSFBGL::getCurrentMatrix(MMSMatrix matrix) {
02195 
02196     INITCHECK;
02197 
02198     copyMatrix(matrix, this->current_matrix);
02199 
02200     return true;
02201 }
02202 
02203 
02204 bool MMSFBGL::scaleCurrentMatrix(GLfloat sx, GLfloat sy, GLfloat sz) {
02205 
02206     INITCHECK;
02207 
02208     scaleMatrix(this->current_matrix, sx, sy, sz);
02209     return setCurrentMatrix(this->current_matrix);
02210 }
02211 
02212 
02213 bool MMSFBGL::translateCurrentMatrix(GLfloat tx, GLfloat ty, GLfloat tz) {
02214 
02215     INITCHECK;
02216 
02217     translateMatrix(this->current_matrix, tx, ty, tz);
02218     return setCurrentMatrix(this->current_matrix);
02219 }
02220 
02221 
02222 bool MMSFBGL::rotateCurrentMatrix(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
02223 
02224     INITCHECK;
02225 
02226     rotateMatrix(this->current_matrix, angle, x, y, z);
02227     return setCurrentMatrix(this->current_matrix);
02228 }
02229 
02230 
02231 
02232 bool MMSFBGL::getParallelProjectionMatrix(MMSMatrix result, float left, float right, float bottom, float top, float nearZ, float farZ) {
02233 
02234     INITCHECK;
02235 
02236     // calculate the new matrix
02237     MMSMatrix matrix;
02238     loadIdentityMatrix(matrix);
02239     orthoMatrix(matrix, left, right, bottom, top, nearZ, farZ);
02240 
02241     // return the matrix to the caller
02242     copyMatrix(result, matrix);
02243 
02244     return true;
02245 }
02246 
02247 
02248 bool MMSFBGL::getCentralProjectionMatrix(MMSMatrix result, float left, float right, float bottom, float top, float nearZ, float farZ) {
02249 
02250     INITCHECK;
02251 
02252     // calculate the new matrix
02253     MMSMatrix matrix;
02254     loadIdentityMatrix(matrix);
02255     frustumMatrix(matrix, left, right, bottom, top, nearZ, farZ);
02256 
02257     // return the matrix to the caller
02258     copyMatrix(result, matrix);
02259 
02260     return true;
02261 }
02262 
02263 
02264 bool MMSFBGL::getPerspectiveMatrix(MMSMatrix result, float fovy, float aspect, float nearZ, float farZ) {
02265 
02266     INITCHECK;
02267 
02268     // calculate the new matrix
02269     MMSMatrix matrix;
02270     loadIdentityMatrix(matrix);
02271     perspectiveMatrix(matrix, fovy, aspect, nearZ, farZ);
02272 
02273     // return the matrix to the caller
02274     copyMatrix(result, matrix);
02275 
02276     return true;
02277 }
02278 
02279 
02280 
02281 bool MMSFBGL::setParallelProjection(float left, float right, float bottom, float top, float nearZ, float farZ) {
02282 
02283     INITCHECK;
02284 
02285     // set the model view matrix for the shader
02286     MMSMatrix matrix;
02287     getParallelProjectionMatrix(matrix, left, right, bottom, top, nearZ, farZ);
02288     glViewport(0, 0, (left<right)?right-left:left-right, (bottom<top)?top-bottom:bottom-top);
02289     ERROR_CHECK_BOOL("glViewport()");
02290     return setCurrentMatrix(matrix);
02291 }
02292 
02293 
02294 bool MMSFBGL::setCentralProjection(float left, float right, float bottom, float top, float nearZ, float farZ) {
02295 
02296     INITCHECK;
02297 
02298     // set the projection matrix for the shader
02299     MMSMatrix matrix;
02300     getCentralProjectionMatrix(matrix, left, right, bottom, top, nearZ, farZ);
02301     glViewport(0, 0, (left<right)?right-left:left-right, (bottom<top)?top-bottom:bottom-top);
02302     ERROR_CHECK_BOOL("glViewport()");
02303     return setCurrentMatrix(matrix);
02304 }
02305 
02306 
02307 bool MMSFBGL::setPerspective(float fovy, float aspect, float nearZ, float farZ) {
02308 
02309     INITCHECK;
02310 
02311     // set the perspective (based on projection matrix) for the shader
02312     MMSMatrix matrix;
02313     getPerspectiveMatrix(matrix, fovy, aspect, nearZ, farZ);
02314     GLfloat w, h;
02315     h = tanf(fovy / 360.0f * MMS_PI) * nearZ;
02316     w = h * aspect;
02317     glViewport(0, 0, w*2, h*2);
02318     ERROR_CHECK_BOOL("glViewport()");
02319     return setCurrentMatrix(matrix);
02320 }
02321 
02322 
02323 bool MMSFBGL::pushCurrentMatrix() {
02324 
02325     INITCHECK;
02326 
02327     // save the current matrix on the matrix stack
02328     this->matrix_stack.push(MMSFBGLStackMatrix(this->current_matrix));
02329     return true;
02330 }
02331 
02332 bool MMSFBGL::popCurrentMatrix() {
02333 
02334     INITCHECK;
02335 
02336     if (this->matrix_stack.size() > 0) {
02337         // restore current matrix from stack
02338         MMSMatrix matrix;
02339         this->matrix_stack.top().getMatrix(matrix);
02340         this->matrix_stack.pop();
02341         setCurrentMatrix(matrix);
02342         return true;
02343     }
02344 
02345     return false;
02346 }
02347 
02348 
02349 bool MMSFBGL::clear(unsigned char r, unsigned char g, unsigned char b, unsigned char a) {
02350 
02351     INITCHECK;
02352 
02353     // specify the clear value for the color buffer
02354     glClearColor((!r)?0:(r==0xff)?1:(float)r/255,
02355                  (!g)?0:(g==0xff)?1:(float)g/255,
02356                  (!b)?0:(b==0xff)?1:(float)b/255,
02357                  (!a)?0:(a==0xff)?1:(float)a/255);
02358     ERROR_CHECK_BOOL("glClearColor()");
02359 
02360 #ifdef __HAVE_GL2__
02361     // specify the clear value for the depth buffer
02362     glClearDepth(1.0);
02363     ERROR_CHECK_BOOL("glClearDepth(1.0)");
02364 #endif
02365 
02366 #ifdef __HAVE_GLES2__
02367     // specify the clear value for the depth buffer
02368     glClearDepthf(1.0);
02369     ERROR_CHECK_BOOL("glClearDepthf(1.0)");
02370 #endif
02371 
02372     // clear color and depth buffer if existent
02373     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
02374     ERROR_CHECK_BOOL("glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)");
02375 
02376     return true;
02377 }
02378 
02379 
02380 bool MMSFBGL::setColor(unsigned char r, unsigned char g, unsigned char b, unsigned char a) {
02381 
02382     INITCHECK;
02383 
02384     // change the current color
02385     this->current_color_r = r;
02386     this->current_color_g = g;
02387     this->current_color_b = b;
02388     this->current_color_a = a;
02389 
02390 #ifdef __HAVE_GL2__
02391     glColor4ub(r, g, b, a);
02392     ERROR_CHECK_BOOL("glColor4ub()");
02393     return true;
02394 #endif
02395 
02396 #ifdef __HAVE_GLES2__
02397     if (!this->FSColorLoc_initialized) {
02398         // get the location of color uniform variable within the fragment shader
02399         this->FSColorLoc = -1;
02400         if (this->po_current) {
02401             this->FSColorLoc = glGetUniformLocation(this->po_current, "FSColor");
02402             ERROR_CHECK_BOOL("glGetUniformLocation(this->po_current, \"FSColor\")");
02403 
02404             this->FSColorLoc_initialized = true;
02405         }
02406     }
02407 
02408     if (this->FSColorLoc >= 0) {
02409         // store the new color for the fragment shader
02410         glUniform4f(this->FSColorLoc,
02411                     (!r)?0:(r==0xff)?1:(float)r/255,
02412                     (!g)?0:(g==0xff)?1:(float)g/255,
02413                     (!b)?0:(b==0xff)?1:(float)b/255,
02414                     (!a)?0:(a==0xff)?1:(float)a/255);
02415         ERROR_CHECK_BOOL("glUniform4f(this->FSColorLoc,...)");
02416     }
02417 
02418     return true;
02419 #endif
02420 }
02421 
02422 
02423 bool MMSFBGL::drawLine2D(float x1, float y1, float x2, float y2) {
02424 
02425     INITCHECK;
02426 
02427     disableVertexBuffer();
02428 
02429 #ifdef __HAVE_GL2__
02430 printf("drawline2d %f,%f,%f,%f\n", x1,y1,x2,y2);
02431     glBegin(GL_LINES);
02432         glVertex2f(x1, y1);
02433         glVertex2f(x2, y2);
02434     glEnd();
02435     ERROR_CHECK_BOOL("glBegin(GL_LINES)");
02436 
02437 #endif
02438 
02439 #ifdef __HAVE_GLES2__
02440 
02441     // configure generic vertex attribute array
02442     GLfloat vertices[] = {x1,y1,x2,y2};
02443     glEnableVertexAttribArray(MMSFBGL_VSV_LOC);
02444     ERROR_CHECK_BOOL("glEnableVertexAttribArray(MMSFBGL_VSV_LOC)");
02445 
02446     glVertexAttribPointer(MMSFBGL_VSV_LOC, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), vertices);
02447     ERROR_CHECK_BOOL("glVertexAttribPointer(MMSFBGL_VSV_LOC,...)");
02448 
02449     // draw it
02450     glDrawArrays(GL_LINES, 0, 3);
02451     ERROR_CHECK_BOOL("glDrawArrays(GL_LINES,...)");
02452 
02453 #endif
02454 
02455     return true;
02456 }
02457 
02458 
02459 bool MMSFBGL::drawLine2Di(int x1, int y1, int x2, int y2) {
02460     if (x1 == x2 || y1 == y2) {
02461         // horizontal or vertical line or only one pixel
02462         return fillRectangle2Di(x1, y1, x2, y2);
02463     }
02464     else {
02465         // change pixel based values to float values and draw it
02466         return drawLine2D(OGL_CALC_COORD_MIDDLE(x1, x2), OGL_CALC_COORD_MIDDLE(y1, y2),
02467                           OGL_CALC_COORD_MIDDLE(x2, x1), OGL_CALC_COORD_MIDDLE(y2, y1));
02468     }
02469 }
02470 
02471 
02472 bool MMSFBGL::drawRectangle2D(float x1, float y1, float x2, float y2) {
02473 
02474     INITCHECK;
02475 
02476     disableVertexBuffer();
02477 
02478 #ifdef __HAVE_GL2__
02479 
02480     glBegin(GL_LINE_STRIP);
02481         glVertex2f(x1, y1);
02482         glVertex2f(x2, y1);
02483         glVertex2f(x2, y2);
02484         glVertex2f(x1, y2);
02485         glVertex2f(x1, y1);
02486     glEnd();
02487     ERROR_CHECK_BOOL("glBegin(GL_LINE_STRIP)");
02488 
02489 #endif
02490 
02491 #ifdef __HAVE_GLES2__
02492 
02493     // configure generic vertex attribute array
02494     GLfloat vertices[] = {x1,y1,x2,y1,x2,y2,x1,y2,x1,y1};
02495     glEnableVertexAttribArray(MMSFBGL_VSV_LOC);
02496     ERROR_CHECK_BOOL("glEnableVertexAttribArray(MMSFBGL_VSV_LOC)");
02497 
02498     glVertexAttribPointer(MMSFBGL_VSV_LOC, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), vertices);
02499     ERROR_CHECK_BOOL("glVertexAttribPointer(MMSFBGL_VSV_LOC,...)");
02500 
02501     // draw it
02502     glDrawArrays(GL_LINE_STRIP, 0, 5);
02503     ERROR_CHECK_BOOL("glDrawArrays(GL_LINE_STRIP,...)");
02504 
02505 #endif
02506 
02507     return true;
02508 }
02509 
02510 
02511 bool MMSFBGL::drawRectangle2Di(int x1, int y1, int x2, int y2) {
02512     // change pixel based values to float values and draw it
02513     return drawRectangle2D(OGL_CALC_COORD_MIDDLE(x1, x2), OGL_CALC_COORD_MIDDLE(y1, y2),
02514                             OGL_CALC_COORD_MIDDLE(x2, x1), OGL_CALC_COORD_MIDDLE(y2, y1));
02515 }
02516 
02517 
02518 
02519 
02520 
02521 
02522 bool MMSFBGL::fillTriangle(float x1, float y1, float z1,
02523                                float x2, float y2, float z2,
02524                                float x3, float y3, float z3) {
02525 
02526     INITCHECK;
02527 
02528     disableVertexBuffer();
02529 
02530     // configure generic vertex attribute array
02531     GLfloat vertices[] = {x1,y1,z1,x2,y2,z2,x3,y3,z3};
02532     glEnableVertexAttribArray(MMSFBGL_VSV_LOC);
02533     ERROR_CHECK_BOOL("glEnableVertexAttribArray(MMSFBGL_VSV_LOC)");
02534 
02535     glVertexAttribPointer(MMSFBGL_VSV_LOC, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), vertices);
02536     ERROR_CHECK_BOOL("glVertexAttribPointer(MMSFBGL_VSV_LOC,...)");
02537 
02538     // draw it
02539     glDrawArrays(GL_TRIANGLES, 0, 3);
02540     ERROR_CHECK_BOOL("glDrawArrays(GL_TRIANGLES,...)");
02541 
02542     return true;
02543 }
02544 
02545 bool MMSFBGL::fillTriangle2D(float x1, float y1, float x2, float y2, float x3, float y3) {
02546 
02547     INITCHECK;
02548 
02549     disableVertexBuffer();
02550 
02551 #ifdef __HAVE_GL2__
02552 
02553     glBegin(GL_POLYGON);
02554     glVertex2f(x1, y1);
02555     glVertex2f(x2, y2);
02556     glVertex2f(x3, y3);
02557     glEnd();
02558     ERROR_CHECK_BOOL("glBegin(GL_POLYGON)");
02559 
02560 #endif
02561 
02562 #ifdef __HAVE_GLES2__
02563 
02564     // configure generic vertex attribute array
02565     GLfloat vertices[] = {x1,y1,x2,y2,x3,y3};
02566     glEnableVertexAttribArray(MMSFBGL_VSV_LOC);
02567     ERROR_CHECK_BOOL("glEnableVertexAttribArray(MMSFBGL_VSV_LOC)");
02568 
02569     glVertexAttribPointer(MMSFBGL_VSV_LOC, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), vertices);
02570     ERROR_CHECK_BOOL("glVertexAttribPointer(MMSFBGL_VSV_LOC,...)");
02571 
02572     // draw it
02573     glDrawArrays(GL_TRIANGLES, 0, 3);
02574     ERROR_CHECK_BOOL("glDrawArrays(GL_TRIANGLES,...)");
02575 
02576 #endif
02577 
02578     return true;
02579 }
02580 
02581 
02582 
02583 bool MMSFBGL::fillRectangle2D(float x1, float y1, float x2, float y2) {
02584 
02585     INITCHECK;
02586 
02587     disableVertexBuffer();
02588 
02589 #ifdef __HAVE_GL2__
02590 
02591     glRectf(x1, y1, x2, y2);
02592     ERROR_CHECK_BOOL("glRectf()");
02593 
02594 #endif
02595 
02596 #ifdef __HAVE_GLES2__
02597 
02598     // configure generic vertex attribute array
02599     GLfloat vertices[] = {x2,y1,x1,y1,x1,y2,x2,y2};
02600     glEnableVertexAttribArray(MMSFBGL_VSV_LOC);
02601     ERROR_CHECK_BOOL("glEnableVertexAttribArray(MMSFBGL_VSV_LOC)");
02602 
02603     glVertexAttribPointer(MMSFBGL_VSV_LOC, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), vertices);
02604     ERROR_CHECK_BOOL("glVertexAttribPointer(MMSFBGL_VSV_LOC,...)");
02605 
02606     // draw it
02607     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
02608     ERROR_CHECK_BOOL("glDrawArrays(GL_TRIANGLE_FAN,...)");
02609 
02610 #endif
02611 
02612     return true;
02613 }
02614 
02615 
02616 bool MMSFBGL::fillRectangle2Di(int x1, int y1, int x2, int y2) {
02617     // change pixel based values to float values and draw it
02618     return fillRectangle2D(OGL_CALC_COORD_F(x1, x2), OGL_CALC_COORD_F(y1, y2),
02619                            OGL_CALC_COORD_S(x2, x1), OGL_CALC_COORD_S(y2, y1));
02620 }
02621 
02622 
02623 
02624 bool MMSFBGL::stretchBlit3D(GLuint src_tex, float sx1, float sy1, float sx2, float sy2,
02625                                   float dx1, float dy1, float dz1,
02626                                   float dx2, float dy2, float dz2,
02627                                   float dx3, float dy3, float dz3,
02628                                   float dx4, float dy4, float dz4) {
02629 
02630     INITCHECK;
02631 
02632     disableVertexBuffer();
02633 
02634     // setup blitting
02635     enableTexture2D(src_tex);
02636 
02637     // setup vertex array and indices
02638     GLfloat vVertices[] = { dx1,  dy1, dz1, // Position 0
02639                             sx1,  sy1,      // TexCoord 0
02640                             dx2, dy2, dz2,  // Position 1
02641                             sx2,  sy1,      // TexCoord 1
02642                             dx3, dy3, dz3,  // Position 2
02643                             sx2,  sy2,      // TexCoord 2
02644                             dx4,  dy4, dz4, // Position 3
02645                             sx1,  sy2       // TexCoord 3
02646                          };
02647 
02648 #ifdef __HAVE_GL2__
02649 
02650     // load the vertex data
02651     glEnableClientState(GL_VERTEX_ARRAY);
02652     ERROR_CHECK_BOOL("glEnableClientState(GL_VERTEX_ARRAY)");
02653     glVertexPointer(3, GL_FLOAT, 5 * sizeof(GLfloat), vVertices);
02654     ERROR_CHECK_BOOL("glVertexPointer()");
02655 
02656     // load the texture coordinates
02657     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
02658     ERROR_CHECK_BOOL("glEnableClientState(GL_TEXTURE_COORD_ARRAY)");
02659     glTexCoordPointer(2, GL_FLOAT, 5 * sizeof(GLfloat), &vVertices[3]);
02660     ERROR_CHECK_BOOL("glTexCoordPointer()");
02661 
02662 #endif
02663 
02664 #ifdef __HAVE_GLES2__
02665 
02666     // load the vertex data
02667     glVertexAttribPointer(MMSFBGL_VSV_LOC, 3, GL_FLOAT,
02668                            GL_FALSE, 5 * sizeof(GLfloat), vVertices );
02669     ERROR_CHECK_BOOL("glVertexAttribPointer(MMSFBGL_VSV_LOC,...)");
02670 
02671     glEnableVertexAttribArray(MMSFBGL_VSV_LOC);
02672     ERROR_CHECK_BOOL("glEnableVertexAttribArray(MMSFBGL_VSV_LOC)");
02673 
02674     // load the texture coordinates
02675     glVertexAttribPointer(VSTexCoordLoc, 2, GL_FLOAT,
02676                            GL_FALSE, 5 * sizeof(GLfloat), &vVertices[3] );
02677     ERROR_CHECK_BOOL("glVertexAttribPointer(VSTexCoordLoc,...)");
02678 
02679     glEnableVertexAttribArray(VSTexCoordLoc);
02680     ERROR_CHECK_BOOL("glEnableVertexAttribArray(VSTexCoordLoc)");
02681 
02682     // bind the texture unit0
02683     glActiveTexture(GL_TEXTURE0);
02684     ERROR_CHECK_BOOL("glActiveTexture(GL_TEXTURE0)");
02685 
02686     glUniform1i(FSTextureLoc, 0);
02687     ERROR_CHECK_BOOL("glUniform1i(FSTextureLoc, 0)");
02688 
02689 #endif
02690 
02691     // finally draw the triangles...
02692     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
02693     ERROR_CHECK_BOOL("glDrawArrays(GL_TRIANGLE_FAN,...)");
02694 
02695     // cleanup
02696     disableTexture2D();
02697 
02698     return true;
02699 }
02700 
02701 
02702 
02703 
02704 bool MMSFBGL::stretchBlit(GLuint src_tex, float sx1, float sy1, float sx2, float sy2,
02705                                           float dx1, float dy1, float dx2, float dy2) {
02706 
02707     INITCHECK;
02708 
02709     disableVertexBuffer();
02710 
02711     // setup blitting
02712     enableTexture2D(src_tex);
02713 
02714 #ifdef __HAVE_GL2__
02715 
02716     glBegin(GL_QUADS);
02717         glTexCoord2f(sx1, sy1);
02718             glVertex2f(dx1, dy1);
02719         glTexCoord2f(sx2, sy1);
02720             glVertex2f(dx2, dy1);
02721         glTexCoord2f(sx2, sy2);
02722             glVertex2f(dx2, dy2);
02723         glTexCoord2f(sx1, sy2);
02724             glVertex2f(dx1, dy2);
02725     glEnd();
02726     ERROR_CHECK_BOOL("glBegin(GL_QUADS)");
02727 
02728 #endif
02729 
02730 #ifdef __HAVE_GLES2__
02731 
02732     GLfloat vVertices[] = { dx1, dy1,   // Position 0
02733                             sx1, sy1,   // TexCoord 0
02734                             dx2, dy1,   // Position 1
02735                             sx2, sy1,   // TexCoord 1
02736                             dx2, dy2,   // Position 2
02737                             sx2, sy2,   // TexCoord 2
02738                             dx1, dy2,   // Position 3
02739                             sx1, sy2    // TexCoord 3
02740                          };
02741 
02742     // Load the vertex position
02743     glVertexAttribPointer (MMSFBGL_VSV_LOC, 2, GL_FLOAT,
02744                            GL_FALSE, 4 * sizeof(GLfloat), vVertices );
02745     ERROR_CHECK_BOOL("glVertexAttribPointer (MMSFBGL_VSV_LOC,...)");
02746 
02747     glEnableVertexAttribArray(MMSFBGL_VSV_LOC);
02748     ERROR_CHECK_BOOL("glEnableVertexAttribArray(MMSFBGL_VSV_LOC)");
02749 
02750     // Load the texture coordinate
02751     glVertexAttribPointer(VSTexCoordLoc, 2, GL_FLOAT,
02752                            GL_FALSE, 4 * sizeof(GLfloat), &vVertices[2]);
02753     ERROR_CHECK_BOOL("glVertexAttribPointer(VSTexCoordLoc,...");
02754 
02755     glEnableVertexAttribArray(VSTexCoordLoc);
02756     ERROR_CHECK_BOOL("glEnableVertexAttribArray(VSTexCoordLoc)");
02757 
02758     // bind the texture unit0
02759     glActiveTexture(GL_TEXTURE0);
02760     ERROR_CHECK_BOOL("glActiveTexture(GL_TEXTURE0)");
02761 
02762     glUniform1i(FSTextureLoc, 0);
02763     ERROR_CHECK_BOOL("glUniform1i(FSTextureLoc,...)");
02764 
02765     // finally draw the triangles...
02766     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
02767     ERROR_CHECK_BOOL("glDrawArrays(GL_TRIANGLE_FAN,...)");
02768 
02769 #endif
02770 
02771     // cleanup
02772     disableTexture2D();
02773 
02774     return true;
02775 }
02776 
02777 
02778 bool MMSFBGL::stretchBliti(GLuint src_tex, int sx1, int sy1, int sx2, int sy2, int sw, int sh,
02779                             int dx1, int dy1, int dx2, int dy2) {
02780 
02781     // change pixel based values to float values and blit it
02782     return stretchBlit(src_tex,
02783                         OGL_CALC_TEXCOORD_F(sx1, sx2, sw),
02784                         OGL_CALC_TEXCOORD_F(sy1, sy2, sh),
02785                         OGL_CALC_TEXCOORD_S(sx2, sx1, sw),
02786                         OGL_CALC_TEXCOORD_S(sy2, sy1, sh),
02787                         OGL_CALC_COORD_F(dx1, dx2),
02788                         OGL_CALC_COORD_F(dy1, dy2),
02789                         OGL_CALC_COORD_S(dx2, dx1),
02790                         OGL_CALC_COORD_S(dy2, dy1));
02791 }
02792 
02793 
02794 
02795 bool MMSFBGL::stretchBlitBuffer(void *buffer, float sx1, float sy1, float sx2, float sy2, int sw, int sh,
02796                                                 float dx1, float dy1, float dx2, float dy2) {
02797 
02798     INITCHECK;
02799 
02800     // alloc and load texture from buffer
02801     GLuint tex;
02802     genTexture(&tex);
02803     initTexture2D(tex, GL_RGBA, buffer, GL_RGBA, sw, sh);
02804 
02805     // blit texture to active FBO
02806     stretchBlit(tex, sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2);
02807 
02808     // delete texture
02809     deleteTexture(tex);
02810 
02811     return true;
02812 }
02813 
02814 
02815 bool MMSFBGL::stretchBlitBufferi(void *buffer, int sx1, int sy1, int sx2, int sy2, int sw, int sh,
02816                                                 int dx1, int dy1, int dx2, int dy2) {
02817 
02818     INITCHECK;
02819 
02820     // alloc and load texture from buffer
02821     GLuint tex;
02822     genTexture(&tex);
02823     initTexture2D(tex, GL_RGBA, buffer, GL_RGBA, sw, sh);
02824 
02825     // blit texture to active FBO
02826     stretchBliti(tex, sx1, sy1, sx2, sy2, sw, sh, dx1, dy1, dx2, dy2);
02827 
02828     // delete texture
02829     deleteTexture(tex);
02830 
02831     return true;
02832 }
02833 
02834 
02835 bool MMSFBGL::blitBuffer2Texture(GLuint dst_tex, bool realloc, void *buffer, int sw, int sh) {
02836 
02837     INITCHECK;
02838 
02839     // load texture from buffer
02840     if (realloc) {
02841         // (re-)allocate texture memory
02842         return initTexture2D(dst_tex, GL_RGBA, buffer, GL_RGBA, sw, sh);
02843     }
02844     else {
02845         // overwrite existing texture memory
02846         return initSubTexture2D(dst_tex, buffer, GL_RGBA, sw, sh, 0, 0);
02847     }
02848 }
02849 
02850 
02851 bool MMSFBGL::drawElements(MMS_VERTEX_ARRAY *vertices, MMS_VERTEX_ARRAY *normals, MMS_VERTEX_ARRAY *texcoords,
02852                            MMS_INDEX_ARRAY *indices) {
02853 
02854     INITCHECK;
02855 
02856     if (!vertices || !indices) {
02857         // minimum parameters are vertices and indices
02858         return false;
02859     }
02860 
02861     disableVertexBuffer();
02862 
02863 #ifdef __HAVE_GL2__
02864 
02865     // load the vertices
02866     if (vertices && vertices->data) {
02867         switch (vertices->dtype) {
02868         case MMS_VERTEX_DATA_TYPE_FLOAT:
02869             glEnableClientState(GL_VERTEX_ARRAY);
02870             glVertexPointer(vertices->eSize, GL_FLOAT, 0, vertices->data);
02871             break;
02872         default:
02873             glDisableClientState(GL_VERTEX_ARRAY);
02874             break;
02875         }
02876     }
02877     else {
02878         glDisableClientState(GL_VERTEX_ARRAY);
02879     }
02880 
02881     // load the normals
02882     if (normals && normals->data) {
02883         switch (normals->dtype) {
02884         case MMS_VERTEX_DATA_TYPE_FLOAT:
02885             glEnableClientState(GL_NORMAL_ARRAY);
02886             glNormalPointer(GL_FLOAT, 0, normals->data);
02887             break;
02888         default:
02889             glDisableClientState(GL_NORMAL_ARRAY);
02890             break;
02891         }
02892     }
02893     else {
02894         glDisableClientState(GL_NORMAL_ARRAY);
02895     }
02896 
02897     // load the texture coordinates
02898     if (texcoords && texcoords->data) {
02899         switch (texcoords->dtype) {
02900         case MMS_VERTEX_DATA_TYPE_FLOAT:
02901             glEnableClientState(GL_TEXTURE_COORD_ARRAY);
02902             glTexCoordPointer(texcoords->eSize, GL_FLOAT, 0, texcoords->data);
02903             break;
02904         default:
02905             glDisableClientState(GL_TEXTURE_COORD_ARRAY);
02906             break;
02907         }
02908     }
02909     else {
02910         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
02911     }
02912 
02913 #endif
02914 
02915 #ifdef __HAVE_GLES2__
02916 
02917     // load the vertices
02918     if (vertices && vertices->data) {
02919         bool enable = false;
02920         switch (vertices->dtype) {
02921         case MMS_VERTEX_DATA_TYPE_FLOAT:
02922             glVertexAttribPointer(MMSFBGL_VSV_LOC, vertices->eSize, GL_FLOAT,
02923                                    GL_FALSE, 0, vertices->data);
02924             ERROR_CHECK_BOOL("glVertexAttribPointer(MMSFBGL_VSV_LOC,,GL_FLOAT,GL_FALSE,...)");
02925             enable = true;
02926             break;
02927 #ifdef GL_HALF_FLOAT_OES
02928         case MMS_VERTEX_DATA_TYPE_HALF_FLOAT:
02929             glVertexAttribPointer(MMSFBGL_VSV_LOC, vertices->eSize, GL_HALF_FLOAT_OES,
02930                                    GL_FALSE, 0, vertices->data);
02931             ERROR_CHECK_BOOL("glVertexAttribPointer(MMSFBGL_VSV_LOC,,GL_HALF_FLOAT_OES,GL_FALSE,...)");
02932             enable = true;
02933             break;
02934 #endif
02935         default:
02936             glDisableVertexAttribArray(MMSFBGL_VSV_LOC);
02937             ERROR_CHECK_BOOL("glDisableVertexAttribArray(MMSFBGL_VSV_LOC)");
02938             break;
02939         }
02940 
02941         if (enable) {
02942             glEnableVertexAttribArray(MMSFBGL_VSV_LOC);
02943             ERROR_CHECK_BOOL("glEnableVertexAttribArray(MMSFBGL_VSV_LOC)");
02944         }
02945     }
02946     else {
02947         glDisableVertexAttribArray(MMSFBGL_VSV_LOC);
02948         ERROR_CHECK_BOOL("glDisableVertexAttribArray(MMSFBGL_VSV_LOC)");
02949     }
02950 
02951     // load the texture coordinates
02952     if (texcoords && texcoords->data) {
02953         bool enable = false;
02954         switch (texcoords->dtype) {
02955         case MMS_VERTEX_DATA_TYPE_FLOAT:
02956             glVertexAttribPointer(VSTexCoordLoc, texcoords->eSize, GL_FLOAT,
02957                                    GL_FALSE, 0, texcoords->data);
02958             ERROR_CHECK_BOOL("glVertexAttribPointer(VSTexCoordLoc,,GL_FLOAT,GL_FALSE,...)");
02959             enable = true;
02960             break;
02961 #ifdef GL_HALF_FLOAT_OES
02962         case MMS_VERTEX_DATA_TYPE_HALF_FLOAT:
02963             glVertexAttribPointer(VSTexCoordLoc, texcoords->eSize, GL_HALF_FLOAT_OES,
02964                                    GL_FALSE, 0, texcoords->data);
02965             ERROR_CHECK_BOOL("glVertexAttribPointer(VSTexCoordLoc,,GL_HALF_FLOAT_OES,GL_FALSE,...)");
02966             enable = true;
02967             break;
02968 #endif
02969         default:
02970             glDisableVertexAttribArray(VSTexCoordLoc);
02971             ERROR_CHECK_BOOL("glDisableVertexAttribArray(VSTexCoordLoc)");
02972             break;
02973         }
02974 
02975         if (enable) {
02976             glEnableVertexAttribArray(VSTexCoordLoc);
02977             ERROR_CHECK_BOOL("glEnableVertexAttribArray(VSTexCoordLoc)");
02978 
02979             // bind the texture unit0
02980             glActiveTexture(GL_TEXTURE0);
02981             ERROR_CHECK_BOOL("glActiveTexture(GL_TEXTURE0)");
02982 
02983             glUniform1i(FSTextureLoc, 0);
02984             ERROR_CHECK_BOOL("glUniform1i(FSTextureLoc, 0)");
02985         }
02986     }
02987     else {
02988         glDisableVertexAttribArray(VSTexCoordLoc);
02989         ERROR_CHECK_BOOL("glDisableVertexAttribArray(VSTexCoordLoc)");
02990     }
02991 
02992 #endif
02993 
02994     // draw elements
02995     // note: MMS_INDEX_ARRAY uses indices with type unsigned int (GL_UNSIGNED_INT)
02996     GLenum mode = GL_TRIANGLES;
02997     switch (indices->type) {
02998     case MMS_INDEX_ARRAY_TYPE_TRIANGLE_STRIP:
02999         mode = GL_TRIANGLE_STRIP;
03000         break;
03001     case MMS_INDEX_ARRAY_TYPE_TRIANGLE_FAN:
03002         mode = GL_TRIANGLE_FAN;
03003         break;
03004     case MMS_INDEX_ARRAY_TYPE_LINES:
03005         mode = GL_LINES;
03006         break;
03007     case MMS_INDEX_ARRAY_TYPE_LINE_STRIP:
03008         mode = GL_LINE_STRIP;
03009         break;
03010     case MMS_INDEX_ARRAY_TYPE_LINE_LOOP:
03011         mode = GL_LINE_LOOP;
03012         break;
03013     default:
03014         break;
03015     }
03016 
03017     if (indices->eNum && indices->data) {
03018         // we have indices
03019         glDrawElements(mode, indices->eNum, GL_UNSIGNED_INT, indices->data);
03020 
03021         // print errors
03022         switch (indices->type) {
03023         case MMS_INDEX_ARRAY_TYPE_TRIANGLES:
03024             ERROR_CHECK_BOOL("glDrawElements(GL_TRIANGLES,...)");
03025             break;
03026         case MMS_INDEX_ARRAY_TYPE_TRIANGLE_STRIP:
03027             ERROR_CHECK_BOOL("glDrawElements(GL_TRIANGLE_STRIP,...)");
03028             break;
03029         case MMS_INDEX_ARRAY_TYPE_TRIANGLE_FAN:
03030             ERROR_CHECK_BOOL("glDrawElements(GL_TRIANGLE_FAN,...)");
03031             break;
03032         case MMS_INDEX_ARRAY_TYPE_LINES:
03033             ERROR_CHECK_BOOL("glDrawElements(GL_LINES,...)");
03034             break;
03035         case MMS_INDEX_ARRAY_TYPE_LINE_STRIP:
03036             ERROR_CHECK_BOOL("glDrawElements(GL_LINE_STRIP,...)");
03037             break;
03038         case MMS_INDEX_ARRAY_TYPE_LINE_LOOP:
03039             ERROR_CHECK_BOOL("glDrawElements(GL_LINE_LOOP,...)");
03040             break;
03041         }
03042     }
03043     else {
03044         // indices not available, we assume that we can access buffers without indices
03045         glDrawArrays(mode, 0, vertices->eNum);
03046 
03047         // print errors
03048         switch (indices->type) {
03049         case MMS_INDEX_ARRAY_TYPE_TRIANGLES:
03050             ERROR_CHECK_BOOL("glDrawArrays(GL_TRIANGLES,...)");
03051             break;
03052         case MMS_INDEX_ARRAY_TYPE_TRIANGLE_STRIP:
03053             ERROR_CHECK_BOOL("glDrawArrays(GL_TRIANGLE_STRIP,...)");
03054             break;
03055         case MMS_INDEX_ARRAY_TYPE_TRIANGLE_FAN:
03056             ERROR_CHECK_BOOL("glDrawArrays(GL_TRIANGLE_FAN,...)");
03057             break;
03058         case MMS_INDEX_ARRAY_TYPE_LINES:
03059             ERROR_CHECK_BOOL("glDrawArrays(GL_LINES,...)");
03060             break;
03061         case MMS_INDEX_ARRAY_TYPE_LINE_STRIP:
03062             ERROR_CHECK_BOOL("glDrawArrays(GL_LINE_STRIP,...)");
03063             break;
03064         case MMS_INDEX_ARRAY_TYPE_LINE_LOOP:
03065             ERROR_CHECK_BOOL("glDrawArrays(GL_LINE_LOOP,...)");
03066             break;
03067         }
03068     }
03069 
03070     return true;
03071 }
03072 
03073 bool MMSFBGL::drawElements(MMS_VERTEX_BUFFER *vertices, MMS_VERTEX_BUFFER *normals, MMS_VERTEX_BUFFER *texcoords,
03074                            MMS_INDEX_BUFFER *indices) {
03075     INITCHECK;
03076 
03077     if (!vertices || !indices) {
03078         // minimum parameters are vertices and indices
03079         return false;
03080     }
03081 
03082 #ifdef __HAVE_GL2__
03083 
03084     // load the vertices
03085     if (vertices && vertices->bo) {
03086         switch (vertices->dtype) {
03087         case MMS_VERTEX_DATA_TYPE_FLOAT:
03088             glEnableClientState(GL_VERTEX_ARRAY);
03089             bindBuffer(GL_ARRAY_BUFFER, vertices->bo);
03090             glVertexPointer(vertices->eSize, GL_FLOAT, 0, (const GLvoid*)vertices->offs);
03091             break;
03092         default:
03093             glDisableClientState(GL_VERTEX_ARRAY);
03094             break;
03095         }
03096     }
03097     else {
03098         glDisableClientState(GL_VERTEX_ARRAY);
03099     }
03100 
03101     // load the normals
03102     if (normals && normals->bo) {
03103         switch (normals->dtype) {
03104         case MMS_VERTEX_DATA_TYPE_FLOAT:
03105             glEnableClientState(GL_NORMAL_ARRAY);
03106             bindBuffer(GL_ARRAY_BUFFER, normals->bo);
03107             glNormalPointer(GL_FLOAT, 0, (const GLvoid*)normals->offs);
03108             break;
03109         default:
03110             glDisableClientState(GL_NORMAL_ARRAY);
03111             break;
03112         }
03113     }
03114     else {
03115         glDisableClientState(GL_NORMAL_ARRAY);
03116     }
03117 
03118     // load the texture coordinates
03119     if (texcoords && texcoords->bo) {
03120         switch (texcoords->dtype) {
03121         case MMS_VERTEX_DATA_TYPE_FLOAT:
03122             glEnableClientState(GL_TEXTURE_COORD_ARRAY);
03123             bindBuffer(GL_ARRAY_BUFFER, texcoords->bo);
03124             glTexCoordPointer(texcoords->eSize, GL_FLOAT, 0, (const GLvoid*)texcoords->offs);
03125             break;
03126         default:
03127             glDisableClientState(GL_TEXTURE_COORD_ARRAY);
03128             break;
03129         }
03130     }
03131     else {
03132         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
03133     }
03134 
03135 #endif
03136 
03137 #ifdef __HAVE_GLES2__
03138 
03139     // load the vertices
03140     if (vertices && vertices->bo) {
03141         bool enable = false;
03142         switch (vertices->dtype) {
03143         case MMS_VERTEX_DATA_TYPE_FLOAT:
03144             bindBuffer(GL_ARRAY_BUFFER, vertices->bo);
03145             glVertexAttribPointer(MMSFBGL_VSV_LOC, vertices->eSize, GL_FLOAT,
03146                                    GL_FALSE, 0, (const GLvoid*)vertices->offs);
03147             ERROR_CHECK_BOOL("glVertexAttribPointer(MMSFBGL_VSV_LOC,,GL_FLOAT,GL_FALSE,...)");
03148             enable = true;
03149             break;
03150 #ifdef GL_HALF_FLOAT_OES
03151         case MMS_VERTEX_DATA_TYPE_HALF_FLOAT:
03152             bindBuffer(GL_ARRAY_BUFFER, vertices->bo);
03153             glVertexAttribPointer(MMSFBGL_VSV_LOC, vertices->eSize, GL_HALF_FLOAT_OES,
03154                                    GL_FALSE, 0, (const GLvoid*)vertices->offs);
03155             ERROR_CHECK_BOOL("glVertexAttribPointer(MMSFBGL_VSV_LOC,,GL_HALF_FLOAT_OES,GL_FALSE,...)");
03156             enable = true;
03157             break;
03158 #endif
03159         default:
03160             glDisableVertexAttribArray(MMSFBGL_VSV_LOC);
03161             ERROR_CHECK_BOOL("glDisableVertexAttribArray(MMSFBGL_VSV_LOC)");
03162             break;
03163         }
03164 
03165         if (enable) {
03166             glEnableVertexAttribArray(MMSFBGL_VSV_LOC);
03167             ERROR_CHECK_BOOL("glEnableVertexAttribArray(MMSFBGL_VSV_LOC)");
03168         }
03169     }
03170     else {
03171         glDisableVertexAttribArray(MMSFBGL_VSV_LOC);
03172         ERROR_CHECK_BOOL("glDisableVertexAttribArray(MMSFBGL_VSV_LOC)");
03173     }
03174 
03175     // load the texture coordinates
03176     if (texcoords && texcoords->bo) {
03177         bool enable = false;
03178         switch (texcoords->dtype) {
03179         case MMS_VERTEX_DATA_TYPE_FLOAT:
03180             bindBuffer(GL_ARRAY_BUFFER, texcoords->bo);
03181             glVertexAttribPointer(VSTexCoordLoc, texcoords->eSize, GL_FLOAT,
03182                                    GL_FALSE, 0, (const GLvoid*)texcoords->offs);
03183             ERROR_CHECK_BOOL("glVertexAttribPointer(VSTexCoordLoc,,GL_FLOAT,GL_FALSE,...)");
03184             enable = true;
03185             break;
03186 #ifdef GL_HALF_FLOAT_OES
03187         case MMS_VERTEX_DATA_TYPE_HALF_FLOAT:
03188             bindBuffer(GL_ARRAY_BUFFER, texcoords->bo);
03189             glVertexAttribPointer(VSTexCoordLoc, texcoords->eSize, GL_HALF_FLOAT_OES,
03190                                    GL_FALSE, 0, (const GLvoid*)texcoords->offs);
03191             ERROR_CHECK_BOOL("glVertexAttribPointer(VSTexCoordLoc,,GL_HALF_FLOAT_OES,GL_FALSE,...)");
03192             enable = true;
03193             break;
03194 #endif
03195         default:
03196             glDisableVertexAttribArray(VSTexCoordLoc);
03197             ERROR_CHECK_BOOL("glDisableVertexAttribArray(VSTexCoordLoc)");
03198             break;
03199         }
03200 
03201         if (enable) {
03202             glEnableVertexAttribArray(VSTexCoordLoc);
03203             ERROR_CHECK_BOOL("glEnableVertexAttribArray(VSTexCoordLoc)");
03204 
03205             // bind the texture unit0
03206             glActiveTexture(GL_TEXTURE0);
03207             ERROR_CHECK_BOOL("glActiveTexture(GL_TEXTURE0)");
03208 
03209             glUniform1i(FSTextureLoc, 0);
03210             ERROR_CHECK_BOOL("glUniform1i(FSTextureLoc, 0)");
03211         }
03212     }
03213     else {
03214         glDisableVertexAttribArray(VSTexCoordLoc);
03215         ERROR_CHECK_BOOL("glDisableVertexAttribArray(VSTexCoordLoc)");
03216     }
03217 
03218 #endif
03219 
03220     // bind the indices
03221 /*  if (indices && indices->bo) {
03222         bindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices->bo);
03223     }
03224     else {
03225         bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
03226     }*/
03227 
03228     // draw elements
03229     // note: MMS_INDEX_ARRAY uses indices with type unsigned int (GL_UNSIGNED_INT)
03230     GLenum mode = GL_TRIANGLES;
03231     switch (indices->type) {
03232     case MMS_INDEX_ARRAY_TYPE_TRIANGLE_STRIP:
03233         mode = GL_TRIANGLE_STRIP;
03234         break;
03235     case MMS_INDEX_ARRAY_TYPE_TRIANGLE_FAN:
03236         mode = GL_TRIANGLE_FAN;
03237         break;
03238     case MMS_INDEX_ARRAY_TYPE_LINES:
03239         mode = GL_LINES;
03240         break;
03241     case MMS_INDEX_ARRAY_TYPE_LINE_STRIP:
03242         mode = GL_LINE_STRIP;
03243         break;
03244     case MMS_INDEX_ARRAY_TYPE_LINE_LOOP:
03245         mode = GL_LINE_LOOP;
03246         break;
03247     default:
03248         break;
03249     }
03250 
03251 
03252     if (indices->eNum && indices->bo) {
03253         // we have indices
03254         glDrawElements(mode, indices->eNum, GL_UNSIGNED_INT, NULL);
03255 
03256         // print errors
03257         switch (indices->type) {
03258         case MMS_INDEX_ARRAY_TYPE_TRIANGLES:
03259             ERROR_CHECK_BOOL("glDrawElements(GL_TRIANGLES,...)");
03260             break;
03261         case MMS_INDEX_ARRAY_TYPE_TRIANGLE_STRIP:
03262             ERROR_CHECK_BOOL("glDrawElements(GL_TRIANGLE_STRIP,...)");
03263             break;
03264         case MMS_INDEX_ARRAY_TYPE_TRIANGLE_FAN:
03265             ERROR_CHECK_BOOL("glDrawElements(GL_TRIANGLE_FAN,...)");
03266             break;
03267         case MMS_INDEX_ARRAY_TYPE_LINES:
03268             ERROR_CHECK_BOOL("glDrawElements(GL_LINES,...)");
03269             break;
03270         case MMS_INDEX_ARRAY_TYPE_LINE_STRIP:
03271             ERROR_CHECK_BOOL("glDrawElements(GL_LINE_STRIP,...)");
03272             break;
03273         case MMS_INDEX_ARRAY_TYPE_LINE_LOOP:
03274             ERROR_CHECK_BOOL("glDrawElements(GL_LINE_LOOP,...)");
03275             break;
03276         }
03277     }
03278     else {
03279         // indices not available, we assume that we can access buffers without indices
03280         glDrawArrays(mode, 0, vertices->eNum);
03281 
03282         // print errors
03283         switch (indices->type) {
03284         case MMS_INDEX_ARRAY_TYPE_TRIANGLES:
03285             ERROR_CHECK_BOOL("glDrawArrays(GL_TRIANGLES,...)");
03286             break;
03287         case MMS_INDEX_ARRAY_TYPE_TRIANGLE_STRIP:
03288             ERROR_CHECK_BOOL("glDrawArrays(GL_TRIANGLE_STRIP,...)");
03289             break;
03290         case MMS_INDEX_ARRAY_TYPE_TRIANGLE_FAN:
03291             ERROR_CHECK_BOOL("glDrawArrays(GL_TRIANGLE_FAN,...)");
03292             break;
03293         case MMS_INDEX_ARRAY_TYPE_LINES:
03294             ERROR_CHECK_BOOL("glDrawArrays(GL_LINES,...)");
03295             break;
03296         case MMS_INDEX_ARRAY_TYPE_LINE_STRIP:
03297             ERROR_CHECK_BOOL("glDrawArrays(GL_LINE_STRIP,...)");
03298             break;
03299         case MMS_INDEX_ARRAY_TYPE_LINE_LOOP:
03300             ERROR_CHECK_BOOL("glDrawArrays(GL_LINE_LOOP,...)");
03301             break;
03302         }
03303     }
03304 
03305     return true;
03306 }
03307 
03308 
03309 #endif
03310 
03311 
03312 
03313 
03314 
03315 
03316 
03317 
03318 

Generated by doxygen