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-2012 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 #else
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 #endif
00367 
00368 
00369 void MMSFBBackEndInterface::processInit(BEI_INIT *req) {
00370 #ifdef __HAVE_OPENGL__
00371 
00372 #ifdef __HAVE_XLIB__
00373 
00374     mmsfbgl.init(req->x_display, req->x_screen, req->x_window, req->x11_win_rect.w, req->x11_win_rect.h);
00375 
00376 #else
00377 
00378     mmsfbgl.init();
00379 
00380 #endif
00381 
00382     // set the coordinate system, here we use the parallel projection as default
00383     this->reset_matrix = true;
00384     int w, h;
00385     mmsfbgl.getResolution(&w, &h);
00386     oglMatrix(false, 0, w, h, 0);
00387 
00388 #endif
00389 }
00390 
00391 
00392 #ifdef __HAVE_OPENGL__
00393 void MMSFBBackEndInterface::oglMatrix(bool central_projection, int left, int right, int bottom, int top, int nearZ, int farZ) {
00394     if (this->reset_matrix || (central_projection != this->matrix_central_projection)
00395       || (left != this->matrix_left) || (right != this->matrix_right)
00396       || (bottom != this->matrix_bottom) || (top != this->matrix_top)
00397       || (nearZ != this->matrix_nearZ) || (farZ != this->matrix_farZ)) {
00398         this->reset_matrix = false;
00399         this->matrix_central_projection = central_projection;
00400         this->matrix_left = left;
00401         this->matrix_right = right;
00402         this->matrix_bottom = bottom;
00403         this->matrix_top = top;
00404         this->matrix_nearZ = nearZ;
00405         this->matrix_farZ = farZ;
00406         if (!central_projection) {
00407             // init parallel projection
00408             mmsfbgl.setParallelProjection(left, right, bottom, top, nearZ, farZ);
00409         }
00410         else {
00411             // init central projection
00412             mmsfbgl.setCentralProjection(left, right, bottom, top, nearZ, farZ);
00413         }
00414     }
00415 }
00416 
00417 
00418 
00419 
00420 void MMSFBBackEndInterface::oglAlloc(MMSFBSurface *surface, bool rbo_required) {
00421 
00422     if (surface->is_sub_surface) {
00423         // surface is a subsurface without own memory
00424         // so set surface to root parents surface for allocation check
00425         surface = surface->root_parent;
00426     }
00427 
00428     MMSFBSurfaceBuffer *sb = surface->config.surface_buffer;
00429 
00430 #ifdef __HAVE_GL2__
00431     if (!sb->ogl_fbo_initialized) {
00432         //TODO: GL2 needs always a renderbuffer???
00433         if (!sb->ogl_tex_initialized) {
00434             // texture is also not initialized
00435             mmsfbgl.allocFBOandRBO(sb->ogl_fbo, sb->ogl_tex, sb->ogl_rbo, surface->config.w, surface->config.h);
00436         }
00437         else {
00438             // texture is already initialized, so we can use it for FBO
00439             mmsfbgl.attachTexture2FrameBuffer(sb->ogl_fbo, sb->ogl_tex);
00440             mmsfbgl.attachRenderBuffer2FrameBuffer(sb->ogl_fbo, sb->ogl_rbo, surface->config.w, surface->config.h);
00441         }
00442 
00443         sb->ogl_fbo_initialized = true;
00444         sb->ogl_tex_initialized = true;
00445         sb->ogl_rbo_initialized = true;
00446 
00447     }
00448 #endif
00449 
00450 #ifdef __HAVE_GLES2__
00451     if (!sb->ogl_fbo_initialized) {
00452         // per default we do NOT attach a renderbuffer to the FBO (not needed for 2D, reduce memory foot print)
00453         sb->ogl_rbo_initialized = false;
00454 
00455         // allocate a texture (color buffer) and bind it to a new FBO
00456         if (!sb->ogl_tex_initialized) {
00457             // texture is also not initialized
00458             if (rbo_required) {
00459                 // additionally have to initialize RBO
00460                 // so, initialize FBO, RBO and texture
00461                 mmsfbgl.allocFBOandRBO(sb->ogl_fbo, sb->ogl_tex, sb->ogl_rbo, surface->config.w, surface->config.h);
00462                 sb->ogl_rbo_initialized = true;
00463             }
00464             else {
00465                 // RBO not needed
00466                 // so, initialize FBO and texture
00467                 mmsfbgl.allocFBO(sb->ogl_fbo, sb->ogl_tex, surface->config.w, surface->config.h);
00468             }
00469         }
00470         else {
00471             // texture is already initialized, so we can use it for FBO
00472             mmsfbgl.attachTexture2FrameBuffer(sb->ogl_fbo, sb->ogl_tex);
00473         }
00474 
00475         sb->ogl_fbo_initialized = true;
00476         sb->ogl_tex_initialized = true;
00477 
00478     }
00479 #endif
00480 
00481     // it can be, that the decision to have an RBO comes later
00482     // so it is possible to have a initialized FBO here without an RBO
00483     if (sb->ogl_fbo_initialized) {
00484         // FBO is already initialized
00485         if (!sb->ogl_rbo_initialized) {
00486             // RBO is not initialized
00487             if (rbo_required) {
00488                 // additionally have to initialize RBO
00489                 mmsfbgl.attachRenderBuffer2FrameBuffer(sb->ogl_fbo, sb->ogl_rbo, surface->config.w, surface->config.h);
00490                 sb->ogl_rbo_initialized = true;
00491             }
00492         }
00493     }
00494 }
00495 
00496 
00497 void MMSFBBackEndInterface::oglBindSurface(MMSFBSurface *surface) {
00498     // allocate FBO, RBO and texture
00499     oglAlloc(surface);
00500 
00501     // bind FBO
00502     mmsfbgl.bindFrameBuffer(surface->config.surface_buffer->ogl_fbo);
00503 
00504     if (surface->config.surface_buffer->ogl_fbo) {
00505         // set the matrix for off-screen FBO's
00506         if (!surface->is_sub_surface) {
00507             oglMatrix(false, 0, surface->config.w, 0, surface->config.h);
00508         }
00509         else {
00510             oglMatrix(false, 0, surface->root_parent->config.w, 0, surface->root_parent->config.h);
00511         }
00512     } else {
00513         // set the matrix for primary FBO
00514         if (!surface->is_sub_surface) {
00515             oglMatrix(false, 0, surface->config.w, surface->config.h, 0);
00516         }
00517         else {
00518             oglMatrix(false, 0, surface->root_parent->config.w, surface->root_parent->config.h, 0);
00519         }
00520     }
00521 }
00522 
00523 void MMSFBBackEndInterface::oglBindSurface(MMSFBSurface *surface, int nearZ, int farZ, bool central_projection) {
00524 
00525     // allocate FBO, RBO and texture
00526     oglAlloc(surface, true);
00527 
00528     // bind FBO
00529     mmsfbgl.bindFrameBuffer(surface->config.surface_buffer->ogl_fbo);
00530 
00531     if (surface->config.surface_buffer->ogl_fbo) {
00532         // set the matrix for off-screen FBO's
00533         if (!surface->is_sub_surface) {
00534             oglMatrix(central_projection,
00535                       -(int)surface->config.w/2, (int)surface->config.w/2,
00536                       -(int)surface->config.h/2, (int)surface->config.h/2,
00537                       nearZ, farZ);
00538         }
00539         else {
00540             oglMatrix(central_projection,
00541                       -(int)surface->root_parent->config.w/2, (int)surface->root_parent->config.w/2,
00542                       -(int)surface->root_parent->config.h/2, (int)surface->root_parent->config.h/2,
00543                       nearZ, farZ);
00544         }
00545     } else {
00546         // set the matrix for primary FBO
00547         if (!surface->is_sub_surface) {
00548             oglMatrix(central_projection,
00549                       -(int)surface->config.w/2, (int)surface->config.w/2,
00550                        (int)surface->config.h/2,-(int)surface->config.h/2,
00551                        nearZ, farZ);
00552         }
00553         else {
00554             oglMatrix(central_projection,
00555                       -(int)surface->root_parent->config.w/2, (int)surface->root_parent->config.w/2,
00556                        (int)surface->root_parent->config.h/2,-(int)surface->root_parent->config.h/2,
00557                        nearZ, farZ);
00558         }
00559     }
00560 }
00561 
00562 
00563 bool MMSFBBackEndInterface::oglDrawBuffer(MMSFBBuffer::BUFFER *buffer,
00564                                           MMSFBBuffer::INDEX_BUFFER *index_buffer,
00565                                           MMSFBBuffer::VERTEX_BUFFER *vertex_buffer) {
00566     if (!buffer) return false;
00567 
00568     if (!index_buffer || !vertex_buffer) {
00569         // get access to index and vertex buffer
00570         if (!buffer->getBuffers(&index_buffer, &vertex_buffer)) return false;
00571     }
00572 
00573     // check if we have index and vertex buffer
00574     if (!index_buffer || !vertex_buffer) return false;
00575 
00576     if (buffer->index_bo.bo && buffer->vertex_bo.bo) {
00577         // index and vertex buffer objects are available
00578         //TODO...
00579         return true;
00580     }
00581     else
00582     if (buffer->vertex_bo.bo) {
00583         // vertex buffer object is available
00584         for (unsigned int i = 0; i < buffer->vertex_bo.num_buffers; i++) {
00585             mmsfbgl.drawElements(&buffer->vertex_bo.buffers[i], NULL, NULL, &buffer->index_bo.buffers[i]);
00586         }
00587         return true;
00588     }
00589     else {
00590         // buffer objects not available, so we have to put indices/vertices over the bus to GPU
00591         for (unsigned int i = 0; i < index_buffer->num_arrays; i++) {
00592             mmsfbgl.drawElements(&vertex_buffer->arrays[i], NULL, NULL, &index_buffer->arrays[i]);
00593         }
00594         return true;
00595     }
00596 
00597     return false;
00598 }
00599 
00600 #endif
00601 
00602 void MMSFBBackEndInterface::swap() {
00603     BEI_SWAP req;
00604     req.type    = BEI_REQUEST_TYPE_SWAP;
00605     trigger((void*)&req, sizeof(req));
00606 }
00607 
00608 void MMSFBBackEndInterface::processSwap(BEI_SWAP *req) {
00609 #ifdef __HAVE_OPENGL__
00610     // swap screen
00611     mmsfbgl.swap();
00612 #endif
00613 }
00614 
00615 void MMSFBBackEndInterface::alloc(MMSFBSurface *surface) {
00616     BEI_ALLOC req;
00617     req.type    = BEI_REQUEST_TYPE_ALLOC;
00618     req.surface = surface;
00619     trigger((void*)&req, sizeof(req));
00620 }
00621 
00622 
00623 void MMSFBBackEndInterface::processAlloc(BEI_ALLOC *req) {
00624 #ifdef  __HAVE_OPENGL__
00625 
00626     MMSFBSurfaceBuffer *sb = req->surface->config.surface_buffer;
00627 
00628     // generate id's for texture, fbo and rbo - but do NOT initialize it
00629     mmsfbgl.genTexture(&sb->ogl_tex);
00630     mmsfbgl.genFrameBuffer(&sb->ogl_fbo);
00631     mmsfbgl.genRenderBuffer(&sb->ogl_rbo);
00632     sb->ogl_fbo_initialized = false;
00633     sb->ogl_tex_initialized = false;
00634     sb->ogl_rbo_initialized = false;
00635 
00636 #endif
00637 }
00638 
00639 
00640 void MMSFBBackEndInterface::free(MMSFBSurface *surface) {
00641     BEI_FREE req;
00642     req.type    = BEI_REQUEST_TYPE_FREE;
00643     req.surface = surface;
00644     trigger((void*)&req, sizeof(req));
00645 }
00646 
00647 
00648 void MMSFBBackEndInterface::processFree(BEI_FREE *req) {
00649 #ifdef  __HAVE_OPENGL__
00650     MMSFBSurfaceBuffer *sb = req->surface->config.surface_buffer;
00651     mmsfbgl.freeFBO(sb->ogl_fbo, sb->ogl_tex, sb->ogl_rbo);
00652 #endif
00653 }
00654 
00655 
00656 void MMSFBBackEndInterface::clear(MMSFBSurface *surface, MMSFBColor &color) {
00657     BEI_CLEAR req;
00658     req.type    = BEI_REQUEST_TYPE_CLEAR;
00659     req.surface = surface;
00660     req.color   = color;
00661     trigger((void*)&req, sizeof(req));
00662 }
00663 
00664 
00665 void MMSFBBackEndInterface::processClear(BEI_CLEAR *req) {
00666 #ifdef  __HAVE_OPENGL__
00667     // lock destination fbo and prepare it
00668     oglBindSurface(req->surface);
00669 
00670     // get subsurface offsets
00671     GET_OFFS(req->surface);
00672 
00673     // set the clip to ogl
00674     MMSFBRectangle crect;
00675     if (req->surface->calcClip(0 + xoff, 0 + yoff, req->surface->config.w, req->surface->config.h, &crect)) {
00676         // inside clipping region
00677         OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
00678 
00679         mmsfbgl.clear(req->color.r, req->color.g, req->color.b, req->color.a);
00680     }
00681 #endif
00682 }
00683 
00684 void MMSFBBackEndInterface::fillRectangle(MMSFBSurface *surface, MMSFBRectangle &rect, MMSFBDrawingFlags drawingflags) {
00685     BEI_FILLRECTANGLE req;
00686     req.type        = BEI_REQUEST_TYPE_FILLRECTANGLE;
00687     req.surface     = surface;
00688     req.rect        = rect;
00689     req.drawingflags= drawingflags;
00690     trigger((void*)&req, sizeof(req));
00691 }
00692 
00693 void MMSFBBackEndInterface::processFillRectangle(BEI_FILLRECTANGLE *req) {
00694 #ifdef  __HAVE_OPENGL__
00695     // lock destination fbo and prepare it
00696     oglBindSurface(req->surface);
00697 
00698     // setup drawing
00699     INIT_OGL_DRAWING(req->surface, req->drawingflags);
00700 
00701     // set ogl clip
00702     OGL_SCISSOR(req->surface, req->rect.x, req->rect.y, req->rect.w, req->rect.h);
00703 
00704     // fill rectangle
00705     mmsfbgl.fillRectangle2Di(req->rect.x,
00706                              req->rect.y,
00707                              req->rect.x + req->rect.w - 1,
00708                              req->rect.y + req->rect.h - 1);
00709 #endif
00710 }
00711 
00712 void MMSFBBackEndInterface::fillTriangle(MMSFBSurface *surface, MMSFBTriangle &triangle) {
00713     BEI_FILLTRIANGLE req;
00714     req.type    = BEI_REQUEST_TYPE_FILLTRIANGLE;
00715     req.surface = surface;
00716     req.triangle= triangle;
00717     trigger((void*)&req, sizeof(req));
00718 }
00719 
00720 void MMSFBBackEndInterface::processFillTriangle(BEI_FILLTRIANGLE *req) {
00721 #ifdef  __HAVE_GL2__
00722     // lock destination fbo and prepare it
00723     oglBindSurface(req->surface);
00724     glDisable(GL_DEPTH_TEST);
00725     glDisable(GL_TEXTURE_2D);
00726 
00727     // setup drawing
00728     INIT_OGL_DRAWING(req->surface, req->surface->config.drawingflags);
00729 
00730     // get subsurface offsets
00731     GET_OFFS(req->surface);
00732 
00733     // set the clip to ogl
00734     MMSFBRectangle crect;
00735     int x, y, w, h;
00736     if (req->triangle.x2 >= req->triangle.x1) {
00737         x = req->triangle.x1;
00738         w = req->triangle.x2 - req->triangle.x1 + 1;
00739     }
00740     else {
00741         x = req->triangle.x2;
00742         w = req->triangle.x1 - req->triangle.x2 + 1;
00743     }
00744     if (req->triangle.y2 >= req->triangle.y1) {
00745         y = req->triangle.y1;
00746         h = req->triangle.y2 - req->triangle.y1 + 1;
00747     }
00748     else {
00749         y = req->triangle.y2;
00750         h = req->triangle.y1 - req->triangle.y2 + 1;
00751     }
00752     if (req->triangle.x3 < x) x = req->triangle.x3;
00753     if (req->triangle.x3 > x + w - 1) w = req->triangle.x3 - x + 1;
00754     if (req->triangle.y3 < y) y = req->triangle.y3;
00755     if (req->triangle.y3 > y + h - 1) h = req->triangle.y3 - y + 1;
00756 
00757     if (req->surface->calcClip(x + xoff, y + yoff, w, h, &crect)) {
00758         // inside clipping region
00759         OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
00760         glEnable(GL_SCISSOR_TEST);
00761 
00762         // fill triangle
00763         OGL_FILL_TRIANGLE(req->triangle.x1 + xoff, req->triangle.y1 + yoff,
00764                           req->triangle.x2 + xoff, req->triangle.y2 + yoff,
00765                           req->triangle.x3 + xoff, req->triangle.y3 + yoff);
00766     }
00767 #endif
00768 }
00769 
00770 void MMSFBBackEndInterface::drawLine(MMSFBSurface *surface, int x1, int y1, int x2, int y2) {
00771     BEI_DRAWLINE req;
00772     req.type    = BEI_REQUEST_TYPE_DRAWLINE;
00773     req.surface = surface;
00774     req.x1  = x1;
00775     req.y1  = y1;
00776     req.x2  = x2;
00777     req.y2  = y2;
00778     trigger((void*)&req, sizeof(req));
00779 }
00780 
00781 void MMSFBBackEndInterface::processDrawLine(BEI_DRAWLINE *req) {
00782 #ifdef  __HAVE_OPENGL__
00783     // lock destination fbo and prepare it
00784     oglBindSurface(req->surface);
00785 
00786     // setup drawing
00787     INIT_OGL_DRAWING(req->surface, req->surface->config.drawingflags);
00788 
00789     // get subsurface offsets
00790     GET_OFFS(req->surface);
00791 
00792     // set the clip to ogl
00793     MMSFBRectangle crect;
00794     int x, y, w, h;
00795     if (req->x2 >= req->x1) {
00796         x = req->x1;
00797         w = req->x2 - req->x1 + 1;
00798     }
00799     else {
00800         x = req->x2;
00801         w = req->x1 - req->x2 + 1;
00802     }
00803     if (req->y2 >= req->y1) {
00804         y = req->y1;
00805         h = req->y2 - req->y1 + 1;
00806     }
00807     else {
00808         y = req->y2;
00809         h = req->y1 - req->y2 + 1;
00810     }
00811 
00812     if (req->surface->calcClip(x + xoff, y + yoff, w, h, &crect)) {
00813         // inside clipping region
00814         OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
00815 
00816         // draw line
00817         mmsfbgl.drawLine2Di(req->x1 + xoff, req->y1 + yoff,
00818                             req->x2 + xoff, req->y2 + yoff);
00819     }
00820 #endif
00821 }
00822 
00823 void MMSFBBackEndInterface::drawRectangle(MMSFBSurface *surface, MMSFBRectangle &rect) {
00824     BEI_DRAWRECTANGLE req;
00825     req.type    = BEI_REQUEST_TYPE_DRAWRECTANGLE;
00826     req.surface = surface;
00827     req.rect    = rect;
00828     trigger((void*)&req, sizeof(req));
00829 }
00830 
00831 void MMSFBBackEndInterface::processDrawRectangle(BEI_DRAWRECTANGLE *req) {
00832 #ifdef  __HAVE_OPENGL__
00833     // lock destination fbo and prepare it
00834     oglBindSurface(req->surface);
00835 
00836     // setup drawing
00837     INIT_OGL_DRAWING(req->surface, req->surface->config.drawingflags);
00838 
00839     // get subsurface offsets
00840     GET_OFFS(req->surface);
00841 
00842     // set the clip to ogl
00843     MMSFBRectangle crect;
00844     if (req->surface->calcClip(req->rect.x + xoff, req->rect.y + yoff, req->rect.w, req->rect.h, &crect)) {
00845         // inside clipping region
00846         OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
00847 
00848         // draw rectangle
00849         OGL_DRAW_RECTANGLE(req->rect.x                      + xoff,
00850                            req->rect.y                      + yoff,
00851                            req->rect.x + req->rect.w - 1    + xoff,
00852                            req->rect.y + req->rect.h - 1    + yoff);
00853     }
00854 #endif
00855 }
00856 
00857 void MMSFBBackEndInterface::drawTriangle(MMSFBSurface *surface, MMSFBTriangle &triangle) {
00858     BEI_DRAWTRIANGLE req;
00859     req.type    = BEI_REQUEST_TYPE_DRAWTRIANGLE;
00860     req.surface = surface;
00861     req.triangle= triangle;
00862     trigger((void*)&req, sizeof(req));
00863 }
00864 
00865 void MMSFBBackEndInterface::processDrawTriangle(BEI_DRAWTRIANGLE *req) {
00866 #ifdef  __HAVE_GL2__
00867     // lock destination fbo and prepare it
00868     oglBindSurface(req->surface);
00869     glDisable(GL_DEPTH_TEST);
00870     glDisable(GL_TEXTURE_2D);
00871 
00872     // setup drawing
00873     INIT_OGL_DRAWING(req->surface, req->surface->config.drawingflags);
00874 
00875     // get subsurface offsets
00876     GET_OFFS(req->surface);
00877 
00878     // set the clip to ogl
00879     MMSFBRectangle crect;
00880     int x, y, w, h;
00881     if (req->triangle.x2 >= req->triangle.x1) {
00882         x = req->triangle.x1;
00883         w = req->triangle.x2 - req->triangle.x1 + 1;
00884     }
00885     else {
00886         x = req->triangle.x2;
00887         w = req->triangle.x1 - req->triangle.x2 + 1;
00888     }
00889     if (req->triangle.y2 >= req->triangle.y1) {
00890         y = req->triangle.y1;
00891         h = req->triangle.y2 - req->triangle.y1 + 1;
00892     }
00893     else {
00894         y = req->triangle.y2;
00895         h = req->triangle.y1 - req->triangle.y2 + 1;
00896     }
00897     if (req->triangle.x3 < x) x = req->triangle.x3;
00898     if (req->triangle.x3 > x + w - 1) w = req->triangle.x3 - x + 1;
00899     if (req->triangle.y3 < y) y = req->triangle.y3;
00900     if (req->triangle.y3 > y + h - 1) h = req->triangle.y3 - y + 1;
00901 
00902     if (req->surface->calcClip(x + xoff, y + yoff, w, h, &crect)) {
00903         // inside clipping region
00904         OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
00905         glEnable(GL_SCISSOR_TEST);
00906 
00907         // draw triangle
00908         OGL_DRAW_TRIANGLE(req->triangle.x1 + xoff, req->triangle.y1 + yoff,
00909                           req->triangle.x2 + xoff, req->triangle.y2 + yoff,
00910                           req->triangle.x3 + xoff, req->triangle.y3 + yoff);
00911     }
00912 #endif
00913 }
00914 
00915 void MMSFBBackEndInterface::blit(MMSFBSurface *surface, MMSFBSurface *source, MMSFBRectangle &src_rect,
00916                                  int x, int y, MMSFBBlittingFlags blittingflags) {
00917     BEI_BLIT req;
00918     req.type            = BEI_REQUEST_TYPE_BLIT;
00919     req.surface         = surface;
00920     req.source          = source;
00921     req.src_rect        = src_rect;
00922     req.x               = x;
00923     req.y               = y;
00924     req.blittingflags   = blittingflags;
00925     trigger((void*)&req, sizeof(req));
00926 }
00927 
00928 void MMSFBBackEndInterface::processBlit(BEI_BLIT *req) {
00929 #ifdef  __HAVE_OPENGL__
00930     // lock destination fbo and bind source texture to it
00931     oglBindSurface(req->surface);
00932 
00933     // setup blitting
00934     INIT_OGL_BLITTING(req->surface, req->blittingflags);
00935 
00936     // get subsurface offsets
00937     GET_OFFS(req->surface);
00938     GET_OFFS_SRC(req->source);
00939 /*
00940     // set the clip to ogl
00941     MMSFBRectangle crect;
00942     if (req->surface->calcClip(req->x + xoff, req->y + yoff, req->src_rect.w, req->src_rect.h, &crect)) {
00943         // inside clipping region
00944         OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
00945 
00946         // get source region
00947         int sx1 = req->src_rect.x + src_xoff;
00948         int sy1 = req->src_rect.y + src_yoff;
00949         int sx2 = req->src_rect.x + req->src_rect.w - 1 + src_xoff;
00950         int sy2 = req->src_rect.y + req->src_rect.h - 1 + src_yoff;
00951 
00952         // get destination region
00953         int dx1 = req->x + xoff;
00954         int dy1 = req->y + yoff;
00955         int dx2 = req->x + req->src_rect.w - 1 + xoff;
00956         int dy2 = req->y + req->src_rect.h - 1 + yoff;
00957 
00958         if (req->source->config.surface_buffer->ogl_tex_initialized) {
00959             // blit source texture to the destination
00960             mmsfbgl.stretchBliti(req->source->config.surface_buffer->ogl_tex,
00961                         sx1, sy1, sx2, sy2, src_rootw, src_rooth,
00962                         dx1, dy1, dx2, dy2);
00963         }
00964         else {
00965             printf("skip blitting from texture which is not initialized\n");
00966         }
00967     }
00968 */
00969 
00970 
00971     // set ogl clip
00972     OGL_SCISSOR(req->surface, req->x, req->y, req->src_rect.w, req->src_rect.h);
00973 //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);
00974 
00975 //((!surface->is_sub_surface && surface->config.surface_buffer && surface->config.surface_buffer->ogl_unchanged_depth_buffer)
00976 //||(surface->is_sub_surface && surface->root_parent->config.surface_buffer && surface->root_parent->config.surface_buffer->ogl_unchanged_depth_buffer))
00977 
00978     if (req->source->config.surface_buffer->ogl_tex_initialized) {
00979         // blit source texture to the destination
00980 //printf("blit: %d,%d,%d,%d %d,%d %d,%d,%d,%d\n",
00981 //      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,
00982 //      src_rootw, src_rooth,
00983 //      req->x, req->y, req->x + req->src_rect.w - 1, req->y + req->src_rect.h - 1);
00984 
00985 
00986         mmsfbgl.stretchBliti(req->source->config.surface_buffer->ogl_tex,
00987                     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,
00988                     src_rootw, src_rooth,
00989                     req->x, req->y, req->x + req->src_rect.w - 1, req->y + req->src_rect.h - 1);
00990     }
00991     else {
00992         printf("skip blitting from texture which is not initialized\n");
00993     }
00994 #endif
00995 }
00996 
00997 void MMSFBBackEndInterface::stretchBlit(MMSFBSurface *surface, MMSFBSurface *source, MMSFBRectangle &src_rect,
00998                                         MMSFBRectangle &dst_rect, MMSFBBlittingFlags blittingflags) {
00999     BEI_STRETCHBLIT req;
01000     req.type            = BEI_REQUEST_TYPE_STRETCHBLIT;
01001     req.surface         = surface;
01002     req.source          = source;
01003     req.src_rect        = src_rect;
01004     req.dst_rect        = dst_rect;
01005     req.blittingflags   = blittingflags;
01006     trigger((void*)&req, sizeof(req));
01007 }
01008 
01009 void MMSFBBackEndInterface::processStretchBlit(BEI_STRETCHBLIT *req) {
01010 #ifdef  __HAVE_OPENGL__
01011     // lock destination fbo and bind source texture to it
01012     oglBindSurface(req->surface);
01013 
01014     // setup blitting
01015     INIT_OGL_BLITTING(req->surface, req->blittingflags);
01016 
01017     // get subsurface offsets
01018     GET_OFFS(req->surface);
01019     GET_OFFS_SRC(req->source);
01020 
01021     // set the clip to ogl
01022     MMSFBRectangle crect;
01023     if (req->surface->calcClip(req->dst_rect.x + xoff, req->dst_rect.y + yoff, req->dst_rect.w, req->dst_rect.h, &crect)) {
01024         // inside clipping region
01025         OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
01026 
01027         // get source region
01028         int sx1 = req->src_rect.x + src_xoff;
01029         int sy1 = req->src_rect.y + src_yoff;
01030         int sx2 = req->src_rect.x + req->src_rect.w - 1 + src_xoff;
01031         int sy2 = req->src_rect.y + req->src_rect.h - 1 + src_yoff;
01032 
01033         // get destination region
01034         int dx1 = req->dst_rect.x + xoff;
01035         int dy1 = req->dst_rect.y + yoff;
01036         int dx2 = req->dst_rect.x + req->dst_rect.w - 1 + xoff;
01037         int dy2 = req->dst_rect.y + req->dst_rect.h - 1 + yoff;
01038 
01039         if (req->source->config.surface_buffer->ogl_tex_initialized) {
01040             // blit source texture to the destination
01041             mmsfbgl.stretchBliti(req->source->config.surface_buffer->ogl_tex,
01042                         sx1, sy1, sx2, sy2, src_rootw, src_rooth,
01043                         dx1, dy1, dx2, dy2);
01044         }
01045         else {
01046             printf("skip blitting from texture which is not initialized\n");
01047         }
01048     }
01049 #endif
01050 }
01051 
01052 void MMSFBBackEndInterface::blitBuffer(MMSFBSurface *surface, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
01053                                        int src_width, int src_height, MMSFBRectangle &src_rect, int x, int y,
01054                                        MMSFBBlittingFlags blittingflags) {
01055     BEI_STRETCHBLITBUFFER req;
01056     req.type            = BEI_REQUEST_TYPE_STRETCHBLITBUFFER;
01057     req.surface         = surface;
01058     req.src_planes      = src_planes;
01059     req.src_pixelformat = src_pixelformat;
01060     req.src_width       = src_width;
01061     req.src_height      = src_height;
01062     req.src_rect        = src_rect;
01063     req.dst_rect.x      = x;
01064     req.dst_rect.y      = y;
01065     req.dst_rect.w      = src_rect.w;
01066     req.dst_rect.h      = src_rect.h;
01067     req.blittingflags   = blittingflags;
01068     trigger((void*)&req, sizeof(req));
01069 }
01070 
01071 void MMSFBBackEndInterface::stretchBlitBuffer(MMSFBSurface *surface, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
01072                                               int src_width, int src_height,MMSFBRectangle &src_rect, MMSFBRectangle &dst_rect,
01073                                               MMSFBBlittingFlags blittingflags) {
01074     BEI_STRETCHBLITBUFFER req;
01075     req.type            = BEI_REQUEST_TYPE_STRETCHBLITBUFFER;
01076     req.surface         = surface;
01077     req.src_planes      = src_planes;
01078     req.src_pixelformat = src_pixelformat;
01079     req.src_width       = src_width;
01080     req.src_height      = src_height;
01081     req.src_rect        = src_rect;
01082     req.dst_rect        = dst_rect;
01083     req.blittingflags   = blittingflags;
01084     trigger((void*)&req, sizeof(req));
01085 }
01086 
01087 void MMSFBBackEndInterface::processStretchBlitBuffer(BEI_STRETCHBLITBUFFER *req) {
01088 #ifdef  __HAVE_OPENGL__
01089 
01090     // check if we can blit to texture without fbo
01091     bool blit2texture = (!req->surface->config.surface_buffer->ogl_fbo_initialized);
01092     if (blit2texture) {
01093         if (req->blittingflags != MMSFB_BLIT_NOFX) {
01094             if (req->blittingflags == MMSFB_BLIT_BLEND_ALPHACHANNEL) {
01095                 if (!MMSFBSURFACE_WRITE_BUFFER(req->surface).opaque) {
01096                     // alphachannel blending and opaque flag not set, so we cannot blit to texture directly
01097                     // note: the opaque flag means, that surface should be opaque AFTER the blit
01098                     blit2texture = false;
01099                 }
01100             }
01101             else {
01102                 // blitting flags does not allow to blit to texture directly
01103                 blit2texture = false;
01104             }
01105         }
01106     }
01107 
01108     if (blit2texture) {
01109         // FBO and it's texture is not initialized and we only have to COPY the buffer in a texture
01110         mmsfbgl.blitBuffer2Texture(req->surface->config.surface_buffer->ogl_tex,
01111                                    (!req->surface->config.surface_buffer->ogl_tex_initialized),
01112                                    req->src_planes->ptr, req->src_width, req->src_height);
01113 
01114         // now we have a texture allocated
01115         req->surface->config.surface_buffer->ogl_tex_initialized = true;
01116 
01117         return;
01118     }
01119 
01120     // lock destination fbo and bind source texture to it
01121     oglBindSurface(req->surface);
01122 
01123     // setup blitting
01124     INIT_OGL_BLITTING(req->surface, req->blittingflags);
01125 
01126     // get subsurface offsets
01127     GET_OFFS(req->surface);
01128 
01129     // set the clip to ogl
01130     MMSFBRectangle crect;
01131     if (req->surface->calcClip(req->dst_rect.x + xoff, req->dst_rect.y + yoff, req->dst_rect.w, req->dst_rect.h, &crect)) {
01132         // inside clipping region
01133         OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
01134 
01135         // get source region
01136         int sx1 = req->src_rect.x;
01137         int sy1 = req->src_rect.y;
01138         int sx2 = req->src_rect.x + req->src_rect.w - 1;
01139         int sy2 = req->src_rect.y + req->src_rect.h - 1;
01140 
01141         // get destination region
01142         int dx1 = req->dst_rect.x + xoff;
01143         int dy1 = req->dst_rect.y + yoff;
01144         int dx2 = req->dst_rect.x + req->dst_rect.w - 1 + xoff;
01145         int dy2 = req->dst_rect.y + req->dst_rect.h - 1 + yoff;
01146 
01147         // blit source texture to the destination
01148         mmsfbgl.stretchBlitBufferi(req->src_planes->ptr,
01149                     sx1, sy1, sx2, sy2, req->src_width, req->src_height,
01150                     dx1, dy1, dx2, dy2);
01151     }
01152 #endif
01153 }
01154 
01155 
01156 
01157 void MMSFBBackEndInterface::createAlphaTexture(unsigned int *texture, unsigned char *buffer, int width, int height) {
01158     BEI_CREATEALPHATEXTURE req;
01159     req.type    = BEI_REQUEST_TYPE_CREATEALPHATEXTURE;
01160     req.texture = texture;
01161     req.buffer  = buffer;
01162     req.width   = width;
01163     req.height  = height;
01164     trigger((void*)&req, sizeof(req));
01165 }
01166 
01167 void MMSFBBackEndInterface::processCreateAlphaTexture(BEI_CREATEALPHATEXTURE *req) {
01168 #ifdef  __HAVE_OPENGL__
01169 
01170     // alloc a texture
01171     mmsfbgl.genTexture(req->texture);
01172 
01173     // specify two-dimensional glyph texture
01174     mmsfbgl.initTexture2D(*(req->texture), GL_ALPHA, req->buffer, GL_ALPHA, req->width, req->height);
01175 
01176 #endif
01177 }
01178 
01179 
01180 void MMSFBBackEndInterface::deleteTexture(unsigned int texture) {
01181     BEI_DELETETEXTURE req;
01182     req.type    = BEI_REQUEST_TYPE_DELETETEXTURE;
01183     req.texture = texture;
01184     trigger((void*)&req, sizeof(req));
01185 }
01186 
01187 void MMSFBBackEndInterface::processDeleteTexture(BEI_DELETETEXTURE *req) {
01188 #ifdef  __HAVE_OPENGL__
01189 
01190     // delete a texture
01191     mmsfbgl.deleteTexture(req->texture);
01192 
01193 #endif
01194 }
01195 
01196 
01197 void MMSFBBackEndInterface::drawString(MMSFBSurface *surface, string &text, int len, int x, int y) {
01198     BEI_DRAWSTRING req;
01199     req.type    = BEI_REQUEST_TYPE_DRAWSTRING;
01200     req.surface = surface;
01201     req.text    = text;
01202     req.len     = len;
01203     req.x       = x;
01204     req.y       = y;
01205     trigger((void*)&req, sizeof(req));
01206 }
01207 
01208 void MMSFBBackEndInterface::processDrawString(BEI_DRAWSTRING *req) {
01209 #ifdef  __HAVE_OPENGL__
01210 
01211     // lock destination fbo and bind source texture to it
01212     oglBindSurface(req->surface);
01213 
01214 #ifndef __HAVE_GLU__
01215     // setup texture blitting
01216     mmsfbgl.enableBlend();
01217     if (req->surface->config.color.a == 0xff)
01218         mmsfbgl.setTexEnvReplace(GL_ALPHA);
01219     else
01220         mmsfbgl.setTexEnvModulate(GL_ALPHA);
01221     mmsfbgl.setColor(req->surface->config.color.r,
01222                     req->surface->config.color.g,
01223                     req->surface->config.color.b,
01224                     req->surface->config.color.a);
01225 #else
01226     // setup drawing
01227     INIT_OGL_DRAWING(req->surface, req->surface->config.drawingflags);
01228 #endif
01229 
01230     // get subsurface offsets
01231     GET_OFFS(req->surface);
01232 
01233     // set the clip to ogl
01234     MMSFBRectangle crect;
01235     if (req->surface->calcClip(0 + xoff, 0 + yoff, req->surface->config.w, req->surface->config.h, &crect)) {
01236         // inside clipping region
01237         OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
01238 
01239 #ifdef __HAVE_GLU__
01240         // save and scale current matrix
01241         mmsfbgl.pushCurrentMatrix();
01242         float scale_coeff = 1.0f;
01243         if (req->surface->config.font->getScaleCoeff(&scale_coeff))
01244             mmsfbgl.scaleCurrentMatrix(scale_coeff, scale_coeff, 1);
01245         int dx1_save = 0;
01246         int dy1_save = 0;
01247 #endif
01248 
01249         // get vertical font settings
01250         int DY = 0;
01251         DY = req->surface->config.font->height;
01252         DY-= req->surface->config.font->descender + 1;
01253 
01254 #ifdef __HAVE_GLU__
01255         // calc base position
01256         req->x = (int)((float)req->x / scale_coeff + 0.5f);
01257         req->y = (int)((float)req->y / scale_coeff + 0.5f);
01258 
01259         // calc subsurface offsets
01260         xoff = (int)((float)xoff / scale_coeff + 0.5f);
01261         yoff = (int)((float)yoff / scale_coeff + 0.5f);
01262 #endif
01263 
01264         // for all characters
01265         MMSFBFONT_GET_UNICODE_CHAR(req->text, req->len) {
01266 
01267             // load the glyph
01268             MMSFBSURFACE_BLIT_TEXT_LOAD_GLYPH(req->surface->config.font, character);
01269 
01270             // start rendering of glyph to destination
01271             if (glyph_loaded) {
01272                 // calc destination position of the character
01273                 int dx = req->x + glyph.left;
01274                 int dy = req->y + DY - glyph.top;
01275 
01276 #ifndef __HAVE_GLU__
01277                 // get destination region
01278                 int dx1 = dx + xoff;
01279                 int dy1 = dy + yoff;
01280                 int dx2 = dx + src_w - 1 + xoff;
01281                 int dy2 = dy + src_h - 1 + yoff;
01282 
01283                 // get source region
01284                 int sx1 = 0;
01285                 int sy1 = 0;
01286                 int sx2 = src_w - 1;
01287                 int sy2 = src_h - 1;
01288 
01289                 if (glyph.texture) {
01290                     // blit glyph texture to the destination
01291                     mmsfbgl.stretchBliti(glyph.texture,
01292                                             sx1, sy1, sx2, sy2, src_pitch_pix, src_h,
01293                                             dx1, dy1, dx2, dy2);
01294                 }
01295 #else
01296                 // get destination offset
01297                 int dx1 = dx + xoff;
01298                 int dy1 = dy + yoff;
01299 
01300                 // move to correct position
01301                 mmsfbgl.translateCurrentMatrix(dx1 - dx1_save, dy1 - dy1_save, 0);
01302                 dx1_save = dx1;
01303                 dy1_save = dy1;
01304 
01305                 MMSFBBuffer::BUFFER *buffer;
01306 
01307                 if (glyph.outline && glyph.outline->getBuffer(&buffer)) {
01308                     MMSFBBuffer::INDEX_BUFFER *index_buffer;
01309                     MMSFBBuffer::VERTEX_BUFFER *vertex_buffer;
01310                     if (buffer->getBuffers(&index_buffer, &vertex_buffer)) {
01311                         // draw glyph outline
01312                         if (index_buffer->num_arrays) {
01313                             // setup special drawing flags
01314                             // glyph outline is used for soft-focus effect, we draw it with 1/3 alphachannel
01315                             mmsfbgl.enableBlend();
01316                             MMSFBColor *color = &req->surface->config.color;
01317                             mmsfbgl.setColor(color->r, color->g, color->b, color->a / 3);
01318 
01319                             // draw primitives: glyph outline
01320                             oglDrawBuffer(buffer, index_buffer, vertex_buffer);
01321 
01322                             // reset drawing flags and color
01323                             mmsfbgl.disableBlend();
01324                             mmsfbgl.setColor(color->r, color->g, color->b, color->a);
01325                         }
01326                     }
01327                 }
01328 
01329                 if (glyph.meshes && glyph.meshes->getBuffer(&buffer)) {
01330                     // draw primitives: glyph meshes
01331                     oglDrawBuffer(buffer);
01332                 }
01333 #endif
01334 
01335                 // prepare for next loop
01336                 req->x+= glyph.advanceX;
01337             }
01338         }}
01339 
01340 #ifdef __HAVE_GLU__
01341         // restore matrix
01342         mmsfbgl.popCurrentMatrix();
01343 #endif
01344     }
01345 
01346 #endif
01347 }
01348 
01349 void MMSFBBackEndInterface::renderScene(MMSFBSurface *surface,
01350                                         MMS_VERTEX_ARRAY    **varrays,
01351                                         MMS_INDEX_ARRAY     **iarrays,
01352                                         MMS3D_MATERIAL      *materials,
01353                                         MMSFBSurface        **texsurfaces,
01354                                         MMS3D_OBJECT        **objects) {
01355     BEI_RENDERSCENE req;
01356     req.type        = BEI_REQUEST_TYPE_RENDERSCENE;
01357     req.surface     = surface;
01358     req.varrays     = varrays;
01359     req.iarrays     = iarrays;
01360     req.materials   = materials;
01361     req.texsurfaces = texsurfaces;
01362     req.objects     = objects;
01363     trigger((void*)&req, sizeof(req));
01364 }
01365 
01366 
01367 
01368 
01369 void setLight() {
01370 #ifdef  __HAVE_GL2__
01371 
01372     glDisable(GL_LIGHT0);
01373 
01374     glEnable(GL_LIGHTING);
01375 
01376     GLfloat am[] = {0.4,0.4,0.4,1};
01377     glLightfv(GL_LIGHT0,GL_AMBIENT,am);
01378 
01379     GLfloat di[] = {0.5,0.5,0.5,1};
01380     glLightfv(GL_LIGHT0,GL_DIFFUSE,di);
01381 
01382     GLfloat sp[] = {0.3,0.3,0.3,1};
01383     glLightfv(GL_LIGHT0,GL_SPECULAR,sp);
01384 
01385     glLightf(GL_LIGHT0,GL_SPOT_EXPONENT,0);
01386 
01387     GLfloat lightPos[] = {40000,10000,-100,1 };
01388     glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
01389 
01390 
01391     glEnable(GL_LIGHT0);
01392 #endif
01393 }
01394 
01395 
01396 
01397 
01398 void MMSFBBackEndInterface::processRenderScene(BEI_RENDERSCENE *req) {
01399 #ifdef  __HAVE_OPENGL__
01400 
01401     // lock destination fbo and bind source texture to it
01402     oglBindSurface(req->surface, 200, 1700, true);
01403 //  oglBindSurface(req->surface);
01404 
01405     // set light
01406 /*  mmsfbgl.rotateCurrentMatrix(0, 1, 0, 0);
01407     mmsfbgl.rotateCurrentMatrix(-45, 0, 0, 1);
01408     mmsfbgl.rotateCurrentMatrix(90, 0, 1, 0);*/
01409     setLight();
01410 
01411 //  oglBindSurface(req->surface, 200, 1700, true);
01412 
01413     // setup blitting
01414 //  mmsfbgl.enableBlend();
01415     mmsfbgl.disableBlend();
01416     mmsfbgl.setTexEnvReplace(GL_RGBA);
01417 
01418     // get subsurface offsets
01419     GET_OFFS(req->surface);
01420 
01421     // set the clip to ogl
01422     MMSFBRectangle crect;
01423     if (req->surface->calcClip(0 + xoff, 0 + yoff, req->surface->config.w, req->surface->config.h, &crect)) {
01424         // inside clipping region
01425         OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
01426 
01427         // clear surface
01428         ENABLE_OGL_DEPTHTEST(req->surface, false);
01429         mmsfbgl.clear();
01430 
01431         // draw objects...
01432         int cnt = 0;
01433         MMS3D_OBJECT *object;
01434 
01435         while ((object = req->objects[cnt])) {
01436 
01437             if (!isMMS3DObjectShown(object) || object->indices < 0) {
01438                 // skip not shown objects
01439                 cnt++;
01440                 continue;
01441             }
01442 
01443             // cull facing, do not draw hidden pixels
01444             if (object->cullface) {
01445 #ifdef  __HAVE_GL2__
01446                 glFrontFace(GL_CCW);
01447                 glCullFace(GL_BACK);
01448                 glEnable(GL_CULL_FACE);
01449 #endif
01450             }
01451             else {
01452 #ifdef  __HAVE_GL2__
01453                 glDisable(GL_CULL_FACE);
01454 #endif
01455             }
01456 
01457             // set matrix
01458             mmsfbgl.setCurrentMatrix(object->matrix);
01459 
01460             // set material
01461             if (object->material >= 0) {
01462 #ifdef  __HAVE_GL2__
01463 
01464                 MMS3D_MATERIAL material = req->materials[object->material];
01465 
01466                 // material emits light
01467                 glMaterialfv(GL_FRONT, GL_EMISSION, (float*)&material.s.emission);
01468 
01469                 // material absorbs ambient light
01470                 glMaterialfv(GL_FRONT, GL_AMBIENT, (float*)&material.s.ambient);
01471 
01472                 // material absorbs diffuse light
01473                 glMaterialfv(GL_FRONT, GL_DIFFUSE, (float*)&material.s.diffuse);
01474 
01475                 // material absorbs specular light
01476                 glMaterialfv(GL_FRONT, GL_SPECULAR, (float*)&material.s.specular);
01477 
01478                 // specular-light exponent
01479                 glMaterialf(GL_FRONT, GL_SHININESS, material.s.shininess * 128);
01480 #endif
01481             }
01482 
01483             // bind object's texture
01484             if (object->texcoords >= 0 && object->texture >= 0) {
01485                 mmsfbgl.enableTexture2D(req->texsurfaces[object->texture]->config.surface_buffer->ogl_tex);
01486             }
01487             else {
01488                 mmsfbgl.disableTexture2D();
01489             }
01490 
01491             // draw object
01492             mmsfbgl.drawElements(
01493                     (object->vertices >= 0) ? req->varrays[object->vertices] : NULL,
01494                     (object->normals >= 0) ? req->varrays[object->normals] : NULL,
01495                     (object->texcoords >= 0 && object->texture >= 0) ? req->varrays[object->texcoords] : NULL,
01496                     (object->indices >= 0) ? req->iarrays[object->indices] : NULL);
01497 
01498             // next object
01499             cnt++;
01500         }
01501 
01502 #ifdef  __HAVE_GL2__
01503         glDisable(GL_CULL_FACE);
01504         glDisable(GL_LIGHTING);
01505 #endif
01506 
01507 
01508         this->reset_matrix = true;
01509 
01510     }
01511 
01512 
01513 #endif
01514 }
01515 
01516 
01517 
01518 void MMSFBBackEndInterface::merge(MMSFBSurface *surface, MMSFBSurface *source1, MMSFBSurface *source2,
01519                                        MMSFBMergingMode mergingmode) {
01520     BEI_MERGE req;
01521     req.type        = BEI_REQUEST_TYPE_MERGE;
01522     req.surface     = surface;
01523     req.source1     = source1;
01524     req.source2     = source2;
01525     req.mergingmode = mergingmode;
01526     trigger((void*)&req, sizeof(req));
01527 }
01528 
01529 
01530 void MMSFBBackEndInterface::processMerge(BEI_MERGE *req) {
01531 #ifdef  __HAVE_OPENGL__
01532     // lock destination fbo and bind source texture to it
01533     oglBindSurface(req->surface);
01534 
01535     // get destination subsurface offset
01536     GET_OFFS(req->surface);
01537 
01538     // merging the two source surfaces
01539     for (int i = 0; i < 2; i++) {
01540         // setup blitting
01541         switch (req->mergingmode) {
01542         case MMSFB_MM_ANAGLYPH_RED_CYAN:
01543             if (!i) {
01544                 // red channel from first source surface
01545                 mmsfbgl.disableBlend();
01546                 mmsfbgl.setTexEnvModulate(GL_RGBA);
01547                 mmsfbgl.setColor(0xff, 0x00, 0x00, 0xff);
01548             }
01549             else {
01550                 // green and blue channels (cyan) from second source surface
01551                 mmsfbgl.enableBlend(GL_ONE, GL_ONE, GL_ONE, GL_ONE);
01552                 mmsfbgl.setTexEnvModulate(GL_RGBA);
01553                 mmsfbgl.setColor(0x00, 0xff, 0xff, 0xff);
01554             }
01555             break;
01556 
01557         case MMSFB_MM_LINE_INTERLEAVED:
01558             if (!i) {
01559                 // even lines from first source surface
01560                 mmsfbgl.disableBlend();
01561                 mmsfbgl.setTexEnvReplace(GL_RGBA);
01562 
01563                 if (IS_OGL_DEPTH_BUFFER_UNCHANGED(req->surface)) {
01564                     // depth buffer has not changed, so we do not have to re-build it
01565                     mmsfbgl.disableDepthTest();
01566                 }
01567                 else {
01568                     // we have to build an interleaved depth buffer needed for blitting of the second source surface
01569                     ENABLE_OGL_DEPTHTEST(req->surface, false);
01570                     mmsfbgl.clear();
01571                     mmsfbgl.setColor(0xff,0xff,0xff,0xff);
01572                     for (int i = 0; i < req->surface->config.h; i+=2) {
01573                         mmsfbgl.fillRectangle2D(0, (float)i, (float)req->surface->config.w - 0.1f, (float)i+0.9);
01574                     }
01575 
01576                     // we mark the depth buffer as "unchanged", so we can save
01577                     // a lot of GPU time next time processMerge() is called
01578                     DISABLE_OGL_DEPTHTEST(req->surface, true);
01579                 }
01580             }
01581             else {
01582                 // odd lines from second source surface
01583                 mmsfbgl.disableBlend();
01584                 mmsfbgl.setTexEnvReplace(GL_RGBA);
01585 
01586                 // we enable the depth test in "readonly" mode, so we leave the depth buffer unchanged
01587                 ENABLE_OGL_DEPTHTEST(req->surface, true);
01588             }
01589             break;
01590         }
01591 
01592         // get source surface
01593         MMSFBSurface *source = (!i)?req->source1:req->source2;
01594 
01595         // get source subsurface offset
01596         GET_OFFS_SRC(source);
01597 
01598         // set the clip to ogl
01599         MMSFBRectangle crect;
01600         if (req->surface->calcClip(0 + xoff, 0 + yoff, req->surface->config.w, req->surface->config.h, &crect)) {
01601             // inside clipping region
01602             OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
01603 
01604             // get source region
01605             int sx1 = 0 + src_xoff;
01606             int sy1 = 0 + src_yoff;
01607             int sx2 = 0 + source->config.w - 1 + src_xoff;
01608             int sy2 = 0 + source->config.h - 1 + src_yoff;
01609 
01610             // get destination region
01611             int dx1 = 0 + xoff;
01612             int dy1 = 0 + yoff;
01613             int dx2 = 0 + req->surface->config.w - 1 + xoff;
01614             int dy2 = 0 + req->surface->config.h - 1 + yoff;
01615 
01616             if (source->config.surface_buffer->ogl_tex_initialized) {
01617                 // blit source texture to the destination
01618                 mmsfbgl.stretchBliti(source->config.surface_buffer->ogl_tex,
01619                             sx1, sy1, sx2, sy2, source->config.w, source->config.h,
01620                             dx1, dy1, dx2, dy2);
01621             }
01622             else {
01623                 printf("skip blitting from texture which is not initialized\n");
01624             }
01625         }
01626     }
01627 #endif
01628 }
01629 
01630 
01631 void MMSFBBackEndInterface::initVertexBuffer(unsigned int *buffer, unsigned int size, void *data) {
01632     BEI_INITVERTEXBUFFER req;
01633     req.type    = BEI_REQUEST_TYPE_INITVERTEXBUFFER;
01634     req.buffer  = buffer;
01635     req.size    = size;
01636     req.data    = data;
01637     trigger((void*)&req, sizeof(req));
01638 }
01639 
01640 void MMSFBBackEndInterface::processInitVertexBuffer(BEI_INITVERTEXBUFFER *req) {
01641 #ifdef  __HAVE_OPENGL__
01642 
01643     // buffer set?
01644     if (!req->buffer) return;
01645 
01646     // buffer already initialized?
01647     if (*(req->buffer)) return;
01648 
01649     // generate new buffer object
01650     if (!mmsfbgl.genBuffer(req->buffer)) return;
01651 
01652     // allocate new vertex buffer and fill it with given data
01653     // if no data is given, the buffer will be allocated but not initialized
01654     if (!mmsfbgl.initVertexBuffer(*(req->buffer), req->size, req->data)) {
01655         // failed
01656         mmsfbgl.deleteBuffer(*(req->buffer));
01657         *(req->buffer) = 0;
01658         return;
01659     }
01660 
01661 #endif
01662 }
01663 
01664 
01665 void MMSFBBackEndInterface::initVertexSubBuffer(unsigned int buffer, unsigned int offset,
01666                                                 unsigned int size, void *data) {
01667     BEI_INITVERTEXSUBBUFFER req;
01668     req.type    = BEI_REQUEST_TYPE_INITVERTEXSUBBUFFER;
01669     req.buffer  = buffer;
01670     req.offset  = offset;
01671     req.size    = size;
01672     req.data    = data;
01673     trigger((void*)&req, sizeof(req));
01674 }
01675 
01676 void MMSFBBackEndInterface::processInitVertexSubBuffer(BEI_INITVERTEXSUBBUFFER *req) {
01677 #ifdef  __HAVE_OPENGL__
01678 
01679     // buffer initialized?
01680     if (!req->buffer) return;
01681 
01682     // initialize a sub region of the vertex buffer
01683     mmsfbgl.initVertexSubBuffer(req->buffer, req->offset, req->size, req->data);
01684 
01685 #endif
01686 }
01687 
01688 
01689 void MMSFBBackEndInterface::initIndexBuffer(unsigned int *buffer, unsigned int size, void *data) {
01690     BEI_INITINDEXBUFFER req;
01691     req.type    = BEI_REQUEST_TYPE_INITINDEXBUFFER;
01692     req.buffer  = buffer;
01693     req.size    = size;
01694     req.data    = data;
01695     trigger((void*)&req, sizeof(req));
01696 }
01697 
01698 void MMSFBBackEndInterface::processInitIndexBuffer(BEI_INITINDEXBUFFER *req) {
01699 #ifdef  __HAVE_OPENGL__
01700 
01701     // buffer set?
01702     if (!req->buffer) return;
01703 
01704     // buffer already initialized?
01705     if (*(req->buffer)) return;
01706 
01707     // generate new buffer object
01708     if (!mmsfbgl.genBuffer(req->buffer)) return;
01709 
01710     // allocate new index buffer and fill it with given data
01711     // if no data is given, the buffer will be allocated but not initialized
01712     if (!mmsfbgl.initIndexBuffer(*(req->buffer), req->size, req->data)) {
01713         // failed
01714         mmsfbgl.deleteBuffer(*(req->buffer));
01715         *(req->buffer) = 0;
01716         return;
01717     }
01718 
01719 #endif
01720 }
01721 
01722 
01723 void MMSFBBackEndInterface::initIndexSubBuffer(unsigned int buffer, unsigned int offset,
01724                                                unsigned int size, void *data) {
01725     BEI_INITINDEXSUBBUFFER req;
01726     req.type    = BEI_REQUEST_TYPE_INITINDEXSUBBUFFER;
01727     req.buffer  = buffer;
01728     req.offset  = offset;
01729     req.size    = size;
01730     req.data    = data;
01731     trigger((void*)&req, sizeof(req));
01732 }
01733 
01734 void MMSFBBackEndInterface::processInitIndexSubBuffer(BEI_INITINDEXSUBBUFFER *req) {
01735 #ifdef  __HAVE_OPENGL__
01736 
01737     // buffer initialized?
01738     if (!req->buffer) return;
01739 
01740     // initialize a sub region of the index buffer
01741     mmsfbgl.initIndexSubBuffer(req->buffer, req->offset, req->size, req->data);
01742 
01743 #endif
01744 }
01745 
01746 
01747 void MMSFBBackEndInterface::deleteBuffer(unsigned int buffer) {
01748     BEI_DELETEBUFFER req;
01749     req.type    = BEI_REQUEST_TYPE_DELETEBUFFER;
01750     req.buffer  = buffer;
01751     trigger((void*)&req, sizeof(req));
01752 }
01753 
01754 void MMSFBBackEndInterface::processDeleteBuffer(BEI_DELETEBUFFER *req) {
01755 #ifdef  __HAVE_OPENGL__
01756 
01757     // delete a buffer object
01758     mmsfbgl.deleteBuffer(req->buffer);
01759 
01760 #endif
01761 }
01762 
01763 
01764 
01765 
01766 
01767 
01768 
01769 

Generated by doxygen