21 #include "../../SDL_internal.h"
23 #if SDL_VIDEO_RENDER_OGL && !SDL_RENDER_DISABLED
29 #include "../SDL_sysrender.h"
33 #include <OpenGL/OpenGL.h>
40 #define RENDERER_CONTEXT_MAJOR 2
41 #define RENDERER_CONTEXT_MINOR 1
52 static const float inv255f = 1.0f / 255.0f;
65 const Uint8 *Yplane,
int Ypitch,
66 const Uint8 *Uplane,
int Upitch,
67 const Uint8 *Vplane,
int Vpitch);
105 typedef struct GL_FBOList GL_FBOList;
119 SDL_bool GL_ARB_debug_output_supported;
121 char **error_messages;
123 GLvoid *next_error_userparam;
125 SDL_bool GL_ARB_texture_non_power_of_two_supported;
126 SDL_bool GL_ARB_texture_rectangle_supported;
133 SDL_bool GL_EXT_framebuffer_object_supported;
137 #define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
142 SDL_bool GL_ARB_multitexture_supported;
144 GLint num_texture_units;
146 PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT;
147 PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT;
148 PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT;
149 PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT;
150 PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT;
179 GL_TranslateError (
GLenum error)
181 #define GL_ERROR_TRANSLATE(e) case e: return #e;
194 #undef GL_ERROR_TRANSLATE
202 if (!
data->debug_enabled)
206 if (
data->GL_ARB_debug_output_supported) {
209 for (
i = 0;
i <
data->errors; ++
i) {
225 GL_CheckAllErrors (
const char *prefix,
SDL_Renderer *
renderer,
const char *file,
int line,
const char *
function)
230 if (!
data->debug_enabled)
234 if (
data->GL_ARB_debug_output_supported) {
237 for (
i = 0;
i <
data->errors; ++
i) {
238 SDL_SetError(
"%s: %s (%d): %s %s", prefix, file, line,
function,
data->error_messages[
i]);
248 if (prefix ==
NULL || prefix[0] ==
'\0') {
251 SDL_SetError(
"%s: %s (%d): %s %s (0x%X)", prefix, file, line,
function, GL_TranslateError(error), error);
262 #define GL_CheckError(prefix, renderer)
264 #define GL_CheckError(prefix, renderer) GL_CheckAllErrors(prefix, renderer, SDL_FILE, SDL_LINE, SDL_FUNCTION)
268 GL_LoadFunctions(GL_RenderData *
data)
270 #ifdef __SDL_NOGETPROCADDR__
271 #define SDL_PROC(ret,func,params) data->func=func;
273 #define SDL_PROC(ret,func,params) \
275 data->func = SDL_GL_GetProcAddress(#func); \
276 if ( ! data->func ) { \
277 return SDL_SetError("Couldn't load GL function %s: %s", #func, SDL_GetError()); \
294 if (SDL_CurrentContext !=
data->context ||
299 SDL_CurrentContext =
data->context;
322 data->current.color = 0xffffffff;
331 data->glLoadIdentity();
344 int errors =
data->errors + 1;
345 char **error_messages =
SDL_realloc(
data->error_messages, errors *
sizeof(*
data->error_messages));
346 if (error_messages) {
347 data->errors = errors;
348 data->error_messages = error_messages;
354 if (
data->next_error_callback) {
394 int profile_mask = 0, major = 0, minor = 0;
457 if (!
data->context) {
466 if (GL_LoadFunctions(
data) < 0) {
493 PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARBFunc = (PFNGLDEBUGMESSAGECALLBACKARBPROC)
SDL_GL_GetProcAddress(
"glDebugMessageCallbackARB");
498 glDebugMessageCallbackARBFunc(GL_HandleDebugMessage,
renderer);
505 data->GL_ARB_texture_non_power_of_two_supported =
SDL_TRUE;
510 if (
data->GL_ARB_texture_rectangle_supported) {
523 if (
data->glActiveTextureARB) {
534 data->shaders ?
"ENABLED" :
"DISABLED");
537 if (
data->shaders &&
data->num_texture_units >= 3) {
550 data->glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)
552 data->glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)
554 data->glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)
556 data->glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)
558 data->glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)
570 if (changed_window) {
587 SDL_CurrentContext =
NULL;
658 if (colorOperation != alphaOperation) {
665 power_of_2(
int input)
676 convert_format(GL_RenderData *renderdata,
Uint32 pixel_format,
679 switch (pixel_format) {
710 GL_TextureData *
data;
713 int texture_w, texture_h;
719 !renderdata->GL_EXT_framebuffer_object_supported) {
720 return SDL_SetError(
"Render targets not supported by OpenGL");
725 return SDL_SetError(
"Texture format %s not supported by OpenGL",
762 renderdata->glGenTextures(1, &
data->texture);
763 if (GL_CheckError(
"glGenTextures()",
renderer) < 0) {
772 if (renderdata->GL_ARB_texture_non_power_of_two_supported) {
778 }
else if (renderdata->GL_ARB_texture_rectangle_supported) {
786 texture_w = power_of_2(
texture->w);
787 texture_h = power_of_2(
texture->h);
795 renderdata->glEnable(
data->type);
796 renderdata->glBindTexture(
data->type,
data->texture);
809 #ifndef GL_TEXTURE_STORAGE_HINT_APPLE
810 #define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC
812 #ifndef STORAGE_CACHED_APPLE
813 #define STORAGE_CACHED_APPLE 0x85BE
815 #ifndef STORAGE_SHARED_APPLE
816 #define STORAGE_SHARED_APPLE 0x85BF
842 renderdata->glDisable(
data->type);
843 if (GL_CheckError(
"glTexImage2D()",
renderer) < 0) {
851 renderdata->glGenTextures(1, &
data->utexture);
852 renderdata->glGenTextures(1, &
data->vtexture);
853 renderdata->glEnable(
data->type);
855 renderdata->glBindTexture(
data->type,
data->utexture);
867 renderdata->glBindTexture(
data->type,
data->vtexture);
879 renderdata->glDisable(
data->type);
886 renderdata->glGenTextures(1, &
data->utexture);
887 renderdata->glEnable(
data->type);
889 renderdata->glBindTexture(
data->type,
data->utexture);
900 renderdata->glDisable(
data->type);
911 GL_TextureData *
data = (GL_TextureData *)
texture->driverdata;
918 renderdata->glEnable(
data->type);
919 renderdata->glBindTexture(
data->type,
data->texture);
931 renderdata->glBindTexture(
data->type,
data->vtexture);
933 renderdata->glBindTexture(
data->type,
data->utexture);
942 renderdata->glBindTexture(
data->type,
data->utexture);
944 renderdata->glBindTexture(
data->type,
data->vtexture);
956 renderdata->glBindTexture(
data->type,
data->utexture);
961 renderdata->glDisable(
data->type);
963 return GL_CheckError(
"glTexSubImage2D()",
renderer);
969 const Uint8 *Yplane,
int Ypitch,
970 const Uint8 *Uplane,
int Upitch,
971 const Uint8 *Vplane,
int Vpitch)
974 GL_TextureData *
data = (GL_TextureData *)
texture->driverdata;
978 renderdata->glEnable(
data->type);
979 renderdata->glBindTexture(
data->type,
data->texture);
987 renderdata->glBindTexture(
data->type,
data->utexture);
990 data->format,
data->formattype, Uplane);
993 renderdata->glBindTexture(
data->type,
data->vtexture);
996 data->format,
data->formattype, Vplane);
997 renderdata->glDisable(
data->type);
999 return GL_CheckError(
"glTexSubImage2D()",
renderer);
1006 GL_TextureData *
data = (GL_TextureData *)
texture->driverdata;
1012 *pitch =
data->pitch;
1019 GL_TextureData *
data = (GL_TextureData *)
texture->driverdata;
1034 GL_TextureData *texturedata;
1039 if (!
data->GL_EXT_framebuffer_object_supported) {
1040 return SDL_SetError(
"Render targets not supported by OpenGL");
1048 texturedata = (GL_TextureData *)
texture->driverdata;
1055 return SDL_SetError(
"glFramebufferTexture2DEXT() failed");
1065 if (SDL_CurrentContext !=
data->context) {
1082 data->glLoadIdentity();
1100 return GL_CheckError(
"",
renderer);
1245 #if defined(__MACOSX__) || defined(__WIN32__)
1264 #if defined(__MACOSX__) || defined(__WIN32__)
1276 }
else if (
x2 >
x1) {
1281 }
else if (
y2 >
y1) {
1287 return GL_CheckError(
"",
renderer);
1303 return GL_CheckError(
"",
renderer);
1310 GL_TextureData *texturedata = (GL_TextureData *)
texture->driverdata;
1312 data->glEnable(texturedata->type);
1313 if (texturedata->yuv) {
1315 data->glBindTexture(texturedata->type, texturedata->vtexture);
1318 data->glBindTexture(texturedata->type, texturedata->utexture);
1322 if (texturedata->nv12) {
1324 data->glBindTexture(texturedata->type, texturedata->utexture);
1328 data->glBindTexture(texturedata->type, texturedata->texture);
1333 GL_SetColor(
data, 255, 255, 255, 255);
1338 if (texturedata->yuv || texturedata->nv12) {
1341 if (texturedata->yuv) {
1350 if (texturedata->yuv) {
1359 if (texturedata->yuv) {
1368 return SDL_SetError(
"Unsupported YUV conversion mode");
1381 GL_TextureData *texturedata = (GL_TextureData *)
texture->driverdata;
1382 GLfloat minx, miny, maxx, maxy;
1383 GLfloat minu, maxu, minv, maxv;
1393 maxx = dstrect->
x + dstrect->
w;
1394 maxy = dstrect->
y + dstrect->
h;
1397 minu *= texturedata->texw;
1399 maxu *= texturedata->texw;
1401 minv *= texturedata->texh;
1403 maxv *= texturedata->texh;
1406 data->glTexCoord2f(minu, minv);
1407 data->glVertex2f(minx, miny);
1408 data->glTexCoord2f(maxu, minv);
1409 data->glVertex2f(maxx, miny);
1410 data->glTexCoord2f(minu, maxv);
1411 data->glVertex2f(minx, maxy);
1412 data->glTexCoord2f(maxu, maxv);
1413 data->glVertex2f(maxx, maxy);
1416 data->glDisable(texturedata->type);
1418 return GL_CheckError(
"",
renderer);
1427 GL_TextureData *texturedata = (GL_TextureData *)
texture->driverdata;
1428 GLfloat minx, miny, maxx, maxy;
1430 GLfloat minu, maxu, minv, maxv;
1438 centerx = center->
x;
1439 centery = center->
y;
1442 minx = dstrect->
w - centerx;
1447 maxx = dstrect->
w - centerx;
1451 miny = dstrect->
h - centery;
1456 maxy = dstrect->
h - centery;
1460 minu *= texturedata->texw;
1462 maxu *= texturedata->texw;
1464 minv *= texturedata->texh;
1466 maxv *= texturedata->texh;
1469 data->glPushMatrix();
1474 data->glTexCoord2f(minu, minv);
1475 data->glVertex2f(minx, miny);
1476 data->glTexCoord2f(maxu, minv);
1477 data->glVertex2f(maxx, miny);
1478 data->glTexCoord2f(minu, maxv);
1479 data->glVertex2f(minx, maxy);
1480 data->glTexCoord2f(maxu, maxv);
1481 data->glVertex2f(maxx, maxy);
1483 data->glPopMatrix();
1485 data->glDisable(texturedata->type);
1487 return GL_CheckError(
"",
renderer);
1507 return SDL_SetError(
"Texture format %s not supported by OpenGL",
1530 if (GL_CheckError(
"glReadPixels()",
renderer) < 0) {
1553 temp_format, temp_pixels, temp_pitch,
1554 pixel_format,
pixels, pitch);
1572 GL_TextureData *
data = (GL_TextureData *)
texture->driverdata;
1579 if (
data->texture) {
1580 renderdata->glDeleteTextures(1, &
data->texture);
1583 renderdata->glDeleteTextures(1, &
data->utexture);
1584 renderdata->glDeleteTextures(1, &
data->vtexture);
1603 if (
data->GL_ARB_debug_output_supported) {
1604 PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARBFunc = (PFNGLDEBUGMESSAGECALLBACKARBPROC)
SDL_GL_GetProcAddress(
"glDebugMessageCallbackARB");
1608 glDebugMessageCallbackARBFunc(
data->next_error_callback,
data->next_error_userparam);
1610 if (
data->shaders) {
1613 if (
data->context) {
1614 while (
data->framebuffers) {
1615 GL_FBOList *nextnode =
data->framebuffers->next;
1617 data->glDeleteFramebuffersEXT(1, &
data->framebuffers->FBO);
1620 data->framebuffers = nextnode;
1633 GL_TextureData *texturedata = (GL_TextureData *)
texture->driverdata;
1636 data->glEnable(texturedata->type);
1637 if (texturedata->yuv) {
1639 data->glBindTexture(texturedata->type, texturedata->vtexture);
1642 data->glBindTexture(texturedata->type, texturedata->utexture);
1646 data->glBindTexture(texturedata->type, texturedata->texture);
1648 if(texw) *texw = (float)texturedata->texw;
1649 if(texh) *texh = (float)texturedata->texh;
1658 GL_TextureData *texturedata = (GL_TextureData *)
texture->driverdata;
1661 if (texturedata->yuv) {
1663 data->glDisable(texturedata->type);
1666 data->glDisable(texturedata->type);
1671 data->glDisable(texturedata->type);