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