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 #include <SDL.h>
00028
00029
00030 #include "util/base/exception.h"
00031 #include "util/log/logger.h"
00032 #include "video/devicecaps.h"
00033
00034 #include "glimage.h"
00035 #include "renderbackendopengl.h"
00036 #include "SDL_image.h"
00037
00038
00039 namespace FIFE {
00040 static Logger _log(LM_VIDEO);
00041
00042 class RenderBackendOpenGL::RenderObject {
00043 public:
00044 RenderObject(GLenum m, uint16_t s, uint32_t t=0):
00045 mode(m),
00046 size(s),
00047 texture_id(t),
00048 src(4),
00049 dst(5),
00050 light(true),
00051 stencil_test(false),
00052 stencil_ref(0),
00053 stencil_op(0),
00054 stencil_func(0),
00055 multitextured(false) {}
00056
00057 GLenum mode;
00058 uint16_t size;
00059 uint32_t texture_id;
00060 int32_t src;
00061 int32_t dst;
00062 bool light;
00063 bool stencil_test;
00064 uint8_t stencil_ref;
00065 GLenum stencil_op;
00066 GLenum stencil_func;
00067 bool multitextured;
00068 uint8_t rgb[3];
00069 };
00070
00071 RenderBackendOpenGL::RenderBackendOpenGL(const SDL_Color& colorkey)
00072 : RenderBackend(colorkey), m_mask_overlays(0){
00073
00074 m_state.tex_enabled[0] = false;
00075 m_state.tex_enabled[1] = false;
00076 m_state.texture[0] = 0;
00077 m_state.texture[1] = 0;
00078 m_state.active_tex = 0;
00079
00080 m_state.color_pointer = 0;
00081 m_state.tex_pointer[0] = 0;
00082 m_state.tex_pointer[1] = 0;
00083 m_state.vertex_pointer = 0;
00084
00085 m_state.sten_enabled = false;
00086 m_state.sten_ref = 0;
00087 m_state.sten_buf = 0;
00088 m_state.sten_op = 0;
00089 m_state.sten_func = 0;
00090
00091 m_state.lightmodel = 0;
00092 m_state.light_enabled = false;
00093
00094 m_state.env_color[0] = 0;
00095 m_state.env_color[1] = 0;
00096 m_state.env_color[2] = 0;
00097 m_state.blend_src = GL_SRC_ALPHA;
00098 m_state.blend_dst = GL_ONE_MINUS_SRC_ALPHA;
00099 m_state.alpha_enabled = false;
00100 m_state.scissor_test = true;
00101 }
00102
00103 RenderBackendOpenGL::~RenderBackendOpenGL() {
00104 glDeleteTextures(1, &m_mask_overlays);
00105 if(GLEE_EXT_framebuffer_object && m_useframebuffer) {
00106 glDeleteFramebuffers(1, &m_fbo_id);
00107 }
00108 deinit();
00109 }
00110
00111 const std::string& RenderBackendOpenGL::getName() const {
00112 static std::string backend_name = "OpenGL";
00113 return backend_name;
00114 }
00115
00116 void RenderBackendOpenGL::init(const std::string& driver) {
00117
00118 Uint32 flags = SDL_INIT_VIDEO;
00119 if (SDL_InitSubSystem(flags) < 0)
00120 throw SDLException(SDL_GetError());
00121 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
00122 SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
00123
00124 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
00125 }
00126
00127 void RenderBackendOpenGL::clearBackBuffer() {
00128 disableScissorTest();
00129 glClear(GL_COLOR_BUFFER_BIT);
00130 enableScissorTest();
00131 }
00132
00133 void RenderBackendOpenGL::createMainScreen(const ScreenMode& mode, const std::string& title, const std::string& icon){
00134 if(icon != "") {
00135 SDL_Surface *img = IMG_Load(icon.c_str());
00136 if(img != NULL) {
00137 SDL_WM_SetIcon(img, 0);
00138 SDL_FreeSurface(img);
00139 }
00140 }
00141
00142 setScreenMode(mode);
00143 SDL_WM_SetCaption(title.c_str(), 0);
00144 }
00145
00146 void RenderBackendOpenGL::setScreenMode(const ScreenMode& mode) {
00147 uint16_t width = mode.getWidth();
00148 uint16_t height = mode.getHeight();
00149 uint16_t bitsPerPixel = mode.getBPP();
00150 bool fs = mode.isFullScreen();
00151 uint32_t flags = mode.getSDLFlags();
00152
00153 if (bitsPerPixel != 0) {
00154 uint16_t bpp = SDL_VideoModeOK(width, height, bitsPerPixel, flags);
00155 if (!bpp){
00156 throw SDLException("Selected video mode not supported!");
00157 }
00158 }
00159
00160 if(m_screen) {
00161 SDL_FreeSurface(m_screen);
00162 }
00163 m_screen = SDL_SetVideoMode(width, height, bitsPerPixel, flags);
00164 if( !m_screen ) {
00165 throw SDLException("Unable to set video mode selected!");
00166 }
00167 m_target = m_screen;
00168
00169 FL_LOG(_log, LMsg("RenderBackendOpenGL")
00170 << "Videomode " << width << "x" << height
00171 << " at " << int32_t(bitsPerPixel) << " bpp");
00172
00173 m_rgba_format = *(m_screen->format);
00174 m_rgba_format.Rmask = RMASK;
00175 m_rgba_format.Gmask = GMASK;
00176 m_rgba_format.Bmask = BMASK;
00177 m_rgba_format.Amask = AMASK;
00178
00179
00180 m_screenMode = ScreenMode(width,
00181 height,
00182 bitsPerPixel,
00183 m_screen->flags);
00184
00185 if (!m_screen) {
00186 throw SDLException(SDL_GetError());
00187 }
00188
00189 glViewport(0, 0, width, height);
00190 glMatrixMode(GL_PROJECTION);
00191 glLoadIdentity();
00192 glOrtho(0, width, height, 0, -1, 1);
00193 glMatrixMode(GL_MODELVIEW);
00194 glLoadIdentity();
00195
00196 glEnable(GL_CULL_FACE);
00197 glFrontFace(GL_CCW);
00198 glCullFace(GL_BACK);
00199
00200 glPixelStorei(GL_PACK_ALIGNMENT, 1);
00201 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00202
00203 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
00204
00205 glEnable(GL_BLEND);
00206 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00207
00208 glEnable(GL_SCISSOR_TEST);
00209
00210 glEnableClientState(GL_COLOR_ARRAY);
00211 glEnableClientState(GL_VERTEX_ARRAY);
00212
00213 prepareForOverlays();
00214
00215 glPointSize(1.0);
00216 glLineWidth(1.0);
00217
00218 if(GLEE_EXT_framebuffer_object && m_useframebuffer) {
00219 glGenFramebuffers(1, &m_fbo_id);
00220 }
00221 }
00222
00223 void RenderBackendOpenGL::startFrame() {
00224 RenderBackend::startFrame();
00225 }
00226
00227 void RenderBackendOpenGL::endFrame() {
00228 SDL_GL_SwapBuffers();
00229 RenderBackend::endFrame();
00230 }
00231
00232 Image* RenderBackendOpenGL::createImage(IResourceLoader* loader) {
00233 return new GLImage(loader);
00234 }
00235
00236 Image* RenderBackendOpenGL::createImage(const std::string& name, IResourceLoader* loader) {
00237 return new GLImage(name, loader);
00238 }
00239
00240 Image* RenderBackendOpenGL::createImage(SDL_Surface* surface) {
00241
00242
00243
00244
00245
00246
00247 if (32 == surface->format->BitsPerPixel
00248 && m_rgba_format.Rmask == surface->format->Rmask
00249 && m_rgba_format.Gmask == surface->format->Gmask
00250 && m_rgba_format.Bmask == surface->format->Bmask
00251 && m_rgba_format.Amask == surface->format->Amask
00252 && m_rgba_format.Rshift == surface->format->Rshift
00253 && m_rgba_format.Gshift == surface->format->Gshift
00254 && m_rgba_format.Bshift == surface->format->Bshift
00255 && m_rgba_format.Ashift == surface->format->Ashift
00256 && m_rgba_format.Rloss == surface->format->Rloss
00257 && m_rgba_format.Gloss == surface->format->Gloss
00258 && m_rgba_format.Bloss == surface->format->Bloss
00259 && m_rgba_format.Aloss == surface->format->Aloss
00260 && surface->flags & SDL_SRCALPHA ) {
00261
00262 return new GLImage(surface);
00263 }
00264
00265 uint8_t bpp = m_rgba_format.BitsPerPixel;
00266 m_rgba_format.BitsPerPixel = 32;
00267 SDL_Surface* conv = SDL_ConvertSurface(surface, &m_rgba_format, SDL_SWSURFACE | SDL_SRCALPHA);
00268 m_rgba_format.BitsPerPixel = bpp;
00269 GLImage* image = new GLImage(conv);
00270
00271 SDL_FreeSurface(surface);
00272 return image;
00273 }
00274
00275 Image* RenderBackendOpenGL::createImage(const std::string& name, SDL_Surface* surface) {
00276
00277
00278
00279
00280
00281
00282 if (32 == surface->format->BitsPerPixel
00283 && m_rgba_format.Rmask == surface->format->Rmask
00284 && m_rgba_format.Gmask == surface->format->Gmask
00285 && m_rgba_format.Bmask == surface->format->Bmask
00286 && m_rgba_format.Amask == surface->format->Amask
00287 && m_rgba_format.Rshift == surface->format->Rshift
00288 && m_rgba_format.Gshift == surface->format->Gshift
00289 && m_rgba_format.Bshift == surface->format->Bshift
00290 && m_rgba_format.Ashift == surface->format->Ashift
00291 && m_rgba_format.Rloss == surface->format->Rloss
00292 && m_rgba_format.Gloss == surface->format->Gloss
00293 && m_rgba_format.Bloss == surface->format->Bloss
00294 && m_rgba_format.Aloss == surface->format->Aloss
00295 && surface->flags & SDL_SRCALPHA ) {
00296
00297 return new GLImage(name, surface);
00298 }
00299
00300 uint8_t bpp = m_rgba_format.BitsPerPixel;
00301 m_rgba_format.BitsPerPixel = 32;
00302 SDL_Surface* conv = SDL_ConvertSurface(surface, &m_rgba_format, SDL_SWSURFACE | SDL_SRCALPHA);
00303 m_rgba_format.BitsPerPixel = bpp;
00304 GLImage* image = new GLImage(name, conv);
00305
00306 SDL_FreeSurface(surface);
00307 return image;
00308 }
00309
00310 Image* RenderBackendOpenGL::createImage(const uint8_t* data, uint32_t width, uint32_t height) {
00311 return new GLImage(data, width, height);
00312 }
00313
00314 Image* RenderBackendOpenGL::createImage(const std::string& name, const uint8_t* data, uint32_t width, uint32_t height) {
00315 return new GLImage(name, data, width, height);
00316 }
00317
00318 void RenderBackendOpenGL::setLightingModel(uint32_t lighting) {
00319 if (m_state.lightmodel != lighting) {
00320 if (m_state.lightmodel != 0) {
00321 disableLighting();
00322 glDisable(GL_COLOR_MATERIAL);
00323 } else if (lighting != 0) {
00324 enableLighting();
00325 glEnable(GL_LIGHT0);
00326 glColorMaterial(GL_FRONT, GL_DIFFUSE);
00327 glEnable(GL_COLOR_MATERIAL);
00328 }
00329 m_state.lightmodel = lighting;
00330 }
00331 }
00332
00333 uint32_t RenderBackendOpenGL::getLightingModel() const {
00334 return m_state.lightmodel;
00335 }
00336
00337 void RenderBackendOpenGL::enableTextures(uint32_t texUnit) {
00338 if(m_state.tex_enabled[texUnit] == false) {
00339 if(m_state.active_tex != texUnit) {
00340 m_state.active_tex = texUnit;
00341 glActiveTexture(GL_TEXTURE0 + texUnit);
00342 }
00343 m_state.tex_enabled[texUnit] = true;
00344
00345 glEnable(GL_TEXTURE_2D);
00346 if(texUnit == 0) {
00347 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
00348 }
00349 }
00350 }
00351
00352 void RenderBackendOpenGL::disableTextures(uint32_t texUnit)
00353 {
00354 if(m_state.tex_enabled[texUnit] == true) {
00355 if(m_state.active_tex != texUnit) {
00356 m_state.active_tex = texUnit;
00357 glActiveTexture(GL_TEXTURE0 + texUnit);
00358 }
00359 m_state.tex_enabled[texUnit] = false;
00360
00361 glDisable(GL_TEXTURE_2D);
00362 if(texUnit == 0) {
00363 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
00364 }
00365 }
00366 }
00367
00368 void RenderBackendOpenGL::bindTexture(uint32_t texUnit, GLuint texId) {
00369 enableTextures(texUnit);
00370
00371 if(m_state.texture[texUnit] != texId) {
00372 if(m_state.active_tex != texUnit) {
00373 m_state.active_tex = texUnit;
00374 glActiveTexture(GL_TEXTURE0 + texUnit);
00375 }
00376 m_state.texture[texUnit] = texId;
00377 glBindTexture(GL_TEXTURE_2D, texId);
00378 }
00379 }
00380
00381 void RenderBackendOpenGL::bindTexture(GLuint texId) {
00382 if(m_state.texture[m_state.active_tex] != texId) {
00383 m_state.texture[m_state.active_tex] = texId;
00384 glBindTexture(GL_TEXTURE_2D, texId);
00385 }
00386 }
00387
00388 void RenderBackendOpenGL::enableLighting() {
00389 if (m_state.lightmodel != 0 && !m_state.light_enabled) {
00390 glEnable(GL_LIGHTING);
00391 m_state.light_enabled = true;
00392 }
00393 }
00394
00395 void RenderBackendOpenGL::disableLighting() {
00396 if (m_state.lightmodel != 0 && m_state.light_enabled) {
00397 glDisable(GL_LIGHTING);
00398 m_state.light_enabled = false;
00399 }
00400 }
00401
00402 void RenderBackendOpenGL::setLighting(float red, float green, float blue) {
00403 if (m_state.lightmodel != 0) {
00404 GLfloat lightDiffuse[] = {red, green, blue, 1.0f};
00405 glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse);
00406 }
00407 }
00408
00409 void RenderBackendOpenGL::resetLighting() {
00410 if (m_state.lightmodel != 0) {
00411 setLighting(1.0, 1.0, 1.0);
00412 }
00413 }
00414
00415 void RenderBackendOpenGL::enableStencilTest() {
00416 if (!m_state.sten_enabled) {
00417 glEnable(GL_STENCIL_TEST);
00418 m_state.sten_enabled = true;
00419 }
00420 }
00421
00422 void RenderBackendOpenGL::disableStencilTest() {
00423 if (m_state.sten_enabled) {
00424 glDisable(GL_STENCIL_TEST);
00425 m_state.sten_enabled = false;
00426 }
00427 }
00428
00429 void RenderBackendOpenGL::setStencilTest(uint8_t stencil_ref, GLenum stencil_op, GLenum stencil_func) {
00430 enableStencilTest();
00431 if(m_state.sten_op != stencil_op) {
00432 m_state.sten_op = stencil_op;
00433 glStencilOp(GL_KEEP, GL_KEEP, m_state.sten_op);
00434 }
00435
00436 if(m_state.sten_ref != stencil_ref || m_state.sten_func != stencil_func) {
00437 m_state.sten_ref = stencil_ref;
00438 m_state.sten_func = stencil_func;
00439 glStencilFunc(m_state.sten_func, stencil_ref, 0xff);
00440 }
00441 }
00442
00443 void RenderBackendOpenGL::resetStencilBuffer(uint8_t buffer) {
00444 if (buffer != m_state.sten_buf) {
00445 m_state.sten_buf = buffer;
00446 glClearStencil(buffer);
00447 }
00448 disableScissorTest();
00449 glClear(GL_STENCIL_BUFFER_BIT);
00450 enableScissorTest();
00451 }
00452
00453 uint8_t RenderBackendOpenGL::getStencilRef() const {
00454 return m_state.sten_ref;
00455 }
00456
00457 void RenderBackendOpenGL::enableAlphaTest() {
00458 if (!m_state.alpha_enabled) {
00459 glEnable(GL_ALPHA_TEST);
00460 m_state.alpha_enabled = true;
00461 }
00462 }
00463
00464 void RenderBackendOpenGL::disableAlphaTest() {
00465 if (m_state.alpha_enabled) {
00466 glDisable(GL_ALPHA_TEST);
00467 m_state.alpha_enabled = false;
00468 }
00469 }
00470
00471 void RenderBackendOpenGL::setAlphaTest(float ref_alpha) {
00472 enableAlphaTest();
00473 glAlphaFunc(GL_GREATER, ref_alpha);
00474 }
00475
00476 void RenderBackendOpenGL::setEnvironmentalColor(const uint8_t* rgb) {
00477 if (memcmp(m_state.env_color, rgb, sizeof(uint8_t) * 3)) {
00478
00479 memcpy(m_state.env_color, rgb, sizeof(uint8_t) * 3);
00480 GLfloat rgbf[4] = {
00481 static_cast<float>(m_state.env_color[0]) / 255.0f,
00482 static_cast<float>(m_state.env_color[1]) / 255.0f,
00483 static_cast<float>(m_state.env_color[2]) / 255.0f, 0.0f};
00484
00485 if(m_state.active_tex != 1) {
00486 m_state.active_tex = 1;
00487 glActiveTexture(GL_TEXTURE1);
00488 }
00489
00490 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, rgbf);
00491 }
00492 }
00493
00494 void RenderBackendOpenGL::setVertexPointer(GLsizei stride, const GLvoid* ptr) {
00495 if(m_state.vertex_pointer != ptr) {
00496 m_state.vertex_pointer = ptr;
00497 glVertexPointer(2, GL_FLOAT, stride, ptr);
00498 }
00499 }
00500
00501 void RenderBackendOpenGL::setColorPointer(GLsizei stride, const GLvoid* ptr) {
00502 if(m_state.color_pointer != ptr) {
00503 m_state.color_pointer = ptr;
00504 glColorPointer(4, GL_UNSIGNED_BYTE, stride, ptr);
00505 }
00506 }
00507
00508 void RenderBackendOpenGL::setTexCoordPointer(uint32_t texUnit, GLsizei stride, const GLvoid* ptr) {
00509 if(m_state.tex_pointer[texUnit] != ptr) {
00510 if(m_state.active_client_tex != texUnit) {
00511 m_state.active_client_tex = texUnit;
00512 glClientActiveTexture(GL_TEXTURE0 + texUnit);
00513 }
00514 m_state.tex_pointer[texUnit] = ptr;
00515 glTexCoordPointer(2, GL_FLOAT, stride, ptr);
00516 }
00517 }
00518
00519 void RenderBackendOpenGL::enableScissorTest() {
00520 if(m_state.scissor_test == false) {
00521 m_state.scissor_test = true;
00522 glEnable(GL_SCISSOR_TEST);
00523 }
00524 }
00525
00526 void RenderBackendOpenGL::disableScissorTest() {
00527 if(m_state.scissor_test == true) {
00528 m_state.scissor_test = false;
00529 glDisable(GL_SCISSOR_TEST);
00530 }
00531 }
00532
00533 void RenderBackendOpenGL::changeBlending(int32_t src, int32_t dst) {
00534 GLenum src_fact;
00535 GLenum dst_fact;
00536
00537 switch(src) {
00538 case 0 : src_fact = GL_ZERO; break;
00539 case 1 : src_fact = GL_ONE; break;
00540 case 2 : src_fact = GL_DST_COLOR; break;
00541 case 3 : src_fact = GL_ONE_MINUS_DST_COLOR; break;
00542 case 4 : src_fact = GL_SRC_ALPHA; break;
00543 case 5 : src_fact = GL_ONE_MINUS_SRC_ALPHA; break;
00544 case 6 : src_fact = GL_DST_ALPHA; break;
00545 case 7 : src_fact = GL_ONE_MINUS_DST_ALPHA; break;
00546
00547 default : src_fact = GL_DST_COLOR; break;
00548 }
00549
00550 switch(dst) {
00551 case 0 : dst_fact = GL_ZERO; break;
00552 case 1 : dst_fact = GL_ONE; break;
00553 case 2 : dst_fact = GL_SRC_COLOR; break;
00554 case 3 : dst_fact = GL_ONE_MINUS_SRC_COLOR; break;
00555 case 4 : dst_fact = GL_SRC_ALPHA; break;
00556 case 5 : dst_fact = GL_ONE_MINUS_SRC_ALPHA; break;
00557 case 6 : dst_fact = GL_DST_ALPHA; break;
00558 case 7 : dst_fact = GL_ONE_MINUS_DST_ALPHA; break;
00559
00560 default : dst_fact = GL_SRC_ALPHA; break;
00561 }
00562
00563 if (m_state.blend_src != src_fact || m_state.blend_dst != dst_fact) {
00564 m_state.blend_src = src_fact;
00565 m_state.blend_dst = dst_fact;
00566 glBlendFunc(src_fact, dst_fact);
00567 }
00568 }
00569
00570 void RenderBackendOpenGL::changeRenderInfos(uint16_t elements, int32_t src, int32_t dst, bool light,
00571 bool stentest, uint8_t stenref, GLConstants stenop, GLConstants stenfunc) {
00572
00573 uint16_t count = 0;
00574 uint32_t size = m_render_objects.size();
00575 while (count != elements) {
00576 ++count;
00577 RenderObject& r = m_render_objects.at(size-count);
00578
00579 r.src = src;
00580 r.dst = dst;
00581 r.light = light;
00582 if (stentest) {
00583 r.stencil_test = stentest;
00584 r.stencil_ref = stenref;
00585 r.stencil_op = stenop;
00586 r.stencil_func = stenfunc;
00587 }
00588 }
00589 }
00590
00591 void RenderBackendOpenGL::renderVertexArrays() {
00592 if (!m_render_objects.empty()) {
00593
00594 bool type = false;
00595 bool texture = false;
00596 bool blending = false;
00597 bool light = false;
00598 bool stencil = false;
00599 bool render = false;
00600 bool mt = false;
00601
00602
00603 const uint32_t stride = sizeof(renderData);
00604 const uint32_t stride2T = sizeof(renderData2T);
00605
00606 if(!m_render_objects[0].multitextured) {
00607
00608 setVertexPointer(stride, &m_render_datas[0].vertex);
00609 setTexCoordPointer(0, stride, &m_render_datas[0].texel);
00610 setColorPointer(stride, &m_render_datas[0].color);
00611 }
00612
00613
00614 int32_t index = 0;
00615
00616 uint32_t elements = 0;
00617
00618 GLenum mode = GL_QUADS;
00619
00620 uint32_t texture_id = 0;
00621
00622 int32_t src = 4;
00623
00624 int32_t dst = 5;
00625
00626 bool multitextured = false;
00627 uint8_t color[3] = {0};
00628
00629 int32_t index2T = 0;
00630 uint32_t elements2T = 0;
00631
00632 int32_t* currentIndex = &index;
00633 uint32_t* currentElements = &elements;
00634
00635 for(std::vector<RenderObject>::iterator ir = m_render_objects.begin(); ir != m_render_objects.end(); ++ir) {
00636 RenderObject& ro = (*ir);
00637
00638
00639 if (ro.mode != mode) {
00640 type = true;
00641 render = true;
00642 }
00643 if (ro.texture_id != texture_id) {
00644 texture = true;
00645 render = true;
00646 }
00647 if (m_state.lightmodel != 0) {
00648 if (ro.src != src || ro.dst != dst) {
00649 blending = true;
00650 render = true;
00651 }
00652 if (ro.light != m_state.light_enabled) {
00653 light = true;
00654 render = true;
00655 }
00656 if (ro.stencil_test != m_state.sten_enabled) {
00657 stencil = true;
00658 render = true;
00659 } else if (ro.stencil_test) {
00660 if (ro.stencil_ref != m_state.sten_ref ||
00661 ro.stencil_op != m_state.sten_op ||
00662 ro.stencil_func != m_state.sten_func) {
00663 stencil = true;
00664 render = true;
00665 }
00666 }
00667 }
00668 if (ro.multitextured != multitextured ||
00669 (ro.multitextured == true && memcmp(color, ro.rgb, sizeof(uint8_t) * 3))) {
00670 mt = true;
00671 render = true;
00672 }
00673
00674
00675 if (render) {
00676 if (*currentElements > 0) {
00677
00678 glDrawArrays(mode, *currentIndex, *currentElements);
00679 *currentIndex += *currentElements;
00680 }
00681
00682 if (type) {
00683 mode = ro.mode;
00684 type = false;
00685 }
00686
00687 if(mt) {
00688 if(ro.multitextured) {
00689 enableTextures(1);
00690 setEnvironmentalColor(ro.rgb);
00691 enableTextures(0);
00692
00693
00694 setVertexPointer(stride2T, &m_render_datas2T[0].vertex);
00695 setColorPointer(stride2T, &m_render_datas2T[0].color);
00696 setTexCoordPointer(1, stride2T, &m_render_datas2T[0].texel2);
00697 setTexCoordPointer(0, stride2T, &m_render_datas2T[0].texel);
00698
00699 memcpy(color, ro.rgb, sizeof(uint8_t) * 3);
00700 multitextured = true;
00701 currentElements = &elements2T;
00702 currentIndex = &index2T;
00703
00704 } else {
00705 disableTextures(1);
00706 enableTextures(0);
00707
00708
00709 setVertexPointer(stride, &m_render_datas[0].vertex);
00710 setTexCoordPointer(0, stride, &m_render_datas[0].texel);
00711 setColorPointer(stride, &m_render_datas[0].color);
00712
00713 multitextured = false;
00714 currentIndex = &index;
00715 currentElements = &elements;
00716 }
00717 mt = false;
00718 }
00719
00720
00721 if (texture) {
00722 if (ro.texture_id != 0) {
00723 bindTexture(0, ro.texture_id);
00724 texture_id = ro.texture_id;
00725 } else {
00726 disableTextures(0);
00727 texture_id = 0;
00728 }
00729 texture = false;
00730 }
00731
00732
00733 *currentElements = ro.size;
00734
00735
00736 if (m_state.lightmodel != 0) {
00737
00738 if (blending) {
00739 src = ro.src;
00740 dst = ro.dst;
00741 changeBlending(ro.src, ro.dst);
00742 blending = false;
00743 }
00744
00745 if (light) {
00746 if (ro.light && !m_state.light_enabled) {
00747 enableLighting();
00748 } else if (!ro.light && m_state.light_enabled) {
00749 disableLighting();
00750 }
00751 light = false;
00752 }
00753
00754 if (stencil) {
00755 if (ro.stencil_test) {
00756 setStencilTest(ro.stencil_ref, ro.stencil_op, ro.stencil_func);
00757 setAlphaTest(0.0);
00758 } else {
00759 disableAlphaTest();
00760 disableStencilTest();
00761 }
00762 stencil = false;
00763 }
00764 }
00765 render = false;
00766 } else {
00767
00768 *currentElements += ro.size;
00769 }
00770 }
00771
00772 glDrawArrays(mode, *currentIndex, *currentElements);
00773
00774
00775 disableTextures(1);
00776 disableTextures(0);
00777
00778 if (m_state.lightmodel != 0) {
00779 changeBlending(4, 5);
00780 disableLighting();
00781 disableStencilTest();
00782 disableAlphaTest();
00783 }
00784
00785 m_render_objects.clear();
00786 m_render_datas.clear();
00787 m_render_datas2T.clear();
00788 }
00789 }
00790
00791 bool RenderBackendOpenGL::putPixel(int32_t x, int32_t y, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
00792 if ((x < 0) || (x >= (int32_t)m_target->w) ||
00793 (y < 0) || (y >= (int32_t)m_target->h)) {
00794 return false;
00795 }
00796 renderData rd;
00797 rd.vertex[0] = static_cast<float>(x);
00798 rd.vertex[1] = static_cast<float>(y);
00799 rd.color[0] = r;
00800 rd.color[1] = g;
00801 rd.color[2] = b;
00802 rd.color[3] = a;
00803 m_render_datas.push_back(rd);
00804
00805 RenderObject ro(GL_POINTS, 1);
00806 m_render_objects.push_back(ro);
00807
00808 return true;
00809 }
00810
00811 void RenderBackendOpenGL::drawLine(const Point& p1, const Point& p2, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
00812 renderData rd;
00813 rd.vertex[0] = static_cast<float>(p1.x);
00814 rd.vertex[1] = static_cast<float>(p1.y);
00815 rd.color[0] = r;
00816 rd.color[1] = g;
00817 rd.color[2] = b;
00818 rd.color[3] = a;
00819 m_render_datas.push_back(rd);
00820
00821 rd.vertex[0] = static_cast<float>(p2.x);
00822 rd.vertex[1] = static_cast<float>(p2.y);
00823 m_render_datas.push_back(rd);
00824
00825 RenderObject ro(GL_LINES, 2);
00826 m_render_objects.push_back(ro);
00827 }
00828
00829 void RenderBackendOpenGL::drawTriangle(const Point& p1, const Point& p2, const Point& p3, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
00830 renderData rd;
00831 rd.vertex[0] = static_cast<float>(p1.x);
00832 rd.vertex[1] = static_cast<float>(p1.y);
00833 rd.color[0] = r;
00834 rd.color[1] = g;
00835 rd.color[2] = b;
00836 rd.color[3] = a;
00837 m_render_datas.push_back(rd);
00838
00839 rd.vertex[0] = static_cast<float>(p2.x);
00840 rd.vertex[1] = static_cast<float>(p2.y);
00841 m_render_datas.push_back(rd);
00842
00843 rd.vertex[0] = static_cast<float>(p3.x);
00844 rd.vertex[1] = static_cast<float>(p3.y);
00845 m_render_datas.push_back(rd);
00846
00847 RenderObject ro(GL_TRIANGLES, 3);
00848 m_render_objects.push_back(ro);
00849 }
00850
00851 void RenderBackendOpenGL::drawRectangle(const Point& p, uint16_t w, uint16_t h, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
00852 renderData rd;
00853 rd.vertex[0] = static_cast<float>(p.x);
00854 rd.vertex[1] = static_cast<float>(p.y);
00855 rd.color[0] = r;
00856 rd.color[1] = g;
00857 rd.color[2] = b;
00858 rd.color[3] = a;
00859 m_render_datas.push_back(rd);
00860 rd.vertex[0] = static_cast<float>(p.x+w);
00861
00862 m_render_datas.push_back(rd);
00863 rd.vertex[1] = static_cast<float>(p.y+h);
00864
00865 m_render_datas.push_back(rd);
00866 rd.vertex[0] = static_cast<float>(p.x);
00867 m_render_datas.push_back(rd);
00868
00869 RenderObject ro(GL_LINE_LOOP, 4);
00870 m_render_objects.push_back(ro);
00871 }
00872
00873 void RenderBackendOpenGL::fillRectangle(const Point& p, uint16_t w, uint16_t h, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
00874 renderData rd;
00875 rd.vertex[0] = static_cast<float>(p.x);
00876 rd.vertex[1] = static_cast<float>(p.y);
00877 rd.color[0] = r;
00878 rd.color[1] = g;
00879 rd.color[2] = b;
00880 rd.color[3] = a;
00881 m_render_datas.push_back(rd);
00882
00883 rd.vertex[1] = static_cast<float>(p.y+h);
00884 m_render_datas.push_back(rd);
00885
00886 rd.vertex[0] = static_cast<float>(p.x+w);
00887 m_render_datas.push_back(rd);
00888
00889 rd.vertex[1] = static_cast<float>(p.y);
00890 m_render_datas.push_back(rd);
00891
00892 RenderObject ro(GL_QUADS, 4);
00893 m_render_objects.push_back(ro);
00894 }
00895
00896 void RenderBackendOpenGL::drawQuad(const Point& p1, const Point& p2, const Point& p3, const Point& p4, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
00897 renderData rd;
00898 rd.vertex[0] = static_cast<float>(p1.x);
00899 rd.vertex[1] = static_cast<float>(p1.y);
00900 rd.color[0] = r;
00901 rd.color[1] = g;
00902 rd.color[2] = b;
00903 rd.color[3] = a;
00904 m_render_datas.push_back(rd);
00905
00906 rd.vertex[0] = static_cast<float>(p2.x);
00907 rd.vertex[1] = static_cast<float>(p2.y);
00908 m_render_datas.push_back(rd);
00909
00910 rd.vertex[0] = static_cast<float>(p3.x);
00911 rd.vertex[1] = static_cast<float>(p3.y);
00912 m_render_datas.push_back(rd);
00913
00914 rd.vertex[0] = static_cast<float>(p4.x);
00915 rd.vertex[1] = static_cast<float>(p4.y);
00916 m_render_datas.push_back(rd);
00917
00918 RenderObject ro(GL_QUADS, 4);
00919 m_render_objects.push_back(ro);
00920 }
00921
00922 void RenderBackendOpenGL::drawVertex(const Point& p, const uint8_t size, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
00923 renderData rd;
00924 rd.vertex[0] = static_cast<float>(p.x-size);
00925 rd.vertex[1] = static_cast<float>(p.y+size);
00926 rd.color[0] = r;
00927 rd.color[1] = g;
00928 rd.color[2] = b;
00929 rd.color[3] = a;
00930 m_render_datas.push_back(rd);
00931
00932 rd.vertex[0] = static_cast<float>(p.x+size);
00933 m_render_datas.push_back(rd);
00934
00935 rd.vertex[1] = static_cast<float>(p.y-size);
00936 m_render_datas.push_back(rd);
00937
00938 rd.vertex[0] = static_cast<float>(p.x-size);
00939 m_render_datas.push_back(rd);
00940
00941 RenderObject ro(GL_LINE_LOOP, 4);
00942 m_render_objects.push_back(ro);
00943 }
00944
00945 void RenderBackendOpenGL::drawLightPrimitive(const Point& p, uint8_t intensity, float radius, int32_t subdivisions, float xstretch, float ystretch, uint8_t red, uint8_t green, uint8_t blue) {
00946 const float step = Mathf::twoPi()/subdivisions;
00947 renderData rd;;
00948 for(float angle=0; angle<=Mathf::twoPi(); angle+=step){
00949 rd.vertex[0] = static_cast<float>(p.x);
00950 rd.vertex[1] = static_cast<float>(p.y);
00951 rd.color[0] = red;
00952 rd.color[1] = green;
00953 rd.color[2] = blue;
00954 rd.color[3] = intensity;
00955 m_render_datas.push_back(rd);
00956
00957 rd.vertex[0] = radius*Mathf::Cos(angle+step)*xstretch + p.x;
00958 rd.vertex[1] = radius*Mathf::Sin(angle+step)*ystretch + p.y;
00959 rd.color[0] = 0;
00960 rd.color[1] = 0;
00961 rd.color[2] = 0;
00962 rd.color[3] = 255;
00963 m_render_datas.push_back(rd);
00964
00965 rd.vertex[0] = radius*Mathf::Cos(angle)*xstretch + p.x;
00966 rd.vertex[1] = radius*Mathf::Sin(angle)*ystretch + p.y;
00967 m_render_datas.push_back(rd);
00968
00969 RenderObject ro(GL_TRIANGLES, 3);
00970 m_render_objects.push_back(ro);
00971 }
00972 }
00973
00974 void RenderBackendOpenGL::addImageToArray(uint32_t id, const Rect& rect, float const* st, uint8_t alpha, uint8_t const* rgb) {
00975 if (!rgb) {
00976 renderData rd;
00977 rd.vertex[0] = static_cast<float>(rect.x);
00978 rd.vertex[1] = static_cast<float>(rect.y);
00979 rd.texel[0] = st[0];
00980 rd.texel[1] = st[1];
00981 rd.color[0] = 255;
00982 rd.color[1] = 255;
00983 rd.color[2] = 255;
00984 rd.color[3] = alpha;
00985 m_render_datas.push_back(rd);
00986
00987 rd.vertex[0] = static_cast<float>(rect.x);
00988 rd.vertex[1] = static_cast<float>(rect.y+rect.h);
00989 rd.texel[1] = st[3];
00990 m_render_datas.push_back(rd);
00991
00992 rd.vertex[0] = static_cast<float>(rect.x+rect.w);
00993 rd.vertex[1] = static_cast<float>(rect.y+rect.h);
00994 rd.texel[0] = st[2];
00995 m_render_datas.push_back(rd);
00996
00997 rd.vertex[0] = static_cast<float>(rect.x+rect.w);
00998 rd.vertex[1] = static_cast<float>(rect.y);
00999 rd.texel[1] = st[1];
01000 m_render_datas.push_back(rd);
01001
01002 RenderObject ro(GL_QUADS, 4, id);
01003 m_render_objects.push_back(ro);
01004 } else {
01005 renderData2T rd;
01006 rd.vertex[0] = static_cast<float>(rect.x);
01007 rd.vertex[1] = static_cast<float>(rect.y);
01008 rd.texel[0] = st[0];
01009 rd.texel[1] = st[1];
01010 rd.texel2[0] = 0.0;
01011 rd.texel2[1] = 0.0;
01012 rd.color[0] = 255;
01013 rd.color[1] = 255;
01014 rd.color[2] = 255;
01015 rd.color[3] = alpha;
01016 m_render_datas2T.push_back(rd);
01017
01018 rd.vertex[0] = static_cast<float>(rect.x);
01019 rd.vertex[1] = static_cast<float>(rect.y+rect.h);
01020 rd.texel[1] = st[3];
01021 rd.texel2[1] = 1.0;
01022 m_render_datas2T.push_back(rd);
01023
01024 rd.vertex[0] = static_cast<float>(rect.x+rect.w);
01025 rd.vertex[1] = static_cast<float>(rect.y+rect.h);
01026 rd.texel[0] = st[2];
01027 rd.texel2[0] = 1.0;
01028 m_render_datas2T.push_back(rd);
01029
01030 rd.vertex[0] = static_cast<float>(rect.x+rect.w);
01031 rd.vertex[1] = static_cast<float>(rect.y);
01032 rd.texel[1] = st[1];
01033 rd.texel2[1] = 0.0;
01034 m_render_datas2T.push_back(rd);
01035
01036 RenderObject ro(GL_QUADS, 4, id);
01037 ro.multitextured = true;
01038 ro.rgb[0] = rgb[0];
01039 ro.rgb[1] = rgb[1];
01040 ro.rgb[2] = rgb[2];
01041 m_render_objects.push_back(ro);
01042 }
01043 }
01044
01045 void RenderBackendOpenGL::prepareForOverlays() {
01046 glActiveTexture(GL_TEXTURE1);
01047 glEnable(GL_TEXTURE_2D);
01048
01049 if(m_mask_overlays == 0) {
01050
01051 glGenTextures(1, &m_mask_overlays);
01052
01053 uint8_t dummydata[3] = {127, 127, 127};
01054 glBindTexture(GL_TEXTURE_2D, m_mask_overlays);
01055 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
01056 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
01057 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
01058 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
01059 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1, 1, 0,
01060 GL_RGB, GL_UNSIGNED_BYTE, dummydata);
01061 } else {
01062 glBindTexture(GL_TEXTURE_2D, m_mask_overlays);
01063 }
01064
01065 m_state.texture[1] = m_mask_overlays;
01066
01067 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
01068 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
01069 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
01070
01071
01072 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE0);
01073 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE0);
01074 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
01075 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
01076
01077
01078
01079
01080
01081
01082 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT);
01083 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
01084
01085
01086 glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_TEXTURE1);
01087 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
01088
01089
01090 glActiveTexture(GL_TEXTURE1);
01091 glDisable(GL_TEXTURE_2D);
01092 glActiveTexture(GL_TEXTURE0);
01093
01094
01095
01096 }
01097
01098 void RenderBackendOpenGL::captureScreen(const std::string& filename) {
01099 const uint32_t swidth = getWidth();
01100 const uint32_t sheight = getHeight();
01101
01102 uint8_t *pixels;
01103 SDL_Surface *surface = SDL_CreateRGBSurface(SDL_SWSURFACE, swidth, sheight, 24,
01104 RMASK, GMASK, BMASK, NULLMASK);
01105
01106 if (!surface) {
01107 return;
01108 }
01109
01110 SDL_LockSurface(surface);
01111 pixels = new uint8_t[swidth * sheight * 3];
01112 glReadPixels(0, 0, swidth, sheight, GL_RGB, GL_UNSIGNED_BYTE, reinterpret_cast<GLvoid*>(pixels));
01113 uint8_t *imagepixels = reinterpret_cast<uint8_t*>(surface->pixels);
01114
01115 for (int32_t y = (sheight - 1); y >= 0; --y) {
01116 uint8_t *rowbegin = pixels + y * swidth * 3;
01117 uint8_t *rowend = rowbegin + swidth * 3;
01118
01119 std::copy(rowbegin, rowend, imagepixels);
01120
01121
01122 imagepixels += surface->pitch;
01123 }
01124
01125 SDL_UnlockSurface(surface);
01126 Image::saveAsPng(filename, *surface);
01127
01128 SDL_FreeSurface(surface);
01129 delete[] pixels;
01130 }
01131
01132 void RenderBackendOpenGL::captureScreen(const std::string& filename, uint32_t width, uint32_t height) {
01133 const uint32_t swidth = getWidth();
01134 const uint32_t sheight = getHeight();
01135 const bool same_size = (width == swidth && height == sheight);
01136
01137 if (width < 1 || height < 1) {
01138 return;
01139 }
01140
01141 if (same_size) {
01142 captureScreen(filename);
01143 return;
01144 }
01145
01146 uint8_t *pixels;
01147
01148 SDL_Surface* src = SDL_CreateRGBSurface(SDL_SWSURFACE, swidth, sheight, 32,
01149 RMASK, GMASK, BMASK, AMASK);
01150
01151 if (!src) {
01152 return;
01153 }
01154
01155 if (SDL_MUSTLOCK(src)) {
01156 SDL_LockSurface(src);
01157 }
01158 pixels = new uint8_t[swidth * sheight * 4];
01159 glReadPixels(0, 0, swidth, sheight, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<GLvoid*>(pixels));
01160
01161 uint8_t* imagepixels = reinterpret_cast<uint8_t*>(src->pixels);
01162
01163 for (int32_t y = (sheight - 1); y >= 0; --y) {
01164 uint8_t *rowbegin = pixels + y * swidth * 4;
01165 uint8_t *rowend = rowbegin + swidth * 4;
01166
01167 std::copy(rowbegin, rowend, imagepixels);
01168
01169
01170 imagepixels += src->pitch;
01171 }
01172
01173
01174 SDL_Surface* dst = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32,
01175 RMASK, GMASK, BMASK, AMASK);
01176
01177 uint32_t* src_pointer = static_cast<uint32_t*>(src->pixels);
01178 uint32_t* src_help_pointer = src_pointer;
01179 uint32_t* dst_pointer = static_cast<uint32_t*>(dst->pixels);
01180
01181 int32_t x, y, *sx_ca, *sy_ca;
01182 int32_t sx = static_cast<int32_t>(0xffff * src->w / dst->w);
01183 int32_t sy = static_cast<int32_t>(0xffff * src->h / dst->h);
01184 int32_t sx_c = 0;
01185 int32_t sy_c = 0;
01186
01187
01188 int32_t* sx_a = new int32_t[dst->w + 1];
01189 sx_ca = sx_a;
01190 for (x = 0; x <= dst->w; x++) {
01191 *sx_ca = sx_c;
01192 sx_ca++;
01193 sx_c &= 0xffff;
01194 sx_c += sx;
01195 }
01196
01197 int32_t* sy_a = new int32_t[dst->h + 1];
01198 sy_ca = sy_a;
01199 for (y = 0; y <= dst->h; y++) {
01200 *sy_ca = sy_c;
01201 sy_ca++;
01202 sy_c &= 0xffff;
01203 sy_c += sy;
01204 }
01205 sy_ca = sy_a;
01206
01207
01208
01209 if (SDL_MUSTLOCK(dst)) {
01210 SDL_LockSurface(dst);
01211 }
01212
01213 for (y = 0; y < dst->h; y++) {
01214 src_pointer = src_help_pointer;
01215 sx_ca = sx_a;
01216 for (x = 0; x < dst->w; x++) {
01217 *dst_pointer = *src_pointer;
01218 sx_ca++;
01219 src_pointer += (*sx_ca >> 16);
01220 dst_pointer++;
01221 }
01222 sy_ca++;
01223 src_help_pointer = (uint32_t*)((uint8_t*)src_help_pointer + (*sy_ca >> 16) * src->pitch);
01224 }
01225
01226 if (SDL_MUSTLOCK(dst)) {
01227 SDL_UnlockSurface(dst);
01228 }
01229 if (SDL_MUSTLOCK(src)) {
01230 SDL_UnlockSurface(src);
01231 }
01232
01233 Image::saveAsPng(filename, *dst);
01234
01235
01236 SDL_FreeSurface(src);
01237 SDL_FreeSurface(dst);
01238 delete[] sx_a;
01239 delete[] sy_a;
01240 delete[] pixels;
01241 }
01242
01243 void RenderBackendOpenGL::setClipArea(const Rect& cliparea, bool clear) {
01244 glScissor(cliparea.x, getHeight() - cliparea.y - cliparea.h, cliparea.w, cliparea.h);
01245 if (clear) {
01246 if (m_isbackgroundcolor) {
01247 float red = float(m_backgroundcolor.r/255.0);
01248 float green = float(m_backgroundcolor.g/255.0);
01249 float blue = float(m_backgroundcolor.b/255.0);
01250 glClearColor(red, green, blue, 0.0);
01251 m_isbackgroundcolor = false;
01252 }
01253 glClear(GL_COLOR_BUFFER_BIT);
01254 }
01255 }
01256
01257 void RenderBackendOpenGL::attachRenderTarget(ImagePtr& img, bool discard) {
01258 m_img_target = img;
01259 m_target_discard = discard;
01260
01261
01262 m_img_target->forceLoadInternal();
01263 m_target = m_img_target->getSurface();
01264
01265 GLImage* glimage = static_cast<GLImage*>(m_img_target.get());
01266
01267 GLuint targetid = glimage->getTexId();
01268 uint32_t w = m_img_target->getWidth();
01269 uint32_t h = m_img_target->getHeight();
01270
01271
01272 if(glimage->isCompressed()) {
01273 bindTexture(targetid);
01274 GLubyte* pixels = new GLubyte[w*h*4];
01275
01276 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
01277 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
01278 delete [] pixels;
01279 glimage->setCompressed(false);
01280 }
01281
01282
01283 if (GLEE_EXT_framebuffer_object && m_useframebuffer) {
01284 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo_id);
01285 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
01286 GL_TEXTURE_2D, targetid, 0);
01287 }
01288
01289 glViewport(0, 0, w, h);
01290 glMatrixMode(GL_PROJECTION);
01291 glLoadIdentity();
01292
01293 glOrtho(0, w, 0, h, -1, 1);
01294 glMatrixMode(GL_MODELVIEW);
01295
01296 glCullFace(GL_FRONT);
01297
01298 if (m_target_discard) {
01299 glClear(GL_COLOR_BUFFER_BIT);
01300 } else if (!m_target_discard && (!GLEE_EXT_framebuffer_object || !m_useframebuffer)) {
01301
01302 addImageToArray(targetid, m_img_target->getArea(),
01303 static_cast<GLImage*>(m_img_target.get())->getTexCoords(), 255, 0);
01304 }
01305 }
01306
01307 void RenderBackendOpenGL::detachRenderTarget() {
01308 assert(m_target != m_screen);
01309
01310
01311 renderVertexArrays();
01312
01313 if (GLEE_EXT_framebuffer_object && m_useframebuffer) {
01314 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
01315 } else {
01316 bindTexture(0, static_cast<GLImage*>(m_img_target.get())->getTexId());
01317 glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0,
01318 m_img_target->getWidth(), m_img_target->getHeight(), 0);
01319 }
01320
01321 m_target = m_screen;
01322 glViewport(0, 0, m_screen->w, m_screen->h);
01323 glMatrixMode(GL_PROJECTION);
01324 glLoadIdentity();
01325 glOrtho(0, m_screen->w, m_screen->h, 0, -1, 1);
01326 glMatrixMode(GL_MODELVIEW);
01327 glCullFace(GL_BACK);
01328 }
01329 }