00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "mmsgui/fb/mmsfbbackendinterface.h"
00035 #include "mmstools/tools.h"
00036
00037 #define BEI_SOURCE_WIDTH ((!req->source->is_sub_surface)?req->source->config.w:req->source->root_parent->config.w)
00038 #define BEI_SOURCE_HEIGHT ((!req->source->is_sub_surface)?req->source->config.h:req->source->root_parent->config.h)
00039
00040 #define BEI_SURFACE_WIDTH ((!req->surface->is_sub_surface)?req->surface->config.w:req->surface->root_parent->config.w)
00041 #define BEI_SURFACE_HEIGHT ((!req->surface->is_sub_surface)?req->surface->config.h:req->surface->root_parent->config.h)
00042 #define BEI_SURFACE_BOTTOM (BEI_SURFACE_HEIGHT - 1)
00043 #define BEI_SURFACE_BOTTOM_F (float)BEI_SURFACE_BOTTOM
00044
00045
00046 #define GET_OFFS(surface) \
00047 int xoff = 0; int yoff = 0; \
00048 if (surface->is_sub_surface) { \
00049 xoff = surface->sub_surface_xoff; \
00050 yoff = surface->sub_surface_yoff; }
00051
00052 #define GET_OFFS_SRC(surface) \
00053 int src_xoff = 0; \
00054 int src_yoff = 0; \
00055 int src_rootw = surface->config.w; \
00056 int src_rooth = surface->config.h; \
00057 if (surface->is_sub_surface) { \
00058 src_xoff = surface->sub_surface_xoff; \
00059 src_yoff = surface->sub_surface_yoff; \
00060 src_rootw = surface->root_parent->config.w; \
00061 src_rooth = surface->root_parent->config.h; }
00062
00063
00064
00065 #ifdef __HAVE_OPENGL__
00066
00067
00068 #define OGL_SCISSOR(surface, X, Y, W, H) \
00069 if (surface->config.surface_buffer->ogl_fbo) mmsfbgl.setScissor(X, Y, W, H); \
00070 else mmsfbgl.setScissor(X, BEI_SURFACE_HEIGHT - (H) - (Y), W, H);
00071
00072
00073 #define INIT_OGL_DRAWING(surface, drawingflags) { \
00074 switch (drawingflags) { \
00075 case MMSFB_DRAW_BLEND: \
00076 mmsfbgl.enableBlend(); \
00077 mmsfbgl.setDrawingMode(); \
00078 break; \
00079 default: \
00080 mmsfbgl.disableBlend(); \
00081 mmsfbgl.setDrawingMode(); \
00082 break; } \
00083 mmsfbgl.setColor(surface->config.color.r, surface->config.color.g, surface->config.color.b, surface->config.color.a); }
00084
00085
00086
00087 #define INIT_OGL_BLITTING(surface, blittingflags) \
00088 switch (blittingflags) { \
00089 case MMSFB_BLIT_BLEND_ALPHACHANNEL: \
00090 mmsfbgl.enableBlend(); \
00091 mmsfbgl.setTexEnvReplace(GL_RGBA); \
00092 break; \
00093 case MMSFB_BLIT_BLEND_COLORALPHA: \
00094 mmsfbgl.disableBlend(); \
00095 mmsfbgl.setTexEnvModulate(GL_RGBA); \
00096 mmsfbgl.setColor(255, 255, 255, surface->config.color.a); \
00097 break; \
00098 case MMSFB_BLIT_BLEND_ALPHACHANNEL + MMSFB_BLIT_BLEND_COLORALPHA: \
00099 mmsfbgl.enableBlend(); \
00100 mmsfbgl.setTexEnvModulate(GL_RGBA); \
00101 mmsfbgl.setColor(255, 255, 255, surface->config.color.a); \
00102 break; \
00103 case MMSFB_BLIT_COLORIZE: \
00104 mmsfbgl.disableBlend(); \
00105 mmsfbgl.setTexEnvModulate(GL_RGBA); \
00106 mmsfbgl.setColor(surface->config.color.r, surface->config.color.g, surface->config.color.b, 0xff); \
00107 break; \
00108 case MMSFB_BLIT_BLEND_ALPHACHANNEL + MMSFB_BLIT_COLORIZE: \
00109 mmsfbgl.enableBlend(); \
00110 mmsfbgl.setTexEnvModulate(GL_RGBA); \
00111 mmsfbgl.setColor(surface->config.color.r, surface->config.color.g, surface->config.color.b, 0xff); \
00112 break; \
00113 case MMSFB_BLIT_BLEND_COLORALPHA + MMSFB_BLIT_COLORIZE: \
00114 mmsfbgl.disableBlend(); \
00115 mmsfbgl.setTexEnvModulate(GL_RGBA); \
00116 mmsfbgl.setColor(surface->config.color.r, surface->config.color.g, surface->config.color.b, surface->config.color.a); \
00117 break; \
00118 case MMSFB_BLIT_BLEND_ALPHACHANNEL + MMSFB_BLIT_BLEND_COLORALPHA + MMSFB_BLIT_COLORIZE: \
00119 mmsfbgl.enableBlend(); \
00120 mmsfbgl.setTexEnvModulate(GL_RGBA); \
00121 mmsfbgl.setColor(surface->config.color.r, surface->config.color.g, surface->config.color.b, surface->config.color.a); \
00122 break; \
00123 default: \
00124 mmsfbgl.disableBlend(); \
00125 mmsfbgl.setTexEnvReplace(GL_RGBA); \
00126 break; }
00127
00128
00129 #define ENABLE_OGL_DEPTHTEST(surface, readonly) \
00130 if (!readonly && surface->config.surface_buffer) { \
00131 if (!surface->is_sub_surface) { \
00132 surface->config.surface_buffer->ogl_unchanged_depth_buffer = false; \
00133 } else { \
00134 surface->root_parent->config.surface_buffer->ogl_unchanged_depth_buffer = surface->config.surface_buffer->ogl_unchanged_depth_buffer = false; \
00135 } \
00136 } \
00137 mmsfbgl.enableDepthTest(readonly);
00138
00139
00140 #define DISABLE_OGL_DEPTHTEST(surface, mark_as_unchanged) \
00141 if (mark_as_unchanged && surface->config.surface_buffer) { \
00142 if (!surface->is_sub_surface) { \
00143 surface->config.surface_buffer->ogl_unchanged_depth_buffer = true; \
00144 } else { \
00145 surface->root_parent->config.surface_buffer->ogl_unchanged_depth_buffer = surface->config.surface_buffer->ogl_unchanged_depth_buffer = true; \
00146 } \
00147 } \
00148 mmsfbgl.disableDepthTest();
00149
00150
00151 #define IS_OGL_DEPTH_BUFFER_UNCHANGED(surface) \
00152 ((!surface->is_sub_surface && surface->config.surface_buffer && surface->config.surface_buffer->ogl_unchanged_depth_buffer) \
00153 ||(surface->is_sub_surface && surface->root_parent->config.surface_buffer && surface->root_parent->config.surface_buffer->ogl_unchanged_depth_buffer))
00154
00155
00156 #ifdef __HAVE_GL2__
00157 #define OGL_DRAW_POINT(x, y) { glBegin(GL_POINTS); glVertex2f((float)(x) + 0.5, (float)(BEI_SURFACE_BOTTOM - (y)) + 0.5); glEnd(); }
00158 #endif
00159
00160 #ifdef __HAVE_GLES2__
00161 #define OGL_DRAW_POINT(x, y) {}
00162 #endif
00163
00164 #define OGL_SINGLE_POINT_FALLBACK(x1, y1, x2, y2) \
00165 if (x1 == x2 && y1 == y2) OGL_DRAW_POINT(x1, y1) else
00166
00167
00168 #define OGL_SINGLE_POINT_FALLBACK2(x1, y1, x2, y2, x3, y3) \
00169 if (x1 == x2 && x1 == x3 && y1 == y2 && y1 == y3) OGL_DRAW_POINT(x1, y1) else
00170
00171
00172 #define OGL_CALC_COORD(v1, v2) (((v1)<(v2)) ? (float)(v1) : (float)(v1) + 0.99)
00173
00174 #define OGL_CALC_2X_N(v1, v2, width) (OGL_CALC_COORD(v1, v2) / (width))
00175 #define OGL_CALC_2Y_N(v1, v2, height) (OGL_CALC_COORD(v1, v2) / (height))
00176
00177
00178 #define OGL_CALC_3X(v1, v2, v3) (((v1)<=(v2) && (v1)<=(v3)) ? (float)(v1) : ((v1)>(v2) && (v1)>(v3)) ? (float)(v1) + 0.99 : (float)(v1) + 0.5)
00179 #define OGL_CALC_3Y(v1, v2, v3) (((v1)<=(v2) && (v1)<=(v3)) ? BEI_SURFACE_BOTTOM_F - (float)(v1) + 0.99 : ((v1)>(v2) && (v1)>(v3)) ? BEI_SURFACE_BOTTOM_F - (float)(v1) : BEI_SURFACE_BOTTOM_F - (float)(v1) + 0.5)
00180
00181
00182
00183 #define OGL_FILL_RECTANGLE(x1, y1, x2, y2) \
00184 OGL_SINGLE_POINT_FALLBACK(x1, y1, x2, y2) \
00185 mmsfbgl.fillRectangle2Di(x1, y1, x2, y2);
00186
00187
00188 #define OGL_DRAW_RECTANGLE(x1, y1, x2, y2) \
00189 OGL_SINGLE_POINT_FALLBACK(x1, y1, x2, y2) \
00190 mmsfbgl.drawRectangle2Di(x1, y1, x2, y2);
00191
00192 #endif
00193
00194
00195 #ifdef __HAVE_GL2__
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226 #define OGL_DRAW_LINE(x1, y1, x2, y2) \
00227 OGL_SINGLE_POINT_FALLBACK(x1, y1, x2, y2) { \
00228 glBegin(GL_LINES); \
00229 glVertex2f(OGL_CALC_COORD(x1, x2), OGL_CALC_COORD(y1, y2)); \
00230 glVertex2f(OGL_CALC_COORD(x2, x1), OGL_CALC_COORD(y2, y1)); \
00231 glEnd(); }
00232
00233
00234 #define OGL_FILL_TRIANGLE(x1, y1, x2, y2, x3, y3) \
00235 OGL_SINGLE_POINT_FALLBACK2(x1, y1, x2, y2, x3, y3) { \
00236 glBegin(GL_TRIANGLES); \
00237 glVertex2f(OGL_CALC_3X(x1, x2, x3), OGL_CALC_3Y(y1, y2, y3)); \
00238 glVertex2f(OGL_CALC_3X(x2, x3, x1), OGL_CALC_3Y(y2, y3, y1)); \
00239 glVertex2f(OGL_CALC_3X(x3, x1, x2), OGL_CALC_3Y(y3, y1, y2)); \
00240 glEnd(); }
00241
00242 #define OGL_DRAW_TRIANGLE(x1, y1, x2, y2, x3, y3) \
00243 OGL_SINGLE_POINT_FALLBACK2(x1, y1, x2, y2, x3, y3) { \
00244 glBegin(GL_LINE_STRIP); \
00245 glVertex2f(OGL_CALC_3X(x1, x2, x3), OGL_CALC_3Y(y1, y2, y3)); \
00246 glVertex2f(OGL_CALC_3X(x2, x3, x1), OGL_CALC_3Y(y2, y3, y1)); \
00247 glVertex2f(OGL_CALC_3X(x3, x1, x2), OGL_CALC_3Y(y3, y1, y2)); \
00248 glVertex2f(OGL_CALC_3X(x1, x2, x3), OGL_CALC_3Y(y1, y2, y3)); \
00249 glEnd(); }
00250
00251
00252 #endif
00253
00254 MMSFBBackEndInterface::MMSFBBackEndInterface(int queue_size) : MMSThreadServer(queue_size, "MMSFBBackEndInterface") {
00255
00256 }
00257
00258 void MMSFBBackEndInterface::processData(void *in_data, int in_data_len, void **out_data, int *out_data_len) {
00259 if (!in_data) return;
00260
00261 BEI_REQUEST_TYPE *type = (BEI_REQUEST_TYPE *)in_data;
00262
00263 switch (*type) {
00264 case BEI_REQUEST_TYPE_INIT:
00265 processInit((BEI_INIT *)in_data);
00266 break;
00267 case BEI_REQUEST_TYPE_SWAP:
00268 processSwap((BEI_SWAP *)in_data);
00269 break;
00270 case BEI_REQUEST_TYPE_ALLOC:
00271 processAlloc((BEI_ALLOC *)in_data);
00272 break;
00273 case BEI_REQUEST_TYPE_FREE:
00274 processFree((BEI_FREE *)in_data);
00275 break;
00276 case BEI_REQUEST_TYPE_CLEAR:
00277 processClear((BEI_CLEAR *)in_data);
00278 break;
00279 case BEI_REQUEST_TYPE_FILLRECTANGLE:
00280 processFillRectangle((BEI_FILLRECTANGLE *)in_data);
00281 break;
00282 case BEI_REQUEST_TYPE_FILLTRIANGLE:
00283 processFillTriangle((BEI_FILLTRIANGLE *)in_data);
00284 break;
00285 case BEI_REQUEST_TYPE_DRAWLINE:
00286 processDrawLine((BEI_DRAWLINE *)in_data);
00287 break;
00288 case BEI_REQUEST_TYPE_DRAWRECTANGLE:
00289 processDrawRectangle((BEI_DRAWRECTANGLE *)in_data);
00290 break;
00291 case BEI_REQUEST_TYPE_DRAWTRIANGLE:
00292 processDrawTriangle((BEI_DRAWTRIANGLE *)in_data);
00293 break;
00294 case BEI_REQUEST_TYPE_BLIT:
00295 processBlit((BEI_BLIT *)in_data);
00296 break;
00297 case BEI_REQUEST_TYPE_STRETCHBLIT:
00298 processStretchBlit((BEI_STRETCHBLIT *)in_data);
00299 break;
00300 case BEI_REQUEST_TYPE_STRETCHBLITBUFFER:
00301 processStretchBlitBuffer((BEI_STRETCHBLITBUFFER *)in_data);
00302 break;
00303 case BEI_REQUEST_TYPE_CREATEALPHATEXTURE:
00304 processCreateAlphaTexture((BEI_CREATEALPHATEXTURE *)in_data);
00305 break;
00306 case BEI_REQUEST_TYPE_DELETETEXTURE:
00307 processDeleteTexture((BEI_DELETETEXTURE *)in_data);
00308 break;
00309 case BEI_REQUEST_TYPE_DRAWSTRING:
00310 processDrawString((BEI_DRAWSTRING *)in_data);
00311 break;
00312 case BEI_REQUEST_TYPE_RENDERSCENE:
00313 processRenderScene((BEI_RENDERSCENE *)in_data);
00314 break;
00315 case BEI_REQUEST_TYPE_MERGE:
00316 processMerge((BEI_MERGE *)in_data);
00317 break;
00318 case BEI_REQUEST_TYPE_INITVERTEXBUFFER:
00319 processInitVertexBuffer((BEI_INITVERTEXBUFFER *)in_data);
00320 break;
00321 case BEI_REQUEST_TYPE_INITVERTEXSUBBUFFER:
00322 processInitVertexSubBuffer((BEI_INITVERTEXSUBBUFFER *)in_data);
00323 break;
00324 case BEI_REQUEST_TYPE_INITINDEXBUFFER:
00325 processInitIndexBuffer((BEI_INITINDEXBUFFER *)in_data);
00326 break;
00327 case BEI_REQUEST_TYPE_INITINDEXSUBBUFFER:
00328 processInitIndexSubBuffer((BEI_INITINDEXSUBBUFFER *)in_data);
00329 break;
00330 case BEI_REQUEST_TYPE_DELETEBUFFER:
00331 processDeleteBuffer((BEI_DELETEBUFFER *)in_data);
00332 break;
00333 default:
00334 break;
00335 }
00336 }
00337
00338 #ifdef __HAVE_XLIB__
00339
00340 void MMSFBBackEndInterface::init(Display *x_display, int x_screen, Window x_window, MMSFBRectangle x11_win_rect) {
00341
00342 start();
00343
00344
00345 BEI_INIT req;
00346 req.type = BEI_REQUEST_TYPE_INIT;
00347 req.x_display = x_display;
00348 req.x_screen = x_screen;
00349 req.x_window = x_window;
00350 req.x11_win_rect= x11_win_rect;
00351 trigger((void*)&req, sizeof(req));
00352 }
00353
00354 #else
00355
00356 void MMSFBBackEndInterface::init() {
00357
00358 start();
00359
00360
00361 BEI_INIT req;
00362 req.type = BEI_REQUEST_TYPE_INIT;
00363 trigger((void*)&req, sizeof(req));
00364 }
00365
00366 #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
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
00408 mmsfbgl.setParallelProjection(left, right, bottom, top, nearZ, farZ);
00409 }
00410 else {
00411
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
00424
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
00433 if (!sb->ogl_tex_initialized) {
00434
00435 mmsfbgl.allocFBOandRBO(sb->ogl_fbo, sb->ogl_tex, sb->ogl_rbo, surface->config.w, surface->config.h);
00436 }
00437 else {
00438
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
00453 sb->ogl_rbo_initialized = false;
00454
00455
00456 if (!sb->ogl_tex_initialized) {
00457
00458 if (rbo_required) {
00459
00460
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
00466
00467 mmsfbgl.allocFBO(sb->ogl_fbo, sb->ogl_tex, surface->config.w, surface->config.h);
00468 }
00469 }
00470 else {
00471
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
00482
00483 if (sb->ogl_fbo_initialized) {
00484
00485 if (!sb->ogl_rbo_initialized) {
00486
00487 if (rbo_required) {
00488
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
00499 oglAlloc(surface);
00500
00501
00502 mmsfbgl.bindFrameBuffer(surface->config.surface_buffer->ogl_fbo);
00503
00504 if (surface->config.surface_buffer->ogl_fbo) {
00505
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
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
00526 oglAlloc(surface, true);
00527
00528
00529 mmsfbgl.bindFrameBuffer(surface->config.surface_buffer->ogl_fbo);
00530
00531 if (surface->config.surface_buffer->ogl_fbo) {
00532
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
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
00570 if (!buffer->getBuffers(&index_buffer, &vertex_buffer)) return false;
00571 }
00572
00573
00574 if (!index_buffer || !vertex_buffer) return false;
00575
00576 if (buffer->index_bo.bo && buffer->vertex_bo.bo) {
00577
00578
00579 return true;
00580 }
00581 else
00582 if (buffer->vertex_bo.bo) {
00583
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
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
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
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
00668 oglBindSurface(req->surface);
00669
00670
00671 GET_OFFS(req->surface);
00672
00673
00674 MMSFBRectangle crect;
00675 if (req->surface->calcClip(0 + xoff, 0 + yoff, req->surface->config.w, req->surface->config.h, &crect)) {
00676
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
00696 oglBindSurface(req->surface);
00697
00698
00699 INIT_OGL_DRAWING(req->surface, req->drawingflags);
00700
00701
00702 OGL_SCISSOR(req->surface, req->rect.x, req->rect.y, req->rect.w, req->rect.h);
00703
00704
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
00723 oglBindSurface(req->surface);
00724 glDisable(GL_DEPTH_TEST);
00725 glDisable(GL_TEXTURE_2D);
00726
00727
00728 INIT_OGL_DRAWING(req->surface, req->surface->config.drawingflags);
00729
00730
00731 GET_OFFS(req->surface);
00732
00733
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
00759 OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
00760 glEnable(GL_SCISSOR_TEST);
00761
00762
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
00784 oglBindSurface(req->surface);
00785
00786
00787 INIT_OGL_DRAWING(req->surface, req->surface->config.drawingflags);
00788
00789
00790 GET_OFFS(req->surface);
00791
00792
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
00814 OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
00815
00816
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
00834 oglBindSurface(req->surface);
00835
00836
00837 INIT_OGL_DRAWING(req->surface, req->surface->config.drawingflags);
00838
00839
00840 GET_OFFS(req->surface);
00841
00842
00843 MMSFBRectangle crect;
00844 if (req->surface->calcClip(req->rect.x + xoff, req->rect.y + yoff, req->rect.w, req->rect.h, &crect)) {
00845
00846 OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
00847
00848
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
00868 oglBindSurface(req->surface);
00869 glDisable(GL_DEPTH_TEST);
00870 glDisable(GL_TEXTURE_2D);
00871
00872
00873 INIT_OGL_DRAWING(req->surface, req->surface->config.drawingflags);
00874
00875
00876 GET_OFFS(req->surface);
00877
00878
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
00904 OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
00905 glEnable(GL_SCISSOR_TEST);
00906
00907
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
00931 oglBindSurface(req->surface);
00932
00933
00934 INIT_OGL_BLITTING(req->surface, req->blittingflags);
00935
00936
00937 GET_OFFS(req->surface);
00938 GET_OFFS_SRC(req->source);
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972 OGL_SCISSOR(req->surface, req->x, req->y, req->src_rect.w, req->src_rect.h);
00973
00974
00975
00976
00977
00978 if (req->source->config.surface_buffer->ogl_tex_initialized) {
00979
00980
00981
00982
00983
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
01012 oglBindSurface(req->surface);
01013
01014
01015 INIT_OGL_BLITTING(req->surface, req->blittingflags);
01016
01017
01018 GET_OFFS(req->surface);
01019 GET_OFFS_SRC(req->source);
01020
01021
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
01025 OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
01026
01027
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
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
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
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
01097
01098 blit2texture = false;
01099 }
01100 }
01101 else {
01102
01103 blit2texture = false;
01104 }
01105 }
01106 }
01107
01108 if (blit2texture) {
01109
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
01115 req->surface->config.surface_buffer->ogl_tex_initialized = true;
01116
01117 return;
01118 }
01119
01120
01121 oglBindSurface(req->surface);
01122
01123
01124 INIT_OGL_BLITTING(req->surface, req->blittingflags);
01125
01126
01127 GET_OFFS(req->surface);
01128
01129
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
01133 OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
01134
01135
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
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
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
01171 mmsfbgl.genTexture(req->texture);
01172
01173
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
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
01212 oglBindSurface(req->surface);
01213
01214 #ifndef __HAVE_GLU__
01215
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
01227 INIT_OGL_DRAWING(req->surface, req->surface->config.drawingflags);
01228 #endif
01229
01230
01231 GET_OFFS(req->surface);
01232
01233
01234 MMSFBRectangle crect;
01235 if (req->surface->calcClip(0 + xoff, 0 + yoff, req->surface->config.w, req->surface->config.h, &crect)) {
01236
01237 OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
01238
01239 #ifdef __HAVE_GLU__
01240
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
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
01256 req->x = (int)((float)req->x / scale_coeff + 0.5f);
01257 req->y = (int)((float)req->y / scale_coeff + 0.5f);
01258
01259
01260 xoff = (int)((float)xoff / scale_coeff + 0.5f);
01261 yoff = (int)((float)yoff / scale_coeff + 0.5f);
01262 #endif
01263
01264
01265 MMSFBFONT_GET_UNICODE_CHAR(req->text, req->len) {
01266
01267
01268 MMSFBSURFACE_BLIT_TEXT_LOAD_GLYPH(req->surface->config.font, character);
01269
01270
01271 if (glyph_loaded) {
01272
01273 int dx = req->x + glyph.left;
01274 int dy = req->y + DY - glyph.top;
01275
01276 #ifndef __HAVE_GLU__
01277
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
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
01291 mmsfbgl.stretchBliti(glyph.texture,
01292 sx1, sy1, sx2, sy2, src_pitch_pix, src_h,
01293 dx1, dy1, dx2, dy2);
01294 }
01295 #else
01296
01297 int dx1 = dx + xoff;
01298 int dy1 = dy + yoff;
01299
01300
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
01312 if (index_buffer->num_arrays) {
01313
01314
01315 mmsfbgl.enableBlend();
01316 MMSFBColor *color = &req->surface->config.color;
01317 mmsfbgl.setColor(color->r, color->g, color->b, color->a / 3);
01318
01319
01320 oglDrawBuffer(buffer, index_buffer, vertex_buffer);
01321
01322
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
01331 oglDrawBuffer(buffer);
01332 }
01333 #endif
01334
01335
01336 req->x+= glyph.advanceX;
01337 }
01338 }}
01339
01340 #ifdef __HAVE_GLU__
01341
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
01402 oglBindSurface(req->surface, 200, 1700, true);
01403
01404
01405
01406
01407
01408
01409 setLight();
01410
01411
01412
01413
01414
01415 mmsfbgl.disableBlend();
01416 mmsfbgl.setTexEnvReplace(GL_RGBA);
01417
01418
01419 GET_OFFS(req->surface);
01420
01421
01422 MMSFBRectangle crect;
01423 if (req->surface->calcClip(0 + xoff, 0 + yoff, req->surface->config.w, req->surface->config.h, &crect)) {
01424
01425 OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
01426
01427
01428 ENABLE_OGL_DEPTHTEST(req->surface, false);
01429 mmsfbgl.clear();
01430
01431
01432 int cnt = 0;
01433 MMS3D_OBJECT *object;
01434
01435 while ((object = req->objects[cnt])) {
01436
01437 if (!isMMS3DObjectShown(object) || object->indices < 0) {
01438
01439 cnt++;
01440 continue;
01441 }
01442
01443
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
01458 mmsfbgl.setCurrentMatrix(object->matrix);
01459
01460
01461 if (object->material >= 0) {
01462 #ifdef __HAVE_GL2__
01463
01464 MMS3D_MATERIAL material = req->materials[object->material];
01465
01466
01467 glMaterialfv(GL_FRONT, GL_EMISSION, (float*)&material.s.emission);
01468
01469
01470 glMaterialfv(GL_FRONT, GL_AMBIENT, (float*)&material.s.ambient);
01471
01472
01473 glMaterialfv(GL_FRONT, GL_DIFFUSE, (float*)&material.s.diffuse);
01474
01475
01476 glMaterialfv(GL_FRONT, GL_SPECULAR, (float*)&material.s.specular);
01477
01478
01479 glMaterialf(GL_FRONT, GL_SHININESS, material.s.shininess * 128);
01480 #endif
01481 }
01482
01483
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
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
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
01533 oglBindSurface(req->surface);
01534
01535
01536 GET_OFFS(req->surface);
01537
01538
01539 for (int i = 0; i < 2; i++) {
01540
01541 switch (req->mergingmode) {
01542 case MMSFB_MM_ANAGLYPH_RED_CYAN:
01543 if (!i) {
01544
01545 mmsfbgl.disableBlend();
01546 mmsfbgl.setTexEnvModulate(GL_RGBA);
01547 mmsfbgl.setColor(0xff, 0x00, 0x00, 0xff);
01548 }
01549 else {
01550
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
01560 mmsfbgl.disableBlend();
01561 mmsfbgl.setTexEnvReplace(GL_RGBA);
01562
01563 if (IS_OGL_DEPTH_BUFFER_UNCHANGED(req->surface)) {
01564
01565 mmsfbgl.disableDepthTest();
01566 }
01567 else {
01568
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
01577
01578 DISABLE_OGL_DEPTHTEST(req->surface, true);
01579 }
01580 }
01581 else {
01582
01583 mmsfbgl.disableBlend();
01584 mmsfbgl.setTexEnvReplace(GL_RGBA);
01585
01586
01587 ENABLE_OGL_DEPTHTEST(req->surface, true);
01588 }
01589 break;
01590 }
01591
01592
01593 MMSFBSurface *source = (!i)?req->source1:req->source2;
01594
01595
01596 GET_OFFS_SRC(source);
01597
01598
01599 MMSFBRectangle crect;
01600 if (req->surface->calcClip(0 + xoff, 0 + yoff, req->surface->config.w, req->surface->config.h, &crect)) {
01601
01602 OGL_SCISSOR(req->surface, crect.x, crect.y, crect.w, crect.h);
01603
01604
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
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
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
01644 if (!req->buffer) return;
01645
01646
01647 if (*(req->buffer)) return;
01648
01649
01650 if (!mmsfbgl.genBuffer(req->buffer)) return;
01651
01652
01653
01654 if (!mmsfbgl.initVertexBuffer(*(req->buffer), req->size, req->data)) {
01655
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
01680 if (!req->buffer) return;
01681
01682
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
01702 if (!req->buffer) return;
01703
01704
01705 if (*(req->buffer)) return;
01706
01707
01708 if (!mmsfbgl.genBuffer(req->buffer)) return;
01709
01710
01711
01712 if (!mmsfbgl.initIndexBuffer(*(req->buffer), req->size, req->data)) {
01713
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
01738 if (!req->buffer) return;
01739
01740
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
01758 mmsfbgl.deleteBuffer(req->buffer);
01759
01760 #endif
01761 }
01762
01763
01764
01765
01766
01767
01768
01769