zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_render_gl.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2013 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_config.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_opengl.h"
28 #include "../SDL_sysrender.h"
29 #include "SDL_shaders_gl.h"
30 
31 #ifdef __MACOSX__
32 #include <OpenGL/OpenGL.h>
33 #endif
34 
35 
36 /* OpenGL renderer implementation */
37 
38 /* Details on optimizing the texture path on Mac OS X:
39  http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_texturedata/opengl_texturedata.html
40 */
41 
42 /* Used to re-create the window with OpenGL capability */
43 extern int SDL_RecreateWindow(SDL_Window * window, Uint32 flags);
44 
45 static const float inv255f = 1.0f / 255.0f;
46 
47 static SDL_Renderer *GL_CreateRenderer(SDL_Window * window, Uint32 flags);
48 static void GL_WindowEvent(SDL_Renderer * renderer,
49  const SDL_WindowEvent *event);
50 static int GL_GetOutputSize(SDL_Renderer * renderer, int *w, int *h);
51 static int GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
52 static int GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
53  const SDL_Rect * rect, const void *pixels,
54  int pitch);
55 static int GL_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
56  const SDL_Rect * rect,
57  const Uint8 *Yplane, int Ypitch,
58  const Uint8 *Uplane, int Upitch,
59  const Uint8 *Vplane, int Vpitch);
60 static int GL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
61  const SDL_Rect * rect, void **pixels, int *pitch);
62 static void GL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
63 static int GL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture);
64 static int GL_UpdateViewport(SDL_Renderer * renderer);
65 static int GL_UpdateClipRect(SDL_Renderer * renderer);
66 static int GL_RenderClear(SDL_Renderer * renderer);
67 static int GL_RenderDrawPoints(SDL_Renderer * renderer,
68  const SDL_FPoint * points, int count);
69 static int GL_RenderDrawLines(SDL_Renderer * renderer,
70  const SDL_FPoint * points, int count);
71 static int GL_RenderFillRects(SDL_Renderer * renderer,
72  const SDL_FRect * rects, int count);
73 static int GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
74  const SDL_Rect * srcrect, const SDL_FRect * dstrect);
75 static int GL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
76  const SDL_Rect * srcrect, const SDL_FRect * dstrect,
77  const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip);
78 static int GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
79  Uint32 pixel_format, void * pixels, int pitch);
80 static void GL_RenderPresent(SDL_Renderer * renderer);
81 static void GL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture);
82 static void GL_DestroyRenderer(SDL_Renderer * renderer);
83 static int GL_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, float *texh);
84 static int GL_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture);
85 
86 SDL_RenderDriver GL_RenderDriver = {
87  GL_CreateRenderer,
88  {
89  "opengl",
91  1,
93  0,
94  0}
95 };
96 
97 typedef struct GL_FBOList GL_FBOList;
98 
99 struct GL_FBOList
100 {
101  Uint32 w, h;
102  GLuint FBO;
103  GL_FBOList *next;
104 };
105 
106 typedef struct
107 {
109 
110  SDL_bool debug_enabled;
111  SDL_bool GL_ARB_debug_output_supported;
112  int errors;
113  char **error_messages;
114  GLDEBUGPROCARB next_error_callback;
115  GLvoid *next_error_userparam;
116 
117  SDL_bool GL_ARB_texture_rectangle_supported;
118  struct {
120  Uint32 color;
121  int blendMode;
122  } current;
123 
124  SDL_bool GL_EXT_framebuffer_object_supported;
125  GL_FBOList *framebuffers;
126 
127  /* OpenGL functions */
128 #define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
129 #include "SDL_glfuncs.h"
130 #undef SDL_PROC
131 
132  /* Multitexture support */
133  SDL_bool GL_ARB_multitexture_supported;
134  PFNGLACTIVETEXTUREARBPROC glActiveTextureARB;
135  GLint num_texture_units;
136 
137  PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT;
138  PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT;
139  PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT;
140  PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT;
141  PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT;
142 
143  /* Shader support */
145 
146 } GL_RenderData;
147 
148 typedef struct
149 {
150  GLuint texture;
151  GLenum type;
152  GLfloat texw;
153  GLfloat texh;
154  GLenum format;
155  GLenum formattype;
156  void *pixels;
157  int pitch;
158  SDL_Rect locked_rect;
159 
160  /* YV12 texture support */
161  SDL_bool yuv;
162  GLuint utexture;
163  GLuint vtexture;
164 
165  GL_FBOList *fbo;
166 } GL_TextureData;
167 
168 SDL_FORCE_INLINE const char*
169 GL_TranslateError (GLenum error)
170 {
171 #define GL_ERROR_TRANSLATE(e) case e: return #e;
172  switch (error) {
173  GL_ERROR_TRANSLATE(GL_INVALID_ENUM)
174  GL_ERROR_TRANSLATE(GL_INVALID_VALUE)
175  GL_ERROR_TRANSLATE(GL_INVALID_OPERATION)
176  GL_ERROR_TRANSLATE(GL_OUT_OF_MEMORY)
177  GL_ERROR_TRANSLATE(GL_NO_ERROR)
178  GL_ERROR_TRANSLATE(GL_STACK_OVERFLOW)
179  GL_ERROR_TRANSLATE(GL_STACK_UNDERFLOW)
180  GL_ERROR_TRANSLATE(GL_TABLE_TOO_LARGE)
181  default:
182  return "UNKNOWN";
183 }
184 #undef GL_ERROR_TRANSLATE
185 }
186 
187 SDL_FORCE_INLINE void
188 GL_ClearErrors(SDL_Renderer *renderer)
189 {
190  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
191 
192  if (!data->debug_enabled)
193  {
194  return;
195  }
196  if (data->GL_ARB_debug_output_supported) {
197  if (data->errors) {
198  int i;
199  for (i = 0; i < data->errors; ++i) {
200  SDL_free(data->error_messages[i]);
201  }
202  SDL_free(data->error_messages);
203 
204  data->errors = 0;
205  data->error_messages = NULL;
206  }
207  } else {
208  while (data->glGetError() != GL_NO_ERROR) {
209  continue;
210  }
211  }
212 }
213 
215 GL_CheckAllErrors (const char *prefix, SDL_Renderer *renderer, const char *file, int line, const char *function)
216 {
217  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
218  int ret = 0;
219 
220  if (!data->debug_enabled)
221  {
222  return 0;
223  }
224  if (data->GL_ARB_debug_output_supported) {
225  if (data->errors) {
226  int i;
227  for (i = 0; i < data->errors; ++i) {
228  SDL_SetError("%s: %s (%d): %s %s", prefix, file, line, function, data->error_messages[i]);
229  ret = -1;
230  }
231  GL_ClearErrors(renderer);
232  }
233  } else {
234  /* check gl errors (can return multiple errors) */
235  for (;;) {
236  GLenum error = data->glGetError();
237  if (error != GL_NO_ERROR) {
238  if (prefix == NULL || prefix[0] == '\0') {
239  prefix = "generic";
240  }
241  SDL_SetError("%s: %s (%d): %s %s (0x%X)", prefix, file, line, function, GL_TranslateError(error), error);
242  ret = -1;
243  } else {
244  break;
245  }
246  }
247  }
248  return ret;
249 }
250 
251 #if 0
252 #define GL_CheckError(prefix, renderer)
253 #elif defined(_MSC_VER)
254 #define GL_CheckError(prefix, renderer) GL_CheckAllErrors(prefix, renderer, __FILE__, __LINE__, __FUNCTION__)
255 #else
256 #define GL_CheckError(prefix, renderer) GL_CheckAllErrors(prefix, renderer, __FILE__, __LINE__, __PRETTY_FUNCTION__)
257 #endif
258 
259 static int
260 GL_LoadFunctions(GL_RenderData * data)
261 {
262 #ifdef __SDL_NOGETPROCADDR__
263 #define SDL_PROC(ret,func,params) data->func=func;
264 #else
265 #define SDL_PROC(ret,func,params) \
266  do { \
267  data->func = SDL_GL_GetProcAddress(#func); \
268  if ( ! data->func ) { \
269  return SDL_SetError("Couldn't load GL function %s: %s\n", #func, SDL_GetError()); \
270  } \
271  } while ( 0 );
272 #endif /* __SDL_NOGETPROCADDR__ */
273 
274 #include "SDL_glfuncs.h"
275 #undef SDL_PROC
276  return 0;
277 }
278 
279 static SDL_GLContext SDL_CurrentContext = NULL;
280 
281 static int
282 GL_ActivateRenderer(SDL_Renderer * renderer)
283 {
284  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
285 
286  if (SDL_CurrentContext != data->context) {
287  if (SDL_GL_MakeCurrent(renderer->window, data->context) < 0) {
288  return -1;
289  }
290  SDL_CurrentContext = data->context;
291 
292  GL_UpdateViewport(renderer);
293  }
294 
295  GL_ClearErrors(renderer);
296 
297  return 0;
298 }
299 
300 /* This is called if we need to invalidate all of the SDL OpenGL state */
301 static void
302 GL_ResetState(SDL_Renderer *renderer)
303 {
304  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
305 
306  if (SDL_CurrentContext == data->context) {
307  GL_UpdateViewport(renderer);
308  } else {
309  GL_ActivateRenderer(renderer);
310  }
311 
312  data->current.shader = SHADER_NONE;
313  data->current.color = 0;
314  data->current.blendMode = -1;
315 
316  data->glDisable(GL_DEPTH_TEST);
317  data->glDisable(GL_CULL_FACE);
318  /* This ended up causing video discrepancies between OpenGL and Direct3D */
319  /* data->glEnable(GL_LINE_SMOOTH); */
320 
321  data->glMatrixMode(GL_MODELVIEW);
322  data->glLoadIdentity();
323 
324  GL_CheckError("", renderer);
325 }
326 
327 static void APIENTRY
328 GL_HandleDebugMessage(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char *message, void *userParam)
329 {
330  SDL_Renderer *renderer = (SDL_Renderer *) userParam;
331  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
332 
333  if (type == GL_DEBUG_TYPE_ERROR_ARB) {
334  /* Record this error */
335  ++data->errors;
336  data->error_messages = SDL_realloc(data->error_messages, data->errors * sizeof(*data->error_messages));
337  if (data->error_messages) {
338  data->error_messages[data->errors-1] = SDL_strdup(message);
339  }
340  }
341 
342  /* If there's another error callback, pass it along, otherwise log it */
343  if (data->next_error_callback) {
344  data->next_error_callback(source, type, id, severity, length, message, data->next_error_userparam);
345  } else {
346  if (type == GL_DEBUG_TYPE_ERROR_ARB) {
347  SDL_LogError(SDL_LOG_CATEGORY_RENDER, "%s", message);
348  } else {
349  SDL_LogDebug(SDL_LOG_CATEGORY_RENDER, "%s", message);
350  }
351  }
352 }
353 
354 static GL_FBOList *
355 GL_GetFBO(GL_RenderData *data, Uint32 w, Uint32 h)
356 {
357  GL_FBOList *result = data->framebuffers;
358 
359  while (result && ((result->w != w) || (result->h != h))) {
360  result = result->next;
361  }
362 
363  if (!result) {
364  result = SDL_malloc(sizeof(GL_FBOList));
365  if (result) {
366  result->w = w;
367  result->h = h;
368  data->glGenFramebuffersEXT(1, &result->FBO);
369  result->next = data->framebuffers;
370  data->framebuffers = result;
371  }
372  }
373  return result;
374 }
375 
376 SDL_Renderer *
377 GL_CreateRenderer(SDL_Window * window, Uint32 flags)
378 {
379  SDL_Renderer *renderer;
380  GL_RenderData *data;
381  const char *hint;
382  GLint value;
383  Uint32 window_flags;
384 
385  window_flags = SDL_GetWindowFlags(window);
386  if (!(window_flags & SDL_WINDOW_OPENGL)) {
387  if (SDL_RecreateWindow(window, window_flags | SDL_WINDOW_OPENGL) < 0) {
388  /* Uh oh, better try to put it back... */
389  SDL_RecreateWindow(window, window_flags);
390  return NULL;
391  }
392  }
393 
394  renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
395  if (!renderer) {
396  SDL_OutOfMemory();
397  return NULL;
398  }
399 
400  data = (GL_RenderData *) SDL_calloc(1, sizeof(*data));
401  if (!data) {
402  GL_DestroyRenderer(renderer);
403  SDL_OutOfMemory();
404  return NULL;
405  }
406 
407  renderer->WindowEvent = GL_WindowEvent;
408  renderer->GetOutputSize = GL_GetOutputSize;
409  renderer->CreateTexture = GL_CreateTexture;
410  renderer->UpdateTexture = GL_UpdateTexture;
411  renderer->UpdateTextureYUV = GL_UpdateTextureYUV;
412  renderer->LockTexture = GL_LockTexture;
413  renderer->UnlockTexture = GL_UnlockTexture;
414  renderer->SetRenderTarget = GL_SetRenderTarget;
415  renderer->UpdateViewport = GL_UpdateViewport;
416  renderer->UpdateClipRect = GL_UpdateClipRect;
417  renderer->RenderClear = GL_RenderClear;
418  renderer->RenderDrawPoints = GL_RenderDrawPoints;
419  renderer->RenderDrawLines = GL_RenderDrawLines;
420  renderer->RenderFillRects = GL_RenderFillRects;
421  renderer->RenderCopy = GL_RenderCopy;
422  renderer->RenderCopyEx = GL_RenderCopyEx;
423  renderer->RenderReadPixels = GL_RenderReadPixels;
424  renderer->RenderPresent = GL_RenderPresent;
425  renderer->DestroyTexture = GL_DestroyTexture;
426  renderer->DestroyRenderer = GL_DestroyRenderer;
427  renderer->GL_BindTexture = GL_BindTexture;
428  renderer->GL_UnbindTexture = GL_UnbindTexture;
429  renderer->info = GL_RenderDriver.info;
430  renderer->info.flags = SDL_RENDERER_ACCELERATED;
431  renderer->driverdata = data;
432  renderer->window = window;
433 
434  data->context = SDL_GL_CreateContext(window);
435  if (!data->context) {
436  GL_DestroyRenderer(renderer);
437  return NULL;
438  }
439  if (SDL_GL_MakeCurrent(window, data->context) < 0) {
440  GL_DestroyRenderer(renderer);
441  return NULL;
442  }
443 
444  if (GL_LoadFunctions(data) < 0) {
445  GL_DestroyRenderer(renderer);
446  return NULL;
447  }
448 
449 #ifdef __MACOSX__
450  /* Enable multi-threaded rendering */
451  /* Disabled until Ryan finishes his VBO/PBO code...
452  CGLEnable(CGLGetCurrentContext(), kCGLCEMPEngine);
453  */
454 #endif
455 
456  if (flags & SDL_RENDERER_PRESENTVSYNC) {
458  } else {
460  }
461  if (SDL_GL_GetSwapInterval() > 0) {
462  renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
463  }
464 
465  /* Check for debug output support */
466  if (SDL_GL_GetAttribute(SDL_GL_CONTEXT_FLAGS, &value) == 0 &&
467  (value & SDL_GL_CONTEXT_DEBUG_FLAG)) {
468  data->debug_enabled = SDL_TRUE;
469  }
470  if (data->debug_enabled && SDL_GL_ExtensionSupported("GL_ARB_debug_output")) {
471  PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARBFunc = (PFNGLDEBUGMESSAGECALLBACKARBPROC) SDL_GL_GetProcAddress("glDebugMessageCallbackARB");
472 
473  data->GL_ARB_debug_output_supported = SDL_TRUE;
474  data->glGetPointerv(GL_DEBUG_CALLBACK_FUNCTION_ARB, (GLvoid **)&data->next_error_callback);
475  data->glGetPointerv(GL_DEBUG_CALLBACK_USER_PARAM_ARB, &data->next_error_userparam);
476  glDebugMessageCallbackARBFunc(GL_HandleDebugMessage, renderer);
477 
478  /* Make sure our callback is called when errors actually happen */
479  data->glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
480  }
481 
482  if (SDL_GL_ExtensionSupported("GL_ARB_texture_rectangle")
483  || SDL_GL_ExtensionSupported("GL_EXT_texture_rectangle")) {
484  data->GL_ARB_texture_rectangle_supported = SDL_TRUE;
485  data->glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, &value);
486  renderer->info.max_texture_width = value;
487  renderer->info.max_texture_height = value;
488  } else {
489  data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
490  renderer->info.max_texture_width = value;
491  renderer->info.max_texture_height = value;
492  }
493 
494  /* Check for multitexture support */
495  if (SDL_GL_ExtensionSupported("GL_ARB_multitexture")) {
496  data->glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC) SDL_GL_GetProcAddress("glActiveTextureARB");
497  if (data->glActiveTextureARB) {
498  data->GL_ARB_multitexture_supported = SDL_TRUE;
499  data->glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &data->num_texture_units);
500  }
501  }
502 
503  /* Check for shader support */
505  if (!hint || *hint != '0') {
506  data->shaders = GL_CreateShaderContext();
507  }
508  SDL_LogInfo(SDL_LOG_CATEGORY_RENDER, "OpenGL shaders: %s",
509  data->shaders ? "ENABLED" : "DISABLED");
510 
511  /* We support YV12 textures using 3 textures and a shader */
512  if (data->shaders && data->num_texture_units >= 3) {
515  }
516 
517  if (SDL_GL_ExtensionSupported("GL_EXT_framebuffer_object")) {
518  data->GL_EXT_framebuffer_object_supported = SDL_TRUE;
519  data->glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)
520  SDL_GL_GetProcAddress("glGenFramebuffersEXT");
521  data->glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)
522  SDL_GL_GetProcAddress("glDeleteFramebuffersEXT");
523  data->glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)
524  SDL_GL_GetProcAddress("glFramebufferTexture2DEXT");
525  data->glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)
526  SDL_GL_GetProcAddress("glBindFramebufferEXT");
527  data->glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)
528  SDL_GL_GetProcAddress("glCheckFramebufferStatusEXT");
530  }
531  data->framebuffers = NULL;
532 
533  /* Set up parameters for rendering */
534  GL_ResetState(renderer);
535 
536  return renderer;
537 }
538 
539 static void
540 GL_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
541 {
542  if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED ||
543  event->event == SDL_WINDOWEVENT_SHOWN ||
544  event->event == SDL_WINDOWEVENT_HIDDEN) {
545  /* Rebind the context to the window area and update matrices */
546  SDL_CurrentContext = NULL;
547  }
548 }
549 
550 static int
551 GL_GetOutputSize(SDL_Renderer * renderer, int *w, int *h)
552 {
553  SDL_GL_GetDrawableSize(renderer->window, w, h);
554 
555  return 0;
556 }
557 
559 power_of_2(int input)
560 {
561  int value = 1;
562 
563  while (value < input) {
564  value <<= 1;
565  }
566  return value;
567 }
568 
570 convert_format(GL_RenderData *renderdata, Uint32 pixel_format,
572 {
573  switch (pixel_format) {
575  *internalFormat = GL_RGBA8;
576  *format = GL_BGRA;
578  break;
581  *internalFormat = GL_LUMINANCE;
582  *format = GL_LUMINANCE;
583  *type = GL_UNSIGNED_BYTE;
584  break;
585  default:
586  return SDL_FALSE;
587  }
588  return SDL_TRUE;
589 }
590 
591 static GLenum
592 GetScaleQuality(void)
593 {
594  const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
595 
596  if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
597  return GL_NEAREST;
598  } else {
599  return GL_LINEAR;
600  }
601 }
602 
603 static int
604 GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
605 {
606  GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
607  GL_TextureData *data;
608  GLint internalFormat;
609  GLenum format, type;
610  int texture_w, texture_h;
611  GLenum scaleMode;
612 
613  GL_ActivateRenderer(renderer);
614 
615  if (!convert_format(renderdata, texture->format, &internalFormat,
616  &format, &type)) {
617  return SDL_SetError("Texture format %s not supported by OpenGL",
618  SDL_GetPixelFormatName(texture->format));
619  }
620 
621  data = (GL_TextureData *) SDL_calloc(1, sizeof(*data));
622  if (!data) {
623  return SDL_OutOfMemory();
624  }
625 
626  if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
627  size_t size;
628  data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
629  size = texture->h * data->pitch;
630  if (texture->format == SDL_PIXELFORMAT_YV12 ||
631  texture->format == SDL_PIXELFORMAT_IYUV) {
632  /* Need to add size for the U and V planes */
633  size += (2 * (texture->h * data->pitch) / 4);
634  }
635  data->pixels = SDL_calloc(1, size);
636  if (!data->pixels) {
637  SDL_free(data);
638  return SDL_OutOfMemory();
639  }
640  }
641 
642  texture->driverdata = data;
643 
644  if (texture->access == SDL_TEXTUREACCESS_TARGET) {
645  data->fbo = GL_GetFBO(renderdata, texture->w, texture->h);
646  } else {
647  data->fbo = NULL;
648  }
649 
650  GL_CheckError("", renderer);
651  renderdata->glGenTextures(1, &data->texture);
652  if (GL_CheckError("glGenTexures()", renderer) < 0) {
653  SDL_free(data);
654  return -1;
655  }
656  if ((renderdata->GL_ARB_texture_rectangle_supported)
657  /* && texture->access != SDL_TEXTUREACCESS_TARGET */){
658  data->type = GL_TEXTURE_RECTANGLE_ARB;
659  texture_w = texture->w;
660  texture_h = texture->h;
661  data->texw = (GLfloat) texture_w;
662  data->texh = (GLfloat) texture_h;
663  } else {
664  data->type = GL_TEXTURE_2D;
665  texture_w = power_of_2(texture->w);
666  texture_h = power_of_2(texture->h);
667  data->texw = (GLfloat) (texture->w) / texture_w;
668  data->texh = (GLfloat) texture->h / texture_h;
669  }
670 
671  data->format = format;
672  data->formattype = type;
673  scaleMode = GetScaleQuality();
674  renderdata->glEnable(data->type);
675  renderdata->glBindTexture(data->type, data->texture);
676  renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER, scaleMode);
677  renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER, scaleMode);
678  /* According to the spec, CLAMP_TO_EDGE is the default for TEXTURE_RECTANGLE
679  and setting it causes an INVALID_ENUM error in the latest NVidia drivers.
680  */
681  if (data->type != GL_TEXTURE_RECTANGLE_ARB) {
682  renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S,
684  renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T,
686  }
687 #ifdef __MACOSX__
688 #ifndef GL_TEXTURE_STORAGE_HINT_APPLE
689 #define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC
690 #endif
691 #ifndef STORAGE_CACHED_APPLE
692 #define STORAGE_CACHED_APPLE 0x85BE
693 #endif
694 #ifndef STORAGE_SHARED_APPLE
695 #define STORAGE_SHARED_APPLE 0x85BF
696 #endif
697  if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
698  renderdata->glTexParameteri(data->type, GL_TEXTURE_STORAGE_HINT_APPLE,
700  } else {
701  renderdata->glTexParameteri(data->type, GL_TEXTURE_STORAGE_HINT_APPLE,
703  }
704  if (texture->access == SDL_TEXTUREACCESS_STREAMING
705  && texture->format == SDL_PIXELFORMAT_ARGB8888
706  && (texture->w % 8) == 0) {
707  renderdata->glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
708  renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
709  renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH,
710  (data->pitch / SDL_BYTESPERPIXEL(texture->format)));
711  renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w,
712  texture_h, 0, format, type, data->pixels);
713  renderdata->glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
714  }
715  else
716 #endif
717  {
718  renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w,
719  texture_h, 0, format, type, NULL);
720  }
721  renderdata->glDisable(data->type);
722  if (GL_CheckError("glTexImage2D()", renderer) < 0) {
723  return -1;
724  }
725 
726  if (texture->format == SDL_PIXELFORMAT_YV12 ||
727  texture->format == SDL_PIXELFORMAT_IYUV) {
728  data->yuv = SDL_TRUE;
729 
730  renderdata->glGenTextures(1, &data->utexture);
731  renderdata->glGenTextures(1, &data->vtexture);
732  renderdata->glEnable(data->type);
733 
734  renderdata->glBindTexture(data->type, data->utexture);
735  renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER,
736  scaleMode);
737  renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER,
738  scaleMode);
739  renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S,
741  renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T,
743  renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w/2,
744  texture_h/2, 0, format, type, NULL);
745 
746  renderdata->glBindTexture(data->type, data->vtexture);
747  renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER,
748  scaleMode);
749  renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER,
750  scaleMode);
751  renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S,
753  renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T,
755  renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w/2,
756  texture_h/2, 0, format, type, NULL);
757 
758  renderdata->glDisable(data->type);
759  }
760 
761  return GL_CheckError("", renderer);
762 }
763 
764 static int
765 GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
766  const SDL_Rect * rect, const void *pixels, int pitch)
767 {
768  GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
769  GL_TextureData *data = (GL_TextureData *) texture->driverdata;
770 
771  GL_ActivateRenderer(renderer);
772 
773  renderdata->glEnable(data->type);
774  renderdata->glBindTexture(data->type, data->texture);
775  renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
776  renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH,
777  (pitch / SDL_BYTESPERPIXEL(texture->format)));
778  renderdata->glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w,
779  rect->h, data->format, data->formattype,
780  pixels);
781  if (data->yuv) {
782  renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, (pitch / 2));
783 
784  /* Skip to the correct offset into the next texture */
785  pixels = (const void*)((const Uint8*)pixels + rect->h * pitch);
786  if (texture->format == SDL_PIXELFORMAT_YV12) {
787  renderdata->glBindTexture(data->type, data->vtexture);
788  } else {
789  renderdata->glBindTexture(data->type, data->utexture);
790  }
791  renderdata->glTexSubImage2D(data->type, 0, rect->x/2, rect->y/2,
792  rect->w/2, rect->h/2,
793  data->format, data->formattype, pixels);
794 
795  /* Skip to the correct offset into the next texture */
796  pixels = (const void*)((const Uint8*)pixels + (rect->h * pitch)/4);
797  if (texture->format == SDL_PIXELFORMAT_YV12) {
798  renderdata->glBindTexture(data->type, data->utexture);
799  } else {
800  renderdata->glBindTexture(data->type, data->vtexture);
801  }
802  renderdata->glTexSubImage2D(data->type, 0, rect->x/2, rect->y/2,
803  rect->w/2, rect->h/2,
804  data->format, data->formattype, pixels);
805  }
806  renderdata->glDisable(data->type);
807  return GL_CheckError("glTexSubImage2D()", renderer);
808 }
809 
810 static int
811 GL_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
812  const SDL_Rect * rect,
813  const Uint8 *Yplane, int Ypitch,
814  const Uint8 *Uplane, int Upitch,
815  const Uint8 *Vplane, int Vpitch)
816 {
817  GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
818  GL_TextureData *data = (GL_TextureData *) texture->driverdata;
819 
820  GL_ActivateRenderer(renderer);
821 
822  renderdata->glEnable(data->type);
823  renderdata->glBindTexture(data->type, data->texture);
824  renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
825  renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, Ypitch);
826  renderdata->glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w,
827  rect->h, data->format, data->formattype,
828  Yplane);
829 
830  renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, Upitch);
831  renderdata->glBindTexture(data->type, data->utexture);
832  renderdata->glTexSubImage2D(data->type, 0, rect->x/2, rect->y/2,
833  rect->w/2, rect->h/2,
834  data->format, data->formattype, Uplane);
835 
836  renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, Vpitch);
837  renderdata->glBindTexture(data->type, data->vtexture);
838  renderdata->glTexSubImage2D(data->type, 0, rect->x/2, rect->y/2,
839  rect->w/2, rect->h/2,
840  data->format, data->formattype, Vplane);
841  renderdata->glDisable(data->type);
842  return GL_CheckError("glTexSubImage2D()", renderer);
843 }
844 
845 static int
846 GL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
847  const SDL_Rect * rect, void **pixels, int *pitch)
848 {
849  GL_TextureData *data = (GL_TextureData *) texture->driverdata;
850 
851  data->locked_rect = *rect;
852  *pixels =
853  (void *) ((Uint8 *) data->pixels + rect->y * data->pitch +
854  rect->x * SDL_BYTESPERPIXEL(texture->format));
855  *pitch = data->pitch;
856  return 0;
857 }
858 
859 static void
860 GL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
861 {
862  GL_TextureData *data = (GL_TextureData *) texture->driverdata;
863  const SDL_Rect *rect;
864  void *pixels;
865 
866  rect = &data->locked_rect;
867  pixels =
868  (void *) ((Uint8 *) data->pixels + rect->y * data->pitch +
869  rect->x * SDL_BYTESPERPIXEL(texture->format));
870  GL_UpdateTexture(renderer, texture, rect, pixels, data->pitch);
871 }
872 
873 static int
874 GL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
875 {
876  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
877  GL_TextureData *texturedata;
878  GLenum status;
879 
880  GL_ActivateRenderer(renderer);
881 
882  if (texture == NULL) {
883  data->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
884  return 0;
885  }
886 
887  texturedata = (GL_TextureData *) texture->driverdata;
888  data->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, texturedata->fbo->FBO);
889  /* TODO: check if texture pixel format allows this operation */
890  data->glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, texturedata->type, texturedata->texture, 0);
891  /* Check FBO status */
892  status = data->glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
893  if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
894  return SDL_SetError("glFramebufferTexture2DEXT() failed");
895  }
896  return 0;
897 }
898 
899 static int
900 GL_UpdateViewport(SDL_Renderer * renderer)
901 {
902  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
903 
904  if (SDL_CurrentContext != data->context) {
905  /* We'll update the viewport after we rebind the context */
906  return 0;
907  }
908 
909  data->glViewport(renderer->viewport.x, renderer->viewport.y,
910  renderer->viewport.w, renderer->viewport.h);
911 
912  data->glMatrixMode(GL_PROJECTION);
913  data->glLoadIdentity();
914  if (renderer->viewport.w && renderer->viewport.h) {
915  if (renderer->target) {
916  data->glOrtho((GLdouble) 0,
917  (GLdouble) renderer->viewport.w,
918  (GLdouble) 0,
919  (GLdouble) renderer->viewport.h,
920  0.0, 1.0);
921  } else {
922  data->glOrtho((GLdouble) 0,
923  (GLdouble) renderer->viewport.w,
924  (GLdouble) renderer->viewport.h,
925  (GLdouble) 0,
926  0.0, 1.0);
927  }
928  }
929  return GL_CheckError("", renderer);
930 }
931 
932 static int
933 GL_UpdateClipRect(SDL_Renderer * renderer)
934 {
935  const SDL_Rect *rect = &renderer->clip_rect;
936  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
937 
938  if (!SDL_RectEmpty(rect)) {
939  data->glEnable(GL_SCISSOR_TEST);
940  data->glScissor(rect->x, renderer->viewport.h - rect->y - rect->h, rect->w, rect->h);
941  } else {
942  data->glDisable(GL_SCISSOR_TEST);
943  }
944  return 0;
945 }
946 
947 static void
948 GL_SetShader(GL_RenderData * data, GL_Shader shader)
949 {
950  if (data->shaders && shader != data->current.shader) {
951  GL_SelectShader(data->shaders, shader);
952  data->current.shader = shader;
953  }
954 }
955 
956 static void
957 GL_SetColor(GL_RenderData * data, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
958 {
959  Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b);
960 
961  if (color != data->current.color) {
962  data->glColor4f((GLfloat) r * inv255f,
963  (GLfloat) g * inv255f,
964  (GLfloat) b * inv255f,
965  (GLfloat) a * inv255f);
966  data->current.color = color;
967  }
968 }
969 
970 static void
971 GL_SetBlendMode(GL_RenderData * data, int blendMode)
972 {
973  if (blendMode != data->current.blendMode) {
974  switch (blendMode) {
975  case SDL_BLENDMODE_NONE:
976  data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
977  data->glDisable(GL_BLEND);
978  break;
979  case SDL_BLENDMODE_BLEND:
981  data->glEnable(GL_BLEND);
983  break;
984  case SDL_BLENDMODE_ADD:
986  data->glEnable(GL_BLEND);
987  data->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ZERO, GL_ONE);
988  break;
989  case SDL_BLENDMODE_MOD:
991  data->glEnable(GL_BLEND);
992  data->glBlendFuncSeparate(GL_ZERO, GL_SRC_COLOR, GL_ZERO, GL_ONE);
993  break;
994  }
995  data->current.blendMode = blendMode;
996  }
997 }
998 
999 static void
1000 GL_SetDrawingState(SDL_Renderer * renderer)
1001 {
1002  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1003 
1004  GL_ActivateRenderer(renderer);
1005 
1006  GL_SetColor(data, renderer->r,
1007  renderer->g,
1008  renderer->b,
1009  renderer->a);
1010 
1011  GL_SetBlendMode(data, renderer->blendMode);
1012 
1013  GL_SetShader(data, SHADER_SOLID);
1014 }
1015 
1016 static int
1017 GL_RenderClear(SDL_Renderer * renderer)
1018 {
1019  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1020 
1021  GL_ActivateRenderer(renderer);
1022 
1023  data->glClearColor((GLfloat) renderer->r * inv255f,
1024  (GLfloat) renderer->g * inv255f,
1025  (GLfloat) renderer->b * inv255f,
1026  (GLfloat) renderer->a * inv255f);
1027 
1028  data->glClear(GL_COLOR_BUFFER_BIT);
1029 
1030  return 0;
1031 }
1032 
1033 static int
1034 GL_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points,
1035  int count)
1036 {
1037  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1038  int i;
1039 
1040  GL_SetDrawingState(renderer);
1041 
1042  data->glBegin(GL_POINTS);
1043  for (i = 0; i < count; ++i) {
1044  data->glVertex2f(0.5f + points[i].x, 0.5f + points[i].y);
1045  }
1046  data->glEnd();
1047 
1048  return 0;
1049 }
1050 
1051 static int
1052 GL_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points,
1053  int count)
1054 {
1055  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1056  int i;
1057 
1058  GL_SetDrawingState(renderer);
1059 
1060  if (count > 2 &&
1061  points[0].x == points[count-1].x && points[0].y == points[count-1].y) {
1062  data->glBegin(GL_LINE_LOOP);
1063  /* GL_LINE_LOOP takes care of the final segment */
1064  --count;
1065  for (i = 0; i < count; ++i) {
1066  data->glVertex2f(0.5f + points[i].x, 0.5f + points[i].y);
1067  }
1068  data->glEnd();
1069  } else {
1070 #if defined(__APPLE__) || defined(__WIN32__)
1071 #else
1072  int x1, y1, x2, y2;
1073 #endif
1074 
1075  data->glBegin(GL_LINE_STRIP);
1076  for (i = 0; i < count; ++i) {
1077  data->glVertex2f(0.5f + points[i].x, 0.5f + points[i].y);
1078  }
1079  data->glEnd();
1080 
1081  /* The line is half open, so we need one more point to complete it.
1082  * http://www.opengl.org/documentation/specs/version1.1/glspec1.1/node47.html
1083  * If we have to, we can use vertical line and horizontal line textures
1084  * for vertical and horizontal lines, and then create custom textures
1085  * for diagonal lines and software render those. It's terrible, but at
1086  * least it would be pixel perfect.
1087  */
1088  data->glBegin(GL_POINTS);
1089 #if defined(__APPLE__) || defined(__WIN32__)
1090  /* Mac OS X and Windows seem to always leave the second point open */
1091  data->glVertex2f(0.5f + points[count-1].x, 0.5f + points[count-1].y);
1092 #else
1093  /* Linux seems to leave the right-most or bottom-most point open */
1094  x1 = points[0].x;
1095  y1 = points[0].y;
1096  x2 = points[count-1].x;
1097  y2 = points[count-1].y;
1098 
1099  if (x1 > x2) {
1100  data->glVertex2f(0.5f + x1, 0.5f + y1);
1101  } else if (x2 > x1) {
1102  data->glVertex2f(0.5f + x2, 0.5f + y2);
1103  } else if (y1 > y2) {
1104  data->glVertex2f(0.5f + x1, 0.5f + y1);
1105  } else if (y2 > y1) {
1106  data->glVertex2f(0.5f + x2, 0.5f + y2);
1107  }
1108 #endif
1109  data->glEnd();
1110  }
1111  return GL_CheckError("", renderer);
1112 }
1113 
1114 static int
1115 GL_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, int count)
1116 {
1117  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1118  int i;
1119 
1120  GL_SetDrawingState(renderer);
1121 
1122  for (i = 0; i < count; ++i) {
1123  const SDL_FRect *rect = &rects[i];
1124 
1125  data->glRectf(rect->x, rect->y, rect->x + rect->w, rect->y + rect->h);
1126  }
1127  return GL_CheckError("", renderer);
1128 }
1129 
1130 static int
1131 GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
1132  const SDL_Rect * srcrect, const SDL_FRect * dstrect)
1133 {
1134  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1135  GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata;
1136  GLfloat minx, miny, maxx, maxy;
1137  GLfloat minu, maxu, minv, maxv;
1138 
1139  GL_ActivateRenderer(renderer);
1140 
1141  data->glEnable(texturedata->type);
1142  if (texturedata->yuv) {
1143  data->glActiveTextureARB(GL_TEXTURE2_ARB);
1144  data->glBindTexture(texturedata->type, texturedata->vtexture);
1145 
1146  data->glActiveTextureARB(GL_TEXTURE1_ARB);
1147  data->glBindTexture(texturedata->type, texturedata->utexture);
1148 
1149  data->glActiveTextureARB(GL_TEXTURE0_ARB);
1150  }
1151  data->glBindTexture(texturedata->type, texturedata->texture);
1152 
1153  if (texture->modMode) {
1154  GL_SetColor(data, texture->r, texture->g, texture->b, texture->a);
1155  } else {
1156  GL_SetColor(data, 255, 255, 255, 255);
1157  }
1158 
1159  GL_SetBlendMode(data, texture->blendMode);
1160 
1161  if (texturedata->yuv) {
1162  GL_SetShader(data, SHADER_YV12);
1163  } else {
1164  GL_SetShader(data, SHADER_RGB);
1165  }
1166 
1167  minx = dstrect->x;
1168  miny = dstrect->y;
1169  maxx = dstrect->x + dstrect->w;
1170  maxy = dstrect->y + dstrect->h;
1171 
1172  minu = (GLfloat) srcrect->x / texture->w;
1173  minu *= texturedata->texw;
1174  maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w;
1175  maxu *= texturedata->texw;
1176  minv = (GLfloat) srcrect->y / texture->h;
1177  minv *= texturedata->texh;
1178  maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h;
1179  maxv *= texturedata->texh;
1180 
1181  data->glBegin(GL_TRIANGLE_STRIP);
1182  data->glTexCoord2f(minu, minv);
1183  data->glVertex2f(minx, miny);
1184  data->glTexCoord2f(maxu, minv);
1185  data->glVertex2f(maxx, miny);
1186  data->glTexCoord2f(minu, maxv);
1187  data->glVertex2f(minx, maxy);
1188  data->glTexCoord2f(maxu, maxv);
1189  data->glVertex2f(maxx, maxy);
1190  data->glEnd();
1191 
1192  data->glDisable(texturedata->type);
1193 
1194  return GL_CheckError("", renderer);
1195 }
1196 
1197 static int
1198 GL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
1199  const SDL_Rect * srcrect, const SDL_FRect * dstrect,
1200  const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
1201 {
1202  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1203  GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata;
1204  GLfloat minx, miny, maxx, maxy;
1205  GLfloat centerx, centery;
1206  GLfloat minu, maxu, minv, maxv;
1207 
1208  GL_ActivateRenderer(renderer);
1209 
1210  data->glEnable(texturedata->type);
1211  if (texturedata->yuv) {
1212  data->glActiveTextureARB(GL_TEXTURE2_ARB);
1213  data->glBindTexture(texturedata->type, texturedata->vtexture);
1214 
1215  data->glActiveTextureARB(GL_TEXTURE1_ARB);
1216  data->glBindTexture(texturedata->type, texturedata->utexture);
1217 
1218  data->glActiveTextureARB(GL_TEXTURE0_ARB);
1219  }
1220  data->glBindTexture(texturedata->type, texturedata->texture);
1221 
1222  if (texture->modMode) {
1223  GL_SetColor(data, texture->r, texture->g, texture->b, texture->a);
1224  } else {
1225  GL_SetColor(data, 255, 255, 255, 255);
1226  }
1227 
1228  GL_SetBlendMode(data, texture->blendMode);
1229 
1230  if (texturedata->yuv) {
1231  GL_SetShader(data, SHADER_YV12);
1232  } else {
1233  GL_SetShader(data, SHADER_RGB);
1234  }
1235 
1236  centerx = center->x;
1237  centery = center->y;
1238 
1239  if (flip & SDL_FLIP_HORIZONTAL) {
1240  minx = dstrect->w - centerx;
1241  maxx = -centerx;
1242  }
1243  else {
1244  minx = -centerx;
1245  maxx = dstrect->w - centerx;
1246  }
1247 
1248  if (flip & SDL_FLIP_VERTICAL) {
1249  miny = dstrect->h - centery;
1250  maxy = -centery;
1251  }
1252  else {
1253  miny = -centery;
1254  maxy = dstrect->h - centery;
1255  }
1256 
1257  minu = (GLfloat) srcrect->x / texture->w;
1258  minu *= texturedata->texw;
1259  maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w;
1260  maxu *= texturedata->texw;
1261  minv = (GLfloat) srcrect->y / texture->h;
1262  minv *= texturedata->texh;
1263  maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h;
1264  maxv *= texturedata->texh;
1265 
1266  /* Translate to flip, rotate, translate to position */
1267  data->glPushMatrix();
1268  data->glTranslatef((GLfloat)dstrect->x + centerx, (GLfloat)dstrect->y + centery, (GLfloat)0.0);
1269  data->glRotated(angle, (GLdouble)0.0, (GLdouble)0.0, (GLdouble)1.0);
1270 
1271  data->glBegin(GL_TRIANGLE_STRIP);
1272  data->glTexCoord2f(minu, minv);
1273  data->glVertex2f(minx, miny);
1274  data->glTexCoord2f(maxu, minv);
1275  data->glVertex2f(maxx, miny);
1276  data->glTexCoord2f(minu, maxv);
1277  data->glVertex2f(minx, maxy);
1278  data->glTexCoord2f(maxu, maxv);
1279  data->glVertex2f(maxx, maxy);
1280  data->glEnd();
1281  data->glPopMatrix();
1282 
1283  data->glDisable(texturedata->type);
1284 
1285  return GL_CheckError("", renderer);
1286 }
1287 
1288 static int
1289 GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
1290  Uint32 pixel_format, void * pixels, int pitch)
1291 {
1292  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1293  Uint32 temp_format = SDL_PIXELFORMAT_ARGB8888;
1294  void *temp_pixels;
1295  int temp_pitch;
1296  GLint internalFormat;
1297  GLenum format, type;
1298  Uint8 *src, *dst, *tmp;
1299  int w, h, length, rows;
1300  int status;
1301 
1302  GL_ActivateRenderer(renderer);
1303 
1304  temp_pitch = rect->w * SDL_BYTESPERPIXEL(temp_format);
1305  temp_pixels = SDL_malloc(rect->h * temp_pitch);
1306  if (!temp_pixels) {
1307  return SDL_OutOfMemory();
1308  }
1309 
1310  convert_format(data, temp_format, &internalFormat, &format, &type);
1311 
1312  SDL_GetRendererOutputSize(renderer, &w, &h);
1313 
1314  data->glPixelStorei(GL_PACK_ALIGNMENT, 1);
1315  data->glPixelStorei(GL_PACK_ROW_LENGTH,
1316  (temp_pitch / SDL_BYTESPERPIXEL(temp_format)));
1317 
1318  data->glReadPixels(rect->x, (h-rect->y)-rect->h, rect->w, rect->h,
1319  format, type, temp_pixels);
1320 
1321  GL_CheckError("", renderer);
1322 
1323  /* Flip the rows to be top-down */
1324  length = rect->w * SDL_BYTESPERPIXEL(temp_format);
1325  src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch;
1326  dst = (Uint8*)temp_pixels;
1327  tmp = SDL_stack_alloc(Uint8, length);
1328  rows = rect->h / 2;
1329  while (rows--) {
1330  SDL_memcpy(tmp, dst, length);
1331  SDL_memcpy(dst, src, length);
1332  SDL_memcpy(src, tmp, length);
1333  dst += temp_pitch;
1334  src -= temp_pitch;
1335  }
1336  SDL_stack_free(tmp);
1337 
1338  status = SDL_ConvertPixels(rect->w, rect->h,
1339  temp_format, temp_pixels, temp_pitch,
1340  pixel_format, pixels, pitch);
1341  SDL_free(temp_pixels);
1342 
1343  return status;
1344 }
1345 
1346 static void
1347 GL_RenderPresent(SDL_Renderer * renderer)
1348 {
1349  GL_ActivateRenderer(renderer);
1350 
1351  SDL_GL_SwapWindow(renderer->window);
1352 }
1353 
1354 static void
1355 GL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
1356 {
1357  GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
1358  GL_TextureData *data = (GL_TextureData *) texture->driverdata;
1359 
1360  GL_ActivateRenderer(renderer);
1361 
1362  if (!data) {
1363  return;
1364  }
1365  if (data->texture) {
1366  renderdata->glDeleteTextures(1, &data->texture);
1367  }
1368  if (data->yuv) {
1369  renderdata->glDeleteTextures(1, &data->utexture);
1370  renderdata->glDeleteTextures(1, &data->vtexture);
1371  }
1372  SDL_free(data->pixels);
1373  SDL_free(data);
1374  texture->driverdata = NULL;
1375 }
1376 
1377 static void
1378 GL_DestroyRenderer(SDL_Renderer * renderer)
1379 {
1380  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1381 
1382  if (data) {
1383  GL_ClearErrors(renderer);
1384  if (data->GL_ARB_debug_output_supported) {
1385  PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARBFunc = (PFNGLDEBUGMESSAGECALLBACKARBPROC) SDL_GL_GetProcAddress("glDebugMessageCallbackARB");
1386 
1387  /* Uh oh, we don't have a safe way of removing ourselves from the callback chain, if it changed after we set our callback. */
1388  /* For now, just always replace the callback with the original one */
1389  glDebugMessageCallbackARBFunc(data->next_error_callback, data->next_error_userparam);
1390  }
1391  if (data->shaders) {
1392  GL_DestroyShaderContext(data->shaders);
1393  }
1394  if (data->context) {
1395  while (data->framebuffers) {
1396  GL_FBOList *nextnode = data->framebuffers->next;
1397  /* delete the framebuffer object */
1398  data->glDeleteFramebuffersEXT(1, &data->framebuffers->FBO);
1399  GL_CheckError("", renderer);
1400  SDL_free(data->framebuffers);
1401  data->framebuffers = nextnode;
1402  }
1403  SDL_GL_DeleteContext(data->context);
1404  }
1405  SDL_free(data);
1406  }
1407  SDL_free(renderer);
1408 }
1409 
1410 static int
1411 GL_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, float *texh)
1412 {
1413  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1414  GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata;
1415  GL_ActivateRenderer(renderer);
1416 
1417  data->glEnable(texturedata->type);
1418  if (texturedata->yuv) {
1419  data->glActiveTextureARB(GL_TEXTURE2_ARB);
1420  data->glBindTexture(texturedata->type, texturedata->vtexture);
1421 
1422  data->glActiveTextureARB(GL_TEXTURE1_ARB);
1423  data->glBindTexture(texturedata->type, texturedata->utexture);
1424 
1425  data->glActiveTextureARB(GL_TEXTURE0_ARB);
1426  }
1427  data->glBindTexture(texturedata->type, texturedata->texture);
1428 
1429  if(texw) *texw = (float)texturedata->texw;
1430  if(texh) *texh = (float)texturedata->texh;
1431 
1432  return 0;
1433 }
1434 
1435 static int
1436 GL_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture)
1437 {
1438  GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
1439  GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata;
1440  GL_ActivateRenderer(renderer);
1441 
1442  if (texturedata->yuv) {
1443  data->glActiveTextureARB(GL_TEXTURE2_ARB);
1444  data->glDisable(texturedata->type);
1445 
1446  data->glActiveTextureARB(GL_TEXTURE1_ARB);
1447  data->glDisable(texturedata->type);
1448 
1449  data->glActiveTextureARB(GL_TEXTURE0_ARB);
1450  }
1451 
1452  data->glDisable(texturedata->type);
1453 
1454  return 0;
1455 }
1456 
1457 #endif /* SDL_VIDEO_RENDER_OGL && !SDL_RENDER_DISABLED */
1458 
1459 /* vi: set ts=4 sw=4 expandtab: */
#define GL_DEBUG_CALLBACK_FUNCTION_ARB
Definition: glew.h:3743
#define GL_TRUE
Definition: gl2.h:51
int(* UpdateClipRect)(SDL_Renderer *renderer)
SDL_BlendMode blendMode
Definition: SDL_sysrender.h:57
#define GL_TEXTURE_STORAGE_HINT_APPLE
Definition: glew.h:3245
return
Definition: pngrutil.c:1266
int GLsizei
Definition: gl2.h:29
#define GL_SRC_COLOR
Definition: gl2.h:75
#define GL_LINE_LOOP
Definition: gl2.h:56
#define GL_LINE_STRIP
Definition: gl2.h:57
#define GL_FALSE
Definition: gl2.h:50
#define GL_BLEND
Definition: gl2.h:147
#define GL_MODULATE
Definition: glew_head.h:620
#define GL_TEXTURE_ENV_MODE
Definition: glew_head.h:622
#define GL_CULL_FACE
Definition: gl2.h:146
DECLSPEC void *SDLCALL SDL_GL_GetProcAddress(const char *proc)
Get the address of an OpenGL function.
Definition: SDL_video.c:2340
#define GL_ZERO
Definition: gl2.h:73
GLfloat GLfloat GLfloat GLfloat h
Definition: glew.h:7294
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum type
Definition: gl2ext.h:845
GLsizei GLsizei GLuint * shaders
Definition: glew.h:1813
DECLSPEC void *SDLCALL SDL_calloc(size_t nmemb, size_t size)
#define GL_CLAMP_TO_EDGE
Definition: gl2.h:375
void(* WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event)
Definition: SDL_sysrender.h:80
GLuint color
Definition: glew.h:7185
GLsizei GLenum GLuint GLuint GLsizei GLchar * message
Definition: glew.h:2540
#define GL_OUT_OF_MEMORY
Definition: gl2.h:161
#define GL_FRAMEBUFFER_COMPLETE_EXT
Definition: glew.h:8938
unsigned int GLenum
Definition: gl2.h:23
SDL_RendererInfo info
DECLSPEC int SDLCALL SDL_GL_GetSwapInterval(void)
Get the swap interval for the current OpenGL context.
Definition: SDL_video.c:2857
#define GL_RGBA8
Definition: glew_head.h:707
#define GL_SRC_ALPHA
Definition: gl2.h:77
DECLSPEC int SDLCALL SDL_ConvertPixels(int width, int height, Uint32 src_format, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch)
Copy a block of pixels of one format to another format.
Definition: SDL_surface.c:984
GLboolean GLboolean g
Definition: glew.h:8736
#define NULL
Definition: ftobjs.h:61
int(* RenderClear)(SDL_Renderer *renderer)
GLclampf f
Definition: glew.h:3390
#define SDL_stack_free(data)
Definition: SDL_stdinc.h:227
#define GL_PACK_ROW_LENGTH
Definition: glew_head.h:454
DECLSPEC SDL_GLContext SDLCALL SDL_GL_CreateContext(SDL_Window *window)
Create an OpenGL context for use with an OpenGL window, and make it current.
Definition: SDL_video.c:2758
int(* RenderDrawPoints)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
GLdouble angle
Definition: glew.h:8396
DECLSPEC const char *SDLCALL SDL_GetPixelFormatName(Uint32 format)
Get the human readable name of a pixel format.
Definition: SDL_pixels.c:86
SDL_bool
Definition: SDL_stdinc.h:116
int(* SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:82
#define GL_TEXTURE_2D
Definition: gl2.h:145
#define SDL_HINT_RENDER_SCALE_QUALITY
A variable controlling the scaling quality.
Definition: SDL_hints.h:118
#define glCheckFramebufferStatusEXT
Definition: glew.h:9001
void * driverdata
#define GL_TABLE_TOO_LARGE
Definition: glew.h:4387
EGLSurface EGLint x
Definition: eglext.h:293
DECLSPEC void *SDLCALL SDL_realloc(void *mem, size_t size)
DECLSPEC int SDLCALL SDL_GL_GetAttribute(SDL_GLattr attr, int *value)
Get the actual value for an attribute from the current context.
Definition: SDL_video.c:2578
#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB
Definition: glew.h:6371
DECLSPEC void SDLCALL SDL_free(void *mem)
Uint32 texture_formats[16]
Definition: SDL_render.h:83
#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
#define GL_DEBUG_TYPE_ERROR_ARB
Definition: glew.h:3751
#define GL_INVALID_OPERATION
Definition: gl2.h:160
#define glBindFramebufferEXT
Definition: glew.h:8999
FILE * file
Definition: visualinfo.c:88
#define GL_LUMINANCE
Definition: gl2.h:249
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:8736
void * SDL_GLContext
An opaque handle to an OpenGL context.
Definition: SDL_video.h:161
#define SDL_BYTESPERPIXEL(X)
Definition: SDL_pixels.h:123
#define GL_STORAGE_CACHED_APPLE
Definition: glew.h:3303
void(* UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:99
#define GL_TEXTURE_MAG_FILTER
Definition: gl2.h:319
#define GL_STACK_OVERFLOW
Definition: glew_head.h:296
DECLSPEC int SDLCALL SDL_GetRendererOutputSize(SDL_Renderer *renderer, int *w, int *h)
Get the output size of a rendering context.
Definition: SDL_render.c:338
SDL_Rect clip_rect
struct GL_ShaderContext GL_ShaderContext
if(!yyg->yy_init)
GLuint GLfloat GLfloat GLfloat GLfloat y1
Definition: glew.h:11582
#define GL_TRIANGLE_STRIP
Definition: gl2.h:59
GLfixed GLfixed GLfixed y2
Definition: glext.h:4559
int max_texture_height
Definition: SDL_render.h:85
SDL_FORCE_INLINE SDL_bool SDL_RectEmpty(const SDL_Rect *r)
Returns true if the rectangle has no area.
Definition: SDL_rect.h:72
#define SDL_FORCE_INLINE
Definition: begin_code.h:141
SDL_Window * window
SDL_RendererInfo info
#define glDeleteFramebuffersEXT
Definition: glew.h:9002
ret
Definition: glew_str_glx.c:2
#define GL_DEBUG_CALLBACK_USER_PARAM_ARB
Definition: glew.h:3744
#define GL_INVALID_VALUE
Definition: gl2.h:159
#define GL_TEXTURE2_ARB
Definition: glew.h:4812
void GL_DestroyShaderContext(GL_ShaderContext *ctx)
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:145
#define GL_REPLACE
Definition: gl2.h:293
const GLuint * framebuffers
Definition: glew.h:4126
DECLSPEC int SDLCALL SDL_GL_MakeCurrent(SDL_Window *window, SDL_GLContext context)
Set up an OpenGL context for rendering into an OpenGL window.
Definition: SDL_video.c:2781
int(* LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
Definition: SDL_sysrender.h:97
#define GL_COLOR_BUFFER_BIT
Definition: gl2.h:47
#define GL_TEXTURE1_ARB
Definition: glew.h:4811
#define GL_NO_ERROR
Definition: gl2.h:157
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
GLuint64EXT * result
Definition: glew.h:12708
GLenum severity
Definition: glew.h:2538
GLuint shader
Definition: glew.h:1799
#define GL_TEXTURE_MIN_FILTER
Definition: gl2.h:320
DECLSPEC int SDLCALL SDL_GL_SetSwapInterval(int interval)
Set the swap interval for the current OpenGL context.
Definition: SDL_video.c:2843
GL_Shader
int(* UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
Definition: SDL_sysrender.h:89
GLenum GLenum dst
Definition: glew.h:2396
#define GL_TEXTURE_ENV
Definition: glew_head.h:624
#define APIENTRY
Definition: glew_head.h:150
SDL_Texture * target
GLsizei GLsizei * length
Definition: gl2ext.h:792
#define GL_ONE
Definition: gl2.h:74
DECLSPEC void SDLCALL SDL_LogDebug(int category, const char *fmt,...)
Log a message with SDL_LOG_PRIORITY_DEBUG.
Definition: SDL_log.c:193
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl2ext.h:848
int SDL_RecreateWindow(SDL_Window *window, Uint32 flags)
Definition: SDL_video.c:1317
FT_Error error
Definition: cffdrivr.c:407
static int GetScaleQuality(void)
DECLSPEC char *SDLCALL SDL_strdup(const char *str)
Definition: SDL_string.c:511
SDL_BlendMode blendMode
#define GL_POINTS
Definition: gl2.h:54
GLint GLsizei count
Definition: gl2ext.h:1011
DECLSPEC void SDLCALL SDL_GL_DeleteContext(SDL_GLContext context)
Delete an OpenGL context.
Definition: SDL_video.c:2889
int(* RenderDrawLines)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
#define GL_PACK_ALIGNMENT
Definition: gl2.h:198
#define GL_MODELVIEW
Definition: glew_head.h:581
GL_ShaderContext * GL_CreateShaderContext()
#define GL_UNPACK_ROW_LENGTH
Definition: gl2ext.h:450
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl2ext.h:845
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
Definition: SDL_error.c:53
DECLSPEC void *SDLCALL SDL_malloc(size_t size)
GLint GLint internalFormat
Definition: glew.h:1240
DECLSPEC Uint32 SDLCALL SDL_GetWindowFlags(SDL_Window *window)
Get the window flags.
Definition: SDL_video.c:1409
int x
Definition: SDL_rect.h:65
DECLSPEC const char *SDLCALL SDL_GetHint(const char *name)
Get a hint.
Definition: SDL_hints.c:104
void(APIENTRY * GLDEBUGPROCARB)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, GLvoid *userParam)
Definition: glew.h:3764
void(* DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
#define GL_UNSIGNED_INT_8_8_8_8_REV
Definition: glew.h:1234
int w
Definition: SDL_rect.h:66
int(* RenderCopy)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect)
GLAPI void GLAPIENTRY glActiveTextureARB(GLenum texture)
static __inline ALuint minu(ALuint a, ALuint b)
Definition: alu.h:61
khronos_float_t GLfloat
Definition: gl2.h:33
#define GL_MAX_TEXTURE_UNITS_ARB
Definition: glew.h:4844
SDL_RendererFlip
Flip constants for SDL_RenderCopyEx.
Definition: SDL_render.h:111
#define glGenFramebuffersEXT
Definition: glew.h:9008
DECLSPEC void SDLCALL SDL_GL_GetDrawableSize(SDL_Window *window, int *w, int *h)
Get the size of a window&#39;s underlying drawable (for use with glViewport).
Definition: SDL_video.c:2831
#define GL_LINEAR
Definition: gl2.h:308
#define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB
Definition: glew.h:3741
#define GL_FRAMEBUFFER_EXT
Definition: glew.h:8965
Window state change event data (event.window.*)
Definition: SDL_events.h:160
#define GL_INVALID_ENUM
Definition: gl2.h:158
GLuint GLfloat GLfloat GLfloat x1
Definition: glew.h:11582
EGLSurface EGLint EGLint y
Definition: eglext.h:293
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
#define GL_COLOR_ATTACHMENT0_EXT
Definition: gl2ext.h:578
double GLdouble
Definition: glew_head.h:205
GLenum GLenum GLuint texture
Definition: gl2ext.h:850
int(* GetOutputSize)(SDL_Renderer *renderer, int *w, int *h)
Definition: SDL_sysrender.h:81
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: gl2ext.h:845
int(* GL_BindTexture)(SDL_Renderer *renderer, SDL_Texture *texture, float *texw, float *texh)
int GLint
Definition: gl2.h:28
GLenum GLenum GLenum input
Definition: glew.h:12631
EGLSurface EGLint void ** value
Definition: eglext.h:301
#define GL_STORAGE_SHARED_APPLE
Definition: glew.h:3304
unsigned int GLuint
Definition: gl2.h:32
int(* RenderReadPixels)(SDL_Renderer *renderer, const SDL_Rect *rect, Uint32 format, void *pixels, int pitch)
#define GL_TEXTURE0_ARB
Definition: glew.h:4810
DECLSPEC void *SDLCALL SDL_memcpy(void *dst, const void *src, size_t len)
Definition: SDL_string.c:293
GLvoid * userParam
Definition: glew.h:2537
GLenum GLsizei GLsizei GLsizei GLsizei GLbitfield flags
Definition: glew.h:2767
int(* GL_UnbindTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
SDL_Rect viewport
#define GL_TEXTURE_WRAP_T
Definition: gl2.h:322
int(* RenderFillRects)(SDL_Renderer *renderer, const SDL_FRect *rects, int count)
int h
Definition: SDL_rect.h:66
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:129
#define GL_PROJECTION
Definition: glew_head.h:582
#define GL_UNSIGNED_BYTE
Definition: gl2.h:236
#define GL_TEXTURE_WRAP_S
Definition: gl2.h:321
GLfixed GLfixed x2
Definition: glext.h:4559
#define GL_STACK_UNDERFLOW
Definition: glew_head.h:297
DECLSPEC void SDLCALL SDL_LogError(int category, const char *fmt,...)
Log a message with SDL_LOG_PRIORITY_ERROR.
Definition: SDL_log.c:223
#define GL_ONE_MINUS_SRC_ALPHA
Definition: gl2.h:78
GLdouble GLdouble GLdouble r
Definition: glew.h:1392
GLdouble GLdouble GLdouble b
Definition: glew.h:8383
Uint32 num_texture_formats
Definition: SDL_render.h:82
Uint32 format
Definition: SDL_sysrender.h:52
GLint GLint GLint GLint GLint w
Definition: gl2ext.h:1215
#define SDL_stack_alloc(type, count)
Definition: SDL_stdinc.h:226
#define GL_UNPACK_ALIGNMENT
Definition: gl2.h:197
void * driverdata
Definition: SDL_sysrender.h:69
#define GL_BGRA
Definition: glew.h:10473
#define GL_UNPACK_CLIENT_STORAGE_APPLE
Definition: glew.h:3064
int(* UpdateViewport)(SDL_Renderer *renderer)
GLuint GLdouble GLdouble GLint GLint const GLdouble * points
Definition: glew.h:3337
void GLvoid
Definition: gl2.h:21
DECLSPEC SDL_bool SDLCALL SDL_GL_ExtensionSupported(const char *extension)
Return true if an OpenGL extension is supported for the current context.
Definition: SDL_video.c:2385
GLenum src
Definition: glew.h:2396
TParseContext * context
int i
Definition: pngrutil.c:1377
int(* RenderCopyEx)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcquad, const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
#define GL_TEXTURE_RECTANGLE_ARB
Definition: glew.h:6368
void(* RenderPresent)(SDL_Renderer *renderer)
void(* DestroyRenderer)(SDL_Renderer *renderer)
#define GL_SCISSOR_TEST
Definition: gl2.h:151
DECLSPEC void SDLCALL SDL_LogInfo(int category, const char *fmt,...)
Log a message with SDL_LOG_PRIORITY_INFO.
Definition: SDL_log.c:203
GLsizei GLsizei GLchar * source
Definition: gl2ext.h:994
int y
Definition: SDL_rect.h:65
DECLSPEC int SDLCALL SDL_strcasecmp(const char *str1, const char *str2)
Definition: SDL_string.c:946
static __inline ALuint maxu(ALuint a, ALuint b)
Definition: alu.h:63
void GL_SelectShader(GL_ShaderContext *ctx, GL_Shader shader)
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:63
#define GL_MAX_TEXTURE_SIZE
Definition: gl2.h:199
DECLSPEC void SDLCALL SDL_GL_SwapWindow(SDL_Window *window)
Swap the OpenGL buffers for a window, if double-buffering is supported.
Definition: SDL_video.c:2871
#define GL_NEAREST
Definition: gl2.h:307
cl_event event
Definition: glew.h:3556
#define glFramebufferTexture2DEXT
Definition: glew.h:9006
#define GL_DEPTH_TEST
Definition: gl2.h:150
GLsizei size
Definition: gl2ext.h:1467