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
00034 #include "mmsgui/fb/mmsfbbackendinterface.h"
00035 #include "mmstools/tools.h"
00036
00037 #define BEI_SOURCE_WIDTH ((!req->source->is_sub_surface)?req->source->config.w:req->source->root_parent->config.w)
00038 #define BEI_SOURCE_HEIGHT ((!req->source->is_sub_surface)?req->source->config.h:req->source->root_parent->config.h)
00039
00040 #define BEI_SURFACE_WIDTH ((!req->surface->is_sub_surface)?req->surface->config.w:req->surface->root_parent->config.w)
00041 #define BEI_SURFACE_HEIGHT ((!req->surface->is_sub_surface)?req->surface->config.h:req->surface->root_parent->config.h)
00042 #define BEI_SURFACE_BOTTOM (BEI_SURFACE_HEIGHT - 1)
00043 #define BEI_SURFACE_BOTTOM_F (float)BEI_SURFACE_BOTTOM
00044
00045
00046 #define GET_OFFS(surface) \
00047 int xoff = 0; int yoff = 0; \
00048 if (surface->is_sub_surface) { \
00049 xoff = surface->sub_surface_xoff; \
00050 yoff = surface->sub_surface_yoff; }
00051
00052 #define GET_OFFS_SRC(surface) \
00053 int src_xoff = 0; \
00054 int src_yoff = 0; \
00055 int src_rootw = surface->config.w; \
00056 int src_rooth = surface->config.h; \
00057 if (surface->is_sub_surface) { \
00058 src_xoff = surface->sub_surface_xoff; \
00059 src_yoff = surface->sub_surface_yoff; \
00060 src_rootw = surface->root_parent->config.w; \
00061 src_rooth = surface->root_parent->config.h; }
00062
00063
00064
00065 #ifdef __HAVE_OPENGL__
00066
00067
00068 #define OGL_SCISSOR(surface, X, Y, W, H) \
00069 if (surface->config.surface_buffer->ogl_fbo) mmsfbgl.setScissor(X, Y, W, H); \
00070 else mmsfbgl.setScissor(X, BEI_SURFACE_HEIGHT - (H) - (Y), W, H);
00071
00072
00073 #define INIT_OGL_DRAWING(surface, drawingflags) { \
00074 switch (drawingflags) { \
00075 case MMSFB_DRAW_BLEND: \
00076 mmsfbgl.enableBlend(); \
00077 mmsfbgl.setDrawingMode(); \
00078 break; \
00079 default: \
00080 mmsfbgl.disableBlend(); \
00081 mmsfbgl.setDrawingMode(); \
00082 break; } \
00083 mmsfbgl.setColor(surface->config.color.r, surface->config.color.g, surface->config.color.b, surface->config.color.a); }
00084
00085
00086
00087 #define INIT_OGL_BLITTING(surface, blittingflags) \
00088 switch (blittingflags) { \
00089 case MMSFB_BLIT_BLEND_ALPHACHANNEL: \
00090 mmsfbgl.enableBlend(); \
00091 mmsfbgl.setTexEnvReplace(GL_RGBA); \
00092 break; \
00093 case MMSFB_BLIT_BLEND_COLORALPHA: \
00094 mmsfbgl.disableBlend(); \
00095 mmsfbgl.setTexEnvModulate(GL_RGBA); \
00096 mmsfbgl.setColor(255, 255, 255, surface->config.color.a); \
00097 break; \
00098 case MMSFB_BLIT_BLEND_ALPHACHANNEL + MMSFB_BLIT_BLEND_COLORALPHA: \
00099 mmsfbgl.enableBlend(); \
00100 mmsfbgl.setTexEnvModulate(GL_RGBA); \
00101 mmsfbgl.setColor(255, 255, 255, surface->config.color.a); \
00102 break; \
00103 case MMSFB_BLIT_COLORIZE: \
00104 mmsfbgl.disableBlend(); \
00105 mmsfbgl.setTexEnvModulate(GL_RGBA); \
00106 mmsfbgl.setColor(surface->config.color.r, surface->config.color.g, surface->config.color.b, 0xff); \
00107 break; \
00108 case MMSFB_BLIT_BLEND_ALPHACHANNEL + MMSFB_BLIT_COLORIZE: \
00109 mmsfbgl.enableBlend(); \
00110 mmsfbgl.setTexEnvModulate(GL_RGBA); \
00111 mmsfbgl.setColor(surface->config.color.r, surface->config.color.g, surface->config.color.b, 0xff); \
00112 break; \
00113 case MMSFB_BLIT_BLEND_COLORALPHA + MMSFB_BLIT_COLORIZE: \
00114 mmsfbgl.disableBlend(); \
00115 mmsfbgl.setTexEnvModulate(GL_RGBA); \
00116 mmsfbgl.setColor(surface->config.color.r, surface->config.color.g, surface->config.color.b, surface->config.color.a); \
00117 break; \
00118 case MMSFB_BLIT_BLEND_ALPHACHANNEL + MMSFB_BLIT_BLEND_COLORALPHA + MMSFB_BLIT_COLORIZE: \
00119 mmsfbgl.enableBlend(); \
00120 mmsfbgl.setTexEnvModulate(GL_RGBA); \
00121 mmsfbgl.setColor(surface->config.color.r, surface->config.color.g, surface->config.color.b, surface->config.color.a); \
00122 break; \
00123 default: \
00124 mmsfbgl.disableBlend(); \
00125 mmsfbgl.setTexEnvReplace(GL_RGBA); \
00126 break; }
00127
00128
00129 #define ENABLE_OGL_DEPTHTEST(surface, readonly) \
00130 if (!readonly && surface->config.surface_buffer) { \
00131 if (!surface->is_sub_surface) { \
00132 surface->config.surface_buffer->ogl_unchanged_depth_buffer = false; \
00133 } else { \
00134 surface->root_parent->config.surface_buffer->ogl_unchanged_depth_buffer = surface->config.surface_buffer->ogl_unchanged_depth_buffer = false; \
00135 } \
00136 } \
00137 mmsfbgl.enableDepthTest(readonly);
00138
00139
00140 #define DISABLE_OGL_DEPTHTEST(surface, mark_as_unchanged) \
00141 if (mark_as_unchanged && surface->config.surface_buffer) { \
00142 if (!surface->is_sub_surface) { \
00143 surface->config.surface_buffer->ogl_unchanged_depth_buffer = true; \
00144 } else { \
00145 surface->root_parent->config.surface_buffer->ogl_unchanged_depth_buffer = surface->config.surface_buffer->ogl_unchanged_depth_buffer = true; \
00146 } \
00147 } \
00148 mmsfbgl.disableDepthTest();
00149
00150
00151 #define IS_OGL_DEPTH_BUFFER_UNCHANGED(surface) \
00152 ((!surface->is_sub_surface && surface->config.surface_buffer && surface->config.surface_buffer->ogl_unchanged_depth_buffer) \
00153 ||(surface->is_sub_surface && surface->root_parent->config.surface_buffer && surface->root_parent->config.surface_buffer->ogl_unchanged_depth_buffer))
00154
00155
00156 #ifdef __HAVE_GL2__
00157 #define OGL_DRAW_POINT(x, y) { glBegin(GL_POINTS); glVertex2f((float)(x) + 0.5, (float)(BEI_SURFACE_BOTTOM - (y)) + 0.5); glEnd(); }
00158 #endif
00159
00160 #ifdef __HAVE_GLES2__
00161 #define OGL_DRAW_POINT(x, y) {}
00162 #endif
00163
00164 #define OGL_SINGLE_POINT_FALLBACK(x1, y1, x2, y2) \
00165 if (x1 == x2 && y1 == y2) OGL_DRAW_POINT(x1, y1) else
00166
00167
00168 #define OGL_SINGLE_POINT_FALLBACK2(x1, y1, x2, y2, x3, y3) \
00169 if (x1 == x2 && x1 == x3 && y1 == y2 && y1 == y3) OGL_DRAW_POINT(x1, y1) else
00170
00171
00172 #define OGL_CALC_COORD(v1, v2) (((v1)<(v2)) ? (float)(v1) : (float)(v1) + 0.99)
00173
00174 #define OGL_CALC_2X_N(v1, v2, width) (OGL_CALC_COORD(v1, v2) / (width))
00175 #define OGL_CALC_2Y_N(v1, v2, height) (OGL_CALC_COORD(v1, v2) / (height))
00176
00177
00178 #define OGL_CALC_3X(v1, v2, v3) (((v1)<=(v2) && (v1)<=(v3)) ? (float)(v1) : ((v1)>(v2) && (v1)>(v3)) ? (float)(v1) + 0.99 : (float)(v1) + 0.5)
00179 #define OGL_CALC_3Y(v1, v2, v3) (((v1)<=(v2) && (v1)<=(v3)) ? BEI_SURFACE_BOTTOM_F - (float)(v1) + 0.99 : ((v1)>(v2) && (v1)>(v3)) ? BEI_SURFACE_BOTTOM_F - (float)(v1) : BEI_SURFACE_BOTTOM_F - (float)(v1) + 0.5)
00180
00181
00182
00183 #define OGL_FILL_RECTANGLE(x1, y1, x2, y2) \
00184 OGL_SINGLE_POINT_FALLBACK(x1, y1, x2, y2) \
00185 mmsfbgl.fillRectangle2Di(x1, y1, x2, y2);
00186
00187
00188 #define OGL_DRAW_RECTANGLE(x1, y1, x2, y2) \
00189 OGL_SINGLE_POINT_FALLBACK(x1, y1, x2, y2) \
00190 mmsfbgl.drawRectangle2Di(x1, y1, x2, y2);
00191
00192 #endif
00193
00194
00195 #ifdef __HAVE_GL2__
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226 #define OGL_DRAW_LINE(x1, y1, x2, y2) \
00227 OGL_SINGLE_POINT_FALLBACK(x1, y1, x2, y2) { \
00228 glBegin(GL_LINES); \
00229 glVertex2f(OGL_CALC_COORD(x1, x2), OGL_CALC_COORD(y1, y2)); \
00230 glVertex2f(OGL_CALC_COORD(x2, x1), OGL_CALC_COORD(y2, y1)); \
00231 glEnd(); }
00232
00233
00234 #define OGL_FILL_TRIANGLE(x1, y1, x2, y2, x3, y3) \
00235 OGL_SINGLE_POINT_FALLBACK2(x1, y1, x2, y2, x3, y3) { \
00236 glBegin(GL_TRIANGLES); \
00237 glVertex2f(OGL_CALC_3X(x1, x2, x3), OGL_CALC_3Y(y1, y2, y3)); \
00238 glVertex2f(OGL_CALC_3X(x2, x3, x1), OGL_CALC_3Y(y2, y3, y1)); \
00239 glVertex2f(OGL_CALC_3X(x3, x1, x2), OGL_CALC_3Y(y3, y1, y2)); \
00240 glEnd(); }
00241
00242 #define OGL_DRAW_TRIANGLE(x1, y1, x2, y2, x3, y3) \
00243 OGL_SINGLE_POINT_FALLBACK2(x1, y1, x2, y2, x3, y3) { \
00244 glBegin(GL_LINE_STRIP); \
00245 glVertex2f(OGL_CALC_3X(x1, x2, x3), OGL_CALC_3Y(y1, y2, y3)); \
00246 glVertex2f(OGL_CALC_3X(x2, x3, x1), OGL_CALC_3Y(y2, y3, y1)); \
00247 glVertex2f(OGL_CALC_3X(x3, x1, x2), OGL_CALC_3Y(y3, y1, y2)); \
00248 glVertex2f(OGL_CALC_3X(x1, x2, x3), OGL_CALC_3Y(y1, y2, y3)); \
00249 glEnd(); }
00250
00251
00252 #endif
00253
00254 MMSFBBackEndInterface::MMSFBBackEndInterface(int queue_size) : MMSThreadServer(queue_size, "MMSFBBackEndInterface") {
00255
00256 }
00257
00258 void MMSFBBackEndInterface::processData(void *in_data, int in_data_len, void **out_data, int *out_data_len) {
00259 if (!in_data) return;
00260
00261 BEI_REQUEST_TYPE *type = (BEI_REQUEST_TYPE *)in_data;
00262
00263 switch (*type) {
00264 case BEI_REQUEST_TYPE_INIT:
00265 processInit((BEI_INIT *)in_data);
00266 break;
00267 case BEI_REQUEST_TYPE_SWAP:
00268 processSwap((BEI_SWAP *)in_data);
00269 break;
00270 case BEI_REQUEST_TYPE_ALLOC:
00271 processAlloc((BEI_ALLOC *)in_data);
00272 break;
00273 case BEI_REQUEST_TYPE_FREE:
00274 processFree((BEI_FREE *)in_data);
00275 break;
00276 case BEI_REQUEST_TYPE_CLEAR:
00277 processClear((BEI_CLEAR *)in_data);
00278 break;
00279 case BEI_REQUEST_TYPE_FILLRECTANGLE:
00280 processFillRectangle((BEI_FILLRECTANGLE *)in_data);
00281 break;
00282 case BEI_REQUEST_TYPE_FILLTRIANGLE:
00283 processFillTriangle((BEI_FILLTRIANGLE *)in_data);
00284 break;
00285 case BEI_REQUEST_TYPE_DRAWLINE:
00286 processDrawLine((BEI_DRAWLINE *)in_data);
00287 break;
00288 case BEI_REQUEST_TYPE_DRAWRECTANGLE:
00289 processDrawRectangle((BEI_DRAWRECTANGLE *)in_data);
00290 break;
00291 case BEI_REQUEST_TYPE_DRAWTRIANGLE:
00292 processDrawTriangle((BEI_DRAWTRIANGLE *)in_data);
00293 break;
00294 case BEI_REQUEST_TYPE_BLIT:
00295 processBlit((BEI_BLIT *)in_data);
00296 break;
00297 case BEI_REQUEST_TYPE_STRETCHBLIT:
00298 processStretchBlit((BEI_STRETCHBLIT *)in_data);
00299 break;
00300 case BEI_REQUEST_TYPE_STRETCHBLITBUFFER:
00301 processStretchBlitBuffer((BEI_STRETCHBLITBUFFER *)in_data);
00302 break;
00303 case BEI_REQUEST_TYPE_CREATEALPHATEXTURE:
00304 processCreateAlphaTexture((BEI_CREATEALPHATEXTURE *)in_data);
00305 break;
00306 case BEI_REQUEST_TYPE_DELETETEXTURE:
00307 processDeleteTexture((BEI_DELETETEXTURE *)in_data);
00308 break;
00309 case BEI_REQUEST_TYPE_DRAWSTRING:
00310 processDrawString((BEI_DRAWSTRING *)in_data);
00311 break;
00312 case BEI_REQUEST_TYPE_RENDERSCENE:
00313 processRenderScene((BEI_RENDERSCENE *)in_data);
00314 break;
00315 case BEI_REQUEST_TYPE_MERGE:
00316 processMerge((BEI_MERGE *)in_data);
00317 break;
00318 case BEI_REQUEST_TYPE_INITVERTEXBUFFER:
00319 processInitVertexBuffer((BEI_INITVERTEXBUFFER *)in_data);
00320 break;
00321 case BEI_REQUEST_TYPE_INITVERTEXSUBBUFFER:
00322 processInitVertexSubBuffer((BEI_INITVERTEXSUBBUFFER *)in_data);
00323 break;
00324 case BEI_REQUEST_TYPE_INITINDEXBUFFER:
00325 processInitIndexBuffer((BEI_INITINDEXBUFFER *)in_data);
00326 break;
00327 case BEI_REQUEST_TYPE_INITINDEXSUBBUFFER:
00328 processInitIndexSubBuffer((BEI_INITINDEXSUBBUFFER *)in_data);
00329 break;
00330 case BEI_REQUEST_TYPE_DELETEBUFFER:
00331 processDeleteBuffer((BEI_DELETEBUFFER *)in_data);
00332 break;
00333 default:
00334 break;
00335 }
00336 }
00337
00338 #ifdef __HAVE_XLIB__
00339
00340 void MMSFBBackEndInterface::init(Display *x_display, int x_screen, Window x_window, MMSFBRectangle x11_win_rect) {
00341
00342 start();
00343
00344
00345 BEI_INIT req;
00346 req.type = BEI_REQUEST_TYPE_INIT;
00347 req.x_display = x_display;
00348 req.x_screen = x_screen;
00349 req.x_window = x_window;
00350 req.x11_win_rect= x11_win_rect;
00351 trigger((void*)&req, sizeof(req));
00352 }
00353
00354 #endif
00355
00356 void MMSFBBackEndInterface::init() {
00357
00358 start();
00359
00360
00361 BEI_INIT req;
00362 req.type = BEI_REQUEST_TYPE_INIT;
00363 trigger((void*)&req, sizeof(req));
00364 }
00365
00366 void MMSFBBackEndInterface::processInit(BEI_INIT *req) {
00367 #ifdef __HAVE_OPENGL__
00368
00369 #ifdef __HAVE_XLIB__
00370
00371 mmsfbgl.init(req->x_display, req->x_screen, req->x_window, req->x11_win_rect.w, req->x11_win_rect.h);
00372
00373 #else
00374
00375 mmsfbgl.init();
00376
00377 #endif
00378
00379
00380 this->reset_matrix = true;
00381 int w, h;
00382 mmsfbgl.getResolution(&w, &h);
00383 oglMatrix(false, 0, w, h, 0);
00384
00385 #endif
00386 }
00387
00388
00389 #ifdef __HAVE_OPENGL__
00390 void MMSFBBackEndInterface::oglMatrix(bool central_projection, int left, int right, int bottom, int top, int nearZ, int farZ) {
00391 if (this->reset_matrix || (central_projection != this->matrix_central_projection)
00392 || (left != this->matrix_left) || (right != this->matrix_right)
00393 || (bottom != this->matrix_bottom) || (top != this->matrix_top)
00394 || (nearZ != this->matrix_nearZ) || (farZ != this->matrix_farZ)) {
00395 this->reset_matrix = false;
00396 this->matrix_central_projection = central_projection;
00397 this->matrix_left = left;
00398 this->matrix_right = right;
00399 this->matrix_bottom = bottom;
00400 this->matrix_top = top;
00401 this->matrix_nearZ = nearZ;
00402 this->matrix_farZ = farZ;
00403 if (!central_projection) {
00404
00405 mmsfbgl.setParallelProjection(left, right, bottom, top, nearZ, farZ);
00406 }
00407 else {
00408
00409 mmsfbgl.setCentralProjection(left, right, bottom, top, nearZ, farZ);
00410 }
00411 }
00412 }
00413
00414
00415
00416
00417 void MMSFBBackEndInterface::oglAlloc(MMSFBSurface *surface, bool rbo_required) {
00418
00419 if (surface->is_sub_surface) {
00420
00421
00422 surface = surface->root_parent;
00423 }
00424
00425 MMSFBSurfaceBuffer *sb = surface->config.surface_buffer;
00426
00427 #ifdef __HAVE_GL2__
00428 if (!sb->ogl_fbo_initialized) {
00429
00430 if (!sb->ogl_tex_initialized) {
00431
00432 mmsfbgl.allocFBOandRBO(sb->ogl_fbo, sb->ogl_tex, sb->ogl_rbo, surface->config.w, surface->config.h);
00433 }
00434 else {
00435
00436 mmsfbgl.attachTexture2FrameBuffer(sb->ogl_fbo, sb->ogl_tex);
00437 mmsfbgl.attachRenderBuffer2FrameBuffer(sb->ogl_fbo, sb->ogl_rbo, surface->config.w, surface->config.h);
00438 }
00439
00440 sb->ogl_fbo_initialized = true;
00441 sb->ogl_tex_initialized = true;
00442 sb->ogl_rbo_initialized = true;
00443
00444 }
00445 #endif
00446
00447 #ifdef __HAVE_GLES2__
00448 if (!sb->ogl_fbo_initialized) {
00449
00450 sb->ogl_rbo_initialized = false;
00451
00452
00453 if (!sb->ogl_tex_initialized) {
00454
00455 if (rbo_required) {
00456
00457
00458 mmsfbgl.allocFBOandRBO(sb->ogl_fbo, sb->ogl_tex, sb->ogl_rbo, surface->config.w, surface->config.h);
00459 sb->ogl_rbo_initialized = true;
00460 }
00461 else {
00462
00463
00464 mmsfbgl.allocFBO(sb->ogl_fbo, sb->ogl_tex, surface->config.w, surface->config.h);
00465 }
00466 }
00467 else {
00468
00469 mmsfbgl.attachTexture2FrameBuffer(sb->ogl_fbo, sb->ogl_tex);
00470 }
00471
00472 sb->ogl_fbo_initialized = true;
00473 sb->ogl_tex_initialized = true;
00474
00475 }
00476 #endif
00477
00478
00479
00480 if (sb->ogl_fbo_initialized) {
00481
00482 if (!sb->ogl_rbo_initialized) {
00483
00484 if (rbo_required) {
00485
00486 mmsfbgl.attachRenderBuffer2FrameBuffer(sb->ogl_fbo, sb->ogl_rbo, surface->config.w, surface->config.h);
00487 sb->ogl_rbo_initialized = true;
00488 }
00489 }
00490 }
00491 }
00492
00493
00494 void MMSFBBackEndInterface::oglBindSurface(MMSFBSurface *surface) {
00495
00496 oglAlloc(surface);
00497
00498
00499 mmsfbgl.bindFrameBuffer(surface->config.surface_buffer->ogl_fbo);
00500
00501 if (surface->config.surface_buffer->ogl_fbo) {
00502
00503 if (!surface->is_sub_surface) {
00504 oglMatrix(false, 0, surface->config.w, 0, surface->config.h);
00505 }
00506 else {
00507 oglMatrix(false, 0, surface->root_parent->config.w, 0, surface->root_parent->config.h);
00508 }
00509 } else {
00510
00511 if (!surface->is_sub_surface) {
00512 oglMatrix(false, 0, surface->config.w, surface->config.h, 0);
00513 }
00514 else {
00515 oglMatrix(false, 0, surface->root_parent->config.w, surface->root_parent->config.h, 0);
00516 }
00517 }
00518 }
00519
00520 void MMSFBBackEndInterface::oglBindSurface(MMSFBSurface *surface, int nearZ, int farZ, bool central_projection) {
00521
00522
00523 oglAlloc(surface, true);
00524
00525
00526 mmsfbgl.bindFrameBuffer(surface->config.surface_buffer->ogl_fbo);
00527
00528 if (surface->config.surface_buffer->ogl_fbo) {
00529
00530 if (!surface->is_sub_surface) {
00531 oglMatrix(central_projection,
00532 -(int)surface->config.w/2, (int)surface->config.w/2,
00533 -(int)surface->config.h/2, (int)surface->config.h/2,
00534 nearZ, farZ);
00535 }
00536 else {
00537 oglMatrix(central_projection,
00538 -(int)surface->root_parent->config.w/2, (int)surface->root_parent->config.w/2,
00539 -(int)surface->root_parent->config.h/2, (int)surface->root_parent->config.h/2,
00540 nearZ, farZ);
00541 }
00542 } else {
00543
00544 if (!surface->is_sub_surface) {
00545 oglMatrix(central_projection,
00546 -(int)surface->config.w/2, (int)surface->config.w/2,
00547 (int)surface->config.h/2,-(int)surface->config.h/2,
00548 nearZ, farZ);
00549 }
00550 else {
00551 oglMatrix(central_projection,
00552 -(int)surface->root_parent->config.w/2, (int)surface->root_parent->config.w/2,
00553 (int)surface->root_parent->config.h/2,-(int)surface->root_parent->config.h/2,
00554 nearZ, farZ);
00555 }
00556 }
00557 }
00558
00559
00560 bool MMSFBBackEndInterface::oglDrawBuffer(MMSFBBuffer::BUFFER *buffer,
00561 MMSFBBuffer::INDEX_BUFFER *index_buffer,
00562 MMSFBBuffer::VERTEX_BUFFER *vertex_buffer) {
00563 if (!buffer) return false;
00564
00565 if (!index_buffer || !vertex_buffer) {
00566
00567 if (!buffer->getBuffers(&index_buffer, &vertex_buffer)) return false;
00568 }
00569
00570
00571 if (!index_buffer || !vertex_buffer) return false;
00572
00573 if (buffer->index_bo.bo && buffer->vertex_bo.bo) {
00574
00575
00576 return true;
00577 }
00578 else
00579 if (buffer->vertex_bo.bo) {
00580
00581 for (unsigned int i = 0; i < buffer->vertex_bo.num_buffers; i++) {
00582 mmsfbgl.drawElements(&buffer->vertex_bo.buffers[i], NULL, NULL, &buffer->index_bo.buffers[i]);
00583 }
00584 return true;
00585 }
00586 else {
00587
00588 for (unsigned int i = 0; i < index_buffer->num_arrays; i++) {
00589 mmsfbgl.drawElements(&vertex_buffer->arrays[i], NULL, NULL, &index_buffer->arrays[i]);
00590 }
00591 return true;
00592 }
00593
00594 return false;
00595 }
00596
00597 #endif
00598
00599 void MMSFBBackEndInterface::swap() {
00600 BEI_SWAP req;
00601 req.type = BEI_REQUEST_TYPE_SWAP;
00602 trigger((void*)&req, sizeof(req));
00603 }
00604
00605 void MMSFBBackEndInterface::processSwap(BEI_SWAP *req) {
00606 #ifdef __HAVE_OPENGL__
00607
00608 mmsfbgl.swap();
00609 #endif
00610 }
00611
00612 void MMSFBBackEndInterface::alloc(MMSFBSurface *surface) {
00613 BEI_ALLOC req;
00614 req.type = BEI_REQUEST_TYPE_ALLOC;
00615 req.surface = surface;
00616 trigger((void*)&req, sizeof(req));
00617 }
00618
00619
00620 void MMSFBBackEndInterface::processAlloc(BEI_ALLOC *req) {
00621 #ifdef __HAVE_OPENGL__
00622
00623 MMSFBSurfaceBuffer *sb = req->surface->config.surface_buffer;
00624
00625
00626 mmsfbgl.genTexture(&sb->ogl_tex);
00627 mmsfbgl.genFrameBuffer(&sb->ogl_fbo);
00628 mmsfbgl.genRenderBuffer(&sb->ogl_rbo);
00629 sb->ogl_fbo_initialized = false;
00630 sb->ogl_tex_initialized = false;
00631 sb->ogl_rbo_initialized = false;
00632
00633 #endif
00634 }
00635
00636
00637 void MMSFBBackEndInterface::free(MMSFBSurface *surface) {
00638 BEI_FREE req;
00639 req.type = BEI_REQUEST_TYPE_FREE;
00640 req.surface = surface;
00641 trigger((void*)&req, sizeof(req));
00642 }
00643
00644
00645 void MMSFBBackEndInterface::processFree(BEI_FREE *req) {
00646 #ifdef __HAVE_OPENGL__
00647 MMSFBSurfaceBuffer *sb = req->surface->config.surface_buffer;
00648 mmsfbgl.freeFBO(sb->ogl_fbo, sb->ogl_tex, sb->ogl_rbo);
00649 #endif
00650 }
00651
00652
00653 void MMSFBBackEndInterface::clear(MMSFBSurface *surface, MMSFBColor &color) {
00654 BEI_CLEAR req;
00655 req.type = BEI_REQUEST_TYPE_CLEAR;
00656 req.surface = surface;
00657 req.color = color;
00658 trigger((void*)&req, sizeof(req));
00659 }
00660
00661
00662 void MMSFBBackEndInterface::processClear(BEI_CLEAR *req) {
00663 #ifdef __HAVE_OPENGL__
00664
00665 oglBindSurface(req->surface);
00666
00667
00668 GET_OFFS(req->surface);
00669
00670
00671 MMSFBRectangle crect;
00672 if (req->surface->calcClip(0 + xoff, 0 + yoff, req->surface->config.w, req->surface->config.h, &crect)) {
00673
00674 OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
00675
00676 mmsfbgl.clear(req->color.r, req->color.g, req->color.b, req->color.a);
00677 }
00678 #endif
00679 }
00680
00681 void MMSFBBackEndInterface::fillRectangle(MMSFBSurface *surface, MMSFBRectangle &rect, MMSFBDrawingFlags drawingflags) {
00682 BEI_FILLRECTANGLE req;
00683 req.type = BEI_REQUEST_TYPE_FILLRECTANGLE;
00684 req.surface = surface;
00685 req.rect = rect;
00686 req.drawingflags= drawingflags;
00687 trigger((void*)&req, sizeof(req));
00688 }
00689
00690 void MMSFBBackEndInterface::processFillRectangle(BEI_FILLRECTANGLE *req) {
00691 #ifdef __HAVE_OPENGL__
00692
00693 oglBindSurface(req->surface);
00694
00695
00696 INIT_OGL_DRAWING(req->surface, req->drawingflags);
00697
00698
00699 OGL_SCISSOR(req->surface, req->rect.x, req->rect.y, req->rect.w, req->rect.h);
00700
00701
00702 mmsfbgl.fillRectangle2Di(req->rect.x,
00703 req->rect.y,
00704 req->rect.x + req->rect.w - 1,
00705 req->rect.y + req->rect.h - 1);
00706 #endif
00707 }
00708
00709 void MMSFBBackEndInterface::fillTriangle(MMSFBSurface *surface, MMSFBTriangle &triangle) {
00710 BEI_FILLTRIANGLE req;
00711 req.type = BEI_REQUEST_TYPE_FILLTRIANGLE;
00712 req.surface = surface;
00713 req.triangle= triangle;
00714 trigger((void*)&req, sizeof(req));
00715 }
00716
00717 void MMSFBBackEndInterface::processFillTriangle(BEI_FILLTRIANGLE *req) {
00718 #ifdef __HAVE_GL2__
00719
00720 oglBindSurface(req->surface);
00721 glDisable(GL_DEPTH_TEST);
00722 glDisable(GL_TEXTURE_2D);
00723
00724
00725 INIT_OGL_DRAWING(req->surface, req->surface->config.drawingflags);
00726
00727
00728 GET_OFFS(req->surface);
00729
00730
00731 MMSFBRectangle crect;
00732 int x, y, w, h;
00733 if (req->triangle.x2 >= req->triangle.x1) {
00734 x = req->triangle.x1;
00735 w = req->triangle.x2 - req->triangle.x1 + 1;
00736 }
00737 else {
00738 x = req->triangle.x2;
00739 w = req->triangle.x1 - req->triangle.x2 + 1;
00740 }
00741 if (req->triangle.y2 >= req->triangle.y1) {
00742 y = req->triangle.y1;
00743 h = req->triangle.y2 - req->triangle.y1 + 1;
00744 }
00745 else {
00746 y = req->triangle.y2;
00747 h = req->triangle.y1 - req->triangle.y2 + 1;
00748 }
00749 if (req->triangle.x3 < x) x = req->triangle.x3;
00750 if (req->triangle.x3 > x + w - 1) w = req->triangle.x3 - x + 1;
00751 if (req->triangle.y3 < y) y = req->triangle.y3;
00752 if (req->triangle.y3 > y + h - 1) h = req->triangle.y3 - y + 1;
00753
00754 if (req->surface->calcClip(x + xoff, y + yoff, w, h, &crect)) {
00755
00756 OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
00757
00758
00759
00760 OGL_FILL_TRIANGLE(req->triangle.x1 + xoff, req->triangle.y1 + yoff,
00761 req->triangle.x2 + xoff, req->triangle.y2 + yoff,
00762 req->triangle.x3 + xoff, req->triangle.y3 + yoff);
00763 }
00764 #endif
00765 }
00766
00767 void MMSFBBackEndInterface::drawLine(MMSFBSurface *surface, int x1, int y1, int x2, int y2) {
00768 BEI_DRAWLINE req;
00769 req.type = BEI_REQUEST_TYPE_DRAWLINE;
00770 req.surface = surface;
00771 req.x1 = x1;
00772 req.y1 = y1;
00773 req.x2 = x2;
00774 req.y2 = y2;
00775 trigger((void*)&req, sizeof(req));
00776 }
00777
00778 void MMSFBBackEndInterface::processDrawLine(BEI_DRAWLINE *req) {
00779 #ifdef __HAVE_OPENGL__
00780
00781 oglBindSurface(req->surface);
00782
00783
00784 INIT_OGL_DRAWING(req->surface, req->surface->config.drawingflags);
00785
00786
00787 GET_OFFS(req->surface);
00788
00789
00790 MMSFBRectangle crect;
00791 int x, y, w, h;
00792 if (req->x2 >= req->x1) {
00793 x = req->x1;
00794 w = req->x2 - req->x1 + 1;
00795 }
00796 else {
00797 x = req->x2;
00798 w = req->x1 - req->x2 + 1;
00799 }
00800 if (req->y2 >= req->y1) {
00801 y = req->y1;
00802 h = req->y2 - req->y1 + 1;
00803 }
00804 else {
00805 y = req->y2;
00806 h = req->y1 - req->y2 + 1;
00807 }
00808
00809 if (req->surface->calcClip(x + xoff, y + yoff, w, h, &crect)) {
00810
00811 OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
00812
00813
00814 mmsfbgl.drawLine2Di(req->x1 + xoff, req->y1 + yoff,
00815 req->x2 + xoff, req->y2 + yoff);
00816 }
00817 #endif
00818 }
00819
00820 void MMSFBBackEndInterface::drawRectangle(MMSFBSurface *surface, MMSFBRectangle &rect) {
00821 BEI_DRAWRECTANGLE req;
00822 req.type = BEI_REQUEST_TYPE_DRAWRECTANGLE;
00823 req.surface = surface;
00824 req.rect = rect;
00825 trigger((void*)&req, sizeof(req));
00826 }
00827
00828 void MMSFBBackEndInterface::processDrawRectangle(BEI_DRAWRECTANGLE *req) {
00829 #ifdef __HAVE_OPENGL__
00830
00831 oglBindSurface(req->surface);
00832
00833
00834 INIT_OGL_DRAWING(req->surface, req->surface->config.drawingflags);
00835
00836
00837 GET_OFFS(req->surface);
00838
00839
00840 MMSFBRectangle crect;
00841 if (req->surface->calcClip(req->rect.x + xoff, req->rect.y + yoff, req->rect.w, req->rect.h, &crect)) {
00842
00843 OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
00844
00845
00846 OGL_DRAW_RECTANGLE(req->rect.x + xoff,
00847 req->rect.y + yoff,
00848 req->rect.x + req->rect.w - 1 + xoff,
00849 req->rect.y + req->rect.h - 1 + yoff);
00850 }
00851 #endif
00852 }
00853
00854 void MMSFBBackEndInterface::drawTriangle(MMSFBSurface *surface, MMSFBTriangle &triangle) {
00855 BEI_DRAWTRIANGLE req;
00856 req.type = BEI_REQUEST_TYPE_DRAWTRIANGLE;
00857 req.surface = surface;
00858 req.triangle= triangle;
00859 trigger((void*)&req, sizeof(req));
00860 }
00861
00862 void MMSFBBackEndInterface::processDrawTriangle(BEI_DRAWTRIANGLE *req) {
00863 #ifdef __HAVE_GL2__
00864
00865 oglBindSurface(req->surface);
00866 glDisable(GL_DEPTH_TEST);
00867 glDisable(GL_TEXTURE_2D);
00868
00869
00870 INIT_OGL_DRAWING(req->surface, req->surface->config.drawingflags);
00871
00872
00873 GET_OFFS(req->surface);
00874
00875
00876 MMSFBRectangle crect;
00877 int x, y, w, h;
00878 if (req->triangle.x2 >= req->triangle.x1) {
00879 x = req->triangle.x1;
00880 w = req->triangle.x2 - req->triangle.x1 + 1;
00881 }
00882 else {
00883 x = req->triangle.x2;
00884 w = req->triangle.x1 - req->triangle.x2 + 1;
00885 }
00886 if (req->triangle.y2 >= req->triangle.y1) {
00887 y = req->triangle.y1;
00888 h = req->triangle.y2 - req->triangle.y1 + 1;
00889 }
00890 else {
00891 y = req->triangle.y2;
00892 h = req->triangle.y1 - req->triangle.y2 + 1;
00893 }
00894 if (req->triangle.x3 < x) x = req->triangle.x3;
00895 if (req->triangle.x3 > x + w - 1) w = req->triangle.x3 - x + 1;
00896 if (req->triangle.y3 < y) y = req->triangle.y3;
00897 if (req->triangle.y3 > y + h - 1) h = req->triangle.y3 - y + 1;
00898
00899 if (req->surface->calcClip(x + xoff, y + yoff, w, h, &crect)) {
00900
00901 OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
00902
00903
00904
00905 OGL_DRAW_TRIANGLE(req->triangle.x1 + xoff, req->triangle.y1 + yoff,
00906 req->triangle.x2 + xoff, req->triangle.y2 + yoff,
00907 req->triangle.x3 + xoff, req->triangle.y3 + yoff);
00908 }
00909 #endif
00910 }
00911
00912 void MMSFBBackEndInterface::blit(MMSFBSurface *surface, MMSFBSurface *source, MMSFBRectangle &src_rect,
00913 int x, int y, MMSFBBlittingFlags blittingflags) {
00914 BEI_BLIT req;
00915 req.type = BEI_REQUEST_TYPE_BLIT;
00916 req.surface = surface;
00917 req.source = source;
00918 req.src_rect = src_rect;
00919 req.x = x;
00920 req.y = y;
00921 req.blittingflags = blittingflags;
00922 trigger((void*)&req, sizeof(req));
00923 }
00924
00925 void MMSFBBackEndInterface::processBlit(BEI_BLIT *req) {
00926 #ifdef __HAVE_OPENGL__
00927
00928 oglBindSurface(req->surface);
00929
00930
00931 INIT_OGL_BLITTING(req->surface, req->blittingflags);
00932
00933
00934 GET_OFFS(req->surface);
00935 GET_OFFS_SRC(req->source);
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969 OGL_SCISSOR(req->surface, req->x, req->y, req->src_rect.w, req->src_rect.h);
00970
00971
00972
00973
00974
00975 if (req->source->config.surface_buffer->ogl_tex_initialized) {
00976
00977
00978
00979
00980
00981
00982
00983 mmsfbgl.stretchBliti(req->source->config.surface_buffer->ogl_tex,
00984 req->src_rect.x, req->src_rect.y, req->src_rect.x + req->src_rect.w - 1, req->src_rect.y + req->src_rect.h - 1,
00985 src_rootw, src_rooth,
00986 req->x, req->y, req->x + req->src_rect.w - 1, req->y + req->src_rect.h - 1);
00987 }
00988 else {
00989 printf("skip blitting from texture which is not initialized\n");
00990 }
00991 #endif
00992 }
00993
00994 void MMSFBBackEndInterface::stretchBlit(MMSFBSurface *surface, MMSFBSurface *source, MMSFBRectangle &src_rect,
00995 MMSFBRectangle &dst_rect, MMSFBBlittingFlags blittingflags) {
00996 BEI_STRETCHBLIT req;
00997 req.type = BEI_REQUEST_TYPE_STRETCHBLIT;
00998 req.surface = surface;
00999 req.source = source;
01000 req.src_rect = src_rect;
01001 req.dst_rect = dst_rect;
01002 req.blittingflags = blittingflags;
01003 trigger((void*)&req, sizeof(req));
01004 }
01005
01006 void MMSFBBackEndInterface::processStretchBlit(BEI_STRETCHBLIT *req) {
01007 #ifdef __HAVE_OPENGL__
01008
01009 oglBindSurface(req->surface);
01010
01011
01012 INIT_OGL_BLITTING(req->surface, req->blittingflags);
01013
01014
01015 GET_OFFS(req->surface);
01016 GET_OFFS_SRC(req->source);
01017
01018
01019 MMSFBRectangle crect;
01020 if (req->surface->calcClip(req->dst_rect.x + xoff, req->dst_rect.y + yoff, req->dst_rect.w, req->dst_rect.h, &crect)) {
01021
01022 OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
01023
01024
01025 int sx1 = req->src_rect.x + src_xoff;
01026 int sy1 = req->src_rect.y + src_yoff;
01027 int sx2 = req->src_rect.x + req->src_rect.w - 1 + src_xoff;
01028 int sy2 = req->src_rect.y + req->src_rect.h - 1 + src_yoff;
01029
01030
01031 int dx1 = req->dst_rect.x + xoff;
01032 int dy1 = req->dst_rect.y + yoff;
01033 int dx2 = req->dst_rect.x + req->dst_rect.w - 1 + xoff;
01034 int dy2 = req->dst_rect.y + req->dst_rect.h - 1 + yoff;
01035
01036 if (req->source->config.surface_buffer->ogl_tex_initialized) {
01037
01038 mmsfbgl.stretchBliti(req->source->config.surface_buffer->ogl_tex,
01039 sx1, sy1, sx2, sy2, src_rootw, src_rooth,
01040 dx1, dy1, dx2, dy2);
01041 }
01042 else {
01043 printf("skip blitting from texture which is not initialized\n");
01044 }
01045 }
01046 #endif
01047 }
01048
01049 void MMSFBBackEndInterface::blitBuffer(MMSFBSurface *surface, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
01050 int src_width, int src_height, MMSFBRectangle &src_rect, int x, int y,
01051 MMSFBBlittingFlags blittingflags) {
01052 BEI_STRETCHBLITBUFFER req;
01053 req.type = BEI_REQUEST_TYPE_STRETCHBLITBUFFER;
01054 req.surface = surface;
01055 req.src_planes = src_planes;
01056 req.src_pixelformat = src_pixelformat;
01057 req.src_width = src_width;
01058 req.src_height = src_height;
01059 req.src_rect = src_rect;
01060 req.dst_rect.x = x;
01061 req.dst_rect.y = y;
01062 req.dst_rect.w = src_rect.w;
01063 req.dst_rect.h = src_rect.h;
01064 req.blittingflags = blittingflags;
01065 trigger((void*)&req, sizeof(req));
01066 }
01067
01068 void MMSFBBackEndInterface::stretchBlitBuffer(MMSFBSurface *surface, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
01069 int src_width, int src_height,MMSFBRectangle &src_rect, MMSFBRectangle &dst_rect,
01070 MMSFBBlittingFlags blittingflags) {
01071 BEI_STRETCHBLITBUFFER req;
01072 req.type = BEI_REQUEST_TYPE_STRETCHBLITBUFFER;
01073 req.surface = surface;
01074 req.src_planes = src_planes;
01075 req.src_pixelformat = src_pixelformat;
01076 req.src_width = src_width;
01077 req.src_height = src_height;
01078 req.src_rect = src_rect;
01079 req.dst_rect = dst_rect;
01080 req.blittingflags = blittingflags;
01081 trigger((void*)&req, sizeof(req));
01082 }
01083
01084 void MMSFBBackEndInterface::processStretchBlitBuffer(BEI_STRETCHBLITBUFFER *req) {
01085 #ifdef __HAVE_OPENGL__
01086
01087
01088 bool blit2texture = (!req->surface->config.surface_buffer->ogl_fbo_initialized);
01089 if (blit2texture) {
01090 if (req->blittingflags != MMSFB_BLIT_NOFX) {
01091 if (req->blittingflags == MMSFB_BLIT_BLEND_ALPHACHANNEL) {
01092 if (!MMSFBSURFACE_WRITE_BUFFER(req->surface).opaque) {
01093
01094
01095 blit2texture = false;
01096 }
01097 }
01098 else {
01099
01100 blit2texture = false;
01101 }
01102 }
01103 }
01104
01105 if (blit2texture) {
01106
01107 mmsfbgl.blitBuffer2Texture(req->surface->config.surface_buffer->ogl_tex,
01108 (!req->surface->config.surface_buffer->ogl_tex_initialized),
01109 req->src_planes->ptr, req->src_width, req->src_height);
01110
01111
01112 req->surface->config.surface_buffer->ogl_tex_initialized = true;
01113
01114 return;
01115 }
01116
01117
01118 oglBindSurface(req->surface);
01119
01120
01121 INIT_OGL_BLITTING(req->surface, req->blittingflags);
01122
01123
01124 GET_OFFS(req->surface);
01125
01126
01127 MMSFBRectangle crect;
01128 if (req->surface->calcClip(req->dst_rect.x + xoff, req->dst_rect.y + yoff, req->dst_rect.w, req->dst_rect.h, &crect)) {
01129
01130 OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
01131
01132
01133 int sx1 = req->src_rect.x;
01134 int sy1 = req->src_rect.y;
01135 int sx2 = req->src_rect.x + req->src_rect.w - 1;
01136 int sy2 = req->src_rect.y + req->src_rect.h - 1;
01137
01138
01139 int dx1 = req->dst_rect.x + xoff;
01140 int dy1 = req->dst_rect.y + yoff;
01141 int dx2 = req->dst_rect.x + req->dst_rect.w - 1 + xoff;
01142 int dy2 = req->dst_rect.y + req->dst_rect.h - 1 + yoff;
01143
01144
01145 mmsfbgl.stretchBlitBufferi(req->src_planes->ptr,
01146 sx1, sy1, sx2, sy2, req->src_width, req->src_height,
01147 dx1, dy1, dx2, dy2);
01148 }
01149 #endif
01150 }
01151
01152
01153
01154 void MMSFBBackEndInterface::createAlphaTexture(unsigned int *texture, unsigned char *buffer, int width, int height) {
01155 BEI_CREATEALPHATEXTURE req;
01156 req.type = BEI_REQUEST_TYPE_CREATEALPHATEXTURE;
01157 req.texture = texture;
01158 req.buffer = buffer;
01159 req.width = width;
01160 req.height = height;
01161 trigger((void*)&req, sizeof(req));
01162 }
01163
01164 void MMSFBBackEndInterface::processCreateAlphaTexture(BEI_CREATEALPHATEXTURE *req) {
01165 #ifdef __HAVE_OPENGL__
01166
01167
01168 mmsfbgl.genTexture(req->texture);
01169
01170
01171 mmsfbgl.initTexture2D(*(req->texture), GL_ALPHA, req->buffer, GL_ALPHA, req->width, req->height);
01172
01173 #endif
01174 }
01175
01176
01177 void MMSFBBackEndInterface::deleteTexture(unsigned int texture) {
01178 BEI_DELETETEXTURE req;
01179 req.type = BEI_REQUEST_TYPE_DELETETEXTURE;
01180 req.texture = texture;
01181 trigger((void*)&req, sizeof(req));
01182 }
01183
01184 void MMSFBBackEndInterface::processDeleteTexture(BEI_DELETETEXTURE *req) {
01185 #ifdef __HAVE_OPENGL__
01186
01187
01188 mmsfbgl.deleteTexture(req->texture);
01189
01190 #endif
01191 }
01192
01193
01194 void MMSFBBackEndInterface::drawString(MMSFBSurface *surface, string &text, int len, int x, int y) {
01195 BEI_DRAWSTRING req;
01196 req.type = BEI_REQUEST_TYPE_DRAWSTRING;
01197 req.surface = surface;
01198 req.text = text;
01199 req.len = len;
01200 req.x = x;
01201 req.y = y;
01202 trigger((void*)&req, sizeof(req));
01203 }
01204
01205 void MMSFBBackEndInterface::processDrawString(BEI_DRAWSTRING *req) {
01206 #ifdef __HAVE_OPENGL__
01207
01208
01209 oglBindSurface(req->surface);
01210
01211 #ifndef __HAVE_GLU__
01212
01213 mmsfbgl.enableBlend();
01214 if (req->surface->config.color.a == 0xff)
01215 mmsfbgl.setTexEnvReplace(GL_ALPHA);
01216 else
01217 mmsfbgl.setTexEnvModulate(GL_ALPHA);
01218 mmsfbgl.setColor(req->surface->config.color.r,
01219 req->surface->config.color.g,
01220 req->surface->config.color.b,
01221 req->surface->config.color.a);
01222 #else
01223
01224 INIT_OGL_DRAWING(req->surface, req->surface->config.drawingflags);
01225 #endif
01226
01227
01228 GET_OFFS(req->surface);
01229
01230
01231 MMSFBRectangle crect;
01232 if (req->surface->calcClip(0 + xoff, 0 + yoff, req->surface->config.w, req->surface->config.h, &crect)) {
01233
01234 OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
01235
01236 #ifdef __HAVE_GLU__
01237
01238 mmsfbgl.pushCurrentMatrix();
01239 float scale_coeff = 1.0f;
01240 if (req->surface->config.font->getScaleCoeff(&scale_coeff))
01241 mmsfbgl.scaleCurrentMatrix(scale_coeff, scale_coeff, 1);
01242 int dx1_save = 0;
01243 int dy1_save = 0;
01244 #endif
01245
01246
01247 int DY = 0;
01248 DY = req->surface->config.font->height;
01249 DY-= req->surface->config.font->descender + 1;
01250
01251 #ifdef __HAVE_GLU__
01252
01253 req->x = (int)((float)req->x / scale_coeff + 0.5f);
01254 req->y = (int)((float)req->y / scale_coeff + 0.5f);
01255
01256
01257 xoff = (int)((float)xoff / scale_coeff + 0.5f);
01258 yoff = (int)((float)yoff / scale_coeff + 0.5f);
01259 #endif
01260
01261
01262 MMSFBFONT_GET_UNICODE_CHAR(req->text, req->len) {
01263
01264
01265 MMSFBSURFACE_BLIT_TEXT_LOAD_GLYPH(req->surface->config.font, character);
01266
01267
01268 if (glyph_loaded) {
01269
01270 int dx = req->x + glyph.left;
01271 int dy = req->y + DY - glyph.top;
01272
01273 #ifndef __HAVE_GLU__
01274
01275 int dx1 = dx + xoff;
01276 int dy1 = dy + yoff;
01277 int dx2 = dx + src_w - 1 + xoff;
01278 int dy2 = dy + src_h - 1 + yoff;
01279
01280
01281 int sx1 = 0;
01282 int sy1 = 0;
01283 int sx2 = src_w - 1;
01284 int sy2 = src_h - 1;
01285
01286 if (glyph.texture) {
01287
01288 mmsfbgl.stretchBliti(glyph.texture,
01289 sx1, sy1, sx2, sy2, src_pitch_pix, src_h,
01290 dx1, dy1, dx2, dy2);
01291 }
01292 #else
01293
01294 int dx1 = dx + xoff;
01295 int dy1 = dy + yoff;
01296
01297
01298 mmsfbgl.translateCurrentMatrix(dx1 - dx1_save, dy1 - dy1_save, 0);
01299 dx1_save = dx1;
01300 dy1_save = dy1;
01301
01302 MMSFBBuffer::BUFFER *buffer;
01303
01304 if (glyph.outline && glyph.outline->getBuffer(&buffer)) {
01305 MMSFBBuffer::INDEX_BUFFER *index_buffer;
01306 MMSFBBuffer::VERTEX_BUFFER *vertex_buffer;
01307 if (buffer->getBuffers(&index_buffer, &vertex_buffer)) {
01308
01309 if (index_buffer->num_arrays) {
01310
01311
01312 mmsfbgl.enableBlend();
01313 MMSFBColor *color = &req->surface->config.color;
01314 mmsfbgl.setColor(color->r, color->g, color->b, color->a / 3);
01315
01316
01317 oglDrawBuffer(buffer, index_buffer, vertex_buffer);
01318
01319
01320 mmsfbgl.disableBlend();
01321 mmsfbgl.setColor(color->r, color->g, color->b, color->a);
01322 }
01323 }
01324 }
01325
01326 if (glyph.meshes && glyph.meshes->getBuffer(&buffer)) {
01327
01328 oglDrawBuffer(buffer);
01329 }
01330 #endif
01331
01332
01333 req->x+= glyph.advanceX;
01334 }
01335 }}
01336
01337 #ifdef __HAVE_GLU__
01338
01339 mmsfbgl.popCurrentMatrix();
01340 #endif
01341 }
01342
01343 #endif
01344 }
01345
01346 void MMSFBBackEndInterface::renderScene(MMSFBSurface *surface,
01347 MMS_VERTEX_ARRAY **varrays,
01348 MMS_INDEX_ARRAY **iarrays,
01349 MMS3D_MATERIAL *materials,
01350 MMSFBSurface **texsurfaces,
01351 MMS3D_OBJECT **objects) {
01352 BEI_RENDERSCENE req;
01353 req.type = BEI_REQUEST_TYPE_RENDERSCENE;
01354 req.surface = surface;
01355 req.varrays = varrays;
01356 req.iarrays = iarrays;
01357 req.materials = materials;
01358 req.texsurfaces = texsurfaces;
01359 req.objects = objects;
01360 trigger((void*)&req, sizeof(req));
01361 }
01362
01363
01364
01365
01366 void setLight() {
01367 #ifdef __HAVE_GL2__
01368
01369 glDisable(GL_LIGHT0);
01370
01371 glEnable(GL_LIGHTING);
01372
01373 GLfloat am[] = {0.4,0.4,0.4,1};
01374 glLightfv(GL_LIGHT0,GL_AMBIENT,am);
01375
01376 GLfloat di[] = {0.5,0.5,0.5,1};
01377 glLightfv(GL_LIGHT0,GL_DIFFUSE,di);
01378
01379 GLfloat sp[] = {0.3,0.3,0.3,1};
01380 glLightfv(GL_LIGHT0,GL_SPECULAR,sp);
01381
01382 glLightf(GL_LIGHT0,GL_SPOT_EXPONENT,0);
01383
01384 GLfloat lightPos[] = {40000,10000,-100,1 };
01385 glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
01386
01387
01388 glEnable(GL_LIGHT0);
01389 #endif
01390 }
01391
01392
01393
01394
01395 void MMSFBBackEndInterface::processRenderScene(BEI_RENDERSCENE *req) {
01396 #ifdef __HAVE_OPENGL__
01397
01398
01399 oglBindSurface(req->surface, 200, 1700, true);
01400
01401
01402
01403
01404
01405
01406 setLight();
01407
01408
01409
01410
01411
01412 mmsfbgl.disableBlend();
01413 mmsfbgl.setTexEnvReplace(GL_RGBA);
01414
01415
01416 GET_OFFS(req->surface);
01417
01418
01419 MMSFBRectangle crect;
01420 if (req->surface->calcClip(0 + xoff, 0 + yoff, req->surface->config.w, req->surface->config.h, &crect)) {
01421
01422 OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
01423
01424
01425 ENABLE_OGL_DEPTHTEST(req->surface, false);
01426 mmsfbgl.clear();
01427
01428
01429 int cnt = 0;
01430 MMS3D_OBJECT *object;
01431
01432 while ((object = req->objects[cnt])) {
01433
01434 if (!isMMS3DObjectShown(object) || object->indices < 0) {
01435
01436 cnt++;
01437 continue;
01438 }
01439
01440
01441 if (object->cullface) {
01442 #ifdef __HAVE_GL2__
01443 glFrontFace(GL_CCW);
01444 glCullFace(GL_BACK);
01445 glEnable(GL_CULL_FACE);
01446 #endif
01447 }
01448 else {
01449 #ifdef __HAVE_GL2__
01450 glDisable(GL_CULL_FACE);
01451 #endif
01452 }
01453
01454
01455 mmsfbgl.setCurrentMatrix(object->matrix);
01456
01457
01458 if (object->material >= 0) {
01459 #ifdef __HAVE_GL2__
01460
01461 MMS3D_MATERIAL material = req->materials[object->material];
01462
01463
01464 glMaterialfv(GL_FRONT, GL_EMISSION, (float*)&material.s.emission);
01465
01466
01467 glMaterialfv(GL_FRONT, GL_AMBIENT, (float*)&material.s.ambient);
01468
01469
01470 glMaterialfv(GL_FRONT, GL_DIFFUSE, (float*)&material.s.diffuse);
01471
01472
01473 glMaterialfv(GL_FRONT, GL_SPECULAR, (float*)&material.s.specular);
01474
01475
01476 glMaterialf(GL_FRONT, GL_SHININESS, material.s.shininess * 128);
01477 #endif
01478 }
01479
01480
01481 if (object->texcoords >= 0 && object->texture >= 0) {
01482 mmsfbgl.enableTexture2D(req->texsurfaces[object->texture]->config.surface_buffer->ogl_tex);
01483 }
01484 else {
01485 mmsfbgl.disableTexture2D();
01486 }
01487
01488
01489 mmsfbgl.drawElements(
01490 (object->vertices >= 0) ? req->varrays[object->vertices] : NULL,
01491 (object->normals >= 0) ? req->varrays[object->normals] : NULL,
01492 (object->texcoords >= 0 && object->texture >= 0) ? req->varrays[object->texcoords] : NULL,
01493 (object->indices >= 0) ? req->iarrays[object->indices] : NULL);
01494
01495
01496 cnt++;
01497 }
01498
01499 #ifdef __HAVE_GL2__
01500 glDisable(GL_CULL_FACE);
01501 glDisable(GL_LIGHTING);
01502 #endif
01503
01504
01505 this->reset_matrix = true;
01506
01507 }
01508
01509
01510 #endif
01511 }
01512
01513
01514
01515 void MMSFBBackEndInterface::merge(MMSFBSurface *surface, MMSFBSurface *source1, MMSFBSurface *source2,
01516 MMSFBMergingMode mergingmode) {
01517 BEI_MERGE req;
01518 req.type = BEI_REQUEST_TYPE_MERGE;
01519 req.surface = surface;
01520 req.source1 = source1;
01521 req.source2 = source2;
01522 req.mergingmode = mergingmode;
01523 trigger((void*)&req, sizeof(req));
01524 }
01525
01526
01527 void MMSFBBackEndInterface::processMerge(BEI_MERGE *req) {
01528 #ifdef __HAVE_OPENGL__
01529
01530 oglBindSurface(req->surface);
01531
01532
01533 GET_OFFS(req->surface);
01534
01535
01536 for (int i = 0; i < 2; i++) {
01537
01538 switch (req->mergingmode) {
01539 case MMSFB_MM_ANAGLYPH_RED_CYAN:
01540 if (!i) {
01541
01542 mmsfbgl.disableBlend();
01543 mmsfbgl.setTexEnvModulate(GL_RGBA);
01544 mmsfbgl.setColor(0xff, 0x00, 0x00, 0xff);
01545 }
01546 else {
01547
01548 mmsfbgl.enableBlend(GL_ONE, GL_ONE, GL_ONE, GL_ONE);
01549 mmsfbgl.setTexEnvModulate(GL_RGBA);
01550 mmsfbgl.setColor(0x00, 0xff, 0xff, 0xff);
01551 }
01552 break;
01553
01554 case MMSFB_MM_LINE_INTERLEAVED:
01555 if (!i) {
01556
01557 mmsfbgl.disableBlend();
01558 mmsfbgl.setTexEnvReplace(GL_RGBA);
01559
01560 if (IS_OGL_DEPTH_BUFFER_UNCHANGED(req->surface)) {
01561
01562 mmsfbgl.disableDepthTest();
01563 }
01564 else {
01565
01566 ENABLE_OGL_DEPTHTEST(req->surface, false);
01567 mmsfbgl.clear();
01568 mmsfbgl.setColor(0xff,0xff,0xff,0xff);
01569 for (int i = 0; i < req->surface->config.h; i+=2) {
01570 mmsfbgl.fillRectangle2D(0, (float)i, (float)req->surface->config.w - 0.1f, (float)i+0.9);
01571 }
01572
01573
01574
01575 DISABLE_OGL_DEPTHTEST(req->surface, true);
01576 }
01577 }
01578 else {
01579
01580 mmsfbgl.disableBlend();
01581 mmsfbgl.setTexEnvReplace(GL_RGBA);
01582
01583
01584 ENABLE_OGL_DEPTHTEST(req->surface, true);
01585 }
01586 break;
01587 }
01588
01589
01590 MMSFBSurface *source = (!i)?req->source1:req->source2;
01591
01592
01593 GET_OFFS_SRC(source);
01594
01595
01596 MMSFBRectangle crect;
01597 if (req->surface->calcClip(0 + xoff, 0 + yoff, req->surface->config.w, req->surface->config.h, &crect)) {
01598
01599 OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
01600
01601
01602 int sx1 = 0 + src_xoff;
01603 int sy1 = 0 + src_yoff;
01604 int sx2 = 0 + source->config.w - 1 + src_xoff;
01605 int sy2 = 0 + source->config.h - 1 + src_yoff;
01606
01607
01608 int dx1 = 0 + xoff;
01609 int dy1 = 0 + yoff;
01610 int dx2 = 0 + req->surface->config.w - 1 + xoff;
01611 int dy2 = 0 + req->surface->config.h - 1 + yoff;
01612
01613 if (source->config.surface_buffer->ogl_tex_initialized) {
01614
01615 mmsfbgl.stretchBliti(source->config.surface_buffer->ogl_tex,
01616 sx1, sy1, sx2, sy2, source->config.w, source->config.h,
01617 dx1, dy1, dx2, dy2);
01618 }
01619 else {
01620 printf("skip blitting from texture which is not initialized\n");
01621 }
01622 }
01623 }
01624 #endif
01625 }
01626
01627
01628 void MMSFBBackEndInterface::initVertexBuffer(unsigned int *buffer, unsigned int size, void *data) {
01629 BEI_INITVERTEXBUFFER req;
01630 req.type = BEI_REQUEST_TYPE_INITVERTEXBUFFER;
01631 req.buffer = buffer;
01632 req.size = size;
01633 req.data = data;
01634 trigger((void*)&req, sizeof(req));
01635 }
01636
01637 void MMSFBBackEndInterface::processInitVertexBuffer(BEI_INITVERTEXBUFFER *req) {
01638 #ifdef __HAVE_OPENGL__
01639
01640
01641 if (!req->buffer) return;
01642
01643
01644 if (*(req->buffer)) return;
01645
01646
01647 if (!mmsfbgl.genBuffer(req->buffer)) return;
01648
01649
01650
01651 if (!mmsfbgl.initVertexBuffer(*(req->buffer), req->size, req->data)) {
01652
01653 mmsfbgl.deleteBuffer(*(req->buffer));
01654 *(req->buffer) = 0;
01655 return;
01656 }
01657
01658 #endif
01659 }
01660
01661
01662 void MMSFBBackEndInterface::initVertexSubBuffer(unsigned int buffer, unsigned int offset,
01663 unsigned int size, void *data) {
01664 BEI_INITVERTEXSUBBUFFER req;
01665 req.type = BEI_REQUEST_TYPE_INITVERTEXSUBBUFFER;
01666 req.buffer = buffer;
01667 req.offset = offset;
01668 req.size = size;
01669 req.data = data;
01670 trigger((void*)&req, sizeof(req));
01671 }
01672
01673 void MMSFBBackEndInterface::processInitVertexSubBuffer(BEI_INITVERTEXSUBBUFFER *req) {
01674 #ifdef __HAVE_OPENGL__
01675
01676
01677 if (!req->buffer) return;
01678
01679
01680 mmsfbgl.initVertexSubBuffer(req->buffer, req->offset, req->size, req->data);
01681
01682 #endif
01683 }
01684
01685
01686 void MMSFBBackEndInterface::initIndexBuffer(unsigned int *buffer, unsigned int size, void *data) {
01687 BEI_INITINDEXBUFFER req;
01688 req.type = BEI_REQUEST_TYPE_INITINDEXBUFFER;
01689 req.buffer = buffer;
01690 req.size = size;
01691 req.data = data;
01692 trigger((void*)&req, sizeof(req));
01693 }
01694
01695 void MMSFBBackEndInterface::processInitIndexBuffer(BEI_INITINDEXBUFFER *req) {
01696 #ifdef __HAVE_OPENGL__
01697
01698
01699 if (!req->buffer) return;
01700
01701
01702 if (*(req->buffer)) return;
01703
01704
01705 if (!mmsfbgl.genBuffer(req->buffer)) return;
01706
01707
01708
01709 if (!mmsfbgl.initIndexBuffer(*(req->buffer), req->size, req->data)) {
01710
01711 mmsfbgl.deleteBuffer(*(req->buffer));
01712 *(req->buffer) = 0;
01713 return;
01714 }
01715
01716 #endif
01717 }
01718
01719
01720 void MMSFBBackEndInterface::initIndexSubBuffer(unsigned int buffer, unsigned int offset,
01721 unsigned int size, void *data) {
01722 BEI_INITINDEXSUBBUFFER req;
01723 req.type = BEI_REQUEST_TYPE_INITINDEXSUBBUFFER;
01724 req.buffer = buffer;
01725 req.offset = offset;
01726 req.size = size;
01727 req.data = data;
01728 trigger((void*)&req, sizeof(req));
01729 }
01730
01731 void MMSFBBackEndInterface::processInitIndexSubBuffer(BEI_INITINDEXSUBBUFFER *req) {
01732 #ifdef __HAVE_OPENGL__
01733
01734
01735 if (!req->buffer) return;
01736
01737
01738 mmsfbgl.initIndexSubBuffer(req->buffer, req->offset, req->size, req->data);
01739
01740 #endif
01741 }
01742
01743
01744 void MMSFBBackEndInterface::deleteBuffer(unsigned int buffer) {
01745 BEI_DELETEBUFFER req;
01746 req.type = BEI_REQUEST_TYPE_DELETEBUFFER;
01747 req.buffer = buffer;
01748 trigger((void*)&req, sizeof(req));
01749 }
01750
01751 void MMSFBBackEndInterface::processDeleteBuffer(BEI_DELETEBUFFER *req) {
01752 #ifdef __HAVE_OPENGL__
01753
01754
01755 mmsfbgl.deleteBuffer(req->buffer);
01756
01757 #endif
01758 }
01759
01760
01761
01762
01763
01764
01765
01766