SDL  2.0
SDL_render_gl.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "../../SDL_internal.h"
22 
23 #if SDL_VIDEO_RENDER_OGL && !SDL_RENDER_DISABLED
24 
25 #include "SDL_hints.h"
26 #include "SDL_log.h"
27 #include "SDL_assert.h"
28 #include "SDL_opengl.h"
29 #include "../SDL_sysrender.h"
30 #include "SDL_shaders_gl.h"
31 
32 #ifdef __MACOSX__
33 #include <OpenGL/OpenGL.h>
34 #endif
35 
36 /* To prevent unnecessary window recreation,
37  * these should match the defaults selected in SDL_GL_ResetAttributes
38  */
39 
40 #define RENDERER_CONTEXT_MAJOR 2
41 #define RENDERER_CONTEXT_MINOR 1
42 
43 /* OpenGL renderer implementation */
44 
45 /* Details on optimizing the texture path on Mac OS X:
46  http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_texturedata/opengl_texturedata.html
47 */
48 
49 /* Used to re-create the window with OpenGL capability */
51 
52 static const float inv255f = 1.0f / 255.0f;
53 
54 static SDL_Renderer *GL_CreateRenderer(SDL_Window * window, Uint32 flags);
55 static void GL_WindowEvent(SDL_Renderer * renderer,
56  const SDL_WindowEvent *event);
57 static int GL_GetOutputSize(SDL_Renderer * renderer, int *w, int *h);
58 static SDL_bool GL_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode);
59 static int GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
60 static int GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
61  const SDL_Rect * rect, const void *pixels,
62  int pitch);
63 static int GL_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
64  const SDL_Rect * rect,
65  const Uint8 *Yplane, int Ypitch,
66  const Uint8 *Uplane, int Upitch,
67  const Uint8 *Vplane, int Vpitch);
68 static int GL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
69  const SDL_Rect * rect, void **pixels, int *pitch);
70 static void GL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
71 static int GL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture);
72 static int GL_UpdateViewport(SDL_Renderer * renderer);
73 static int GL_UpdateClipRect(SDL_Renderer * renderer);
74 static int GL_RenderClear(SDL_Renderer * renderer);
75 static int GL_RenderDrawPoints(SDL_Renderer * renderer,
76  const SDL_FPoint * points, int count);
77 static int GL_RenderDrawLines(SDL_Renderer * renderer,
78  const SDL_FPoint * points, int count);
79 static int GL_RenderFillRects(SDL_Renderer * renderer,
80  const SDL_FRect * rects, int count);
81 static int GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
82  const SDL_Rect * srcrect, const SDL_FRect * dstrect);
83 static int GL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
84  const SDL_Rect * srcrect, const SDL_FRect * dstrect,
85  const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip);
86 static int GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
87  Uint32 pixel_format, void * pixels, int pitch);
88 static void GL_RenderPresent(SDL_Renderer * renderer);
89 static void GL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture);
90 static void GL_DestroyRenderer(SDL_Renderer * renderer);
91 static int GL_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, float *texh);
92 static int GL_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture);
93 
95  GL_CreateRenderer,
96  {
97  "opengl",
99  1,
101  0,
102  0}
103 };
104 
105 typedef struct GL_FBOList GL_FBOList;
106 
107 struct GL_FBOList
108 {
109  Uint32 w, h;
110  GLuint FBO;
111  GL_FBOList *next;
112 };
113 
114 typedef struct
115 {
117 
118  SDL_bool debug_enabled;
119  SDL_bool GL_ARB_debug_output_supported;
120  int errors;
121  char **error_messages;
122  GLDEBUGPROCARB next_error_callback;
123  GLvoid *next_error_userparam;
124 
125  SDL_bool GL_ARB_texture_non_power_of_two_supported;
126  SDL_bool GL_ARB_texture_rectangle_supported;
127  struct {
129  Uint32 color;
131  } current;
132 
133  SDL_bool GL_EXT_framebuffer_object_supported;
134  GL_FBOList *framebuffers;
135 
136  /* OpenGL functions */
137 #define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
138 #include "SDL_glfuncs.h"
139 #undef SDL_PROC
140 
141  /* Multitexture support */
142  SDL_bool GL_ARB_multitexture_supported;
143  PFNGLACTIVETEXTUREARBPROC glActiveTextureARB;
144  GLint num_texture_units;
145 
146  PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT;
147  PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT;
148  PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT;
149  PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT;
150  PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT;
151 
152  /* Shader support */
154 
155 } GL_RenderData;
156 
157 typedef struct
158 {
159  GLuint texture;
160  GLenum type;
161  GLfloat texw;
162  GLfloat texh;
163  GLenum format;
164  GLenum formattype;
165  void *pixels;
166  int pitch;
167  SDL_Rect locked_rect;
168 
169  /* YUV texture support */
170  SDL_bool yuv;
171  SDL_bool nv12;
172  GLuint utexture;
173  GLuint vtexture;
174 
175  GL_FBOList *fbo;
176 } GL_TextureData;
177 
178 SDL_FORCE_INLINE const char*
179 GL_TranslateError (GLenum error)
180 {
181 #define GL_ERROR_TRANSLATE(e) case e: return #e;
182  switch (error) {
183  GL_ERROR_TRANSLATE(GL_INVALID_ENUM)
184  GL_ERROR_TRANSLATE(GL_INVALID_VALUE)
185  GL_ERROR_TRANSLATE(GL_INVALID_OPERATION)
186  GL_ERROR_TRANSLATE(GL_OUT_OF_MEMORY)
187  GL_ERROR_TRANSLATE(GL_NO_ERROR)
188  GL_ERROR_TRANSLATE(GL_STACK_OVERFLOW)
189  GL_ERROR_TRANSLATE(GL_STACK_UNDERFLOW)
190  GL_ERROR_TRANSLATE(GL_TABLE_TOO_LARGE)
191  default:
192  return "UNKNOWN";
193 }
194 #undef GL_ERROR_TRANSLATE
195 }
196 
197 SDL_FORCE_INLINE void
198 GL_ClearErrors(SDL_Renderer *renderer)
199 {
200  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
201 
202  if (!data->debug_enabled)
203  {
204  return;
205  }
206  if (data->GL_ARB_debug_output_supported) {
207  if (data->errors) {
208  int i;
209  for (i = 0; i < data->errors; ++i) {
210  SDL_free(data->error_messages[i]);
211  }
212  SDL_free(data->error_messages);
213 
214  data->errors = 0;
215  data->error_messages = NULL;
216  }
217  } else {
218  while (data->glGetError() != GL_NO_ERROR) {
219  continue;
220  }
221  }
222 }
223 
225 GL_CheckAllErrors (const char *prefix, SDL_Renderer *renderer, const char *file, int line, const char *function)
226 {
227  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
228  int ret = 0;
229 
230  if (!data->debug_enabled)
231  {
232  return 0;
233  }
234  if (data->GL_ARB_debug_output_supported) {
235  if (data->errors) {
236  int i;
237  for (i = 0; i < data->errors; ++i) {
238  SDL_SetError("%s: %s (%d): %s %s", prefix, file, line, function, data->error_messages[i]);
239  ret = -1;
240  }
241  GL_ClearErrors(renderer);
242  }
243  } else {
244  /* check gl errors (can return multiple errors) */
245  for (;;) {
246  GLenum error = data->glGetError();
247  if (error != GL_NO_ERROR) {
248  if (prefix == NULL || prefix[0] == '\0') {
249  prefix = "generic";
250  }
251  SDL_SetError("%s: %s (%d): %s %s (0x%X)", prefix, file, line, function, GL_TranslateError(error), error);
252  ret = -1;
253  } else {
254  break;
255  }
256  }
257  }
258  return ret;
259 }
260 
261 #if 0
262 #define GL_CheckError(prefix, renderer)
263 #elif defined(_MSC_VER) || defined(__WATCOMC__)
264 #define GL_CheckError(prefix, renderer) GL_CheckAllErrors(prefix, renderer, __FILE__, __LINE__, __FUNCTION__)
265 #else
266 #define GL_CheckError(prefix, renderer) GL_CheckAllErrors(prefix, renderer, __FILE__, __LINE__, __PRETTY_FUNCTION__)
267 #endif
268 
269 static int
270 GL_LoadFunctions(GL_RenderData * data)
271 {
272 #ifdef __SDL_NOGETPROCADDR__
273 #define SDL_PROC(ret,func,params) data->func=func;
274 #else
275 #define SDL_PROC(ret,func,params) \
276  do { \
277  data->func = SDL_GL_GetProcAddress(#func); \
278  if ( ! data->func ) { \
279  return SDL_SetError("Couldn't load GL function %s: %s", #func, SDL_GetError()); \
280  } \
281  } while ( 0 );
282 #endif /* __SDL_NOGETPROCADDR__ */
283 
284 #include "SDL_glfuncs.h"
285 #undef SDL_PROC
286  return 0;
287 }
288 
289 static SDL_GLContext SDL_CurrentContext = NULL;
290 
291 static int
292 GL_ActivateRenderer(SDL_Renderer * renderer)
293 {
294  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
295 
296  if (SDL_CurrentContext != data->context ||
297  SDL_GL_GetCurrentContext() != data->context) {
298  if (SDL_GL_MakeCurrent(renderer->window, data->context) < 0) {
299  return -1;
300  }
301  SDL_CurrentContext = data->context;
302 
303  GL_UpdateViewport(renderer);
304  }
305 
306  GL_ClearErrors(renderer);
307 
308  return 0;
309 }
310 
311 /* This is called if we need to invalidate all of the SDL OpenGL state */
312 static void
313 GL_ResetState(SDL_Renderer *renderer)
314 {
315  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
316 
317  if (SDL_GL_GetCurrentContext() == data->context) {
318  GL_UpdateViewport(renderer);
319  } else {
320  GL_ActivateRenderer(renderer);
321  }
322 
323  data->current.shader = SHADER_NONE;
324  data->current.color = 0xffffffff;
325  data->current.blendMode = SDL_BLENDMODE_INVALID;
326 
327  data->glDisable(GL_DEPTH_TEST);
328  data->glDisable(GL_CULL_FACE);
329  /* This ended up causing video discrepancies between OpenGL and Direct3D */
330  /* data->glEnable(GL_LINE_SMOOTH); */
331 
332  data->glMatrixMode(GL_MODELVIEW);
333  data->glLoadIdentity();
334 
335  GL_CheckError("", renderer);
336 }
337 
338 static void APIENTRY
339 GL_HandleDebugMessage(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char *message, const void *userParam)
340 {
341  SDL_Renderer *renderer = (SDL_Renderer *) userParam;
342  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
343 
344  if (type == GL_DEBUG_TYPE_ERROR_ARB) {
345  /* Record this error */
346  int errors = data->errors + 1;
347  char **error_messages = SDL_realloc(data->error_messages, errors * sizeof(*data->error_messages));
348  if (error_messages) {
349  data->errors = errors;
350  data->error_messages = error_messages;
351  data->error_messages[data->errors-1] = SDL_strdup(message);
352  }
353  }
354 
355  /* If there's another error callback, pass it along, otherwise log it */
356  if (data->next_error_callback) {
357  data->next_error_callback(source, type, id, severity, length, message, data->next_error_userparam);
358  } else {
359  if (type == GL_DEBUG_TYPE_ERROR_ARB) {
360  SDL_LogError(SDL_LOG_CATEGORY_RENDER, "%s", message);
361  } else {
362  SDL_LogDebug(SDL_LOG_CATEGORY_RENDER, "%s", message);
363  }
364  }
365 }
366 
367 static GL_FBOList *
368 GL_GetFBO(GL_RenderData *data, Uint32 w, Uint32 h)
369 {
370  GL_FBOList *result = data->framebuffers;
371 
372  while (result && ((result->w != w) || (result->h != h))) {
373  result = result->next;
374  }
375 
376  if (!result) {
377  result = SDL_malloc(sizeof(GL_FBOList));
378  if (result) {
379  result->w = w;
380  result->h = h;
381  data->glGenFramebuffersEXT(1, &result->FBO);
382  result->next = data->framebuffers;
383  data->framebuffers = result;
384  }
385  }
386  return result;
387 }
388 
389 SDL_Renderer *
390 GL_CreateRenderer(SDL_Window * window, Uint32 flags)
391 {
393  GL_RenderData *data;
394  GLint value;
395  Uint32 window_flags;
396  int profile_mask = 0, major = 0, minor = 0;
397  SDL_bool changed_window = SDL_FALSE;
398 
402 
403  window_flags = SDL_GetWindowFlags(window);
404  if (!(window_flags & SDL_WINDOW_OPENGL) ||
405  profile_mask == SDL_GL_CONTEXT_PROFILE_ES || major != RENDERER_CONTEXT_MAJOR || minor != RENDERER_CONTEXT_MINOR) {
406 
407  changed_window = SDL_TRUE;
409  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, RENDERER_CONTEXT_MAJOR);
410  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, RENDERER_CONTEXT_MINOR);
411 
412  if (SDL_RecreateWindow(window, window_flags | SDL_WINDOW_OPENGL) < 0) {
413  goto error;
414  }
415  }
416 
417  renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
418  if (!renderer) {
419  SDL_OutOfMemory();
420  goto error;
421  }
422 
423  data = (GL_RenderData *) SDL_calloc(1, sizeof(*data));
424  if (!data) {
425  GL_DestroyRenderer(renderer);
426  SDL_OutOfMemory();
427  goto error;
428  }
429 
430  renderer->WindowEvent = GL_WindowEvent;
431  renderer->GetOutputSize = GL_GetOutputSize;
432  renderer->SupportsBlendMode = GL_SupportsBlendMode;
433  renderer->CreateTexture = GL_CreateTexture;
434  renderer->UpdateTexture = GL_UpdateTexture;
435  renderer->UpdateTextureYUV = GL_UpdateTextureYUV;
436  renderer->LockTexture = GL_LockTexture;
437  renderer->UnlockTexture = GL_UnlockTexture;
438  renderer->SetRenderTarget = GL_SetRenderTarget;
439  renderer->UpdateViewport = GL_UpdateViewport;
440  renderer->UpdateClipRect = GL_UpdateClipRect;
441  renderer->RenderClear = GL_RenderClear;
442  renderer->RenderDrawPoints = GL_RenderDrawPoints;
443  renderer->RenderDrawLines = GL_RenderDrawLines;
444  renderer->RenderFillRects = GL_RenderFillRects;
445  renderer->RenderCopy = GL_RenderCopy;
446  renderer->RenderCopyEx = GL_RenderCopyEx;
447  renderer->RenderReadPixels = GL_RenderReadPixels;
448  renderer->RenderPresent = GL_RenderPresent;
449  renderer->DestroyTexture = GL_DestroyTexture;
450  renderer->DestroyRenderer = GL_DestroyRenderer;
451  renderer->GL_BindTexture = GL_BindTexture;
452  renderer->GL_UnbindTexture = GL_UnbindTexture;
453  renderer->info = GL_RenderDriver.info;
454  renderer->info.flags = SDL_RENDERER_ACCELERATED;
455  renderer->driverdata = data;
456  renderer->window = window;
457 
458  data->context = SDL_GL_CreateContext(window);
459  if (!data->context) {
460  GL_DestroyRenderer(renderer);
461  goto error;
462  }
463  if (SDL_GL_MakeCurrent(window, data->context) < 0) {
464  GL_DestroyRenderer(renderer);
465  goto error;
466  }
467 
468  if (GL_LoadFunctions(data) < 0) {
469  GL_DestroyRenderer(renderer);
470  goto error;
471  }
472 
473 #ifdef __MACOSX__
474  /* Enable multi-threaded rendering */
475  /* Disabled until Ryan finishes his VBO/PBO code...
476  CGLEnable(CGLGetCurrentContext(), kCGLCEMPEngine);
477  */
478 #endif
479 
480  if (flags & SDL_RENDERER_PRESENTVSYNC) {
482  } else {
484  }
485  if (SDL_GL_GetSwapInterval() > 0) {
486  renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
487  }
488 
489  /* Check for debug output support */
490  if (SDL_GL_GetAttribute(SDL_GL_CONTEXT_FLAGS, &value) == 0 &&
491  (value & SDL_GL_CONTEXT_DEBUG_FLAG)) {
492  data->debug_enabled = SDL_TRUE;
493  }
494  if (data->debug_enabled && SDL_GL_ExtensionSupported("GL_ARB_debug_output")) {
495  PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARBFunc = (PFNGLDEBUGMESSAGECALLBACKARBPROC) SDL_GL_GetProcAddress("glDebugMessageCallbackARB");
496 
497  data->GL_ARB_debug_output_supported = SDL_TRUE;
498  data->glGetPointerv(GL_DEBUG_CALLBACK_FUNCTION_ARB, (GLvoid **)(char *)&data->next_error_callback);
499  data->glGetPointerv(GL_DEBUG_CALLBACK_USER_PARAM_ARB, &data->next_error_userparam);
500  glDebugMessageCallbackARBFunc(GL_HandleDebugMessage, renderer);
501 
502  /* Make sure our callback is called when errors actually happen */
503  data->glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
504  }
505 
506  if (SDL_GL_ExtensionSupported("GL_ARB_texture_non_power_of_two")) {
507  data->GL_ARB_texture_non_power_of_two_supported = SDL_TRUE;
508  } else if (SDL_GL_ExtensionSupported("GL_ARB_texture_rectangle") ||
509  SDL_GL_ExtensionSupported("GL_EXT_texture_rectangle")) {
510  data->GL_ARB_texture_rectangle_supported = SDL_TRUE;
511  }
512  if (data->GL_ARB_texture_rectangle_supported) {
513  data->glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, &value);
514  renderer->info.max_texture_width = value;
515  renderer->info.max_texture_height = value;
516  } else {
517  data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
518  renderer->info.max_texture_width = value;
519  renderer->info.max_texture_height = value;
520  }
521 
522  /* Check for multitexture support */
523  if (SDL_GL_ExtensionSupported("GL_ARB_multitexture")) {
524  data->glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC) SDL_GL_GetProcAddress("glActiveTextureARB");
525  if (data->glActiveTextureARB) {
526  data->GL_ARB_multitexture_supported = SDL_TRUE;
527  data->glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &data->num_texture_units);
528  }
529  }
530 
531  /* Check for shader support */
533  data->shaders = GL_CreateShaderContext();
534  }
535  SDL_LogInfo(SDL_LOG_CATEGORY_RENDER, "OpenGL shaders: %s",
536  data->shaders ? "ENABLED" : "DISABLED");
537 
538  /* We support YV12 textures using 3 textures and a shader */
539  if (data->shaders && data->num_texture_units >= 3) {
544  }
545 
546 #ifdef __MACOSX__
548 #endif
549 
550  if (SDL_GL_ExtensionSupported("GL_EXT_framebuffer_object")) {
551  data->GL_EXT_framebuffer_object_supported = SDL_TRUE;
552  data->glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)
553  SDL_GL_GetProcAddress("glGenFramebuffersEXT");
554  data->glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)
555  SDL_GL_GetProcAddress("glDeleteFramebuffersEXT");
556  data->glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)
557  SDL_GL_GetProcAddress("glFramebufferTexture2DEXT");
558  data->glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)
559  SDL_GL_GetProcAddress("glBindFramebufferEXT");
560  data->glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)
561  SDL_GL_GetProcAddress("glCheckFramebufferStatusEXT");
563  }
564  data->framebuffers = NULL;
565 
566  /* Set up parameters for rendering */
567  GL_ResetState(renderer);
568 
569  return renderer;
570 
571 error:
572  if (changed_window) {
573  /* Uh oh, better try to put it back... */
577  SDL_RecreateWindow(window, window_flags);
578  }
579  return NULL;
580 }
581 
582 static void
583 GL_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
584 {
585  if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED ||
586  event->event == SDL_WINDOWEVENT_SHOWN ||
587  event->event == SDL_WINDOWEVENT_HIDDEN) {
588  /* Rebind the context to the window area and update matrices */
589  SDL_CurrentContext = NULL;
590  }
591 }
592 
593 static int
594 GL_GetOutputSize(SDL_Renderer * renderer, int *w, int *h)
595 {
596  SDL_GL_GetDrawableSize(renderer->window, w, h);
597  return 0;
598 }
599 
600 static GLenum GetBlendFunc(SDL_BlendFactor factor)
601 {
602  switch (factor) {
604  return GL_ZERO;
605  case SDL_BLENDFACTOR_ONE:
606  return GL_ONE;
608  return GL_SRC_COLOR;
610  return GL_ONE_MINUS_SRC_COLOR;
612  return GL_SRC_ALPHA;
614  return GL_ONE_MINUS_SRC_ALPHA;
616  return GL_DST_COLOR;
618  return GL_ONE_MINUS_DST_COLOR;
620  return GL_DST_ALPHA;
622  return GL_ONE_MINUS_DST_ALPHA;
623  default:
624  return GL_INVALID_ENUM;
625  }
626 }
627 
628 static GLenum GetBlendEquation(SDL_BlendOperation operation)
629 {
630  switch (operation) {
632  return GL_FUNC_ADD;
634  return GL_FUNC_SUBTRACT;
637  default:
638  return GL_INVALID_ENUM;
639  }
640 }
641 
642 static SDL_bool
643 GL_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode)
644 {
645  SDL_BlendFactor srcColorFactor = SDL_GetBlendModeSrcColorFactor(blendMode);
646  SDL_BlendFactor srcAlphaFactor = SDL_GetBlendModeSrcAlphaFactor(blendMode);
647  SDL_BlendOperation colorOperation = SDL_GetBlendModeColorOperation(blendMode);
648  SDL_BlendFactor dstColorFactor = SDL_GetBlendModeDstColorFactor(blendMode);
649  SDL_BlendFactor dstAlphaFactor = SDL_GetBlendModeDstAlphaFactor(blendMode);
650  SDL_BlendOperation alphaOperation = SDL_GetBlendModeAlphaOperation(blendMode);
651 
652  if (GetBlendFunc(srcColorFactor) == GL_INVALID_ENUM ||
653  GetBlendFunc(srcAlphaFactor) == GL_INVALID_ENUM ||
654  GetBlendEquation(colorOperation) == GL_INVALID_ENUM ||
655  GetBlendFunc(dstColorFactor) == GL_INVALID_ENUM ||
656  GetBlendFunc(dstAlphaFactor) == GL_INVALID_ENUM ||
657  GetBlendEquation(alphaOperation) == GL_INVALID_ENUM) {
658  return SDL_FALSE;
659  }
660  if (colorOperation != alphaOperation) {
661  return SDL_FALSE;
662  }
663  return SDL_TRUE;
664 }
665 
667 power_of_2(int input)
668 {
669  int value = 1;
670 
671  while (value < input) {
672  value <<= 1;
673  }
674  return value;
675 }
676 
678 convert_format(GL_RenderData *renderdata, Uint32 pixel_format,
680 {
681  switch (pixel_format) {
683  *internalFormat = GL_RGBA8;
684  *format = GL_BGRA;
686  break;
691  *internalFormat = GL_LUMINANCE;
692  *format = GL_LUMINANCE;
693  *type = GL_UNSIGNED_BYTE;
694  break;
695 #ifdef __MACOSX__
697  *internalFormat = GL_RGB8;
698  *format = GL_YCBCR_422_APPLE;
700  break;
701 #endif
702  default:
703  return SDL_FALSE;
704  }
705  return SDL_TRUE;
706 }
707 
708 static GLenum
709 GetScaleQuality(void)
710 {
711  const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
712 
713  if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
714  return GL_NEAREST;
715  } else {
716  return GL_LINEAR;
717  }
718 }
719 
720 static int
721 GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
722 {
723  GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
724  GL_TextureData *data;
725  GLint internalFormat;
726  GLenum format, type;
727  int texture_w, texture_h;
728  GLenum scaleMode;
729 
730  GL_ActivateRenderer(renderer);
731 
732  if (texture->access == SDL_TEXTUREACCESS_TARGET &&
733  !renderdata->GL_EXT_framebuffer_object_supported) {
734  return SDL_SetError("Render targets not supported by OpenGL");
735  }
736 
737  if (!convert_format(renderdata, texture->format, &internalFormat,
738  &format, &type)) {
739  return SDL_SetError("Texture format %s not supported by OpenGL",
740  SDL_GetPixelFormatName(texture->format));
741  }
742 
743  data = (GL_TextureData *) SDL_calloc(1, sizeof(*data));
744  if (!data) {
745  return SDL_OutOfMemory();
746  }
747 
748  if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
749  size_t size;
750  data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
751  size = texture->h * data->pitch;
752  if (texture->format == SDL_PIXELFORMAT_YV12 ||
753  texture->format == SDL_PIXELFORMAT_IYUV) {
754  /* Need to add size for the U and V planes */
755  size += (2 * (texture->h * data->pitch) / 4);
756  }
757  if (texture->format == SDL_PIXELFORMAT_NV12 ||
758  texture->format == SDL_PIXELFORMAT_NV21) {
759  /* Need to add size for the U/V plane */
760  size += ((texture->h * data->pitch) / 2);
761  }
762  data->pixels = SDL_calloc(1, size);
763  if (!data->pixels) {
764  SDL_free(data);
765  return SDL_OutOfMemory();
766  }
767  }
768 
769  if (texture->access == SDL_TEXTUREACCESS_TARGET) {
770  data->fbo = GL_GetFBO(renderdata, texture->w, texture->h);
771  } else {
772  data->fbo = NULL;
773  }
774 
775  GL_CheckError("", renderer);
776  renderdata->glGenTextures(1, &data->texture);
777  if (GL_CheckError("glGenTextures()", renderer) < 0) {
778  if (data->pixels) {
779  SDL_free(data->pixels);
780  }
781  SDL_free(data);
782  return -1;
783  }
784  texture->driverdata = data;
785 
786  if (renderdata->GL_ARB_texture_non_power_of_two_supported) {
787  data->type = GL_TEXTURE_2D;
788  texture_w = texture->w;
789  texture_h = texture->h;
790  data->texw = 1.0f;
791  data->texh = 1.0f;
792  } else if (renderdata->GL_ARB_texture_rectangle_supported) {
793  data->type = GL_TEXTURE_RECTANGLE_ARB;
794  texture_w = texture->w;
795  texture_h = texture->h;
796  data->texw = (GLfloat) texture_w;
797  data->texh = (GLfloat) texture_h;
798  } else {
799  data->type = GL_TEXTURE_2D;
800  texture_w = power_of_2(texture->w);
801  texture_h = power_of_2(texture->h);
802  data->texw = (GLfloat) (texture->w) / texture_w;
803  data->texh = (GLfloat) texture->h / texture_h;
804  }
805 
806  data->format = format;
807  data->formattype = type;
808  scaleMode = GetScaleQuality();
809  renderdata->glEnable(data->type);
810  renderdata->glBindTexture(data->type, data->texture);
811  renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER, scaleMode);
812  renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER, scaleMode);
813  /* According to the spec, CLAMP_TO_EDGE is the default for TEXTURE_RECTANGLE
814  and setting it causes an INVALID_ENUM error in the latest NVidia drivers.
815  */
816  if (data->type != GL_TEXTURE_RECTANGLE_ARB) {
817  renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S,
819  renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T,
821  }
822 #ifdef __MACOSX__
823 #ifndef GL_TEXTURE_STORAGE_HINT_APPLE
824 #define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC
825 #endif
826 #ifndef STORAGE_CACHED_APPLE
827 #define STORAGE_CACHED_APPLE 0x85BE
828 #endif
829 #ifndef STORAGE_SHARED_APPLE
830 #define STORAGE_SHARED_APPLE 0x85BF
831 #endif
832  if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
833  renderdata->glTexParameteri(data->type, GL_TEXTURE_STORAGE_HINT_APPLE,
835  } else {
836  renderdata->glTexParameteri(data->type, GL_TEXTURE_STORAGE_HINT_APPLE,
838  }
839  if (texture->access == SDL_TEXTUREACCESS_STREAMING
840  && texture->format == SDL_PIXELFORMAT_ARGB8888
841  && (texture->w % 8) == 0) {
842  renderdata->glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
843  renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
844  renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH,
845  (data->pitch / SDL_BYTESPERPIXEL(texture->format)));
846  renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w,
847  texture_h, 0, format, type, data->pixels);
848  renderdata->glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
849  }
850  else
851 #endif
852  {
853  renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w,
854  texture_h, 0, format, type, NULL);
855  }
856  renderdata->glDisable(data->type);
857  if (GL_CheckError("glTexImage2D()", renderer) < 0) {
858  return -1;
859  }
860 
861  if (texture->format == SDL_PIXELFORMAT_YV12 ||
862  texture->format == SDL_PIXELFORMAT_IYUV) {
863  data->yuv = SDL_TRUE;
864 
865  renderdata->glGenTextures(1, &data->utexture);
866  renderdata->glGenTextures(1, &data->vtexture);
867  renderdata->glEnable(data->type);
868 
869  renderdata->glBindTexture(data->type, data->utexture);
870  renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER,
871  scaleMode);
872  renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER,
873  scaleMode);
874  renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S,
876  renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T,
878  renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w/2,
879  texture_h/2, 0, format, type, NULL);
880 
881  renderdata->glBindTexture(data->type, data->vtexture);
882  renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER,
883  scaleMode);
884  renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER,
885  scaleMode);
886  renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S,
888  renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T,
890  renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w/2,
891  texture_h/2, 0, format, type, NULL);
892 
893  renderdata->glDisable(data->type);
894  }
895 
896  if (texture->format == SDL_PIXELFORMAT_NV12 ||
897  texture->format == SDL_PIXELFORMAT_NV21) {
898  data->nv12 = SDL_TRUE;
899 
900  renderdata->glGenTextures(1, &data->utexture);
901  renderdata->glEnable(data->type);
902 
903  renderdata->glBindTexture(data->type, data->utexture);
904  renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER,
905  scaleMode);
906  renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER,
907  scaleMode);
908  renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S,
910  renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T,
912  renderdata->glTexImage2D(data->type, 0, GL_LUMINANCE_ALPHA, texture_w/2,
913  texture_h/2, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL);
914  renderdata->glDisable(data->type);
915  }
916 
917  return GL_CheckError("", renderer);
918 }
919 
920 static int
921 GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
922  const SDL_Rect * rect, const void *pixels, int pitch)
923 {
924  GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
925  GL_TextureData *data = (GL_TextureData *) texture->driverdata;
926  const int texturebpp = SDL_BYTESPERPIXEL(texture->format);
927 
928  SDL_assert(texturebpp != 0); /* otherwise, division by zero later. */
929 
930  GL_ActivateRenderer(renderer);
931 
932  renderdata->glEnable(data->type);
933  renderdata->glBindTexture(data->type, data->texture);
934  renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
935  renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, (pitch / texturebpp));
936  renderdata->glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w,
937  rect->h, data->format, data->formattype,
938  pixels);
939  if (data->yuv) {
940  renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, (pitch / 2));
941 
942  /* Skip to the correct offset into the next texture */
943  pixels = (const void*)((const Uint8*)pixels + rect->h * pitch);
944  if (texture->format == SDL_PIXELFORMAT_YV12) {
945  renderdata->glBindTexture(data->type, data->vtexture);
946  } else {
947  renderdata->glBindTexture(data->type, data->utexture);
948  }
949  renderdata->glTexSubImage2D(data->type, 0, rect->x/2, rect->y/2,
950  rect->w/2, rect->h/2,
951  data->format, data->formattype, pixels);
952 
953  /* Skip to the correct offset into the next texture */
954  pixels = (const void*)((const Uint8*)pixels + (rect->h * pitch)/4);
955  if (texture->format == SDL_PIXELFORMAT_YV12) {
956  renderdata->glBindTexture(data->type, data->utexture);
957  } else {
958  renderdata->glBindTexture(data->type, data->vtexture);
959  }
960  renderdata->glTexSubImage2D(data->type, 0, rect->x/2, rect->y/2,
961  rect->w/2, rect->h/2,
962  data->format, data->formattype, pixels);
963  }
964 
965  if (data->nv12) {
966  renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, (pitch / 2));
967 
968  /* Skip to the correct offset into the next texture */
969  pixels = (const void*)((const Uint8*)pixels + rect->h * pitch);
970  renderdata->glBindTexture(data->type, data->utexture);
971  renderdata->glTexSubImage2D(data->type, 0, rect->x/2, rect->y/2,
972  rect->w/2, rect->h/2,
974  }
975  renderdata->glDisable(data->type);
976 
977  return GL_CheckError("glTexSubImage2D()", renderer);
978 }
979 
980 static int
981 GL_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
982  const SDL_Rect * rect,
983  const Uint8 *Yplane, int Ypitch,
984  const Uint8 *Uplane, int Upitch,
985  const Uint8 *Vplane, int Vpitch)
986 {
987  GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
988  GL_TextureData *data = (GL_TextureData *) texture->driverdata;
989 
990  GL_ActivateRenderer(renderer);
991 
992  renderdata->glEnable(data->type);
993  renderdata->glBindTexture(data->type, data->texture);
994  renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
995  renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, Ypitch);
996  renderdata->glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w,
997  rect->h, data->format, data->formattype,
998  Yplane);
999 
1000  renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, Upitch);
1001  renderdata->glBindTexture(data->type, data->utexture);
1002  renderdata->glTexSubImage2D(data->type, 0, rect->x/2, rect->y/2,
1003  rect->w/2, rect->h/2,
1004  data->format, data->formattype, Uplane);
1005 
1006  renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, Vpitch);
1007  renderdata->glBindTexture(data->type, data->vtexture);
1008  renderdata->glTexSubImage2D(data->type, 0, rect->x/2, rect->y/2,
1009  rect->w/2, rect->h/2,
1010  data->format, data->formattype, Vplane);
1011  renderdata->glDisable(data->type);
1012 
1013  return GL_CheckError("glTexSubImage2D()", renderer);
1014 }
1015 
1016 static int
1017 GL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
1018  const SDL_Rect * rect, void **pixels, int *pitch)
1019 {
1020  GL_TextureData *data = (GL_TextureData *) texture->driverdata;
1021 
1022  data->locked_rect = *rect;
1023  *pixels =
1024  (void *) ((Uint8 *) data->pixels + rect->y * data->pitch +
1025  rect->x * SDL_BYTESPERPIXEL(texture->format));
1026  *pitch = data->pitch;
1027  return 0;
1028 }
1029 
1030 static void
1031 GL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
1032 {
1033  GL_TextureData *data = (GL_TextureData *) texture->driverdata;
1034  const SDL_Rect *rect;
1035  void *pixels;
1036 
1037  rect = &data->locked_rect;
1038  pixels =
1039  (void *) ((Uint8 *) data->pixels + rect->y * data->pitch +
1040  rect->x * SDL_BYTESPERPIXEL(texture->format));
1041  GL_UpdateTexture(renderer, texture, rect, pixels, data->pitch);
1042 }
1043 
1044 static int
1045 GL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
1046 {
1047  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1048  GL_TextureData *texturedata;
1049  GLenum status;
1050 
1051  GL_ActivateRenderer(renderer);
1052 
1053  if (!data->GL_EXT_framebuffer_object_supported) {
1054  return SDL_SetError("Render targets not supported by OpenGL");
1055  }
1056 
1057  if (texture == NULL) {
1058  data->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1059  return 0;
1060  }
1061 
1062  texturedata = (GL_TextureData *) texture->driverdata;
1063  data->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, texturedata->fbo->FBO);
1064  /* TODO: check if texture pixel format allows this operation */
1065  data->glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, texturedata->type, texturedata->texture, 0);
1066  /* Check FBO status */
1067  status = data->glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
1068  if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
1069  return SDL_SetError("glFramebufferTexture2DEXT() failed");
1070  }
1071  return 0;
1072 }
1073 
1074 static int
1075 GL_UpdateViewport(SDL_Renderer * renderer)
1076 {
1077  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1078 
1079  if (SDL_CurrentContext != data->context) {
1080  /* We'll update the viewport after we rebind the context */
1081  return 0;
1082  }
1083 
1084  if (renderer->target) {
1085  data->glViewport(renderer->viewport.x, renderer->viewport.y,
1086  renderer->viewport.w, renderer->viewport.h);
1087  } else {
1088  int w, h;
1089 
1090  SDL_GL_GetDrawableSize(renderer->window, &w, &h);
1091  data->glViewport(renderer->viewport.x, (h - renderer->viewport.y - renderer->viewport.h),
1092  renderer->viewport.w, renderer->viewport.h);
1093  }
1094 
1095  data->glMatrixMode(GL_PROJECTION);
1096  data->glLoadIdentity();
1097  if (renderer->viewport.w && renderer->viewport.h) {
1098  if (renderer->target) {
1099  data->glOrtho((GLdouble) 0,
1100  (GLdouble) renderer->viewport.w,
1101  (GLdouble) 0,
1102  (GLdouble) renderer->viewport.h,
1103  0.0, 1.0);
1104  } else {
1105  data->glOrtho((GLdouble) 0,
1106  (GLdouble) renderer->viewport.w,
1107  (GLdouble) renderer->viewport.h,
1108  (GLdouble) 0,
1109  0.0, 1.0);
1110  }
1111  }
1112  data->glMatrixMode(GL_MODELVIEW);
1113 
1114  return GL_CheckError("", renderer);
1115 }
1116 
1117 static int
1118 GL_UpdateClipRect(SDL_Renderer * renderer)
1119 {
1120  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1121 
1122  if (renderer->clipping_enabled) {
1123  const SDL_Rect *rect = &renderer->clip_rect;
1124  data->glEnable(GL_SCISSOR_TEST);
1125  if (renderer->target) {
1126  data->glScissor(renderer->viewport.x + rect->x, renderer->viewport.y + rect->y, rect->w, rect->h);
1127  } else {
1128  int w, h;
1129 
1130  SDL_GL_GetDrawableSize(renderer->window, &w, &h);
1131  data->glScissor(renderer->viewport.x + rect->x, h - renderer->viewport.y - rect->y - rect->h, rect->w, rect->h);
1132  }
1133  } else {
1134  data->glDisable(GL_SCISSOR_TEST);
1135  }
1136  return 0;
1137 }
1138 
1139 static void
1140 GL_SetShader(GL_RenderData * data, GL_Shader shader)
1141 {
1142  if (data->shaders && shader != data->current.shader) {
1143  GL_SelectShader(data->shaders, shader);
1144  data->current.shader = shader;
1145  }
1146 }
1147 
1148 static void
1149 GL_SetColor(GL_RenderData * data, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
1150 {
1151  Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b);
1152 
1153  if (color != data->current.color) {
1154  data->glColor4f((GLfloat) r * inv255f,
1155  (GLfloat) g * inv255f,
1156  (GLfloat) b * inv255f,
1157  (GLfloat) a * inv255f);
1158  data->current.color = color;
1159  }
1160 }
1161 
1162 static void
1163 GL_SetBlendMode(GL_RenderData * data, SDL_BlendMode blendMode)
1164 {
1165  if (blendMode != data->current.blendMode) {
1166  if (blendMode == SDL_BLENDMODE_NONE) {
1167  data->glDisable(GL_BLEND);
1168  } else {
1169  data->glEnable(GL_BLEND);
1170  data->glBlendFuncSeparate(GetBlendFunc(SDL_GetBlendModeSrcColorFactor(blendMode)),
1171  GetBlendFunc(SDL_GetBlendModeDstColorFactor(blendMode)),
1172  GetBlendFunc(SDL_GetBlendModeSrcAlphaFactor(blendMode)),
1173  GetBlendFunc(SDL_GetBlendModeDstAlphaFactor(blendMode)));
1174  data->glBlendEquation(GetBlendEquation(SDL_GetBlendModeColorOperation(blendMode)));
1175  }
1176  data->current.blendMode = blendMode;
1177  }
1178 }
1179 
1180 static void
1181 GL_SetDrawingState(SDL_Renderer * renderer)
1182 {
1183  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1184 
1185  GL_ActivateRenderer(renderer);
1186 
1187  GL_SetColor(data, renderer->r,
1188  renderer->g,
1189  renderer->b,
1190  renderer->a);
1191 
1192  GL_SetBlendMode(data, renderer->blendMode);
1193 
1194  GL_SetShader(data, SHADER_SOLID);
1195 }
1196 
1197 static int
1198 GL_RenderClear(SDL_Renderer * renderer)
1199 {
1200  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1201 
1202  GL_ActivateRenderer(renderer);
1203 
1204  data->glClearColor((GLfloat) renderer->r * inv255f,
1205  (GLfloat) renderer->g * inv255f,
1206  (GLfloat) renderer->b * inv255f,
1207  (GLfloat) renderer->a * inv255f);
1208 
1209  if (renderer->clipping_enabled) {
1210  data->glDisable(GL_SCISSOR_TEST);
1211  }
1212 
1213  data->glClear(GL_COLOR_BUFFER_BIT);
1214 
1215  if (renderer->clipping_enabled) {
1216  data->glEnable(GL_SCISSOR_TEST);
1217  }
1218 
1219  return 0;
1220 }
1221 
1222 static int
1223 GL_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points,
1224  int count)
1225 {
1226  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1227  int i;
1228 
1229  GL_SetDrawingState(renderer);
1230 
1231  data->glBegin(GL_POINTS);
1232  for (i = 0; i < count; ++i) {
1233  data->glVertex2f(0.5f + points[i].x, 0.5f + points[i].y);
1234  }
1235  data->glEnd();
1236 
1237  return 0;
1238 }
1239 
1240 static int
1241 GL_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points,
1242  int count)
1243 {
1244  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1245  int i;
1246 
1247  GL_SetDrawingState(renderer);
1248 
1249  if (count > 2 &&
1250  points[0].x == points[count-1].x && points[0].y == points[count-1].y) {
1251  data->glBegin(GL_LINE_LOOP);
1252  /* GL_LINE_LOOP takes care of the final segment */
1253  --count;
1254  for (i = 0; i < count; ++i) {
1255  data->glVertex2f(0.5f + points[i].x, 0.5f + points[i].y);
1256  }
1257  data->glEnd();
1258  } else {
1259 #if defined(__MACOSX__) || defined(__WIN32__)
1260 #else
1261  int x1, y1, x2, y2;
1262 #endif
1263 
1264  data->glBegin(GL_LINE_STRIP);
1265  for (i = 0; i < count; ++i) {
1266  data->glVertex2f(0.5f + points[i].x, 0.5f + points[i].y);
1267  }
1268  data->glEnd();
1269 
1270  /* The line is half open, so we need one more point to complete it.
1271  * http://www.opengl.org/documentation/specs/version1.1/glspec1.1/node47.html
1272  * If we have to, we can use vertical line and horizontal line textures
1273  * for vertical and horizontal lines, and then create custom textures
1274  * for diagonal lines and software render those. It's terrible, but at
1275  * least it would be pixel perfect.
1276  */
1277  data->glBegin(GL_POINTS);
1278 #if defined(__MACOSX__) || defined(__WIN32__)
1279  /* Mac OS X and Windows seem to always leave the last point open */
1280  data->glVertex2f(0.5f + points[count-1].x, 0.5f + points[count-1].y);
1281 #else
1282  /* Linux seems to leave the right-most or bottom-most point open */
1283  x1 = points[0].x;
1284  y1 = points[0].y;
1285  x2 = points[count-1].x;
1286  y2 = points[count-1].y;
1287 
1288  if (x1 > x2) {
1289  data->glVertex2f(0.5f + x1, 0.5f + y1);
1290  } else if (x2 > x1) {
1291  data->glVertex2f(0.5f + x2, 0.5f + y2);
1292  }
1293  if (y1 > y2) {
1294  data->glVertex2f(0.5f + x1, 0.5f + y1);
1295  } else if (y2 > y1) {
1296  data->glVertex2f(0.5f + x2, 0.5f + y2);
1297  }
1298 #endif
1299  data->glEnd();
1300  }
1301  return GL_CheckError("", renderer);
1302 }
1303 
1304 static int
1305 GL_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, int count)
1306 {
1307  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1308  int i;
1309 
1310  GL_SetDrawingState(renderer);
1311 
1312  for (i = 0; i < count; ++i) {
1313  const SDL_FRect *rect = &rects[i];
1314 
1315  data->glRectf(rect->x, rect->y, rect->x + rect->w, rect->y + rect->h);
1316  }
1317  return GL_CheckError("", renderer);
1318 }
1319 
1320 static int
1321 GL_SetupCopy(SDL_Renderer * renderer, SDL_Texture * texture)
1322 {
1323  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1324  GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata;
1325 
1326  data->glEnable(texturedata->type);
1327  if (texturedata->yuv) {
1328  data->glActiveTextureARB(GL_TEXTURE2_ARB);
1329  data->glBindTexture(texturedata->type, texturedata->vtexture);
1330 
1331  data->glActiveTextureARB(GL_TEXTURE1_ARB);
1332  data->glBindTexture(texturedata->type, texturedata->utexture);
1333 
1334  data->glActiveTextureARB(GL_TEXTURE0_ARB);
1335  }
1336  if (texturedata->nv12) {
1337  data->glActiveTextureARB(GL_TEXTURE1_ARB);
1338  data->glBindTexture(texturedata->type, texturedata->utexture);
1339 
1340  data->glActiveTextureARB(GL_TEXTURE0_ARB);
1341  }
1342  data->glBindTexture(texturedata->type, texturedata->texture);
1343 
1344  if (texture->modMode) {
1345  GL_SetColor(data, texture->r, texture->g, texture->b, texture->a);
1346  } else {
1347  GL_SetColor(data, 255, 255, 255, 255);
1348  }
1349 
1350  GL_SetBlendMode(data, texture->blendMode);
1351 
1352  if (texturedata->yuv) {
1353  GL_SetShader(data, SHADER_YUV);
1354  } else if (texturedata->nv12) {
1355  if (texture->format == SDL_PIXELFORMAT_NV12) {
1356  GL_SetShader(data, SHADER_NV12);
1357  } else {
1358  GL_SetShader(data, SHADER_NV21);
1359  }
1360  } else {
1361  GL_SetShader(data, SHADER_RGB);
1362  }
1363  return 0;
1364 }
1365 
1366 static int
1367 GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
1368  const SDL_Rect * srcrect, const SDL_FRect * dstrect)
1369 {
1370  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1371  GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata;
1372  GLfloat minx, miny, maxx, maxy;
1373  GLfloat minu, maxu, minv, maxv;
1374 
1375  GL_ActivateRenderer(renderer);
1376 
1377  if (GL_SetupCopy(renderer, texture) < 0) {
1378  return -1;
1379  }
1380 
1381  minx = dstrect->x;
1382  miny = dstrect->y;
1383  maxx = dstrect->x + dstrect->w;
1384  maxy = dstrect->y + dstrect->h;
1385 
1386  minu = (GLfloat) srcrect->x / texture->w;
1387  minu *= texturedata->texw;
1388  maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w;
1389  maxu *= texturedata->texw;
1390  minv = (GLfloat) srcrect->y / texture->h;
1391  minv *= texturedata->texh;
1392  maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h;
1393  maxv *= texturedata->texh;
1394 
1395  data->glBegin(GL_TRIANGLE_STRIP);
1396  data->glTexCoord2f(minu, minv);
1397  data->glVertex2f(minx, miny);
1398  data->glTexCoord2f(maxu, minv);
1399  data->glVertex2f(maxx, miny);
1400  data->glTexCoord2f(minu, maxv);
1401  data->glVertex2f(minx, maxy);
1402  data->glTexCoord2f(maxu, maxv);
1403  data->glVertex2f(maxx, maxy);
1404  data->glEnd();
1405 
1406  data->glDisable(texturedata->type);
1407 
1408  return GL_CheckError("", renderer);
1409 }
1410 
1411 static int
1412 GL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
1413  const SDL_Rect * srcrect, const SDL_FRect * dstrect,
1414  const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
1415 {
1416  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1417  GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata;
1418  GLfloat minx, miny, maxx, maxy;
1419  GLfloat centerx, centery;
1420  GLfloat minu, maxu, minv, maxv;
1421 
1422  GL_ActivateRenderer(renderer);
1423 
1424  if (GL_SetupCopy(renderer, texture) < 0) {
1425  return -1;
1426  }
1427 
1428  centerx = center->x;
1429  centery = center->y;
1430 
1431  if (flip & SDL_FLIP_HORIZONTAL) {
1432  minx = dstrect->w - centerx;
1433  maxx = -centerx;
1434  }
1435  else {
1436  minx = -centerx;
1437  maxx = dstrect->w - centerx;
1438  }
1439 
1440  if (flip & SDL_FLIP_VERTICAL) {
1441  miny = dstrect->h - centery;
1442  maxy = -centery;
1443  }
1444  else {
1445  miny = -centery;
1446  maxy = dstrect->h - centery;
1447  }
1448 
1449  minu = (GLfloat) srcrect->x / texture->w;
1450  minu *= texturedata->texw;
1451  maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w;
1452  maxu *= texturedata->texw;
1453  minv = (GLfloat) srcrect->y / texture->h;
1454  minv *= texturedata->texh;
1455  maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h;
1456  maxv *= texturedata->texh;
1457 
1458  /* Translate to flip, rotate, translate to position */
1459  data->glPushMatrix();
1460  data->glTranslatef((GLfloat)dstrect->x + centerx, (GLfloat)dstrect->y + centery, (GLfloat)0.0);
1461  data->glRotated(angle, (GLdouble)0.0, (GLdouble)0.0, (GLdouble)1.0);
1462 
1463  data->glBegin(GL_TRIANGLE_STRIP);
1464  data->glTexCoord2f(minu, minv);
1465  data->glVertex2f(minx, miny);
1466  data->glTexCoord2f(maxu, minv);
1467  data->glVertex2f(maxx, miny);
1468  data->glTexCoord2f(minu, maxv);
1469  data->glVertex2f(minx, maxy);
1470  data->glTexCoord2f(maxu, maxv);
1471  data->glVertex2f(maxx, maxy);
1472  data->glEnd();
1473  data->glPopMatrix();
1474 
1475  data->glDisable(texturedata->type);
1476 
1477  return GL_CheckError("", renderer);
1478 }
1479 
1480 static int
1481 GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
1482  Uint32 pixel_format, void * pixels, int pitch)
1483 {
1484  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1485  Uint32 temp_format = renderer->target ? renderer->target->format : SDL_PIXELFORMAT_ARGB8888;
1486  void *temp_pixels;
1487  int temp_pitch;
1488  GLint internalFormat;
1489  GLenum format, type;
1490  Uint8 *src, *dst, *tmp;
1491  int w, h, length, rows;
1492  int status;
1493 
1494  GL_ActivateRenderer(renderer);
1495 
1496  if (!convert_format(data, temp_format, &internalFormat, &format, &type)) {
1497  return SDL_SetError("Texture format %s not supported by OpenGL",
1498  SDL_GetPixelFormatName(temp_format));
1499  }
1500 
1501  if (!rect->w || !rect->h) {
1502  return 0; /* nothing to do. */
1503  }
1504 
1505  temp_pitch = rect->w * SDL_BYTESPERPIXEL(temp_format);
1506  temp_pixels = SDL_malloc(rect->h * temp_pitch);
1507  if (!temp_pixels) {
1508  return SDL_OutOfMemory();
1509  }
1510 
1511  SDL_GetRendererOutputSize(renderer, &w, &h);
1512 
1513  data->glPixelStorei(GL_PACK_ALIGNMENT, 1);
1514  data->glPixelStorei(GL_PACK_ROW_LENGTH,
1515  (temp_pitch / SDL_BYTESPERPIXEL(temp_format)));
1516 
1517  data->glReadPixels(rect->x, renderer->target ? rect->y : (h-rect->y)-rect->h,
1518  rect->w, rect->h, format, type, temp_pixels);
1519 
1520  if (GL_CheckError("glReadPixels()", renderer) < 0) {
1521  SDL_free(temp_pixels);
1522  return -1;
1523  }
1524 
1525  /* Flip the rows to be top-down if necessary */
1526  if (!renderer->target) {
1527  length = rect->w * SDL_BYTESPERPIXEL(temp_format);
1528  src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch;
1529  dst = (Uint8*)temp_pixels;
1530  tmp = SDL_stack_alloc(Uint8, length);
1531  rows = rect->h / 2;
1532  while (rows--) {
1533  SDL_memcpy(tmp, dst, length);
1534  SDL_memcpy(dst, src, length);
1535  SDL_memcpy(src, tmp, length);
1536  dst += temp_pitch;
1537  src -= temp_pitch;
1538  }
1539  SDL_stack_free(tmp);
1540  }
1541 
1542  status = SDL_ConvertPixels(rect->w, rect->h,
1543  temp_format, temp_pixels, temp_pitch,
1544  pixel_format, pixels, pitch);
1545  SDL_free(temp_pixels);
1546 
1547  return status;
1548 }
1549 
1550 static void
1551 GL_RenderPresent(SDL_Renderer * renderer)
1552 {
1553  GL_ActivateRenderer(renderer);
1554 
1555  SDL_GL_SwapWindow(renderer->window);
1556 }
1557 
1558 static void
1559 GL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
1560 {
1561  GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
1562  GL_TextureData *data = (GL_TextureData *) texture->driverdata;
1563 
1564  GL_ActivateRenderer(renderer);
1565 
1566  if (!data) {
1567  return;
1568  }
1569  if (data->texture) {
1570  renderdata->glDeleteTextures(1, &data->texture);
1571  }
1572  if (data->yuv) {
1573  renderdata->glDeleteTextures(1, &data->utexture);
1574  renderdata->glDeleteTextures(1, &data->vtexture);
1575  }
1576  SDL_free(data->pixels);
1577  SDL_free(data);
1578  texture->driverdata = NULL;
1579 }
1580 
1581 static void
1582 GL_DestroyRenderer(SDL_Renderer * renderer)
1583 {
1584  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1585 
1586  if (data) {
1587  if (data->context != NULL) {
1588  /* make sure we delete the right resources! */
1589  GL_ActivateRenderer(renderer);
1590  }
1591 
1592  GL_ClearErrors(renderer);
1593  if (data->GL_ARB_debug_output_supported) {
1594  PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARBFunc = (PFNGLDEBUGMESSAGECALLBACKARBPROC) SDL_GL_GetProcAddress("glDebugMessageCallbackARB");
1595 
1596  /* Uh oh, we don't have a safe way of removing ourselves from the callback chain, if it changed after we set our callback. */
1597  /* For now, just always replace the callback with the original one */
1598  glDebugMessageCallbackARBFunc(data->next_error_callback, data->next_error_userparam);
1599  }
1600  if (data->shaders) {
1601  GL_DestroyShaderContext(data->shaders);
1602  }
1603  if (data->context) {
1604  while (data->framebuffers) {
1605  GL_FBOList *nextnode = data->framebuffers->next;
1606  /* delete the framebuffer object */
1607  data->glDeleteFramebuffersEXT(1, &data->framebuffers->FBO);
1608  GL_CheckError("", renderer);
1609  SDL_free(data->framebuffers);
1610  data->framebuffers = nextnode;
1611  }
1612  SDL_GL_DeleteContext(data->context);
1613  }
1614  SDL_free(data);
1615  }
1616  SDL_free(renderer);
1617 }
1618 
1619 static int
1620 GL_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, float *texh)
1621 {
1622  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1623  GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata;
1624  GL_ActivateRenderer(renderer);
1625 
1626  data->glEnable(texturedata->type);
1627  if (texturedata->yuv) {
1628  data->glActiveTextureARB(GL_TEXTURE2_ARB);
1629  data->glBindTexture(texturedata->type, texturedata->vtexture);
1630 
1631  data->glActiveTextureARB(GL_TEXTURE1_ARB);
1632  data->glBindTexture(texturedata->type, texturedata->utexture);
1633 
1634  data->glActiveTextureARB(GL_TEXTURE0_ARB);
1635  }
1636  data->glBindTexture(texturedata->type, texturedata->texture);
1637 
1638  if(texw) *texw = (float)texturedata->texw;
1639  if(texh) *texh = (float)texturedata->texh;
1640 
1641  return 0;
1642 }
1643 
1644 static int
1645 GL_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture)
1646 {
1647  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1648  GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata;
1649  GL_ActivateRenderer(renderer);
1650 
1651  if (texturedata->yuv) {
1652  data->glActiveTextureARB(GL_TEXTURE2_ARB);
1653  data->glDisable(texturedata->type);
1654 
1655  data->glActiveTextureARB(GL_TEXTURE1_ARB);
1656  data->glDisable(texturedata->type);
1657 
1658  data->glActiveTextureARB(GL_TEXTURE0_ARB);
1659  }
1660 
1661  data->glDisable(texturedata->type);
1662 
1663  return 0;
1664 }
1665 
1666 #endif /* SDL_VIDEO_RENDER_OGL && !SDL_RENDER_DISABLED */
1667 
1668 /* vi: set ts=4 sw=4 expandtab: */
SDL_BlendFactor SDL_GetBlendModeSrcColorFactor(SDL_BlendMode blendMode)
Definition: SDL_render.c:2143
SDL_BlendFactor
The normalized factor used to multiply pixel components.
Definition: SDL_blendmode.h:75
#define GL_ONE
Definition: SDL_opengl.h:401
#define GL_STACK_UNDERFLOW
Definition: SDL_opengl.h:724
int(* UpdateClipRect)(SDL_Renderer *renderer)
SDL_BlendMode blendMode
Definition: SDL_sysrender.h:57
#define SDL_GL_ExtensionSupported
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2079
#define GL_INVALID_ENUM
Definition: SDL_opengl.h:720
#define GL_FALSE
Definition: SDL_opengl.h:199
#define GL_STORAGE_CACHED_APPLE
#define GL_UNPACK_CLIENT_STORAGE_APPLE
GLuint GLfloat GLfloat GLfloat x1
GL_ShaderContext * GL_CreateShaderContext(void)
#define GL_INVALID_OPERATION
Definition: SDL_opengl.h:722
GLuint64EXT * result
#define GL_SCISSOR_TEST
Definition: SDL_opengl.h:615
void(* WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event)
Definition: SDL_sysrender.h:80
#define GL_UNSIGNED_INT_8_8_8_8_REV
Definition: SDL_opengl.h:1521
#define SDL_GL_CreateContext
const GLuint * framebuffers
SDL_RendererInfo info
#define GL_TEXTURE0_ARB
Definition: SDL_opengl.h:1990
GLenum GLenum dst
#define GL_TRUE
Definition: SDL_opengl.h:200
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
#define GL_YCBCR_422_APPLE
int(* RenderClear)(SDL_Renderer *renderer)
GLuint GLsizei const GLchar * message
#define GL_DEBUG_CALLBACK_USER_PARAM_ARB
#define GL_PROJECTION
Definition: SDL_opengl.h:272
#define GL_TEXTURE2_ARB
Definition: SDL_opengl.h:1992
SDL_BlendMode
The blend mode used in SDL_RenderCopy() and drawing operations.
Definition: SDL_blendmode.h:40
int(* RenderDrawPoints)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
GLuint GLuint GLsizei count
Definition: SDL_opengl.h:1571
SDL_Rect rect
Definition: testrelative.c:27
int(* SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:83
#define GL_LINEAR
Definition: SDL_opengl.h:447
#define SDL_HINT_RENDER_SCALE_QUALITY
A variable controlling the scaling quality.
Definition: SDL_hints.h:142
#define GL_CLAMP_TO_EDGE
Definition: SDL_opengl.h:1507
GLfloat GLfloat GLfloat GLfloat h
#define GL_RGBA8
Definition: SDL_opengl.h:788
void * driverdata
GLfixed GLfixed GLfixed y2
#define APIENTRY
Definition: SDL_opengl.h:139
int GLint
Definition: SDL_opengl.h:182
Uint32 texture_formats[16]
Definition: SDL_render.h:83
static screen_context_t context
Definition: video.c:25
SDL_BlendFactor SDL_GetBlendModeDstAlphaFactor(SDL_BlendMode blendMode)
Definition: SDL_render.c:2171
#define SDL_GetHint
#define SDL_GetWindowFlags
#define SDL_HINT_RENDER_OPENGL_SHADERS
A variable controlling whether the OpenGL render driver uses shaders if they are available.
Definition: SDL_hints.h:95
SDL_BlendOperation SDL_GetBlendModeColorOperation(SDL_BlendMode blendMode)
Definition: SDL_render.c:2157
GLfloat f
#define SDL_BYTESPERPIXEL(X)
Definition: SDL_pixels.h:128
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
#define GL_TEXTURE_MAG_FILTER
Definition: SDL_opengl.h:674
#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB
GLsizei GLsizei GLuint * shaders
void(* UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
#define GL_TEXTURE_STORAGE_HINT_APPLE
SDL_RenderDriver GL_RenderDriver
SDL_Rect clip_rect
#define GL_TRIANGLE_STRIP
Definition: SDL_opengl.h:221
uint32_t Uint32
Definition: SDL_stdinc.h:181
float GLfloat
Definition: SDL_opengl.h:187
#define SDL_realloc
#define SDL_strcasecmp
GLenum src
struct GL_ShaderContext GL_ShaderContext
int max_texture_height
Definition: SDL_render.h:85
#define GL_MAX_TEXTURE_UNITS_ARB
Definition: SDL_opengl.h:2024
#define GL_ONE_MINUS_SRC_ALPHA
Definition: SDL_opengl.h:405
SDL_BlendOperation
The blend operation used when combining source and destination pixel components.
Definition: SDL_blendmode.h:62
#define GL_UNPACK_ROW_LENGTH
Definition: SDL_opengl.h:660
#define SDL_FORCE_INLINE
Definition: begin_code.h:144
#define GL_LUMINANCE
Definition: SDL_opengl.h:510
SDL_Window * window
SDL_RendererInfo info
#define GL_ONE_MINUS_SRC_COLOR
Definition: SDL_opengl.h:403
GLfixed GLfixed x2
#define GL_FRAMEBUFFER_COMPLETE_EXT
GLfixed GLfixed GLint GLint GLfixed points
void(APIENTRY * GLDEBUGPROCARB)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam)
#define GL_PACK_ROW_LENGTH
Definition: SDL_opengl.h:654
#define GL_TEXTURE_RECTANGLE_ARB
#define SDL_GetHintBoolean
GLfixed y1
#define GL_PACK_ALIGNMENT
Definition: SDL_opengl.h:652
void GL_DestroyShaderContext(GL_ShaderContext *ctx)
#define SDL_LogError
#define GL_MAX_TEXTURE_SIZE
Definition: SDL_opengl.h:536
#define GL_NO_ERROR
Definition: SDL_opengl.h:719
static SDL_BlendMode blendMode
Definition: testdraw2.c:34
#define GL_BLEND
Definition: SDL_opengl.h:397
#define GL_TABLE_TOO_LARGE
Definition: SDL_opengl.h:1648
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
#define GL_SRC_COLOR
Definition: SDL_opengl.h:402
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1572
#define SDL_GL_SetAttribute
int(* LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
Definition: SDL_sysrender.h:98
#define SDL_GL_GetDrawableSize
#define GL_ONE_MINUS_DST_ALPHA
Definition: SDL_opengl.h:407
#define SDL_memcpy
GLenum GLenum GLuint texture
void * SDL_calloc(size_t nmemb, size_t size)
SDL_BlendOperation SDL_GetBlendModeAlphaOperation(SDL_BlendMode blendMode)
Definition: SDL_render.c:2178
int(* UpdateTextureYUV)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const Uint8 *Yplane, int Ypitch, const Uint8 *Uplane, int Upitch, const Uint8 *Vplane, int Vpitch)
Definition: SDL_sysrender.h:93
#define SDL_LogDebug
void * SDL_GLContext
An opaque handle to an OpenGL context.
Definition: SDL_video.h:173
#define SDL_GL_GetSwapInterval
GL_Shader
int(* UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
Definition: SDL_sysrender.h:90
GLenum GLenum GLenum input
SDL_Texture * target
int SDL_RecreateWindow(SDL_Window *window, Uint32 flags)
Definition: SDL_video.c:1542
#define GL_STACK_OVERFLOW
Definition: SDL_opengl.h:723
static int GetScaleQuality(void)
static SDL_Renderer * renderer
GLenum GLenum severity
uint8_t Uint8
Definition: SDL_stdinc.h:157
#define SDL_stack_alloc(type, count)
Definition: SDL_stdinc.h:354
struct _cl_event * event
SDL_BlendMode blendMode
#define SDL_GL_SetSwapInterval
#define SDL_GL_GetProcAddress
#define GL_LINE_STRIP
Definition: SDL_opengl.h:219
void SDL_free(void *mem)
#define GL_COLOR_ATTACHMENT0_EXT
#define GL_TEXTURE_WRAP_T
Definition: SDL_opengl.h:673
int(* RenderDrawLines)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
#define GL_LINE_LOOP
Definition: SDL_opengl.h:218
#define GL_LUMINANCE_ALPHA
Definition: SDL_opengl.h:511
#define GL_TEXTURE_2D
Definition: SDL_opengl.h:671
GLubyte GLubyte GLubyte GLubyte w
GLsizei const GLfloat * value
#define GL_UNSIGNED_BYTE
Definition: SDL_opengl.h:204
GLsizei GLsizei GLchar * source
#define GL_DEBUG_CALLBACK_FUNCTION_ARB
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
#define GL_DST_COLOR
Definition: SDL_opengl.h:408
int x
Definition: SDL_rect.h:66
#define GL_TEXTURE1_ARB
Definition: SDL_opengl.h:1991
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: SDL_opengl.h:1572
#define GL_COLOR_BUFFER_BIT
Definition: SDL_opengl.h:742
#define GL_INVALID_VALUE
Definition: SDL_opengl.h:721
void(* DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
int w
Definition: SDL_rect.h:67
int(* RenderCopy)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect)
#define GL_RGB8
Definition: SDL_opengl.h:781
#define GL_STORAGE_SHARED_APPLE
GLsizeiptr size
SDL_RendererFlip
Flip constants for SDL_RenderCopyEx.
Definition: SDL_render.h:111
Window state change event data (event.window.*)
Definition: SDL_events.h:174
#define SDL_assert(condition)
Definition: SDL_assert.h:169
unsigned int GLenum
Definition: SDL_opengl.h:176
GLenum internalFormat
#define GL_POINTS
Definition: SDL_opengl.h:216
#define NULL
Definition: begin_code.h:164
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_bool
Definition: SDL_stdinc.h:139
#define GL_CULL_FACE
Definition: SDL_opengl.h:302
#define GL_MODELVIEW
Definition: SDL_opengl.h:271
#define SDL_GL_GetCurrentContext
SDL_BlendFactor SDL_GetBlendModeSrcAlphaFactor(SDL_BlendMode blendMode)
Definition: SDL_render.c:2164
int(* GetOutputSize)(SDL_Renderer *renderer, int *w, int *h)
Definition: SDL_sysrender.h:81
void GLvoid
Definition: SDL_opengl.h:179
int(* GL_BindTexture)(SDL_Renderer *renderer, SDL_Texture *texture, float *texw, float *texh)
unsigned int GLuint
Definition: SDL_opengl.h:185
#define SDL_SetError
#define GL_OUT_OF_MEMORY
Definition: SDL_opengl.h:725
GLbitfield flags
GLAPI void GLAPIENTRY glActiveTextureARB(GLenum texture)
int(* RenderReadPixels)(SDL_Renderer *renderer, const SDL_Rect *rect, Uint32 format, void *pixels, int pitch)
#define SDL_GL_MakeCurrent
int(* GL_UnbindTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
#define SDL_GetRendererOutputSize
#define GL_FUNC_REVERSE_SUBTRACT
Definition: SDL_opengl.h:1654
#define SDL_LogInfo
SDL_Rect viewport
int(* RenderFillRects)(SDL_Renderer *renderer, const SDL_FRect *rects, int count)
int h
Definition: SDL_rect.h:67
#define SDL_strdup
The type used to identify a window.
Definition: SDL_sysvideo.h:73
#define GL_ZERO
Definition: SDL_opengl.h:400
#define GL_ONE_MINUS_DST_COLOR
Definition: SDL_opengl.h:409
SDL_BlendFactor SDL_GetBlendModeDstColorFactor(SDL_BlendMode blendMode)
Definition: SDL_render.c:2150
GLuint color
SDL_bool(* SupportsBlendMode)(SDL_Renderer *renderer, SDL_BlendMode blendMode)
Definition: SDL_sysrender.h:82
#define GL_SRC_ALPHA
Definition: SDL_opengl.h:404
#define GL_NEAREST
Definition: SDL_opengl.h:704
GLfloat angle
#define GL_FUNC_SUBTRACT
Definition: SDL_opengl.h:1653
Uint32 pixel_format
Definition: testoverlay2.c:152
Uint32 num_texture_formats
Definition: SDL_render.h:82
GLuint GLuint GLsizei GLenum type
Definition: SDL_opengl.h:1571
Uint32 format
Definition: SDL_sysrender.h:52
#define GL_DST_ALPHA
Definition: SDL_opengl.h:406
void * driverdata
Definition: SDL_sysrender.h:69
#define GL_DEPTH_TEST
Definition: SDL_opengl.h:327
#define SDL_malloc
#define SDL_GL_GetAttribute
int(* UpdateViewport)(SDL_Renderer *renderer)
#define SDL_ConvertPixels
#define GL_UNSIGNED_SHORT_8_8_APPLE
int GLsizei
Definition: SDL_opengl.h:186
double GLdouble
Definition: SDL_opengl.h:189
#define SDL_GL_DeleteContext
EGLSurface EGLint * rects
Definition: eglext.h:282
#define SDL_stack_free(data)
Definition: SDL_stdinc.h:355
int(* RenderCopyEx)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcquad, const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
#define GL_TEXTURE_WRAP_S
Definition: SDL_opengl.h:672
GLuint GLsizei GLsizei * length
#define GL_TEXTURE_MIN_FILTER
Definition: SDL_opengl.h:675
void(* RenderPresent)(SDL_Renderer *renderer)
GLboolean GLboolean GLboolean GLboolean a
void(* DestroyRenderer)(SDL_Renderer *renderer)
#define GL_UNPACK_ALIGNMENT
Definition: SDL_opengl.h:658
#define GL_FUNC_ADD
Definition: SDL_opengl.h:1652
#define GL_DEBUG_TYPE_ERROR_ARB
const void * userParam
GLboolean GLboolean g
GLboolean GLboolean GLboolean b
int y
Definition: SDL_rect.h:66
#define SDL_GL_SwapWindow
void GL_SelectShader(GL_ShaderContext *ctx, GL_Shader shader)
SDL_bool clipping_enabled
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:64
GLuint shader
#define GL_BGRA
Definition: SDL_opengl.h:1511
#define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB
#define GL_FRAMEBUFFER_EXT
#define SDL_GetPixelFormatName