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  GLint value;
394  Uint32 window_flags;
395  int profile_mask = 0, major = 0, minor = 0;
396  SDL_bool changed_window = SDL_FALSE;
397 
401 
402  window_flags = SDL_GetWindowFlags(window);
403  if (!(window_flags & SDL_WINDOW_OPENGL) ||
404  profile_mask == SDL_GL_CONTEXT_PROFILE_ES || major != RENDERER_CONTEXT_MAJOR || minor != RENDERER_CONTEXT_MINOR) {
405 
406  changed_window = SDL_TRUE;
408  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, RENDERER_CONTEXT_MAJOR);
409  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, RENDERER_CONTEXT_MINOR);
410 
411  if (SDL_RecreateWindow(window, window_flags | SDL_WINDOW_OPENGL) < 0) {
412  goto error;
413  }
414  }
415 
416  renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
417  if (!renderer) {
418  SDL_OutOfMemory();
419  goto error;
420  }
421 
422  data = (GL_RenderData *) SDL_calloc(1, sizeof(*data));
423  if (!data) {
424  GL_DestroyRenderer(renderer);
425  SDL_OutOfMemory();
426  goto error;
427  }
428 
429  renderer->WindowEvent = GL_WindowEvent;
430  renderer->GetOutputSize = GL_GetOutputSize;
431  renderer->CreateTexture = GL_CreateTexture;
432  renderer->UpdateTexture = GL_UpdateTexture;
433  renderer->UpdateTextureYUV = GL_UpdateTextureYUV;
434  renderer->LockTexture = GL_LockTexture;
435  renderer->UnlockTexture = GL_UnlockTexture;
436  renderer->SetRenderTarget = GL_SetRenderTarget;
437  renderer->UpdateViewport = GL_UpdateViewport;
438  renderer->UpdateClipRect = GL_UpdateClipRect;
439  renderer->RenderClear = GL_RenderClear;
440  renderer->RenderDrawPoints = GL_RenderDrawPoints;
441  renderer->RenderDrawLines = GL_RenderDrawLines;
442  renderer->RenderFillRects = GL_RenderFillRects;
443  renderer->RenderCopy = GL_RenderCopy;
444  renderer->RenderCopyEx = GL_RenderCopyEx;
445  renderer->RenderReadPixels = GL_RenderReadPixels;
446  renderer->RenderPresent = GL_RenderPresent;
447  renderer->DestroyTexture = GL_DestroyTexture;
448  renderer->DestroyRenderer = GL_DestroyRenderer;
449  renderer->GL_BindTexture = GL_BindTexture;
450  renderer->GL_UnbindTexture = GL_UnbindTexture;
451  renderer->info = GL_RenderDriver.info;
452  renderer->info.flags = SDL_RENDERER_ACCELERATED;
453  renderer->driverdata = data;
454  renderer->window = window;
455 
456  data->context = SDL_GL_CreateContext(window);
457  if (!data->context) {
458  GL_DestroyRenderer(renderer);
459  goto error;
460  }
461  if (SDL_GL_MakeCurrent(window, data->context) < 0) {
462  GL_DestroyRenderer(renderer);
463  goto error;
464  }
465 
466  if (GL_LoadFunctions(data) < 0) {
467  GL_DestroyRenderer(renderer);
468  goto error;
469  }
470 
471 #ifdef __MACOSX__
472  /* Enable multi-threaded rendering */
473  /* Disabled until Ryan finishes his VBO/PBO code...
474  CGLEnable(CGLGetCurrentContext(), kCGLCEMPEngine);
475  */
476 #endif
477 
478  if (flags & SDL_RENDERER_PRESENTVSYNC) {
480  } else {
482  }
483  if (SDL_GL_GetSwapInterval() > 0) {
484  renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
485  }
486 
487  /* Check for debug output support */
488  if (SDL_GL_GetAttribute(SDL_GL_CONTEXT_FLAGS, &value) == 0 &&
489  (value & SDL_GL_CONTEXT_DEBUG_FLAG)) {
490  data->debug_enabled = SDL_TRUE;
491  }
492  if (data->debug_enabled && SDL_GL_ExtensionSupported("GL_ARB_debug_output")) {
493  PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARBFunc = (PFNGLDEBUGMESSAGECALLBACKARBPROC) SDL_GL_GetProcAddress("glDebugMessageCallbackARB");
494 
495  data->GL_ARB_debug_output_supported = SDL_TRUE;
496  data->glGetPointerv(GL_DEBUG_CALLBACK_FUNCTION_ARB, (GLvoid **)&data->next_error_callback);
497  data->glGetPointerv(GL_DEBUG_CALLBACK_USER_PARAM_ARB, &data->next_error_userparam);
498  glDebugMessageCallbackARBFunc(GL_HandleDebugMessage, renderer);
499 
500  /* Make sure our callback is called when errors actually happen */
501  data->glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
502  }
503 
504  if (SDL_GL_ExtensionSupported("GL_ARB_texture_non_power_of_two")) {
505  data->GL_ARB_texture_non_power_of_two_supported = SDL_TRUE;
506  } else if (SDL_GL_ExtensionSupported("GL_ARB_texture_rectangle") ||
507  SDL_GL_ExtensionSupported("GL_EXT_texture_rectangle")) {
508  data->GL_ARB_texture_rectangle_supported = SDL_TRUE;
509  }
510  if (data->GL_ARB_texture_rectangle_supported) {
511  data->glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, &value);
512  renderer->info.max_texture_width = value;
513  renderer->info.max_texture_height = value;
514  } else {
515  data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
516  renderer->info.max_texture_width = value;
517  renderer->info.max_texture_height = value;
518  }
519 
520  /* Check for multitexture support */
521  if (SDL_GL_ExtensionSupported("GL_ARB_multitexture")) {
522  data->glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC) SDL_GL_GetProcAddress("glActiveTextureARB");
523  if (data->glActiveTextureARB) {
524  data->GL_ARB_multitexture_supported = SDL_TRUE;
525  data->glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &data->num_texture_units);
526  }
527  }
528 
529  /* Check for shader support */
531  data->shaders = GL_CreateShaderContext();
532  }
533  SDL_LogInfo(SDL_LOG_CATEGORY_RENDER, "OpenGL shaders: %s",
534  data->shaders ? "ENABLED" : "DISABLED");
535 
536  /* We support YV12 textures using 3 textures and a shader */
537  if (data->shaders && data->num_texture_units >= 3) {
542  }
543 
544 #ifdef __MACOSX__
546 #endif
547 
548  if (SDL_GL_ExtensionSupported("GL_EXT_framebuffer_object")) {
549  data->GL_EXT_framebuffer_object_supported = SDL_TRUE;
550  data->glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)
551  SDL_GL_GetProcAddress("glGenFramebuffersEXT");
552  data->glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)
553  SDL_GL_GetProcAddress("glDeleteFramebuffersEXT");
554  data->glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)
555  SDL_GL_GetProcAddress("glFramebufferTexture2DEXT");
556  data->glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)
557  SDL_GL_GetProcAddress("glBindFramebufferEXT");
558  data->glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)
559  SDL_GL_GetProcAddress("glCheckFramebufferStatusEXT");
561  }
562  data->framebuffers = NULL;
563 
564  /* Set up parameters for rendering */
565  GL_ResetState(renderer);
566 
567  return renderer;
568 
569 error:
570  if (changed_window) {
571  /* Uh oh, better try to put it back... */
575  SDL_RecreateWindow(window, window_flags);
576  }
577  return NULL;
578 }
579 
580 static void
581 GL_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
582 {
583  if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED ||
584  event->event == SDL_WINDOWEVENT_SHOWN ||
585  event->event == SDL_WINDOWEVENT_HIDDEN) {
586  /* Rebind the context to the window area and update matrices */
587  SDL_CurrentContext = NULL;
588  }
589 }
590 
591 static int
592 GL_GetOutputSize(SDL_Renderer * renderer, int *w, int *h)
593 {
594  SDL_GL_GetDrawableSize(renderer->window, w, h);
595  return 0;
596 }
597 
599 power_of_2(int input)
600 {
601  int value = 1;
602 
603  while (value < input) {
604  value <<= 1;
605  }
606  return value;
607 }
608 
610 convert_format(GL_RenderData *renderdata, Uint32 pixel_format,
612 {
613  switch (pixel_format) {
615  *internalFormat = GL_RGBA8;
616  *format = GL_BGRA;
618  break;
623  *internalFormat = GL_LUMINANCE;
624  *format = GL_LUMINANCE;
625  *type = GL_UNSIGNED_BYTE;
626  break;
627 #ifdef __MACOSX__
629  *internalFormat = GL_RGB8;
630  *format = GL_YCBCR_422_APPLE;
632  break;
633 #endif
634  default:
635  return SDL_FALSE;
636  }
637  return SDL_TRUE;
638 }
639 
640 static GLenum
641 GetScaleQuality(void)
642 {
643  const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
644 
645  if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
646  return GL_NEAREST;
647  } else {
648  return GL_LINEAR;
649  }
650 }
651 
652 static int
653 GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
654 {
655  GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
656  GL_TextureData *data;
657  GLint internalFormat;
658  GLenum format, type;
659  int texture_w, texture_h;
660  GLenum scaleMode;
661 
662  GL_ActivateRenderer(renderer);
663 
664  if (texture->access == SDL_TEXTUREACCESS_TARGET &&
665  !renderdata->GL_EXT_framebuffer_object_supported) {
666  return SDL_SetError("Render targets not supported by OpenGL");
667  }
668 
669  if (!convert_format(renderdata, texture->format, &internalFormat,
670  &format, &type)) {
671  return SDL_SetError("Texture format %s not supported by OpenGL",
672  SDL_GetPixelFormatName(texture->format));
673  }
674 
675  data = (GL_TextureData *) SDL_calloc(1, sizeof(*data));
676  if (!data) {
677  return SDL_OutOfMemory();
678  }
679 
680  if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
681  size_t size;
682  data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
683  size = texture->h * data->pitch;
684  if (texture->format == SDL_PIXELFORMAT_YV12 ||
685  texture->format == SDL_PIXELFORMAT_IYUV) {
686  /* Need to add size for the U and V planes */
687  size += (2 * (texture->h * data->pitch) / 4);
688  }
689  if (texture->format == SDL_PIXELFORMAT_NV12 ||
690  texture->format == SDL_PIXELFORMAT_NV21) {
691  /* Need to add size for the U/V plane */
692  size += ((texture->h * data->pitch) / 2);
693  }
694  data->pixels = SDL_calloc(1, size);
695  if (!data->pixels) {
696  SDL_free(data);
697  return SDL_OutOfMemory();
698  }
699  }
700 
701  if (texture->access == SDL_TEXTUREACCESS_TARGET) {
702  data->fbo = GL_GetFBO(renderdata, texture->w, texture->h);
703  } else {
704  data->fbo = NULL;
705  }
706 
707  GL_CheckError("", renderer);
708  renderdata->glGenTextures(1, &data->texture);
709  if (GL_CheckError("glGenTextures()", renderer) < 0) {
710  if (data->pixels) {
711  SDL_free(data->pixels);
712  }
713  SDL_free(data);
714  return -1;
715  }
716  texture->driverdata = data;
717 
718  if (renderdata->GL_ARB_texture_non_power_of_two_supported) {
719  data->type = GL_TEXTURE_2D;
720  texture_w = texture->w;
721  texture_h = texture->h;
722  data->texw = 1.0f;
723  data->texh = 1.0f;
724  } else if (renderdata->GL_ARB_texture_rectangle_supported) {
725  data->type = GL_TEXTURE_RECTANGLE_ARB;
726  texture_w = texture->w;
727  texture_h = texture->h;
728  data->texw = (GLfloat) texture_w;
729  data->texh = (GLfloat) texture_h;
730  } else {
731  data->type = GL_TEXTURE_2D;
732  texture_w = power_of_2(texture->w);
733  texture_h = power_of_2(texture->h);
734  data->texw = (GLfloat) (texture->w) / texture_w;
735  data->texh = (GLfloat) texture->h / texture_h;
736  }
737 
738  data->format = format;
739  data->formattype = type;
740  scaleMode = GetScaleQuality();
741  renderdata->glEnable(data->type);
742  renderdata->glBindTexture(data->type, data->texture);
743  renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER, scaleMode);
744  renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER, scaleMode);
745  /* According to the spec, CLAMP_TO_EDGE is the default for TEXTURE_RECTANGLE
746  and setting it causes an INVALID_ENUM error in the latest NVidia drivers.
747  */
748  if (data->type != GL_TEXTURE_RECTANGLE_ARB) {
749  renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S,
751  renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T,
753  }
754 #ifdef __MACOSX__
755 #ifndef GL_TEXTURE_STORAGE_HINT_APPLE
756 #define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC
757 #endif
758 #ifndef STORAGE_CACHED_APPLE
759 #define STORAGE_CACHED_APPLE 0x85BE
760 #endif
761 #ifndef STORAGE_SHARED_APPLE
762 #define STORAGE_SHARED_APPLE 0x85BF
763 #endif
764  if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
765  renderdata->glTexParameteri(data->type, GL_TEXTURE_STORAGE_HINT_APPLE,
767  } else {
768  renderdata->glTexParameteri(data->type, GL_TEXTURE_STORAGE_HINT_APPLE,
770  }
771  if (texture->access == SDL_TEXTUREACCESS_STREAMING
772  && texture->format == SDL_PIXELFORMAT_ARGB8888
773  && (texture->w % 8) == 0) {
774  renderdata->glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
775  renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
776  renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH,
777  (data->pitch / SDL_BYTESPERPIXEL(texture->format)));
778  renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w,
779  texture_h, 0, format, type, data->pixels);
780  renderdata->glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
781  }
782  else
783 #endif
784  {
785  renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w,
786  texture_h, 0, format, type, NULL);
787  }
788  renderdata->glDisable(data->type);
789  if (GL_CheckError("glTexImage2D()", renderer) < 0) {
790  return -1;
791  }
792 
793  if (texture->format == SDL_PIXELFORMAT_YV12 ||
794  texture->format == SDL_PIXELFORMAT_IYUV) {
795  data->yuv = SDL_TRUE;
796 
797  renderdata->glGenTextures(1, &data->utexture);
798  renderdata->glGenTextures(1, &data->vtexture);
799  renderdata->glEnable(data->type);
800 
801  renderdata->glBindTexture(data->type, data->utexture);
802  renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER,
803  scaleMode);
804  renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER,
805  scaleMode);
806  renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S,
808  renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T,
810  renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w/2,
811  texture_h/2, 0, format, type, NULL);
812 
813  renderdata->glBindTexture(data->type, data->vtexture);
814  renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER,
815  scaleMode);
816  renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER,
817  scaleMode);
818  renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S,
820  renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T,
822  renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w/2,
823  texture_h/2, 0, format, type, NULL);
824 
825  renderdata->glDisable(data->type);
826  }
827 
828  if (texture->format == SDL_PIXELFORMAT_NV12 ||
829  texture->format == SDL_PIXELFORMAT_NV21) {
830  data->nv12 = SDL_TRUE;
831 
832  renderdata->glGenTextures(1, &data->utexture);
833  renderdata->glEnable(data->type);
834 
835  renderdata->glBindTexture(data->type, data->utexture);
836  renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER,
837  scaleMode);
838  renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER,
839  scaleMode);
840  renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S,
842  renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T,
844  renderdata->glTexImage2D(data->type, 0, GL_LUMINANCE_ALPHA, texture_w/2,
845  texture_h/2, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL);
846  renderdata->glDisable(data->type);
847  }
848 
849  return GL_CheckError("", renderer);
850 }
851 
852 static int
853 GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
854  const SDL_Rect * rect, const void *pixels, int pitch)
855 {
856  GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
857  GL_TextureData *data = (GL_TextureData *) texture->driverdata;
858  const int texturebpp = SDL_BYTESPERPIXEL(texture->format);
859 
860  SDL_assert(texturebpp != 0); /* otherwise, division by zero later. */
861 
862  GL_ActivateRenderer(renderer);
863 
864  renderdata->glEnable(data->type);
865  renderdata->glBindTexture(data->type, data->texture);
866  renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
867  renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, (pitch / texturebpp));
868  renderdata->glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w,
869  rect->h, data->format, data->formattype,
870  pixels);
871  if (data->yuv) {
872  renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, (pitch / 2));
873 
874  /* Skip to the correct offset into the next texture */
875  pixels = (const void*)((const Uint8*)pixels + rect->h * pitch);
876  if (texture->format == SDL_PIXELFORMAT_YV12) {
877  renderdata->glBindTexture(data->type, data->vtexture);
878  } else {
879  renderdata->glBindTexture(data->type, data->utexture);
880  }
881  renderdata->glTexSubImage2D(data->type, 0, rect->x/2, rect->y/2,
882  rect->w/2, rect->h/2,
883  data->format, data->formattype, pixels);
884 
885  /* Skip to the correct offset into the next texture */
886  pixels = (const void*)((const Uint8*)pixels + (rect->h * pitch)/4);
887  if (texture->format == SDL_PIXELFORMAT_YV12) {
888  renderdata->glBindTexture(data->type, data->utexture);
889  } else {
890  renderdata->glBindTexture(data->type, data->vtexture);
891  }
892  renderdata->glTexSubImage2D(data->type, 0, rect->x/2, rect->y/2,
893  rect->w/2, rect->h/2,
894  data->format, data->formattype, pixels);
895  }
896 
897  if (data->nv12) {
898  renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, (pitch / 2));
899 
900  /* Skip to the correct offset into the next texture */
901  pixels = (const void*)((const Uint8*)pixels + rect->h * pitch);
902  renderdata->glBindTexture(data->type, data->utexture);
903  renderdata->glTexSubImage2D(data->type, 0, rect->x/2, rect->y/2,
904  rect->w/2, rect->h/2,
906  }
907  renderdata->glDisable(data->type);
908 
909  return GL_CheckError("glTexSubImage2D()", renderer);
910 }
911 
912 static int
913 GL_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
914  const SDL_Rect * rect,
915  const Uint8 *Yplane, int Ypitch,
916  const Uint8 *Uplane, int Upitch,
917  const Uint8 *Vplane, int Vpitch)
918 {
919  GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
920  GL_TextureData *data = (GL_TextureData *) texture->driverdata;
921 
922  GL_ActivateRenderer(renderer);
923 
924  renderdata->glEnable(data->type);
925  renderdata->glBindTexture(data->type, data->texture);
926  renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
927  renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, Ypitch);
928  renderdata->glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w,
929  rect->h, data->format, data->formattype,
930  Yplane);
931 
932  renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, Upitch);
933  renderdata->glBindTexture(data->type, data->utexture);
934  renderdata->glTexSubImage2D(data->type, 0, rect->x/2, rect->y/2,
935  rect->w/2, rect->h/2,
936  data->format, data->formattype, Uplane);
937 
938  renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, Vpitch);
939  renderdata->glBindTexture(data->type, data->vtexture);
940  renderdata->glTexSubImage2D(data->type, 0, rect->x/2, rect->y/2,
941  rect->w/2, rect->h/2,
942  data->format, data->formattype, Vplane);
943  renderdata->glDisable(data->type);
944 
945  return GL_CheckError("glTexSubImage2D()", renderer);
946 }
947 
948 static int
949 GL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
950  const SDL_Rect * rect, void **pixels, int *pitch)
951 {
952  GL_TextureData *data = (GL_TextureData *) texture->driverdata;
953 
954  data->locked_rect = *rect;
955  *pixels =
956  (void *) ((Uint8 *) data->pixels + rect->y * data->pitch +
957  rect->x * SDL_BYTESPERPIXEL(texture->format));
958  *pitch = data->pitch;
959  return 0;
960 }
961 
962 static void
963 GL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
964 {
965  GL_TextureData *data = (GL_TextureData *) texture->driverdata;
966  const SDL_Rect *rect;
967  void *pixels;
968 
969  rect = &data->locked_rect;
970  pixels =
971  (void *) ((Uint8 *) data->pixels + rect->y * data->pitch +
972  rect->x * SDL_BYTESPERPIXEL(texture->format));
973  GL_UpdateTexture(renderer, texture, rect, pixels, data->pitch);
974 }
975 
976 static int
977 GL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
978 {
979  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
980  GL_TextureData *texturedata;
981  GLenum status;
982 
983  GL_ActivateRenderer(renderer);
984 
985  if (!data->GL_EXT_framebuffer_object_supported) {
986  return SDL_SetError("Render targets not supported by OpenGL");
987  }
988 
989  if (texture == NULL) {
990  data->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
991  return 0;
992  }
993 
994  texturedata = (GL_TextureData *) texture->driverdata;
995  data->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, texturedata->fbo->FBO);
996  /* TODO: check if texture pixel format allows this operation */
997  data->glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, texturedata->type, texturedata->texture, 0);
998  /* Check FBO status */
999  status = data->glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
1000  if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
1001  return SDL_SetError("glFramebufferTexture2DEXT() failed");
1002  }
1003  return 0;
1004 }
1005 
1006 static int
1007 GL_UpdateViewport(SDL_Renderer * renderer)
1008 {
1009  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1010 
1011  if (SDL_CurrentContext != data->context) {
1012  /* We'll update the viewport after we rebind the context */
1013  return 0;
1014  }
1015 
1016  if (renderer->target) {
1017  data->glViewport(renderer->viewport.x, renderer->viewport.y,
1018  renderer->viewport.w, renderer->viewport.h);
1019  } else {
1020  int w, h;
1021 
1022  SDL_GL_GetDrawableSize(renderer->window, &w, &h);
1023  data->glViewport(renderer->viewport.x, (h - renderer->viewport.y - renderer->viewport.h),
1024  renderer->viewport.w, renderer->viewport.h);
1025  }
1026 
1027  data->glMatrixMode(GL_PROJECTION);
1028  data->glLoadIdentity();
1029  if (renderer->viewport.w && renderer->viewport.h) {
1030  if (renderer->target) {
1031  data->glOrtho((GLdouble) 0,
1032  (GLdouble) renderer->viewport.w,
1033  (GLdouble) 0,
1034  (GLdouble) renderer->viewport.h,
1035  0.0, 1.0);
1036  } else {
1037  data->glOrtho((GLdouble) 0,
1038  (GLdouble) renderer->viewport.w,
1039  (GLdouble) renderer->viewport.h,
1040  (GLdouble) 0,
1041  0.0, 1.0);
1042  }
1043  }
1044  return GL_CheckError("", renderer);
1045 }
1046 
1047 static int
1048 GL_UpdateClipRect(SDL_Renderer * renderer)
1049 {
1050  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1051 
1052  if (renderer->clipping_enabled) {
1053  const SDL_Rect *rect = &renderer->clip_rect;
1054  data->glEnable(GL_SCISSOR_TEST);
1055  if (renderer->target) {
1056  data->glScissor(renderer->viewport.x + rect->x, renderer->viewport.y + rect->y, rect->w, rect->h);
1057  } else {
1058  int w, h;
1059 
1060  SDL_GL_GetDrawableSize(renderer->window, &w, &h);
1061  data->glScissor(renderer->viewport.x + rect->x, h - renderer->viewport.y - rect->y - rect->h, rect->w, rect->h);
1062  }
1063  } else {
1064  data->glDisable(GL_SCISSOR_TEST);
1065  }
1066  return 0;
1067 }
1068 
1069 static void
1070 GL_SetShader(GL_RenderData * data, GL_Shader shader)
1071 {
1072  if (data->shaders && shader != data->current.shader) {
1073  GL_SelectShader(data->shaders, shader);
1074  data->current.shader = shader;
1075  }
1076 }
1077 
1078 static void
1079 GL_SetColor(GL_RenderData * data, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
1080 {
1081  Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b);
1082 
1083  if (color != data->current.color) {
1084  data->glColor4f((GLfloat) r * inv255f,
1085  (GLfloat) g * inv255f,
1086  (GLfloat) b * inv255f,
1087  (GLfloat) a * inv255f);
1088  data->current.color = color;
1089  }
1090 }
1091 
1092 static void
1093 GL_SetBlendMode(GL_RenderData * data, int blendMode)
1094 {
1095  if (blendMode != data->current.blendMode) {
1096  switch (blendMode) {
1097  case SDL_BLENDMODE_NONE:
1098  data->glDisable(GL_BLEND);
1099  break;
1100  case SDL_BLENDMODE_BLEND:
1101  data->glEnable(GL_BLEND);
1102  data->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1103  break;
1104  case SDL_BLENDMODE_ADD:
1105  data->glEnable(GL_BLEND);
1106  data->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ZERO, GL_ONE);
1107  break;
1108  case SDL_BLENDMODE_MOD:
1109  data->glEnable(GL_BLEND);
1110  data->glBlendFuncSeparate(GL_ZERO, GL_SRC_COLOR, GL_ZERO, GL_ONE);
1111  break;
1112  }
1113  data->current.blendMode = blendMode;
1114  }
1115 }
1116 
1117 static void
1118 GL_SetDrawingState(SDL_Renderer * renderer)
1119 {
1120  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1121 
1122  GL_ActivateRenderer(renderer);
1123 
1124  GL_SetColor(data, renderer->r,
1125  renderer->g,
1126  renderer->b,
1127  renderer->a);
1128 
1129  GL_SetBlendMode(data, renderer->blendMode);
1130 
1131  GL_SetShader(data, SHADER_SOLID);
1132 }
1133 
1134 static int
1135 GL_RenderClear(SDL_Renderer * renderer)
1136 {
1137  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1138 
1139  GL_ActivateRenderer(renderer);
1140 
1141  data->glClearColor((GLfloat) renderer->r * inv255f,
1142  (GLfloat) renderer->g * inv255f,
1143  (GLfloat) renderer->b * inv255f,
1144  (GLfloat) renderer->a * inv255f);
1145 
1146  if (renderer->clipping_enabled) {
1147  data->glDisable(GL_SCISSOR_TEST);
1148  }
1149 
1150  data->glClear(GL_COLOR_BUFFER_BIT);
1151 
1152  if (renderer->clipping_enabled) {
1153  data->glEnable(GL_SCISSOR_TEST);
1154  }
1155 
1156  return 0;
1157 }
1158 
1159 static int
1160 GL_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points,
1161  int count)
1162 {
1163  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1164  int i;
1165 
1166  GL_SetDrawingState(renderer);
1167 
1168  data->glBegin(GL_POINTS);
1169  for (i = 0; i < count; ++i) {
1170  data->glVertex2f(0.5f + points[i].x, 0.5f + points[i].y);
1171  }
1172  data->glEnd();
1173 
1174  return 0;
1175 }
1176 
1177 static int
1178 GL_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points,
1179  int count)
1180 {
1181  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1182  int i;
1183 
1184  GL_SetDrawingState(renderer);
1185 
1186  if (count > 2 &&
1187  points[0].x == points[count-1].x && points[0].y == points[count-1].y) {
1188  data->glBegin(GL_LINE_LOOP);
1189  /* GL_LINE_LOOP takes care of the final segment */
1190  --count;
1191  for (i = 0; i < count; ++i) {
1192  data->glVertex2f(0.5f + points[i].x, 0.5f + points[i].y);
1193  }
1194  data->glEnd();
1195  } else {
1196 #if defined(__MACOSX__) || defined(__WIN32__)
1197 #else
1198  int x1, y1, x2, y2;
1199 #endif
1200 
1201  data->glBegin(GL_LINE_STRIP);
1202  for (i = 0; i < count; ++i) {
1203  data->glVertex2f(0.5f + points[i].x, 0.5f + points[i].y);
1204  }
1205  data->glEnd();
1206 
1207  /* The line is half open, so we need one more point to complete it.
1208  * http://www.opengl.org/documentation/specs/version1.1/glspec1.1/node47.html
1209  * If we have to, we can use vertical line and horizontal line textures
1210  * for vertical and horizontal lines, and then create custom textures
1211  * for diagonal lines and software render those. It's terrible, but at
1212  * least it would be pixel perfect.
1213  */
1214  data->glBegin(GL_POINTS);
1215 #if defined(__MACOSX__) || defined(__WIN32__)
1216  /* Mac OS X and Windows seem to always leave the last point open */
1217  data->glVertex2f(0.5f + points[count-1].x, 0.5f + points[count-1].y);
1218 #else
1219  /* Linux seems to leave the right-most or bottom-most point open */
1220  x1 = points[0].x;
1221  y1 = points[0].y;
1222  x2 = points[count-1].x;
1223  y2 = points[count-1].y;
1224 
1225  if (x1 > x2) {
1226  data->glVertex2f(0.5f + x1, 0.5f + y1);
1227  } else if (x2 > x1) {
1228  data->glVertex2f(0.5f + x2, 0.5f + y2);
1229  }
1230  if (y1 > y2) {
1231  data->glVertex2f(0.5f + x1, 0.5f + y1);
1232  } else if (y2 > y1) {
1233  data->glVertex2f(0.5f + x2, 0.5f + y2);
1234  }
1235 #endif
1236  data->glEnd();
1237  }
1238  return GL_CheckError("", renderer);
1239 }
1240 
1241 static int
1242 GL_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, int count)
1243 {
1244  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1245  int i;
1246 
1247  GL_SetDrawingState(renderer);
1248 
1249  for (i = 0; i < count; ++i) {
1250  const SDL_FRect *rect = &rects[i];
1251 
1252  data->glRectf(rect->x, rect->y, rect->x + rect->w, rect->y + rect->h);
1253  }
1254  return GL_CheckError("", renderer);
1255 }
1256 
1257 static int
1258 GL_SetupCopy(SDL_Renderer * renderer, SDL_Texture * texture)
1259 {
1260  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1261  GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata;
1262 
1263  data->glEnable(texturedata->type);
1264  if (texturedata->yuv) {
1265  data->glActiveTextureARB(GL_TEXTURE2_ARB);
1266  data->glBindTexture(texturedata->type, texturedata->vtexture);
1267 
1268  data->glActiveTextureARB(GL_TEXTURE1_ARB);
1269  data->glBindTexture(texturedata->type, texturedata->utexture);
1270 
1271  data->glActiveTextureARB(GL_TEXTURE0_ARB);
1272  }
1273  if (texturedata->nv12) {
1274  data->glActiveTextureARB(GL_TEXTURE1_ARB);
1275  data->glBindTexture(texturedata->type, texturedata->utexture);
1276 
1277  data->glActiveTextureARB(GL_TEXTURE0_ARB);
1278  }
1279  data->glBindTexture(texturedata->type, texturedata->texture);
1280 
1281  if (texture->modMode) {
1282  GL_SetColor(data, texture->r, texture->g, texture->b, texture->a);
1283  } else {
1284  GL_SetColor(data, 255, 255, 255, 255);
1285  }
1286 
1287  GL_SetBlendMode(data, texture->blendMode);
1288 
1289  if (texturedata->yuv) {
1290  GL_SetShader(data, SHADER_YUV);
1291  } else if (texturedata->nv12) {
1292  if (texture->format == SDL_PIXELFORMAT_NV12) {
1293  GL_SetShader(data, SHADER_NV12);
1294  } else {
1295  GL_SetShader(data, SHADER_NV21);
1296  }
1297  } else {
1298  GL_SetShader(data, SHADER_RGB);
1299  }
1300  return 0;
1301 }
1302 
1303 static int
1304 GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
1305  const SDL_Rect * srcrect, const SDL_FRect * dstrect)
1306 {
1307  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1308  GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata;
1309  GLfloat minx, miny, maxx, maxy;
1310  GLfloat minu, maxu, minv, maxv;
1311 
1312  GL_ActivateRenderer(renderer);
1313 
1314  if (GL_SetupCopy(renderer, texture) < 0) {
1315  return -1;
1316  }
1317 
1318  minx = dstrect->x;
1319  miny = dstrect->y;
1320  maxx = dstrect->x + dstrect->w;
1321  maxy = dstrect->y + dstrect->h;
1322 
1323  minu = (GLfloat) srcrect->x / texture->w;
1324  minu *= texturedata->texw;
1325  maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w;
1326  maxu *= texturedata->texw;
1327  minv = (GLfloat) srcrect->y / texture->h;
1328  minv *= texturedata->texh;
1329  maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h;
1330  maxv *= texturedata->texh;
1331 
1332  data->glBegin(GL_TRIANGLE_STRIP);
1333  data->glTexCoord2f(minu, minv);
1334  data->glVertex2f(minx, miny);
1335  data->glTexCoord2f(maxu, minv);
1336  data->glVertex2f(maxx, miny);
1337  data->glTexCoord2f(minu, maxv);
1338  data->glVertex2f(minx, maxy);
1339  data->glTexCoord2f(maxu, maxv);
1340  data->glVertex2f(maxx, maxy);
1341  data->glEnd();
1342 
1343  data->glDisable(texturedata->type);
1344 
1345  return GL_CheckError("", renderer);
1346 }
1347 
1348 static int
1349 GL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
1350  const SDL_Rect * srcrect, const SDL_FRect * dstrect,
1351  const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
1352 {
1353  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1354  GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata;
1355  GLfloat minx, miny, maxx, maxy;
1356  GLfloat centerx, centery;
1357  GLfloat minu, maxu, minv, maxv;
1358 
1359  GL_ActivateRenderer(renderer);
1360 
1361  if (GL_SetupCopy(renderer, texture) < 0) {
1362  return -1;
1363  }
1364 
1365  centerx = center->x;
1366  centery = center->y;
1367 
1368  if (flip & SDL_FLIP_HORIZONTAL) {
1369  minx = dstrect->w - centerx;
1370  maxx = -centerx;
1371  }
1372  else {
1373  minx = -centerx;
1374  maxx = dstrect->w - centerx;
1375  }
1376 
1377  if (flip & SDL_FLIP_VERTICAL) {
1378  miny = dstrect->h - centery;
1379  maxy = -centery;
1380  }
1381  else {
1382  miny = -centery;
1383  maxy = dstrect->h - centery;
1384  }
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  /* Translate to flip, rotate, translate to position */
1396  data->glPushMatrix();
1397  data->glTranslatef((GLfloat)dstrect->x + centerx, (GLfloat)dstrect->y + centery, (GLfloat)0.0);
1398  data->glRotated(angle, (GLdouble)0.0, (GLdouble)0.0, (GLdouble)1.0);
1399 
1400  data->glBegin(GL_TRIANGLE_STRIP);
1401  data->glTexCoord2f(minu, minv);
1402  data->glVertex2f(minx, miny);
1403  data->glTexCoord2f(maxu, minv);
1404  data->glVertex2f(maxx, miny);
1405  data->glTexCoord2f(minu, maxv);
1406  data->glVertex2f(minx, maxy);
1407  data->glTexCoord2f(maxu, maxv);
1408  data->glVertex2f(maxx, maxy);
1409  data->glEnd();
1410  data->glPopMatrix();
1411 
1412  data->glDisable(texturedata->type);
1413 
1414  return GL_CheckError("", renderer);
1415 }
1416 
1417 static int
1418 GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
1419  Uint32 pixel_format, void * pixels, int pitch)
1420 {
1421  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1422  Uint32 temp_format = renderer->target ? renderer->target->format : SDL_PIXELFORMAT_ARGB8888;
1423  void *temp_pixels;
1424  int temp_pitch;
1425  GLint internalFormat;
1426  GLenum format, type;
1427  Uint8 *src, *dst, *tmp;
1428  int w, h, length, rows;
1429  int status;
1430 
1431  GL_ActivateRenderer(renderer);
1432 
1433  temp_pitch = rect->w * SDL_BYTESPERPIXEL(temp_format);
1434  temp_pixels = SDL_malloc(rect->h * temp_pitch);
1435  if (!temp_pixels) {
1436  return SDL_OutOfMemory();
1437  }
1438 
1439  if (!convert_format(data, temp_format, &internalFormat, &format, &type)) {
1440  SDL_free(temp_pixels);
1441  return SDL_SetError("Texture format %s not supported by OpenGL",
1442  SDL_GetPixelFormatName(temp_format));
1443  }
1444 
1445  SDL_GetRendererOutputSize(renderer, &w, &h);
1446 
1447  data->glPixelStorei(GL_PACK_ALIGNMENT, 1);
1448  data->glPixelStorei(GL_PACK_ROW_LENGTH,
1449  (temp_pitch / SDL_BYTESPERPIXEL(temp_format)));
1450 
1451  data->glReadPixels(rect->x, renderer->target ? rect->y : (h-rect->y)-rect->h,
1452  rect->w, rect->h, format, type, temp_pixels);
1453 
1454  if (GL_CheckError("glReadPixels()", renderer) < 0) {
1455  SDL_free(temp_pixels);
1456  return -1;
1457  }
1458 
1459  /* Flip the rows to be top-down if necessary */
1460  if (!renderer->target) {
1461  length = rect->w * SDL_BYTESPERPIXEL(temp_format);
1462  src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch;
1463  dst = (Uint8*)temp_pixels;
1464  tmp = SDL_stack_alloc(Uint8, length);
1465  rows = rect->h / 2;
1466  while (rows--) {
1467  SDL_memcpy(tmp, dst, length);
1468  SDL_memcpy(dst, src, length);
1469  SDL_memcpy(src, tmp, length);
1470  dst += temp_pitch;
1471  src -= temp_pitch;
1472  }
1473  SDL_stack_free(tmp);
1474  }
1475 
1476  status = SDL_ConvertPixels(rect->w, rect->h,
1477  temp_format, temp_pixels, temp_pitch,
1478  pixel_format, pixels, pitch);
1479  SDL_free(temp_pixels);
1480 
1481  return status;
1482 }
1483 
1484 static void
1485 GL_RenderPresent(SDL_Renderer * renderer)
1486 {
1487  GL_ActivateRenderer(renderer);
1488 
1489  SDL_GL_SwapWindow(renderer->window);
1490 }
1491 
1492 static void
1493 GL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
1494 {
1495  GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
1496  GL_TextureData *data = (GL_TextureData *) texture->driverdata;
1497 
1498  GL_ActivateRenderer(renderer);
1499 
1500  if (!data) {
1501  return;
1502  }
1503  if (data->texture) {
1504  renderdata->glDeleteTextures(1, &data->texture);
1505  }
1506  if (data->yuv) {
1507  renderdata->glDeleteTextures(1, &data->utexture);
1508  renderdata->glDeleteTextures(1, &data->vtexture);
1509  }
1510  SDL_free(data->pixels);
1511  SDL_free(data);
1512  texture->driverdata = NULL;
1513 }
1514 
1515 static void
1516 GL_DestroyRenderer(SDL_Renderer * renderer)
1517 {
1518  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1519 
1520  if (data) {
1521  GL_ClearErrors(renderer);
1522  if (data->GL_ARB_debug_output_supported) {
1523  PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARBFunc = (PFNGLDEBUGMESSAGECALLBACKARBPROC) SDL_GL_GetProcAddress("glDebugMessageCallbackARB");
1524 
1525  /* Uh oh, we don't have a safe way of removing ourselves from the callback chain, if it changed after we set our callback. */
1526  /* For now, just always replace the callback with the original one */
1527  glDebugMessageCallbackARBFunc(data->next_error_callback, data->next_error_userparam);
1528  }
1529  if (data->shaders) {
1530  GL_DestroyShaderContext(data->shaders);
1531  }
1532  if (data->context) {
1533  while (data->framebuffers) {
1534  GL_FBOList *nextnode = data->framebuffers->next;
1535  /* delete the framebuffer object */
1536  data->glDeleteFramebuffersEXT(1, &data->framebuffers->FBO);
1537  GL_CheckError("", renderer);
1538  SDL_free(data->framebuffers);
1539  data->framebuffers = nextnode;
1540  }
1541  SDL_GL_DeleteContext(data->context);
1542  }
1543  SDL_free(data);
1544  }
1545  SDL_free(renderer);
1546 }
1547 
1548 static int
1549 GL_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, float *texh)
1550 {
1551  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1552  GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata;
1553  GL_ActivateRenderer(renderer);
1554 
1555  data->glEnable(texturedata->type);
1556  if (texturedata->yuv) {
1557  data->glActiveTextureARB(GL_TEXTURE2_ARB);
1558  data->glBindTexture(texturedata->type, texturedata->vtexture);
1559 
1560  data->glActiveTextureARB(GL_TEXTURE1_ARB);
1561  data->glBindTexture(texturedata->type, texturedata->utexture);
1562 
1563  data->glActiveTextureARB(GL_TEXTURE0_ARB);
1564  }
1565  data->glBindTexture(texturedata->type, texturedata->texture);
1566 
1567  if(texw) *texw = (float)texturedata->texw;
1568  if(texh) *texh = (float)texturedata->texh;
1569 
1570  return 0;
1571 }
1572 
1573 static int
1574 GL_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture)
1575 {
1576  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1577  GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata;
1578  GL_ActivateRenderer(renderer);
1579 
1580  if (texturedata->yuv) {
1581  data->glActiveTextureARB(GL_TEXTURE2_ARB);
1582  data->glDisable(texturedata->type);
1583 
1584  data->glActiveTextureARB(GL_TEXTURE1_ARB);
1585  data->glDisable(texturedata->type);
1586 
1587  data->glActiveTextureARB(GL_TEXTURE0_ARB);
1588  }
1589 
1590  data->glDisable(texturedata->type);
1591 
1592  return 0;
1593 }
1594 
1595 #endif /* SDL_VIDEO_RENDER_OGL && !SDL_RENDER_DISABLED */
1596 
1597 /* 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
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1565
#define SDL_GL_ExtensionSupported
#define GL_INVALID_ENUM
Definition: SDL_opengl.h:713
int(* RenderDrawPoints)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
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
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2072
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
#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
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1567
GLuint GLuint GLsizei count
Definition: SDL_opengl.h:1564
SDL_Rect rect
Definition: testrelative.c:27
#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
static SDL_Window * window
#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
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:128
#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
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:159
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
#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_TEXTURE_RECTANGLE_ARB
#define SDL_GetHintBoolean
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
#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
#define SDL_GL_SetAttribute
#define SDL_GL_GetDrawableSize
GLuint GLuint GLsizei GLenum type
Definition: SDL_opengl.h:1564
#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:172
#define SDL_GL_GetSwapInterval
GL_Shader
GLenum GLenum GLenum input
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1567
SDL_Texture * target
int SDL_RecreateWindow(SDL_Window *window, Uint32 flags)
Definition: SDL_video.c:1509
GLsizei const GLfloat * value
#define GL_STACK_OVERFLOW
Definition: SDL_opengl.h:716
static int GetScaleQuality(void)
static SDL_Renderer * renderer
GLenum GLenum severity
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:143
#define SDL_stack_alloc(type, count)
Definition: SDL_stdinc.h:328
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
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
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:174
#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
SDL_bool
Definition: SDL_stdinc.h:130
#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
#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
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
#define SDL_GL_DeleteContext
#define SDL_stack_free(data)
Definition: SDL_stdinc.h:329
#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