30 #include "util/base/exception.h"
31 #include "util/log/logger.h"
32 #include "video/devicecaps.h"
35 #include "renderbackendopengl.h"
36 #include "SDL_image.h"
40 static Logger _log(LM_VIDEO);
42 class RenderBackendOpenGL::RenderObject {
44 RenderObject(GLenum m, uint16_t s, uint32_t t=0):
55 multitextured(false) {}
71 RenderBackendOpenGL::RenderBackendOpenGL(
const SDL_Color& colorkey)
72 : RenderBackend(colorkey), m_mask_overlays(0){
74 m_state.tex_enabled[0] =
false;
75 m_state.tex_enabled[1] =
false;
76 m_state.texture[0] = 0;
77 m_state.texture[1] = 0;
78 m_state.active_tex = 0;
80 m_state.color_pointer = 0;
81 m_state.tex_pointer[0] = 0;
82 m_state.tex_pointer[1] = 0;
83 m_state.vertex_pointer = 0;
85 m_state.sten_enabled =
false;
89 m_state.sten_func = 0;
91 m_state.lightmodel = 0;
92 m_state.light_enabled =
false;
94 m_state.env_color[0] = 0;
95 m_state.env_color[1] = 0;
96 m_state.env_color[2] = 0;
97 m_state.blend_src = GL_SRC_ALPHA;
98 m_state.blend_dst = GL_ONE_MINUS_SRC_ALPHA;
99 m_state.alpha_enabled =
false;
100 m_state.scissor_test =
true;
103 RenderBackendOpenGL::~RenderBackendOpenGL() {
104 glDeleteTextures(1, &m_mask_overlays);
105 if(GLEE_EXT_framebuffer_object && m_useframebuffer) {
106 glDeleteFramebuffers(1, &m_fbo_id);
112 static std::string backend_name =
"OpenGL";
118 Uint32 flags = SDL_INIT_VIDEO;
119 if (SDL_InitSubSystem(flags) < 0)
120 throw SDLException(SDL_GetError());
121 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
122 SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
124 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
128 disableScissorTest();
129 glClear(GL_COLOR_BUFFER_BIT);
135 SDL_Surface *img = IMG_Load(icon.c_str());
137 SDL_WM_SetIcon(img, 0);
138 SDL_FreeSurface(img);
143 SDL_WM_SetCaption(title.c_str(), 0);
147 uint16_t width = mode.getWidth();
148 uint16_t height = mode.getHeight();
149 uint16_t bitsPerPixel = mode.getBPP();
150 bool fs = mode.isFullScreen();
151 uint32_t flags = mode.getSDLFlags();
153 if (bitsPerPixel != 0) {
154 uint16_t bpp = SDL_VideoModeOK(width, height, bitsPerPixel, flags);
156 throw SDLException(
"Selected video mode not supported!");
161 SDL_FreeSurface(m_screen);
163 m_screen = SDL_SetVideoMode(width, height, bitsPerPixel, flags);
165 throw SDLException(
"Unable to set video mode selected!");
169 FL_LOG(_log,
LMsg(
"RenderBackendOpenGL")
170 <<
"Videomode " << width <<
"x" << height
171 <<
" at " << int32_t(bitsPerPixel) <<
" bpp");
173 m_rgba_format = *(m_screen->format);
174 m_rgba_format.Rmask = RMASK;
175 m_rgba_format.Gmask = GMASK;
176 m_rgba_format.Bmask = BMASK;
177 m_rgba_format.Amask = AMASK;
180 m_screenMode = ScreenMode(width,
186 throw SDLException(SDL_GetError());
189 glViewport(0, 0, width, height);
190 glMatrixMode(GL_PROJECTION);
192 glOrtho(0, width, height, 0, -1, 1);
193 glMatrixMode(GL_MODELVIEW);
196 glEnable(GL_CULL_FACE);
200 glPixelStorei(GL_PACK_ALIGNMENT, 1);
201 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
203 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
206 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
208 glEnable(GL_SCISSOR_TEST);
210 glEnableClientState(GL_COLOR_ARRAY);
211 glEnableClientState(GL_VERTEX_ARRAY);
213 prepareForOverlays();
218 if(GLEE_EXT_framebuffer_object && m_useframebuffer) {
219 glGenFramebuffers(1, &m_fbo_id);
228 SDL_GL_SwapBuffers();
232 Image* RenderBackendOpenGL::createImage(IResourceLoader* loader) {
236 Image* RenderBackendOpenGL::createImage(
const std::string& name, IResourceLoader* loader) {
237 return new GLImage(name, loader);
240 Image* RenderBackendOpenGL::createImage(SDL_Surface* surface) {
247 if (32 == surface->format->BitsPerPixel
248 && m_rgba_format.Rmask == surface->format->Rmask
249 && m_rgba_format.Gmask == surface->format->Gmask
250 && m_rgba_format.Bmask == surface->format->Bmask
251 && m_rgba_format.Amask == surface->format->Amask
252 && m_rgba_format.Rshift == surface->format->Rshift
253 && m_rgba_format.Gshift == surface->format->Gshift
254 && m_rgba_format.Bshift == surface->format->Bshift
255 && m_rgba_format.Ashift == surface->format->Ashift
256 && m_rgba_format.Rloss == surface->format->Rloss
257 && m_rgba_format.Gloss == surface->format->Gloss
258 && m_rgba_format.Bloss == surface->format->Bloss
259 && m_rgba_format.Aloss == surface->format->Aloss
260 && surface->flags & SDL_SRCALPHA ) {
265 uint8_t bpp = m_rgba_format.BitsPerPixel;
266 m_rgba_format.BitsPerPixel = 32;
267 SDL_Surface* conv = SDL_ConvertSurface(surface, &m_rgba_format, SDL_SWSURFACE | SDL_SRCALPHA);
268 m_rgba_format.BitsPerPixel = bpp;
271 SDL_FreeSurface(surface);
275 Image* RenderBackendOpenGL::createImage(
const std::string& name, SDL_Surface* surface) {
282 if (32 == surface->format->BitsPerPixel
283 && m_rgba_format.Rmask == surface->format->Rmask
284 && m_rgba_format.Gmask == surface->format->Gmask
285 && m_rgba_format.Bmask == surface->format->Bmask
286 && m_rgba_format.Amask == surface->format->Amask
287 && m_rgba_format.Rshift == surface->format->Rshift
288 && m_rgba_format.Gshift == surface->format->Gshift
289 && m_rgba_format.Bshift == surface->format->Bshift
290 && m_rgba_format.Ashift == surface->format->Ashift
291 && m_rgba_format.Rloss == surface->format->Rloss
292 && m_rgba_format.Gloss == surface->format->Gloss
293 && m_rgba_format.Bloss == surface->format->Bloss
294 && m_rgba_format.Aloss == surface->format->Aloss
295 && surface->flags & SDL_SRCALPHA ) {
297 return new GLImage(name, surface);
300 uint8_t bpp = m_rgba_format.BitsPerPixel;
301 m_rgba_format.BitsPerPixel = 32;
302 SDL_Surface* conv = SDL_ConvertSurface(surface, &m_rgba_format, SDL_SWSURFACE | SDL_SRCALPHA);
303 m_rgba_format.BitsPerPixel = bpp;
304 GLImage* image =
new GLImage(name, conv);
306 SDL_FreeSurface(surface);
310 Image* RenderBackendOpenGL::createImage(
const uint8_t* data, uint32_t width, uint32_t height) {
311 return new GLImage(data, width, height);
314 Image* RenderBackendOpenGL::createImage(
const std::string& name,
const uint8_t* data, uint32_t width, uint32_t height) {
315 return new GLImage(name, data, width, height);
319 if (m_state.lightmodel != lighting) {
320 if (m_state.lightmodel != 0) {
322 glDisable(GL_COLOR_MATERIAL);
323 }
else if (lighting != 0) {
326 glColorMaterial(GL_FRONT, GL_DIFFUSE);
327 glEnable(GL_COLOR_MATERIAL);
329 m_state.lightmodel = lighting;
334 return m_state.lightmodel;
337 void RenderBackendOpenGL::enableTextures(uint32_t texUnit) {
338 if(m_state.tex_enabled[texUnit] ==
false) {
339 if(m_state.active_tex != texUnit) {
340 m_state.active_tex = texUnit;
341 glActiveTexture(GL_TEXTURE0 + texUnit);
343 m_state.tex_enabled[texUnit] =
true;
345 glEnable(GL_TEXTURE_2D);
347 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
352 void RenderBackendOpenGL::disableTextures(uint32_t texUnit)
354 if(m_state.tex_enabled[texUnit] ==
true) {
355 if(m_state.active_tex != texUnit) {
356 m_state.active_tex = texUnit;
357 glActiveTexture(GL_TEXTURE0 + texUnit);
359 m_state.tex_enabled[texUnit] =
false;
361 glDisable(GL_TEXTURE_2D);
363 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
368 void RenderBackendOpenGL::bindTexture(uint32_t texUnit, GLuint texId) {
369 enableTextures(texUnit);
371 if(m_state.texture[texUnit] != texId) {
372 if(m_state.active_tex != texUnit) {
373 m_state.active_tex = texUnit;
374 glActiveTexture(GL_TEXTURE0 + texUnit);
376 m_state.texture[texUnit] = texId;
377 glBindTexture(GL_TEXTURE_2D, texId);
381 void RenderBackendOpenGL::bindTexture(GLuint texId) {
382 if(m_state.texture[m_state.active_tex] != texId) {
383 m_state.texture[m_state.active_tex] = texId;
384 glBindTexture(GL_TEXTURE_2D, texId);
388 void RenderBackendOpenGL::enableLighting() {
389 if (m_state.lightmodel != 0 && !m_state.light_enabled) {
390 glEnable(GL_LIGHTING);
391 m_state.light_enabled =
true;
395 void RenderBackendOpenGL::disableLighting() {
396 if (m_state.lightmodel != 0 && m_state.light_enabled) {
397 glDisable(GL_LIGHTING);
398 m_state.light_enabled =
false;
403 if (m_state.lightmodel != 0) {
404 GLfloat lightDiffuse[] = {red, green, blue, 1.0f};
405 glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse);
410 if (m_state.lightmodel != 0) {
415 void RenderBackendOpenGL::enableStencilTest() {
416 if (!m_state.sten_enabled) {
417 glEnable(GL_STENCIL_TEST);
418 m_state.sten_enabled =
true;
422 void RenderBackendOpenGL::disableStencilTest() {
423 if (m_state.sten_enabled) {
424 glDisable(GL_STENCIL_TEST);
425 m_state.sten_enabled =
false;
429 void RenderBackendOpenGL::setStencilTest(uint8_t stencil_ref, GLenum stencil_op, GLenum stencil_func) {
431 if(m_state.sten_op != stencil_op) {
432 m_state.sten_op = stencil_op;
433 glStencilOp(GL_KEEP, GL_KEEP, m_state.sten_op);
436 if(m_state.sten_ref != stencil_ref || m_state.sten_func != stencil_func) {
437 m_state.sten_ref = stencil_ref;
438 m_state.sten_func = stencil_func;
439 glStencilFunc(m_state.sten_func, stencil_ref, 0xff);
444 if (buffer != m_state.sten_buf) {
445 m_state.sten_buf = buffer;
446 glClearStencil(buffer);
448 disableScissorTest();
449 glClear(GL_STENCIL_BUFFER_BIT);
453 uint8_t RenderBackendOpenGL::getStencilRef()
const {
454 return m_state.sten_ref;
457 void RenderBackendOpenGL::enableAlphaTest() {
458 if (!m_state.alpha_enabled) {
459 glEnable(GL_ALPHA_TEST);
460 m_state.alpha_enabled =
true;
464 void RenderBackendOpenGL::disableAlphaTest() {
465 if (m_state.alpha_enabled) {
466 glDisable(GL_ALPHA_TEST);
467 m_state.alpha_enabled =
false;
471 void RenderBackendOpenGL::setAlphaTest(
float ref_alpha) {
473 glAlphaFunc(GL_GREATER, ref_alpha);
476 void RenderBackendOpenGL::setEnvironmentalColor(
const uint8_t* rgb) {
477 if (memcmp(m_state.env_color, rgb,
sizeof(uint8_t) * 3)) {
479 memcpy(m_state.env_color, rgb,
sizeof(uint8_t) * 3);
481 static_cast<float>(m_state.env_color[0]) / 255.0f,
482 static_cast<float>(m_state.env_color[1]) / 255.0f,
483 static_cast<float>(m_state.env_color[2]) / 255.0f, 0.0f};
485 if(m_state.active_tex != 1) {
486 m_state.active_tex = 1;
487 glActiveTexture(GL_TEXTURE1);
490 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, rgbf);
494 void RenderBackendOpenGL::setVertexPointer(GLsizei stride,
const GLvoid* ptr) {
495 if(m_state.vertex_pointer != ptr) {
496 m_state.vertex_pointer = ptr;
497 glVertexPointer(2, GL_FLOAT, stride, ptr);
501 void RenderBackendOpenGL::setColorPointer(GLsizei stride,
const GLvoid* ptr) {
502 if(m_state.color_pointer != ptr) {
503 m_state.color_pointer = ptr;
504 glColorPointer(4, GL_UNSIGNED_BYTE, stride, ptr);
508 void RenderBackendOpenGL::setTexCoordPointer(uint32_t texUnit, GLsizei stride,
const GLvoid* ptr) {
509 if(m_state.tex_pointer[texUnit] != ptr) {
510 if(m_state.active_client_tex != texUnit) {
511 m_state.active_client_tex = texUnit;
512 glClientActiveTexture(GL_TEXTURE0 + texUnit);
514 m_state.tex_pointer[texUnit] = ptr;
515 glTexCoordPointer(2, GL_FLOAT, stride, ptr);
519 void RenderBackendOpenGL::enableScissorTest() {
520 if(m_state.scissor_test ==
false) {
521 m_state.scissor_test =
true;
522 glEnable(GL_SCISSOR_TEST);
526 void RenderBackendOpenGL::disableScissorTest() {
527 if(m_state.scissor_test ==
true) {
528 m_state.scissor_test =
false;
529 glDisable(GL_SCISSOR_TEST);
538 case 0 : src_fact = GL_ZERO;
break;
539 case 1 : src_fact = GL_ONE;
break;
540 case 2 : src_fact = GL_DST_COLOR;
break;
541 case 3 : src_fact = GL_ONE_MINUS_DST_COLOR;
break;
542 case 4 : src_fact = GL_SRC_ALPHA;
break;
543 case 5 : src_fact = GL_ONE_MINUS_SRC_ALPHA;
break;
544 case 6 : src_fact = GL_DST_ALPHA;
break;
545 case 7 : src_fact = GL_ONE_MINUS_DST_ALPHA;
break;
547 default : src_fact = GL_DST_COLOR;
break;
551 case 0 : dst_fact = GL_ZERO;
break;
552 case 1 : dst_fact = GL_ONE;
break;
553 case 2 : dst_fact = GL_SRC_COLOR;
break;
554 case 3 : dst_fact = GL_ONE_MINUS_SRC_COLOR;
break;
555 case 4 : dst_fact = GL_SRC_ALPHA;
break;
556 case 5 : dst_fact = GL_ONE_MINUS_SRC_ALPHA;
break;
557 case 6 : dst_fact = GL_DST_ALPHA;
break;
558 case 7 : dst_fact = GL_ONE_MINUS_DST_ALPHA;
break;
560 default : dst_fact = GL_SRC_ALPHA;
break;
563 if (m_state.blend_src != src_fact || m_state.blend_dst != dst_fact) {
564 m_state.blend_src = src_fact;
565 m_state.blend_dst = dst_fact;
566 glBlendFunc(src_fact, dst_fact);
571 bool stentest, uint8_t stenref, GLConstants stenop, GLConstants stenfunc) {
574 uint32_t size = m_render_objects.size();
575 while (count != elements) {
577 RenderObject& r = m_render_objects.at(size-count);
583 r.stencil_test = stentest;
584 r.stencil_ref = stenref;
585 r.stencil_op = stenop;
586 r.stencil_func = stenfunc;
592 if (!m_render_objects.empty()) {
595 bool texture =
false;
596 bool blending =
false;
598 bool stencil =
false;
603 const uint32_t stride =
sizeof(renderData);
604 const uint32_t stride2T =
sizeof(renderData2T);
606 if(!m_render_objects[0].multitextured) {
608 setVertexPointer(stride, &m_render_datas[0].vertex);
609 setTexCoordPointer(0, stride, &m_render_datas[0].texel);
610 setColorPointer(stride, &m_render_datas[0].color);
616 uint32_t elements = 0;
618 GLenum mode = GL_QUADS;
620 uint32_t texture_id = 0;
626 bool multitextured =
false;
627 uint8_t color[3] = {0};
630 uint32_t elements2T = 0;
632 int32_t* currentIndex = &index;
633 uint32_t* currentElements = &elements;
635 for(std::vector<RenderObject>::iterator ir = m_render_objects.begin(); ir != m_render_objects.end(); ++ir) {
636 RenderObject& ro = (*ir);
639 if (ro.mode != mode) {
643 if (ro.texture_id != texture_id) {
647 if (m_state.lightmodel != 0) {
648 if (ro.src != src || ro.dst != dst) {
652 if (ro.light != m_state.light_enabled) {
656 if (ro.stencil_test != m_state.sten_enabled) {
659 }
else if (ro.stencil_test) {
660 if (ro.stencil_ref != m_state.sten_ref ||
661 ro.stencil_op != m_state.sten_op ||
662 ro.stencil_func != m_state.sten_func) {
668 if (ro.multitextured != multitextured ||
669 (ro.multitextured ==
true && memcmp(color, ro.rgb,
sizeof(uint8_t) * 3))) {
676 if (*currentElements > 0) {
678 glDrawArrays(mode, *currentIndex, *currentElements);
679 *currentIndex += *currentElements;
688 if(ro.multitextured) {
690 setEnvironmentalColor(ro.rgb);
694 setVertexPointer(stride2T, &m_render_datas2T[0].vertex);
695 setColorPointer(stride2T, &m_render_datas2T[0].color);
696 setTexCoordPointer(1, stride2T, &m_render_datas2T[0].texel2);
697 setTexCoordPointer(0, stride2T, &m_render_datas2T[0].texel);
699 memcpy(color, ro.rgb,
sizeof(uint8_t) * 3);
700 multitextured =
true;
701 currentElements = &elements2T;
702 currentIndex = &index2T;
709 setVertexPointer(stride, &m_render_datas[0].vertex);
710 setTexCoordPointer(0, stride, &m_render_datas[0].texel);
711 setColorPointer(stride, &m_render_datas[0].color);
713 multitextured =
false;
714 currentIndex = &index;
715 currentElements = &elements;
722 if (ro.texture_id != 0) {
723 bindTexture(0, ro.texture_id);
724 texture_id = ro.texture_id;
733 *currentElements = ro.size;
736 if (m_state.lightmodel != 0) {
746 if (ro.light && !m_state.light_enabled) {
748 }
else if (!ro.light && m_state.light_enabled) {
755 if (ro.stencil_test) {
756 setStencilTest(ro.stencil_ref, ro.stencil_op, ro.stencil_func);
760 disableStencilTest();
768 *currentElements += ro.size;
772 glDrawArrays(mode, *currentIndex, *currentElements);
778 if (m_state.lightmodel != 0) {
781 disableStencilTest();
785 m_render_objects.clear();
786 m_render_datas.clear();
787 m_render_datas2T.clear();
792 if ((x < 0) || (x >= (int32_t)m_target->w) ||
793 (y < 0) || (y >= (int32_t)m_target->h)) {
797 rd.vertex[0] =
static_cast<float>(x);
798 rd.vertex[1] =
static_cast<float>(y);
803 m_render_datas.push_back(rd);
805 RenderObject ro(GL_POINTS, 1);
806 m_render_objects.push_back(ro);
813 rd.vertex[0] =
static_cast<float>(p1.x);
814 rd.vertex[1] =
static_cast<float>(p1.y);
819 m_render_datas.push_back(rd);
821 rd.vertex[0] =
static_cast<float>(p2.x);
822 rd.vertex[1] =
static_cast<float>(p2.y);
823 m_render_datas.push_back(rd);
825 RenderObject ro(GL_LINES, 2);
826 m_render_objects.push_back(ro);
831 rd.vertex[0] =
static_cast<float>(p1.x);
832 rd.vertex[1] =
static_cast<float>(p1.y);
837 m_render_datas.push_back(rd);
839 rd.vertex[0] =
static_cast<float>(p2.x);
840 rd.vertex[1] =
static_cast<float>(p2.y);
841 m_render_datas.push_back(rd);
843 rd.vertex[0] =
static_cast<float>(p3.x);
844 rd.vertex[1] =
static_cast<float>(p3.y);
845 m_render_datas.push_back(rd);
847 RenderObject ro(GL_TRIANGLES, 3);
848 m_render_objects.push_back(ro);
853 rd.vertex[0] =
static_cast<float>(p.x);
854 rd.vertex[1] =
static_cast<float>(p.y);
859 m_render_datas.push_back(rd);
860 rd.vertex[0] =
static_cast<float>(p.x+w);
862 m_render_datas.push_back(rd);
863 rd.vertex[1] =
static_cast<float>(p.y+h);
865 m_render_datas.push_back(rd);
866 rd.vertex[0] =
static_cast<float>(p.x);
867 m_render_datas.push_back(rd);
869 RenderObject ro(GL_LINE_LOOP, 4);
870 m_render_objects.push_back(ro);
875 rd.vertex[0] =
static_cast<float>(p.x);
876 rd.vertex[1] =
static_cast<float>(p.y);
881 m_render_datas.push_back(rd);
883 rd.vertex[1] =
static_cast<float>(p.y+h);
884 m_render_datas.push_back(rd);
886 rd.vertex[0] =
static_cast<float>(p.x+w);
887 m_render_datas.push_back(rd);
889 rd.vertex[1] =
static_cast<float>(p.y);
890 m_render_datas.push_back(rd);
892 RenderObject ro(GL_QUADS, 4);
893 m_render_objects.push_back(ro);
898 rd.vertex[0] =
static_cast<float>(p1.x);
899 rd.vertex[1] =
static_cast<float>(p1.y);
904 m_render_datas.push_back(rd);
906 rd.vertex[0] =
static_cast<float>(p2.x);
907 rd.vertex[1] =
static_cast<float>(p2.y);
908 m_render_datas.push_back(rd);
910 rd.vertex[0] =
static_cast<float>(p3.x);
911 rd.vertex[1] =
static_cast<float>(p3.y);
912 m_render_datas.push_back(rd);
914 rd.vertex[0] =
static_cast<float>(p4.x);
915 rd.vertex[1] =
static_cast<float>(p4.y);
916 m_render_datas.push_back(rd);
918 RenderObject ro(GL_QUADS, 4);
919 m_render_objects.push_back(ro);
924 rd.vertex[0] =
static_cast<float>(p.x-size);
925 rd.vertex[1] =
static_cast<float>(p.y+size);
930 m_render_datas.push_back(rd);
932 rd.vertex[0] =
static_cast<float>(p.x+size);
933 m_render_datas.push_back(rd);
935 rd.vertex[1] =
static_cast<float>(p.y-size);
936 m_render_datas.push_back(rd);
938 rd.vertex[0] =
static_cast<float>(p.x-size);
939 m_render_datas.push_back(rd);
941 RenderObject ro(GL_LINE_LOOP, 4);
942 m_render_objects.push_back(ro);
946 const float step = Mathf::twoPi()/subdivisions;
948 for(
float angle=0; angle<=Mathf::twoPi(); angle+=step){
949 rd.vertex[0] =
static_cast<float>(p.x);
950 rd.vertex[1] =
static_cast<float>(p.y);
954 rd.color[3] = intensity;
955 m_render_datas.push_back(rd);
957 rd.vertex[0] = radius*Mathf::Cos(angle+step)*xstretch + p.x;
958 rd.vertex[1] = radius*Mathf::Sin(angle+step)*ystretch + p.y;
963 m_render_datas.push_back(rd);
965 rd.vertex[0] = radius*Mathf::Cos(angle)*xstretch + p.x;
966 rd.vertex[1] = radius*Mathf::Sin(angle)*ystretch + p.y;
967 m_render_datas.push_back(rd);
969 RenderObject ro(GL_TRIANGLES, 3);
970 m_render_objects.push_back(ro);
977 rd.vertex[0] =
static_cast<float>(rect.
x);
978 rd.vertex[1] =
static_cast<float>(rect.
y);
985 m_render_datas.push_back(rd);
987 rd.vertex[0] =
static_cast<float>(rect.
x);
988 rd.vertex[1] =
static_cast<float>(rect.
y+rect.
h);
990 m_render_datas.push_back(rd);
992 rd.vertex[0] =
static_cast<float>(rect.
x+rect.
w);
993 rd.vertex[1] =
static_cast<float>(rect.
y+rect.
h);
995 m_render_datas.push_back(rd);
997 rd.vertex[0] =
static_cast<float>(rect.
x+rect.
w);
998 rd.vertex[1] =
static_cast<float>(rect.
y);
1000 m_render_datas.push_back(rd);
1002 RenderObject ro(GL_QUADS, 4,
id);
1003 m_render_objects.push_back(ro);
1006 rd.vertex[0] =
static_cast<float>(rect.
x);
1007 rd.vertex[1] =
static_cast<float>(rect.
y);
1008 rd.texel[0] = st[0];
1009 rd.texel[1] = st[1];
1015 rd.color[3] = alpha;
1016 m_render_datas2T.push_back(rd);
1018 rd.vertex[0] =
static_cast<float>(rect.
x);
1019 rd.vertex[1] =
static_cast<float>(rect.
y+rect.
h);
1020 rd.texel[1] = st[3];
1022 m_render_datas2T.push_back(rd);
1024 rd.vertex[0] =
static_cast<float>(rect.
x+rect.
w);
1025 rd.vertex[1] =
static_cast<float>(rect.
y+rect.
h);
1026 rd.texel[0] = st[2];
1028 m_render_datas2T.push_back(rd);
1030 rd.vertex[0] =
static_cast<float>(rect.
x+rect.
w);
1031 rd.vertex[1] =
static_cast<float>(rect.
y);
1032 rd.texel[1] = st[1];
1034 m_render_datas2T.push_back(rd);
1036 RenderObject ro(GL_QUADS, 4,
id);
1037 ro.multitextured =
true;
1041 m_render_objects.push_back(ro);
1045 void RenderBackendOpenGL::prepareForOverlays() {
1046 glActiveTexture(GL_TEXTURE1);
1047 glEnable(GL_TEXTURE_2D);
1049 if(m_mask_overlays == 0) {
1051 glGenTextures(1, &m_mask_overlays);
1053 uint8_t dummydata[3] = {127, 127, 127};
1054 glBindTexture(GL_TEXTURE_2D, m_mask_overlays);
1055 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1056 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1057 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1058 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1059 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1, 1, 0,
1060 GL_RGB, GL_UNSIGNED_BYTE, dummydata);
1062 glBindTexture(GL_TEXTURE_2D, m_mask_overlays);
1065 m_state.texture[1] = m_mask_overlays;
1067 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
1068 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
1069 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
1072 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE0);
1073 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE0);
1074 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
1075 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
1082 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT);
1083 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
1086 glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_TEXTURE1);
1087 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
1090 glActiveTexture(GL_TEXTURE1);
1091 glDisable(GL_TEXTURE_2D);
1092 glActiveTexture(GL_TEXTURE0);
1099 const uint32_t swidth = getWidth();
1100 const uint32_t sheight = getHeight();
1103 SDL_Surface *surface = SDL_CreateRGBSurface(SDL_SWSURFACE, swidth, sheight, 24,
1104 RMASK, GMASK, BMASK, NULLMASK);
1110 SDL_LockSurface(surface);
1111 pixels =
new uint8_t[swidth * sheight * 3];
1112 glReadPixels(0, 0, swidth, sheight, GL_RGB, GL_UNSIGNED_BYTE, reinterpret_cast<GLvoid*>(pixels));
1113 uint8_t *imagepixels =
reinterpret_cast<uint8_t*
>(surface->pixels);
1115 for (int32_t y = (sheight - 1); y >= 0; --y) {
1116 uint8_t *rowbegin = pixels + y * swidth * 3;
1117 uint8_t *rowend = rowbegin + swidth * 3;
1119 std::copy(rowbegin, rowend, imagepixels);
1122 imagepixels += surface->pitch;
1125 SDL_UnlockSurface(surface);
1128 SDL_FreeSurface(surface);
1133 const uint32_t swidth = getWidth();
1134 const uint32_t sheight = getHeight();
1135 const bool same_size = (width == swidth && height == sheight);
1137 if (width < 1 || height < 1) {
1148 SDL_Surface* src = SDL_CreateRGBSurface(SDL_SWSURFACE, swidth, sheight, 32,
1149 RMASK, GMASK, BMASK, AMASK);
1155 if (SDL_MUSTLOCK(src)) {
1156 SDL_LockSurface(src);
1158 pixels =
new uint8_t[swidth * sheight * 4];
1159 glReadPixels(0, 0, swidth, sheight, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<GLvoid*>(pixels));
1161 uint8_t* imagepixels =
reinterpret_cast<uint8_t*
>(src->pixels);
1163 for (int32_t y = (sheight - 1); y >= 0; --y) {
1164 uint8_t *rowbegin = pixels + y * swidth * 4;
1165 uint8_t *rowend = rowbegin + swidth * 4;
1167 std::copy(rowbegin, rowend, imagepixels);
1170 imagepixels += src->pitch;
1174 SDL_Surface* dst = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32,
1175 RMASK, GMASK, BMASK, AMASK);
1177 uint32_t* src_pointer =
static_cast<uint32_t*
>(src->pixels);
1178 uint32_t* src_help_pointer = src_pointer;
1179 uint32_t* dst_pointer =
static_cast<uint32_t*
>(dst->pixels);
1181 int32_t x, y, *sx_ca, *sy_ca;
1182 int32_t sx =
static_cast<int32_t
>(0xffff * src->w / dst->w);
1183 int32_t sy =
static_cast<int32_t
>(0xffff * src->h / dst->h);
1188 int32_t* sx_a =
new int32_t[dst->w + 1];
1190 for (x = 0; x <= dst->w; x++) {
1197 int32_t* sy_a =
new int32_t[dst->h + 1];
1199 for (y = 0; y <= dst->h; y++) {
1209 if (SDL_MUSTLOCK(dst)) {
1210 SDL_LockSurface(dst);
1213 for (y = 0; y < dst->h; y++) {
1214 src_pointer = src_help_pointer;
1216 for (x = 0; x < dst->w; x++) {
1217 *dst_pointer = *src_pointer;
1219 src_pointer += (*sx_ca >> 16);
1223 src_help_pointer = (uint32_t*)((uint8_t*)src_help_pointer + (*sy_ca >> 16) * src->pitch);
1226 if (SDL_MUSTLOCK(dst)) {
1227 SDL_UnlockSurface(dst);
1229 if (SDL_MUSTLOCK(src)) {
1230 SDL_UnlockSurface(src);
1236 SDL_FreeSurface(src);
1237 SDL_FreeSurface(dst);
1244 glScissor(cliparea.
x, getHeight() - cliparea.
y - cliparea.
h, cliparea.
w, cliparea.
h);
1246 if (m_isbackgroundcolor) {
1247 float red = float(m_backgroundcolor.r/255.0);
1248 float green = float(m_backgroundcolor.g/255.0);
1249 float blue = float(m_backgroundcolor.b/255.0);
1250 glClearColor(red, green, blue, 0.0);
1251 m_isbackgroundcolor =
false;
1253 glClear(GL_COLOR_BUFFER_BIT);
1259 m_target_discard = discard;
1263 m_target = m_img_target->getSurface();
1267 GLuint targetid = glimage->getTexId();
1268 uint32_t w = m_img_target->getWidth();
1269 uint32_t h = m_img_target->getHeight();
1272 if(glimage->isCompressed()) {
1273 bindTexture(targetid);
1274 GLubyte* pixels =
new GLubyte[w*h*4];
1276 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1277 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1279 glimage->setCompressed(
false);
1283 if (GLEE_EXT_framebuffer_object && m_useframebuffer) {
1284 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo_id);
1285 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
1286 GL_TEXTURE_2D, targetid, 0);
1289 glViewport(0, 0, w, h);
1290 glMatrixMode(GL_PROJECTION);
1293 glOrtho(0, w, 0, h, -1, 1);
1294 glMatrixMode(GL_MODELVIEW);
1296 glCullFace(GL_FRONT);
1298 if (m_target_discard) {
1299 glClear(GL_COLOR_BUFFER_BIT);
1300 }
else if (!m_target_discard && (!GLEE_EXT_framebuffer_object || !m_useframebuffer)) {
1303 static_cast<GLImage*
>(m_img_target.
get())->getTexCoords(), 255, 0);
1308 assert(m_target != m_screen);
1313 if (GLEE_EXT_framebuffer_object && m_useframebuffer) {
1314 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1316 bindTexture(0, static_cast<GLImage*>(m_img_target.
get())->getTexId());
1317 glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0,
1318 m_img_target->getWidth(), m_img_target->getHeight(), 0);
1321 m_target = m_screen;
1322 glViewport(0, 0, m_screen->w, m_screen->h);
1323 glMatrixMode(GL_PROJECTION);
1325 glOrtho(0, m_screen->w, m_screen->h, 0, -1, 1);
1326 glMatrixMode(GL_MODELVIEW);
1327 glCullFace(GL_BACK);