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