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