Logo
  • Main Page
  • Related Pages
  • Modules
  • Classes
  • Files

mmsfbbackendinterface.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2005-2007 Stefan Schwarzer, Jens Schneider,             *
00003  *                           Matthias Hardt, Guido Madaus                  *
00004  *                                                                         *
00005  *   Copyright (C) 2007-2008 BerLinux Solutions GbR                        *
00006  *                           Stefan Schwarzer & Guido Madaus               *
00007  *                                                                         *
00008  *   Copyright (C) 2009-2013 BerLinux Solutions GmbH                       *
00009  *                                                                         *
00010  *   Authors:                                                              *
00011  *      Stefan Schwarzer   <stefan.schwarzer@diskohq.org>,                 *
00012  *      Matthias Hardt     <matthias.hardt@diskohq.org>,                   *
00013  *      Jens Schneider     <jens.schneider@diskohq.org>,                   *
00014  *      Guido Madaus       <guido.madaus@diskohq.org>,                     *
00015  *      Patrick Helterhoff <patrick.helterhoff@diskohq.org>,               *
00016  *      René Bählkow       <rene.baehlkow@diskohq.org>                     *
00017  *                                                                         *
00018  *   This library is free software; you can redistribute it and/or         *
00019  *   modify it under the terms of the GNU Lesser General Public            *
00020  *   License version 2.1 as published by the Free Software Foundation.     *
00021  *                                                                         *
00022  *   This library is distributed in the hope that it will be useful,       *
00023  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00024  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00025  *   Lesser General Public Licen
00026  *   se for more details.                       *
00027  *                                                                         *
00028  *   You should have received a copy of the GNU Lesser General Public      *
00029  *   License along with this library; if not, write to the                 *
00030  *   Free Software Foundation, Inc.,                                       *
00031  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
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 //TODO: am dreieck nochwas???
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 #define OGL_DRAW_POINT(x, y) { glBegin(GL_POINTS); glVertex2f((float)(x) + 0.5, (float)(BEI_SURFACE_BOTTOM - (y)) + 0.5); glEnd(); }
00201 
00202 #define OGL_SINGLE_POINT_FALLBACK(x1, y1, x2, y2) \
00203         if (x1 == x2 && y1 == y2) OGL_DRAW_POINT(x1, y1) else
00204 
00205 //TODO: am dreieck nochwas???
00206 #define OGL_SINGLE_POINT_FALLBACK2(x1, y1, x2, y2, x3, y3) \
00207         if (x1 == x2 && x1 == x3 && y1 == y2 && y1 == y3) OGL_DRAW_POINT(x1, y1) else
00208 
00209 
00210 
00211 #define OGL_CALC_2X(v1, v2) (((v1)<(v2)) ? (float)(v1) : (float)(v1) + 0.99)
00212 #define OGL_CALC_2Y(v1, v2) OGL_CALC_2Y_H(v1, v2, BEI_SURFACE_HEIGHT)
00213 #define OGL_CALC_2Y_H(v1, v2, height) (((v1)<(v2)) ? (float)(height-1) - (float)(v1) + 0.99 : (float)(height-1) - (float)(v1))
00214 
00215 #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)
00216 #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)
00217 
00218 #define OGL_CALC_2X_N(v1, v2, width)    (OGL_CALC_2X(v1, v2) / (width))
00219 #define OGL_CALC_2Y_N(v1, v2, height)   (OGL_CALC_2Y_H(v1, v2, height) / (height))
00220 
00221 #define OGL_FILL_RECTANGLE(x1, y1, x2, y2) \
00222         OGL_SINGLE_POINT_FALLBACK(x1, y1, x2, y2) \
00223         glRectf(OGL_CALC_2X(x1, x2), OGL_CALC_2Y(y1, y2), OGL_CALC_2X(x2, x1), OGL_CALC_2Y(y2, y1));
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     // start the server thread
00342     start();
00343 
00344     // trigger the init request
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     // start the server thread
00358     start();
00359 
00360     // trigger the init request
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     // set the coordinate system, here we use the parallel projection as default
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             // init parallel projection
00405             mmsfbgl.setParallelProjection(left, right, bottom, top, nearZ, farZ);
00406         }
00407         else {
00408             // init central projection
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         // surface is a subsurface without own memory
00421         // so set surface to root parents surface for allocation check
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         //TODO: GL2 needs always a renderbuffer???
00430         if (!sb->ogl_tex_initialized) {
00431             // texture is also not initialized
00432             mmsfbgl.allocFBOandRBO(sb->ogl_fbo, sb->ogl_tex, sb->ogl_rbo, surface->config.w, surface->config.h);
00433         }
00434         else {
00435             // texture is already initialized, so we can use it for FBO
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         // per default we do NOT attach a renderbuffer to the FBO (not needed for 2D, reduce memory foot print)
00450         sb->ogl_rbo_initialized = false;
00451 
00452         // allocate a texture (color buffer) and bind it to a new FBO
00453         if (!sb->ogl_tex_initialized) {
00454             // texture is also not initialized
00455             if (rbo_required) {
00456                 // additionally have to initialize RBO
00457                 // so, initialize FBO, RBO and texture
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                 // RBO not needed
00463                 // so, initialize FBO and texture
00464                 mmsfbgl.allocFBO(sb->ogl_fbo, sb->ogl_tex, surface->config.w, surface->config.h);
00465             }
00466         }
00467         else {
00468             // texture is already initialized, so we can use it for FBO
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     // it can be, that the decision to have an RBO comes later
00479     // so it is possible to have a initialized FBO here without an RBO
00480     if (sb->ogl_fbo_initialized) {
00481         // FBO is already initialized
00482         if (!sb->ogl_rbo_initialized) {
00483             // RBO is not initialized
00484             if (rbo_required) {
00485                 // additionally have to initialize RBO
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     // allocate FBO, RBO and texture
00496     oglAlloc(surface);
00497 
00498     // bind FBO
00499     mmsfbgl.bindFrameBuffer(surface->config.surface_buffer->ogl_fbo);
00500 
00501     if (surface->config.surface_buffer->ogl_fbo) {
00502         // set the matrix for off-screen FBO's
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         // set the matrix for primary FBO
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     // allocate FBO, RBO and texture
00523     oglAlloc(surface, true);
00524 
00525     // bind FBO
00526     mmsfbgl.bindFrameBuffer(surface->config.surface_buffer->ogl_fbo);
00527 
00528     if (surface->config.surface_buffer->ogl_fbo) {
00529         // set the matrix for off-screen FBO's
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         // set the matrix for primary FBO
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         // get access to index and vertex buffer
00567         if (!buffer->getBuffers(&index_buffer, &vertex_buffer)) return false;
00568     }
00569 
00570     // check if we have index and vertex buffer
00571     if (!index_buffer || !vertex_buffer) return false;
00572 
00573     if (buffer->index_bo.bo && buffer->vertex_bo.bo) {
00574         // index and vertex buffer objects are available
00575         //TODO...
00576         return true;
00577     }
00578     else
00579     if (buffer->vertex_bo.bo) {
00580         // vertex buffer object is available
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         // buffer objects not available, so we have to put indices/vertices over the bus to GPU
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     // swap screen
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     // generate id's for texture, fbo and rbo - but do NOT initialize it
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     // lock destination fbo and prepare it
00665     oglBindSurface(req->surface);
00666 
00667     // get subsurface offsets
00668     GET_OFFS(req->surface);
00669 
00670     // set the clip to ogl
00671     MMSFBRectangle crect;
00672     if (req->surface->calcClip(0 + xoff, 0 + yoff, req->surface->config.w, req->surface->config.h, &crect)) {
00673         // inside clipping region
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     // lock destination fbo and prepare it
00693     oglBindSurface(req->surface);
00694 
00695     // setup drawing
00696     INIT_OGL_DRAWING(req->surface, req->drawingflags);
00697 
00698     // set ogl clip
00699     OGL_SCISSOR(req->surface, req->rect.x, req->rect.y, req->rect.w, req->rect.h);
00700 
00701     // fill rectangle
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     // lock destination fbo and prepare it
00720     oglBindSurface(req->surface);
00721     glDisable(GL_DEPTH_TEST);
00722     glDisable(GL_TEXTURE_2D);
00723 
00724     // setup drawing
00725     INIT_OGL_DRAWING(req->surface, req->surface->config.drawingflags);
00726 
00727     // get subsurface offsets
00728     GET_OFFS(req->surface);
00729 
00730     // set the clip to ogl
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         // inside clipping region
00756         OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
00757 //      glEnable(GL_SCISSOR_TEST);
00758 
00759         // fill triangle
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     // lock destination fbo and prepare it
00781     oglBindSurface(req->surface);
00782 
00783     // setup drawing
00784     INIT_OGL_DRAWING(req->surface, req->surface->config.drawingflags);
00785 
00786     // get subsurface offsets
00787     GET_OFFS(req->surface);
00788 
00789     // set the clip to ogl
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         // inside clipping region
00811         OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
00812 
00813         // draw line
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     // lock destination fbo and prepare it
00831     oglBindSurface(req->surface);
00832 
00833     // setup drawing
00834     INIT_OGL_DRAWING(req->surface, req->surface->config.drawingflags);
00835 
00836     // get subsurface offsets
00837     GET_OFFS(req->surface);
00838 
00839     // set the clip to ogl
00840     MMSFBRectangle crect;
00841     if (req->surface->calcClip(req->rect.x + xoff, req->rect.y + yoff, req->rect.w, req->rect.h, &crect)) {
00842         // inside clipping region
00843         OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
00844 
00845         // draw rectangle
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     // lock destination fbo and prepare it
00865     oglBindSurface(req->surface);
00866     glDisable(GL_DEPTH_TEST);
00867     glDisable(GL_TEXTURE_2D);
00868 
00869     // setup drawing
00870     INIT_OGL_DRAWING(req->surface, req->surface->config.drawingflags);
00871 
00872     // get subsurface offsets
00873     GET_OFFS(req->surface);
00874 
00875     // set the clip to ogl
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         // inside clipping region
00901         OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
00902 //      glEnable(GL_SCISSOR_TEST);
00903 
00904         // draw triangle
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     // lock destination fbo and bind source texture to it
00928     oglBindSurface(req->surface);
00929 
00930     // setup blitting
00931     INIT_OGL_BLITTING(req->surface, req->blittingflags);
00932 
00933     // get subsurface offsets
00934     GET_OFFS(req->surface);
00935     GET_OFFS_SRC(req->source);
00936 /*
00937     // set the clip to ogl
00938     MMSFBRectangle crect;
00939     if (req->surface->calcClip(req->x + xoff, req->y + yoff, req->src_rect.w, req->src_rect.h, &crect)) {
00940         // inside clipping region
00941         OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
00942 
00943         // get source region
00944         int sx1 = req->src_rect.x + src_xoff;
00945         int sy1 = req->src_rect.y + src_yoff;
00946         int sx2 = req->src_rect.x + req->src_rect.w - 1 + src_xoff;
00947         int sy2 = req->src_rect.y + req->src_rect.h - 1 + src_yoff;
00948 
00949         // get destination region
00950         int dx1 = req->x + xoff;
00951         int dy1 = req->y + yoff;
00952         int dx2 = req->x + req->src_rect.w - 1 + xoff;
00953         int dy2 = req->y + req->src_rect.h - 1 + yoff;
00954 
00955         if (req->source->config.surface_buffer->ogl_tex_initialized) {
00956             // blit source texture to the destination
00957             mmsfbgl.stretchBliti(req->source->config.surface_buffer->ogl_tex,
00958                         sx1, sy1, sx2, sy2, src_rootw, src_rooth,
00959                         dx1, dy1, dx2, dy2);
00960         }
00961         else {
00962             printf("skip blitting from texture which is not initialized\n");
00963         }
00964     }
00965 */
00966 
00967 
00968     // set ogl clip
00969     OGL_SCISSOR(req->surface, req->x, req->y, req->src_rect.w, req->src_rect.h);
00970 //printf("src: %d,%d,%d,%d %d,%d\n", req->src_rect.x, req->src_rect.y, req->src_rect.w, req->src_rect.h,req->source->config.w, req->source->config.h);
00971 
00972 //((!surface->is_sub_surface && surface->config.surface_buffer && surface->config.surface_buffer->ogl_unchanged_depth_buffer)
00973 //||(surface->is_sub_surface && surface->root_parent->config.surface_buffer && surface->root_parent->config.surface_buffer->ogl_unchanged_depth_buffer))
00974 
00975     if (req->source->config.surface_buffer->ogl_tex_initialized) {
00976         // blit source texture to the destination
00977 //printf("blit: %d,%d,%d,%d %d,%d %d,%d,%d,%d\n",
00978 //      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,
00979 //      src_rootw, src_rooth,
00980 //      req->x, req->y, req->x + req->src_rect.w - 1, req->y + req->src_rect.h - 1);
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     // lock destination fbo and bind source texture to it
01009     oglBindSurface(req->surface);
01010 
01011     // setup blitting
01012     INIT_OGL_BLITTING(req->surface, req->blittingflags);
01013 
01014     // get subsurface offsets
01015     GET_OFFS(req->surface);
01016     GET_OFFS_SRC(req->source);
01017 
01018     // set the clip to ogl
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         // inside clipping region
01022         OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
01023 
01024         // get source region
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         // get destination region
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             // blit source texture to the destination
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     // check if we can blit to texture without fbo
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                     // alphachannel blending and opaque flag not set, so we cannot blit to texture directly
01094                     // note: the opaque flag means, that surface should be opaque AFTER the blit
01095                     blit2texture = false;
01096                 }
01097             }
01098             else {
01099                 // blitting flags does not allow to blit to texture directly
01100                 blit2texture = false;
01101             }
01102         }
01103     }
01104 
01105     if (blit2texture) {
01106         // FBO and it's texture is not initialized and we only have to COPY the buffer in a texture
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         // now we have a texture allocated
01112         req->surface->config.surface_buffer->ogl_tex_initialized = true;
01113 
01114         return;
01115     }
01116 
01117     // lock destination fbo and bind source texture to it
01118     oglBindSurface(req->surface);
01119 
01120     // setup blitting
01121     INIT_OGL_BLITTING(req->surface, req->blittingflags);
01122 
01123     // get subsurface offsets
01124     GET_OFFS(req->surface);
01125 
01126     // set the clip to ogl
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         // inside clipping region
01130         OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
01131 
01132         // get source region
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         // get destination region
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         // blit source texture to the destination
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     // alloc a texture
01168     mmsfbgl.genTexture(req->texture);
01169 
01170     // specify two-dimensional glyph texture
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     // delete a texture
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     // lock destination fbo and bind source texture to it
01209     oglBindSurface(req->surface);
01210 
01211 #ifndef __HAVE_GLU__
01212     // setup texture blitting
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     // setup drawing
01224     INIT_OGL_DRAWING(req->surface, req->surface->config.drawingflags);
01225 #endif
01226 
01227     // get subsurface offsets
01228     GET_OFFS(req->surface);
01229 
01230     // set the clip to ogl
01231     MMSFBRectangle crect;
01232     if (req->surface->calcClip(0 + xoff, 0 + yoff, req->surface->config.w, req->surface->config.h, &crect)) {
01233         // inside clipping region
01234         OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
01235 
01236 #ifdef __HAVE_GLU__
01237         // save and scale current matrix
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         // get vertical font settings
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         // calc base position
01253         req->x = (int)((float)req->x / scale_coeff + 0.5f);
01254         req->y = (int)((float)req->y / scale_coeff + 0.5f);
01255 
01256         // calc subsurface offsets
01257         xoff = (int)((float)xoff / scale_coeff + 0.5f);
01258         yoff = (int)((float)yoff / scale_coeff + 0.5f);
01259 #endif
01260 
01261         // for all characters
01262         MMSFBFONT_GET_UNICODE_CHAR(req->text, req->len) {
01263 
01264             // load the glyph
01265             MMSFBSURFACE_BLIT_TEXT_LOAD_GLYPH(req->surface->config.font, character);
01266 
01267             // start rendering of glyph to destination
01268             if (glyph_loaded) {
01269                 // calc destination position of the character
01270                 int dx = req->x + glyph.left;
01271                 int dy = req->y + DY - glyph.top;
01272 
01273 #ifndef __HAVE_GLU__
01274                 // get destination region
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                 // get source region
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                     // blit glyph texture to the destination
01288                     mmsfbgl.stretchBliti(glyph.texture,
01289                                             sx1, sy1, sx2, sy2, src_pitch_pix, src_h,
01290                                             dx1, dy1, dx2, dy2);
01291                 }
01292 #else
01293                 // get destination offset
01294                 int dx1 = dx + xoff;
01295                 int dy1 = dy + yoff;
01296 
01297                 // move to correct position
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                         // draw glyph outline
01309                         if (index_buffer->num_arrays) {
01310                             // setup special drawing flags
01311                             // glyph outline is used for soft-focus effect, we draw it with 1/3 alphachannel
01312                             mmsfbgl.enableBlend();
01313                             MMSFBColor *color = &req->surface->config.color;
01314                             mmsfbgl.setColor(color->r, color->g, color->b, color->a / 3);
01315 
01316                             // draw primitives: glyph outline
01317                             oglDrawBuffer(buffer, index_buffer, vertex_buffer);
01318 
01319                             // reset drawing flags and color
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                     // draw primitives: glyph meshes
01328                     oglDrawBuffer(buffer);
01329                 }
01330 #endif
01331 
01332                 // prepare for next loop
01333                 req->x+= glyph.advanceX;
01334             }
01335         }}
01336 
01337 #ifdef __HAVE_GLU__
01338         // restore matrix
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     // lock destination fbo and bind source texture to it
01399     oglBindSurface(req->surface, 200, 1700, true);
01400 //  oglBindSurface(req->surface);
01401 
01402     // set light
01403 /*  mmsfbgl.rotateCurrentMatrix(0, 1, 0, 0);
01404     mmsfbgl.rotateCurrentMatrix(-45, 0, 0, 1);
01405     mmsfbgl.rotateCurrentMatrix(90, 0, 1, 0);*/
01406     setLight();
01407 
01408 //  oglBindSurface(req->surface, 200, 1700, true);
01409 
01410     // setup blitting
01411 //  mmsfbgl.enableBlend();
01412     mmsfbgl.disableBlend();
01413     mmsfbgl.setTexEnvReplace(GL_RGBA);
01414 
01415     // get subsurface offsets
01416     GET_OFFS(req->surface);
01417 
01418     // set the clip to ogl
01419     MMSFBRectangle crect;
01420     if (req->surface->calcClip(0 + xoff, 0 + yoff, req->surface->config.w, req->surface->config.h, &crect)) {
01421         // inside clipping region
01422         OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
01423 
01424         // clear surface
01425         ENABLE_OGL_DEPTHTEST(req->surface, false);
01426         mmsfbgl.clear();
01427 
01428         // draw objects...
01429         int cnt = 0;
01430         MMS3D_OBJECT *object;
01431 
01432         while ((object = req->objects[cnt])) {
01433 
01434             if (!isMMS3DObjectShown(object) || object->indices < 0) {
01435                 // skip not shown objects
01436                 cnt++;
01437                 continue;
01438             }
01439 
01440             // cull facing, do not draw hidden pixels
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             // set matrix
01455             mmsfbgl.setCurrentMatrix(object->matrix);
01456 
01457             // set material
01458             if (object->material >= 0) {
01459 #ifdef  __HAVE_GL2__
01460 
01461                 MMS3D_MATERIAL material = req->materials[object->material];
01462 
01463                 // material emits light
01464                 glMaterialfv(GL_FRONT, GL_EMISSION, (float*)&material.s.emission);
01465 
01466                 // material absorbs ambient light
01467                 glMaterialfv(GL_FRONT, GL_AMBIENT, (float*)&material.s.ambient);
01468 
01469                 // material absorbs diffuse light
01470                 glMaterialfv(GL_FRONT, GL_DIFFUSE, (float*)&material.s.diffuse);
01471 
01472                 // material absorbs specular light
01473                 glMaterialfv(GL_FRONT, GL_SPECULAR, (float*)&material.s.specular);
01474 
01475                 // specular-light exponent
01476                 glMaterialf(GL_FRONT, GL_SHININESS, material.s.shininess * 128);
01477 #endif
01478             }
01479 
01480             // bind object's texture
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             // draw object
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             // next object
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     // lock destination fbo and bind source texture to it
01530     oglBindSurface(req->surface);
01531 
01532     // get destination subsurface offset
01533     GET_OFFS(req->surface);
01534 
01535     // merging the two source surfaces
01536     for (int i = 0; i < 2; i++) {
01537         // setup blitting
01538         switch (req->mergingmode) {
01539         case MMSFB_MM_ANAGLYPH_RED_CYAN:
01540             if (!i) {
01541                 // red channel from first source surface
01542                 mmsfbgl.disableBlend();
01543                 mmsfbgl.setTexEnvModulate(GL_RGBA);
01544                 mmsfbgl.setColor(0xff, 0x00, 0x00, 0xff);
01545             }
01546             else {
01547                 // green and blue channels (cyan) from second source surface
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                 // even lines from first source surface
01557                 mmsfbgl.disableBlend();
01558                 mmsfbgl.setTexEnvReplace(GL_RGBA);
01559 
01560                 if (IS_OGL_DEPTH_BUFFER_UNCHANGED(req->surface)) {
01561                     // depth buffer has not changed, so we do not have to re-build it
01562                     mmsfbgl.disableDepthTest();
01563                 }
01564                 else {
01565                     // we have to build an interleaved depth buffer needed for blitting of the second source surface
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                     // we mark the depth buffer as "unchanged", so we can save
01574                     // a lot of GPU time next time processMerge() is called
01575                     DISABLE_OGL_DEPTHTEST(req->surface, true);
01576                 }
01577             }
01578             else {
01579                 // odd lines from second source surface
01580                 mmsfbgl.disableBlend();
01581                 mmsfbgl.setTexEnvReplace(GL_RGBA);
01582 
01583                 // we enable the depth test in "readonly" mode, so we leave the depth buffer unchanged
01584                 ENABLE_OGL_DEPTHTEST(req->surface, true);
01585             }
01586             break;
01587         }
01588 
01589         // get source surface
01590         MMSFBSurface *source = (!i)?req->source1:req->source2;
01591 
01592         // get source subsurface offset
01593         GET_OFFS_SRC(source);
01594 
01595         // set the clip to ogl
01596         MMSFBRectangle crect;
01597         if (req->surface->calcClip(0 + xoff, 0 + yoff, req->surface->config.w, req->surface->config.h, &crect)) {
01598             // inside clipping region
01599             OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
01600 
01601             // get source region
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             // get destination region
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                 // blit source texture to the destination
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     // buffer set?
01641     if (!req->buffer) return;
01642 
01643     // buffer already initialized?
01644     if (*(req->buffer)) return;
01645 
01646     // generate new buffer object
01647     if (!mmsfbgl.genBuffer(req->buffer)) return;
01648 
01649     // allocate new vertex buffer and fill it with given data
01650     // if no data is given, the buffer will be allocated but not initialized
01651     if (!mmsfbgl.initVertexBuffer(*(req->buffer), req->size, req->data)) {
01652         // failed
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     // buffer initialized?
01677     if (!req->buffer) return;
01678 
01679     // initialize a sub region of the vertex buffer
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     // buffer set?
01699     if (!req->buffer) return;
01700 
01701     // buffer already initialized?
01702     if (*(req->buffer)) return;
01703 
01704     // generate new buffer object
01705     if (!mmsfbgl.genBuffer(req->buffer)) return;
01706 
01707     // allocate new index buffer and fill it with given data
01708     // if no data is given, the buffer will be allocated but not initialized
01709     if (!mmsfbgl.initIndexBuffer(*(req->buffer), req->size, req->data)) {
01710         // failed
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     // buffer initialized?
01735     if (!req->buffer) return;
01736 
01737     // initialize a sub region of the index buffer
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     // delete a buffer object
01755     mmsfbgl.deleteBuffer(req->buffer);
01756 
01757 #endif
01758 }
01759 
01760 
01761 
01762 
01763 
01764 
01765 
01766 

Generated by doxygen