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

Generated by doxygen