21 #include "../../SDL_internal.h"
23 #if SDL_VIDEO_RENDER_OGL_ES && !SDL_RENDER_DISABLED
27 #include "../SDL_sysrender.h"
33 #define RENDERER_CONTEXT_MAJOR 1
34 #define RENDERER_CONTEXT_MINOR 1
36 #if defined(SDL_VIDEO_DRIVER_PANDORA)
53 static const float inv255f = 1.0f / 255.0f;
55 typedef struct GLES_FBOList GLES_FBOList;
80 } GLES_DrawStateCache;
86 #define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
87 #define SDL_PROC_OES SDL_PROC
91 SDL_bool GL_OES_framebuffer_object_supported;
95 SDL_bool GL_OES_blend_func_separate_supported;
96 SDL_bool GL_OES_blend_equation_separate_supported;
97 SDL_bool GL_OES_blend_subtract_supported;
99 GLES_DrawStateCache drawstate;
122 error =
"GL_NO_ERROR";
125 error =
"GL_INVALID_ENUM";
128 error =
"GL_INVALID_VALUE";
131 error =
"GL_INVALID_OPERATION";
134 error =
"GL_STACK_OVERFLOW";
137 error =
"GL_STACK_UNDERFLOW";
140 error =
"GL_OUT_OF_MEMORY";
149 static int GLES_LoadFunctions(GLES_RenderData *
data)
151 #if SDL_VIDEO_DRIVER_UIKIT
152 #define __SDL_NOGETPROCADDR__
153 #elif SDL_VIDEO_DRIVER_ANDROID
154 #define __SDL_NOGETPROCADDR__
155 #elif SDL_VIDEO_DRIVER_PANDORA
156 #define __SDL_NOGETPROCADDR__
159 #ifdef __SDL_NOGETPROCADDR__
160 #define SDL_PROC(ret,func,params) data->func=func;
161 #define SDL_PROC_OES(ret,func,params) data->func=func;
163 #define SDL_PROC(ret,func,params) \
165 data->func = SDL_GL_GetProcAddress(#func); \
166 if ( ! data->func ) { \
167 return SDL_SetError("Couldn't load GLES function %s: %s", #func, SDL_GetError()); \
170 #define SDL_PROC_OES(ret,func,params) \
172 data->func = SDL_GL_GetProcAddress(#func); \
182 static GLES_FBOList *
265 return GL_FUNC_ADD_OES;
267 return GL_FUNC_SUBTRACT_OES;
269 return GL_FUNC_REVERSE_SUBTRACT_OES;
294 if ((srcColorFactor != srcAlphaFactor || dstColorFactor != dstAlphaFactor) && !
data->GL_OES_blend_func_separate_supported) {
297 if (colorOperation != alphaOperation && !
data->GL_OES_blend_equation_separate_supported) {
307 power_of_2(
int input)
321 GLES_TextureData *
data;
324 int texture_w, texture_h;
356 if (!renderdata->GL_OES_framebuffer_object_supported) {
358 return SDL_SetError(
"GL_OES_framebuffer_object not supported");
366 renderdata->glGetError();
368 renderdata->glGenTextures(1, &
data->texture);
369 result = renderdata->glGetError();
372 return GLES_SetError(
"glGenTextures()",
result);
377 texture_w = power_of_2(
texture->w);
378 texture_h = power_of_2(
texture->h);
385 renderdata->glBindTexture(
data->type,
data->texture);
394 renderdata->drawstate.texture =
texture;
395 renderdata->drawstate.texturing =
SDL_FALSE;
397 result = renderdata->glGetError();
400 return GLES_SetError(
"glTexImage2D()",
result);
412 GLES_TextureData *
data = (GLES_TextureData *)
texture->driverdata;
428 if (pitch != srcPitch) {
443 renderdata->glGetError();
444 renderdata->glEnable(
data->type);
445 renderdata->glBindTexture(
data->type,
data->texture);
447 renderdata->glTexSubImage2D(
data->type,
456 renderdata->glDisable(
data->type);
459 renderdata->drawstate.texture =
texture;
460 renderdata->drawstate.texturing =
SDL_FALSE;
472 GLES_TextureData *
data = (GLES_TextureData *)
texture->driverdata;
477 *pitch =
data->pitch;
484 GLES_TextureData *
data = (GLES_TextureData *)
texture->driverdata;
499 GLES_TextureData *texturedata =
NULL;
502 if (!
data->GL_OES_framebuffer_object_supported) {
503 return SDL_SetError(
"Can't enable render target support in this renderer");
509 data->glBindFramebufferOES(GL_FRAMEBUFFER_OES,
data->window_framebuffer);
513 texturedata = (GLES_TextureData *)
texture->driverdata;
514 data->glBindFramebufferOES(GL_FRAMEBUFFER_OES, texturedata->fbo->FBO);
516 data->glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, texturedata->type, texturedata->texture, 0);
518 status =
data->glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
519 if (status != GL_FRAMEBUFFER_COMPLETE_OES) {
520 return SDL_SetError(
"glFramebufferTexture2DOES() failed");
586 GLES_TextureData *texturedata = (GLES_TextureData *)
texture->driverdata;
587 GLfloat minx, miny, maxx, maxy;
588 GLfloat minu, maxu, minv, maxv;
599 maxx = dstrect->
x + dstrect->
w;
600 maxy = dstrect->
y + dstrect->
h;
603 minu *= texturedata->texw;
605 maxu *= texturedata->texw;
607 minv *= texturedata->texh;
609 maxv *= texturedata->texh;
637 GLES_TextureData *texturedata = (GLES_TextureData *)
texture->driverdata;
638 GLfloat minx, miny, maxx, maxy;
640 GLfloat minu, maxu, minv, maxv;
651 minx = dstrect->
w - centerx;
656 maxx = dstrect->
w - centerx;
660 miny = dstrect->
h - centery;
665 maxy = dstrect->
h - centery;
669 minu *= texturedata->texw;
671 maxu *= texturedata->texw;
673 minv *= texturedata->texh;
675 maxv *= texturedata->texh;
697 *(verts++) = (
GLfloat) dstrect->
x + centerx;
698 *(verts++) = (
GLfloat) dstrect->
y + centery;
719 data->glColor4f(fr, fg, fb, fa);
723 if (
data->drawstate.viewport_dirty) {
727 data->glLoadIdentity();
741 if (
data->drawstate.cliprect_enabled_dirty) {
742 if (
data->drawstate.cliprect_enabled) {
750 if (
data->drawstate.cliprect_enabled &&
data->drawstate.cliprect_dirty) {
760 if (blend !=
data->drawstate.blend) {
765 if (
data->GL_OES_blend_func_separate_supported) {
774 if (
data->GL_OES_blend_equation_separate_supported) {
777 }
else if (
data->GL_OES_blend_subtract_supported) {
781 data->drawstate.blend = blend;
804 GLES_TextureData *texturedata = (GLES_TextureData *)
texture->driverdata;
816 if (GLES_ActivateRenderer(
renderer) < 0) {
860 if (
color !=
data->drawstate.clear_color) {
865 data->glClearColor(fr, fg, fb, fa);
869 if (
data->drawstate.cliprect_enabled) {
893 if (
count > 2 && (verts[0] == verts[(
count-1)*2]) && (verts[1] == verts[(
count*2)-1])) {
918 SetCopyState(
data, cmd);
927 const GLfloat translatex = verts[16];
928 const GLfloat translatey = verts[17];
930 SetCopyState(
data, cmd);
935 data->glPushMatrix();
936 data->glTranslatef(translatex, translatey, 0.0
f);
999 temp_format, temp_pixels, temp_pitch,
1000 pixel_format,
pixels, pitch);
1019 GLES_TextureData *
data = (GLES_TextureData *)
texture->driverdata;
1023 if (renderdata->drawstate.texture ==
texture) {
1024 renderdata->drawstate.texture =
NULL;
1026 if (renderdata->drawstate.target ==
texture) {
1027 renderdata->drawstate.target =
NULL;
1033 if (
data->texture) {
1034 renderdata->glDeleteTextures(1, &
data->texture);
1047 if (
data->context) {
1048 while (
data->framebuffers) {
1049 GLES_FBOList *nextnode =
data->framebuffers->next;
1050 data->glDeleteFramebuffersOES(1, &
data->framebuffers->FBO);
1052 data->framebuffers = nextnode;
1064 GLES_TextureData *texturedata = (GLES_TextureData *)
texture->driverdata;
1068 data->glBindTexture(texturedata->type, texturedata->texture);
1074 *texw = (float)texturedata->texw;
1077 *texh = (float)texturedata->texh;
1086 GLES_TextureData *texturedata = (GLES_TextureData *)
texture->driverdata;
1088 data->glDisable(texturedata->type);
1100 GLES_RenderData *
data;
1103 int profile_mask = 0, major = 0, minor = 0;
1165 if (!
data->context) {
1174 if (GLES_LoadFunctions(
data) < 0) {
1201 data->glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &
value);
1210 data->GL_OES_blend_equation_separate_supported =
SDL_TRUE;
1221 data->glLoadIdentity();
1226 data->glClearColor(1.0
f, 1.0
f, 1.0
f, 1.0
f);
1229 data->drawstate.color = 0xFFFFFFFF;
1230 data->drawstate.clear_color = 0xFFFFFFFF;
1235 if (changed_window) {
1246 GLES_CreateRenderer,