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