SDL  2.0
SDL_render_gles.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_ES && !SDL_RENDER_DISABLED
24 
25 #include "SDL_hints.h"
26 #include "SDL_opengles.h"
27 #include "../SDL_sysrender.h"
28 
29 /* To prevent unnecessary window recreation,
30  * these should match the defaults selected in SDL_GL_ResetAttributes
31  */
32 
33 #define RENDERER_CONTEXT_MAJOR 1
34 #define RENDERER_CONTEXT_MINOR 1
35 
36 #if defined(SDL_VIDEO_DRIVER_PANDORA)
37 
38 /* Empty function stub to get OpenGL ES 1.x support without */
39 /* OpenGL ES extension GL_OES_draw_texture supported */
40 GL_API void GL_APIENTRY
41 glDrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height)
42 {
43  return;
44 }
45 
46 #endif /* SDL_VIDEO_DRIVER_PANDORA */
47 
48 /* OpenGL ES 1.1 renderer implementation, based on the OpenGL renderer */
49 
50 /* Used to re-create the window with OpenGL ES capability */
52 
53 static const float inv255f = 1.0f / 255.0f;
54 
55 static SDL_Renderer *GLES_CreateRenderer(SDL_Window * window, Uint32 flags);
56 static void GLES_WindowEvent(SDL_Renderer * renderer,
57  const SDL_WindowEvent *event);
58 static int GLES_GetOutputSize(SDL_Renderer * renderer, int *w, int *h);
59 static int GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
60 static int GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
61  const SDL_Rect * rect, const void *pixels,
62  int pitch);
63 static int GLES_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
64  const SDL_Rect * rect, void **pixels, int *pitch);
65 static void GLES_UnlockTexture(SDL_Renderer * renderer,
67 static int GLES_SetRenderTarget(SDL_Renderer * renderer,
69 static int GLES_UpdateViewport(SDL_Renderer * renderer);
70 static int GLES_UpdateClipRect(SDL_Renderer * renderer);
71 static int GLES_RenderClear(SDL_Renderer * renderer);
72 static int GLES_RenderDrawPoints(SDL_Renderer * renderer,
73  const SDL_FPoint * points, int count);
74 static int GLES_RenderDrawLines(SDL_Renderer * renderer,
75  const SDL_FPoint * points, int count);
76 static int GLES_RenderFillRects(SDL_Renderer * renderer,
77  const SDL_FRect * rects, int count);
78 static int GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
79  const SDL_Rect * srcrect,
80  const SDL_FRect * dstrect);
81 static int GLES_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
82  const SDL_Rect * srcrect, const SDL_FRect * dstrect,
83  const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip);
84 static int GLES_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
85  Uint32 pixel_format, void * pixels, int pitch);
86 static void GLES_RenderPresent(SDL_Renderer * renderer);
87 static void GLES_DestroyTexture(SDL_Renderer * renderer,
89 static void GLES_DestroyRenderer(SDL_Renderer * renderer);
90 static int GLES_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, float *texh);
91 static int GLES_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture);
92 
93 typedef struct GLES_FBOList GLES_FBOList;
94 
95 struct GLES_FBOList
96 {
97  Uint32 w, h;
98  GLuint FBO;
99  GLES_FBOList *next;
100 };
101 
102 
103 SDL_RenderDriver GLES_RenderDriver = {
104  GLES_CreateRenderer,
105  {
106  "opengles",
108  1,
110  0,
111  0}
112 };
113 
114 typedef struct
115 {
116  SDL_GLContext context;
117  struct {
118  Uint32 color;
119  int blendMode;
120  SDL_bool tex_coords;
121  } current;
122 
123 #define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
124 #define SDL_PROC_OES SDL_PROC
125 #include "SDL_glesfuncs.h"
126 #undef SDL_PROC
127 #undef SDL_PROC_OES
128  SDL_bool GL_OES_framebuffer_object_supported;
129  GLES_FBOList *framebuffers;
130  GLuint window_framebuffer;
131 
132  SDL_bool GL_OES_blend_func_separate_supported;
133 } GLES_RenderData;
134 
135 typedef struct
136 {
137  GLuint texture;
138  GLenum type;
139  GLfloat texw;
140  GLfloat texh;
141  GLenum format;
142  GLenum formattype;
143  void *pixels;
144  int pitch;
145  GLES_FBOList *fbo;
146 } GLES_TextureData;
147 
148 static int
149 GLES_SetError(const char *prefix, GLenum result)
150 {
151  const char *error;
152 
153  switch (result) {
154  case GL_NO_ERROR:
155  error = "GL_NO_ERROR";
156  break;
157  case GL_INVALID_ENUM:
158  error = "GL_INVALID_ENUM";
159  break;
160  case GL_INVALID_VALUE:
161  error = "GL_INVALID_VALUE";
162  break;
164  error = "GL_INVALID_OPERATION";
165  break;
166  case GL_STACK_OVERFLOW:
167  error = "GL_STACK_OVERFLOW";
168  break;
169  case GL_STACK_UNDERFLOW:
170  error = "GL_STACK_UNDERFLOW";
171  break;
172  case GL_OUT_OF_MEMORY:
173  error = "GL_OUT_OF_MEMORY";
174  break;
175  default:
176  error = "UNKNOWN";
177  break;
178  }
179  return SDL_SetError("%s: %s", prefix, error);
180 }
181 
182 static int GLES_LoadFunctions(GLES_RenderData * data)
183 {
184 #if SDL_VIDEO_DRIVER_UIKIT
185 #define __SDL_NOGETPROCADDR__
186 #elif SDL_VIDEO_DRIVER_ANDROID
187 #define __SDL_NOGETPROCADDR__
188 #elif SDL_VIDEO_DRIVER_PANDORA
189 #define __SDL_NOGETPROCADDR__
190 #endif
191 
192 #ifdef __SDL_NOGETPROCADDR__
193 #define SDL_PROC(ret,func,params) data->func=func;
194 #define SDL_PROC_OES(ret,func,params) data->func=func;
195 #else
196 #define SDL_PROC(ret,func,params) \
197  do { \
198  data->func = SDL_GL_GetProcAddress(#func); \
199  if ( ! data->func ) { \
200  return SDL_SetError("Couldn't load GLES function %s: %s\n", #func, SDL_GetError()); \
201  } \
202  } while ( 0 );
203 #define SDL_PROC_OES(ret,func,params) \
204  do { \
205  data->func = SDL_GL_GetProcAddress(#func); \
206  } while ( 0 );
207 #endif /* __SDL_NOGETPROCADDR__ */
208 
209 #include "SDL_glesfuncs.h"
210 #undef SDL_PROC
211 #undef SDL_PROC_OES
212  return 0;
213 }
214 
215 static SDL_GLContext SDL_CurrentContext = NULL;
216 
217 GLES_FBOList *
218 GLES_GetFBO(GLES_RenderData *data, Uint32 w, Uint32 h)
219 {
220  GLES_FBOList *result = data->framebuffers;
221  while ((result) && ((result->w != w) || (result->h != h)) ) {
222  result = result->next;
223  }
224  if (result == NULL) {
225  result = SDL_malloc(sizeof(GLES_FBOList));
226  result->w = w;
227  result->h = h;
228  data->glGenFramebuffersOES(1, &result->FBO);
229  result->next = data->framebuffers;
230  data->framebuffers = result;
231  }
232  return result;
233 }
234 
235 
236 static int
237 GLES_ActivateRenderer(SDL_Renderer * renderer)
238 {
239  GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
240 
241  if (SDL_CurrentContext != data->context) {
242  if (SDL_GL_MakeCurrent(renderer->window, data->context) < 0) {
243  return -1;
244  }
245  SDL_CurrentContext = data->context;
246 
247  GLES_UpdateViewport(renderer);
248  }
249  return 0;
250 }
251 
252 /* This is called if we need to invalidate all of the SDL OpenGL state */
253 static void
254 GLES_ResetState(SDL_Renderer *renderer)
255 {
256  GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
257 
258  if (SDL_CurrentContext == data->context) {
259  GLES_UpdateViewport(renderer);
260  } else {
261  GLES_ActivateRenderer(renderer);
262  }
263 
264  data->current.color = 0;
265  data->current.blendMode = -1;
266  data->current.tex_coords = SDL_FALSE;
267 
268  data->glDisable(GL_DEPTH_TEST);
269  data->glDisable(GL_CULL_FACE);
270 
271  data->glMatrixMode(GL_MODELVIEW);
272  data->glLoadIdentity();
273 
274  data->glEnableClientState(GL_VERTEX_ARRAY);
275  data->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
276 }
277 
278 SDL_Renderer *
279 GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
280 {
281 
283  GLES_RenderData *data;
284  GLint value;
285  Uint32 window_flags;
286  int profile_mask = 0, major = 0, minor = 0;
287  SDL_bool changed_window = SDL_FALSE;
288 
292 
293  window_flags = SDL_GetWindowFlags(window);
294  if (!(window_flags & SDL_WINDOW_OPENGL) ||
295  profile_mask != SDL_GL_CONTEXT_PROFILE_ES || major != RENDERER_CONTEXT_MAJOR || minor != RENDERER_CONTEXT_MINOR) {
296 
297  changed_window = SDL_TRUE;
299  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, RENDERER_CONTEXT_MAJOR);
300  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, RENDERER_CONTEXT_MINOR);
301 
302  if (SDL_RecreateWindow(window, window_flags | SDL_WINDOW_OPENGL) < 0) {
303  goto error;
304  }
305  }
306 
307  renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
308  if (!renderer) {
309  SDL_OutOfMemory();
310  goto error;
311  }
312 
313  data = (GLES_RenderData *) SDL_calloc(1, sizeof(*data));
314  if (!data) {
315  GLES_DestroyRenderer(renderer);
316  SDL_OutOfMemory();
317  goto error;
318  }
319 
320  renderer->WindowEvent = GLES_WindowEvent;
321  renderer->GetOutputSize = GLES_GetOutputSize;
322  renderer->CreateTexture = GLES_CreateTexture;
323  renderer->UpdateTexture = GLES_UpdateTexture;
324  renderer->LockTexture = GLES_LockTexture;
325  renderer->UnlockTexture = GLES_UnlockTexture;
326  renderer->SetRenderTarget = GLES_SetRenderTarget;
327  renderer->UpdateViewport = GLES_UpdateViewport;
328  renderer->UpdateClipRect = GLES_UpdateClipRect;
329  renderer->RenderClear = GLES_RenderClear;
330  renderer->RenderDrawPoints = GLES_RenderDrawPoints;
331  renderer->RenderDrawLines = GLES_RenderDrawLines;
332  renderer->RenderFillRects = GLES_RenderFillRects;
333  renderer->RenderCopy = GLES_RenderCopy;
334  renderer->RenderCopyEx = GLES_RenderCopyEx;
335  renderer->RenderReadPixels = GLES_RenderReadPixels;
336  renderer->RenderPresent = GLES_RenderPresent;
337  renderer->DestroyTexture = GLES_DestroyTexture;
338  renderer->DestroyRenderer = GLES_DestroyRenderer;
339  renderer->GL_BindTexture = GLES_BindTexture;
340  renderer->GL_UnbindTexture = GLES_UnbindTexture;
341  renderer->info = GLES_RenderDriver.info;
342  renderer->info.flags = SDL_RENDERER_ACCELERATED;
343  renderer->driverdata = data;
344  renderer->window = window;
345 
346  data->context = SDL_GL_CreateContext(window);
347  if (!data->context) {
348  GLES_DestroyRenderer(renderer);
349  goto error;
350  }
351  if (SDL_GL_MakeCurrent(window, data->context) < 0) {
352  GLES_DestroyRenderer(renderer);
353  goto error;
354  }
355 
356  if (GLES_LoadFunctions(data) < 0) {
357  GLES_DestroyRenderer(renderer);
358  goto error;
359  }
360 
361  if (flags & SDL_RENDERER_PRESENTVSYNC) {
363  } else {
365  }
366  if (SDL_GL_GetSwapInterval() > 0) {
367  renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
368  }
369 
370  value = 0;
371  data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
372  renderer->info.max_texture_width = value;
373  value = 0;
374  data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
375  renderer->info.max_texture_height = value;
376 
377  /* Android does not report GL_OES_framebuffer_object but the functionality seems to be there anyway */
378  if (SDL_GL_ExtensionSupported("GL_OES_framebuffer_object") || data->glGenFramebuffersOES) {
379  data->GL_OES_framebuffer_object_supported = SDL_TRUE;
381 
382  value = 0;
383  data->glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &value);
384  data->window_framebuffer = (GLuint)value;
385  }
386  data->framebuffers = NULL;
387 
388  if (SDL_GL_ExtensionSupported("GL_OES_blend_func_separate")) {
389  data->GL_OES_blend_func_separate_supported = SDL_TRUE;
390  }
391 
392  /* Set up parameters for rendering */
393  GLES_ResetState(renderer);
394 
395  return renderer;
396 
397 error:
398  if (changed_window) {
399  /* Uh oh, better try to put it back... */
403  SDL_RecreateWindow(window, window_flags);
404  }
405  return NULL;
406 }
407 
408 static void
409 GLES_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
410 {
411  GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
412 
413  if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED ||
414  event->event == SDL_WINDOWEVENT_SHOWN ||
415  event->event == SDL_WINDOWEVENT_HIDDEN) {
416  /* Rebind the context to the window area and update matrices */
417  SDL_CurrentContext = NULL;
418  }
419 
420  if (event->event == SDL_WINDOWEVENT_MINIMIZED) {
421  /* According to Apple documentation, we need to finish drawing NOW! */
422  data->glFinish();
423  }
424 }
425 
426 static int
427 GLES_GetOutputSize(SDL_Renderer * renderer, int *w, int *h)
428 {
429  SDL_GL_GetDrawableSize(renderer->window, w, h);
430  return 0;
431 }
432 
433 static SDL_INLINE int
434 power_of_2(int input)
435 {
436  int value = 1;
437 
438  while (value < input) {
439  value <<= 1;
440  }
441  return value;
442 }
443 
444 static GLenum
445 GetScaleQuality(void)
446 {
447  const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
448 
449  if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
450  return GL_NEAREST;
451  } else {
452  return GL_LINEAR;
453  }
454 }
455 
456 static int
457 GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
458 {
459  GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata;
460  GLES_TextureData *data;
462  GLenum format, type;
463  int texture_w, texture_h;
464  GLenum scaleMode;
465  GLenum result;
466 
467  GLES_ActivateRenderer(renderer);
468 
469  switch (texture->format) {
472  format = GL_RGBA;
474  break;
475  default:
476  return SDL_SetError("Texture format not supported");
477  }
478 
479  data = (GLES_TextureData *) SDL_calloc(1, sizeof(*data));
480  if (!data) {
481  return SDL_OutOfMemory();
482  }
483 
484  if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
485  data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
486  data->pixels = SDL_calloc(1, texture->h * data->pitch);
487  if (!data->pixels) {
488  SDL_free(data);
489  return SDL_OutOfMemory();
490  }
491  }
492 
493 
494  if (texture->access == SDL_TEXTUREACCESS_TARGET) {
495  if (!renderdata->GL_OES_framebuffer_object_supported) {
496  SDL_free(data);
497  return SDL_SetError("GL_OES_framebuffer_object not supported");
498  }
499  data->fbo = GLES_GetFBO(renderer->driverdata, texture->w, texture->h);
500  } else {
501  data->fbo = NULL;
502  }
503 
504 
505  renderdata->glGetError();
506  renderdata->glEnable(GL_TEXTURE_2D);
507  renderdata->glGenTextures(1, &data->texture);
508  result = renderdata->glGetError();
509  if (result != GL_NO_ERROR) {
510  SDL_free(data);
511  return GLES_SetError("glGenTextures()", result);
512  }
513 
514  data->type = GL_TEXTURE_2D;
515  /* no NPOV textures allowed in OpenGL ES (yet) */
516  texture_w = power_of_2(texture->w);
517  texture_h = power_of_2(texture->h);
518  data->texw = (GLfloat) texture->w / texture_w;
519  data->texh = (GLfloat) texture->h / texture_h;
520 
521  data->format = format;
522  data->formattype = type;
523  scaleMode = GetScaleQuality();
524  renderdata->glBindTexture(data->type, data->texture);
525  renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER, scaleMode);
526  renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER, scaleMode);
527  renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
528  renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
529 
530  renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w,
531  texture_h, 0, format, type, NULL);
532  renderdata->glDisable(GL_TEXTURE_2D);
533 
534  result = renderdata->glGetError();
535  if (result != GL_NO_ERROR) {
536  SDL_free(data);
537  return GLES_SetError("glTexImage2D()", result);
538  }
539 
540  texture->driverdata = data;
541  return 0;
542 }
543 
544 static int
545 GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
546  const SDL_Rect * rect, const void *pixels, int pitch)
547 {
548  GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata;
549  GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
550  Uint8 *blob = NULL;
551  Uint8 *src;
552  int srcPitch;
553  int y;
554 
555  GLES_ActivateRenderer(renderer);
556 
557  /* Bail out if we're supposed to update an empty rectangle */
558  if (rect->w <= 0 || rect->h <= 0) {
559  return 0;
560  }
561 
562  /* Reformat the texture data into a tightly packed array */
563  srcPitch = rect->w * SDL_BYTESPERPIXEL(texture->format);
564  src = (Uint8 *)pixels;
565  if (pitch != srcPitch) {
566  blob = (Uint8 *)SDL_malloc(srcPitch * rect->h);
567  if (!blob) {
568  return SDL_OutOfMemory();
569  }
570  src = blob;
571  for (y = 0; y < rect->h; ++y) {
572  SDL_memcpy(src, pixels, srcPitch);
573  src += srcPitch;
574  pixels = (Uint8 *)pixels + pitch;
575  }
576  src = blob;
577  }
578 
579  /* Create a texture subimage with the supplied data */
580  renderdata->glGetError();
581  renderdata->glEnable(data->type);
582  renderdata->glBindTexture(data->type, data->texture);
583  renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
584  renderdata->glTexSubImage2D(data->type,
585  0,
586  rect->x,
587  rect->y,
588  rect->w,
589  rect->h,
590  data->format,
591  data->formattype,
592  src);
593  renderdata->glDisable(data->type);
594  SDL_free(blob);
595 
596  if (renderdata->glGetError() != GL_NO_ERROR) {
597  return SDL_SetError("Failed to update texture");
598  }
599  return 0;
600 }
601 
602 static int
603 GLES_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
604  const SDL_Rect * rect, void **pixels, int *pitch)
605 {
606  GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
607 
608  *pixels =
609  (void *) ((Uint8 *) data->pixels + rect->y * data->pitch +
610  rect->x * SDL_BYTESPERPIXEL(texture->format));
611  *pitch = data->pitch;
612  return 0;
613 }
614 
615 static void
616 GLES_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
617 {
618  GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
619  SDL_Rect rect;
620 
621  /* We do whole texture updates, at least for now */
622  rect.x = 0;
623  rect.y = 0;
624  rect.w = texture->w;
625  rect.h = texture->h;
626  GLES_UpdateTexture(renderer, texture, &rect, data->pixels, data->pitch);
627 }
628 
629 static int
630 GLES_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
631 {
632  GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
633  GLES_TextureData *texturedata = NULL;
634  GLenum status;
635 
636  GLES_ActivateRenderer(renderer);
637 
638  if (!data->GL_OES_framebuffer_object_supported) {
639  return SDL_SetError("Can't enable render target support in this renderer");
640  }
641 
642  if (texture == NULL) {
643  data->glBindFramebufferOES(GL_FRAMEBUFFER_OES, data->window_framebuffer);
644  return 0;
645  }
646 
647  texturedata = (GLES_TextureData *) texture->driverdata;
648  data->glBindFramebufferOES(GL_FRAMEBUFFER_OES, texturedata->fbo->FBO);
649  /* TODO: check if texture pixel format allows this operation */
650  data->glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, texturedata->type, texturedata->texture, 0);
651  /* Check FBO status */
652  status = data->glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
653  if (status != GL_FRAMEBUFFER_COMPLETE_OES) {
654  return SDL_SetError("glFramebufferTexture2DOES() failed");
655  }
656  return 0;
657 }
658 
659 static int
660 GLES_UpdateViewport(SDL_Renderer * renderer)
661 {
662  GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
663 
664  if (SDL_CurrentContext != data->context) {
665  /* We'll update the viewport after we rebind the context */
666  return 0;
667  }
668 
669  if (renderer->target) {
670  data->glViewport(renderer->viewport.x, renderer->viewport.y,
671  renderer->viewport.w, renderer->viewport.h);
672  } else {
673  int w, h;
674 
675  SDL_GL_GetDrawableSize(renderer->window, &w, &h);
676  data->glViewport(renderer->viewport.x, (h - renderer->viewport.y - renderer->viewport.h),
677  renderer->viewport.w, renderer->viewport.h);
678  }
679 
680  data->glMatrixMode(GL_PROJECTION);
681  data->glLoadIdentity();
682  if (renderer->viewport.w && renderer->viewport.h) {
683  if (renderer->target) {
684  data->glOrthof((GLfloat) 0,
685  (GLfloat) renderer->viewport.w,
686  (GLfloat) 0,
687  (GLfloat) renderer->viewport.h,
688  0.0, 1.0);
689  } else {
690  data->glOrthof((GLfloat) 0,
691  (GLfloat) renderer->viewport.w,
692  (GLfloat) renderer->viewport.h,
693  (GLfloat) 0,
694  0.0, 1.0);
695  }
696  }
697  return 0;
698 }
699 
700 static int
701 GLES_UpdateClipRect(SDL_Renderer * renderer)
702 {
703  GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
704 
705  if (SDL_CurrentContext != data->context) {
706  /* We'll update the clip rect after we rebind the context */
707  return 0;
708  }
709 
710  if (renderer->clipping_enabled) {
711  const SDL_Rect *rect = &renderer->clip_rect;
712  data->glEnable(GL_SCISSOR_TEST);
713  if (renderer->target) {
714  data->glScissor(renderer->viewport.x + rect->x, renderer->viewport.y + rect->y, rect->w, rect->h);
715  } else {
716  int w, h;
717 
718  SDL_GL_GetDrawableSize(renderer->window, &w, &h);
719  data->glScissor(renderer->viewport.x + rect->x, h - renderer->viewport.y - rect->y - rect->h, rect->w, rect->h);
720  }
721  } else {
722  data->glDisable(GL_SCISSOR_TEST);
723  }
724  return 0;
725 }
726 
727 static void
728 GLES_SetColor(GLES_RenderData * data, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
729 {
730  Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b);
731 
732  if (color != data->current.color) {
733  data->glColor4f((GLfloat) r * inv255f,
734  (GLfloat) g * inv255f,
735  (GLfloat) b * inv255f,
736  (GLfloat) a * inv255f);
737  data->current.color = color;
738  }
739 }
740 
741 static void
742 GLES_SetBlendMode(GLES_RenderData * data, int blendMode)
743 {
744  if (blendMode != data->current.blendMode) {
745  switch (blendMode) {
746  case SDL_BLENDMODE_NONE:
747  data->glDisable(GL_BLEND);
748  break;
749  case SDL_BLENDMODE_BLEND:
750  data->glEnable(GL_BLEND);
751  if (data->GL_OES_blend_func_separate_supported) {
752  data->glBlendFuncSeparateOES(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
753  } else {
754  data->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
755  }
756  break;
757  case SDL_BLENDMODE_ADD:
758  data->glEnable(GL_BLEND);
759  if (data->GL_OES_blend_func_separate_supported) {
760  data->glBlendFuncSeparateOES(GL_SRC_ALPHA, GL_ONE, GL_ZERO, GL_ONE);
761  } else {
762  data->glBlendFunc(GL_SRC_ALPHA, GL_ONE);
763  }
764  break;
765  case SDL_BLENDMODE_MOD:
766  data->glEnable(GL_BLEND);
767  if (data->GL_OES_blend_func_separate_supported) {
768  data->glBlendFuncSeparateOES(GL_ZERO, GL_SRC_COLOR, GL_ZERO, GL_ONE);
769  } else {
770  data->glBlendFunc(GL_ZERO, GL_SRC_COLOR);
771  }
772  break;
773  }
774  data->current.blendMode = blendMode;
775  }
776 }
777 
778 static void
779 GLES_SetTexCoords(GLES_RenderData * data, SDL_bool enabled)
780 {
781  if (enabled != data->current.tex_coords) {
782  if (enabled) {
783  data->glEnableClientState(GL_TEXTURE_COORD_ARRAY);
784  } else {
785  data->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
786  }
787  data->current.tex_coords = enabled;
788  }
789 }
790 
791 static void
792 GLES_SetDrawingState(SDL_Renderer * renderer)
793 {
794  GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
795 
796  GLES_ActivateRenderer(renderer);
797 
798  GLES_SetColor(data, (GLfloat) renderer->r,
799  (GLfloat) renderer->g,
800  (GLfloat) renderer->b,
801  (GLfloat) renderer->a);
802 
803  GLES_SetBlendMode(data, renderer->blendMode);
804 
805  GLES_SetTexCoords(data, SDL_FALSE);
806 }
807 
808 static int
809 GLES_RenderClear(SDL_Renderer * renderer)
810 {
811  GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
812 
813  GLES_ActivateRenderer(renderer);
814 
815  data->glClearColor((GLfloat) renderer->r * inv255f,
816  (GLfloat) renderer->g * inv255f,
817  (GLfloat) renderer->b * inv255f,
818  (GLfloat) renderer->a * inv255f);
819 
820  if (renderer->clipping_enabled) {
821  data->glDisable(GL_SCISSOR_TEST);
822  }
823 
824  data->glClear(GL_COLOR_BUFFER_BIT);
825 
826  if (renderer->clipping_enabled) {
827  data->glEnable(GL_SCISSOR_TEST);
828  }
829 
830  return 0;
831 }
832 
833 static int
834 GLES_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points,
835  int count)
836 {
837  GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
838  GLfloat *vertices;
839  int idx;
840 
841  GLES_SetDrawingState(renderer);
842 
843  /* Emit the specified vertices as points */
844  vertices = SDL_stack_alloc(GLfloat, count * 2);
845  for (idx = 0; idx < count; ++idx) {
846  GLfloat x = points[idx].x + 0.5f;
847  GLfloat y = points[idx].y + 0.5f;
848 
849  vertices[idx * 2] = x;
850  vertices[(idx * 2) + 1] = y;
851  }
852 
853  data->glVertexPointer(2, GL_FLOAT, 0, vertices);
854  data->glDrawArrays(GL_POINTS, 0, count);
855  SDL_stack_free(vertices);
856  return 0;
857 }
858 
859 static int
860 GLES_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points,
861  int count)
862 {
863  GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
864  GLfloat *vertices;
865  int idx;
866 
867  GLES_SetDrawingState(renderer);
868 
869  /* Emit a line strip including the specified vertices */
870  vertices = SDL_stack_alloc(GLfloat, count * 2);
871  for (idx = 0; idx < count; ++idx) {
872  GLfloat x = points[idx].x + 0.5f;
873  GLfloat y = points[idx].y + 0.5f;
874 
875  vertices[idx * 2] = x;
876  vertices[(idx * 2) + 1] = y;
877  }
878 
879  data->glVertexPointer(2, GL_FLOAT, 0, vertices);
880  if (count > 2 &&
881  points[0].x == points[count-1].x && points[0].y == points[count-1].y) {
882  /* GL_LINE_LOOP takes care of the final segment */
883  --count;
884  data->glDrawArrays(GL_LINE_LOOP, 0, count);
885  } else {
886  data->glDrawArrays(GL_LINE_STRIP, 0, count);
887  /* We need to close the endpoint of the line */
888  data->glDrawArrays(GL_POINTS, count-1, 1);
889  }
890  SDL_stack_free(vertices);
891 
892  return 0;
893 }
894 
895 static int
896 GLES_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects,
897  int count)
898 {
899  GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
900  int i;
901 
902  GLES_SetDrawingState(renderer);
903 
904  for (i = 0; i < count; ++i) {
905  const SDL_FRect *rect = &rects[i];
906  GLfloat minx = rect->x;
907  GLfloat maxx = rect->x + rect->w;
908  GLfloat miny = rect->y;
909  GLfloat maxy = rect->y + rect->h;
910  GLfloat vertices[8];
911  vertices[0] = minx;
912  vertices[1] = miny;
913  vertices[2] = maxx;
914  vertices[3] = miny;
915  vertices[4] = minx;
916  vertices[5] = maxy;
917  vertices[6] = maxx;
918  vertices[7] = maxy;
919 
920  data->glVertexPointer(2, GL_FLOAT, 0, vertices);
921  data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
922  }
923 
924  return 0;
925 }
926 
927 static int
928 GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
929  const SDL_Rect * srcrect, const SDL_FRect * dstrect)
930 {
931  GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
932  GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata;
933  GLfloat minx, miny, maxx, maxy;
934  GLfloat minu, maxu, minv, maxv;
935  GLfloat vertices[8];
936  GLfloat texCoords[8];
937 
938  GLES_ActivateRenderer(renderer);
939 
940  data->glEnable(GL_TEXTURE_2D);
941 
942  data->glBindTexture(texturedata->type, texturedata->texture);
943 
944  if (texture->modMode) {
945  GLES_SetColor(data, texture->r, texture->g, texture->b, texture->a);
946  } else {
947  GLES_SetColor(data, 255, 255, 255, 255);
948  }
949 
950  GLES_SetBlendMode(data, texture->blendMode);
951 
952  GLES_SetTexCoords(data, SDL_TRUE);
953 
954  minx = dstrect->x;
955  miny = dstrect->y;
956  maxx = dstrect->x + dstrect->w;
957  maxy = dstrect->y + dstrect->h;
958 
959  minu = (GLfloat) srcrect->x / texture->w;
960  minu *= texturedata->texw;
961  maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w;
962  maxu *= texturedata->texw;
963  minv = (GLfloat) srcrect->y / texture->h;
964  minv *= texturedata->texh;
965  maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h;
966  maxv *= texturedata->texh;
967 
968  vertices[0] = minx;
969  vertices[1] = miny;
970  vertices[2] = maxx;
971  vertices[3] = miny;
972  vertices[4] = minx;
973  vertices[5] = maxy;
974  vertices[6] = maxx;
975  vertices[7] = maxy;
976 
977  texCoords[0] = minu;
978  texCoords[1] = minv;
979  texCoords[2] = maxu;
980  texCoords[3] = minv;
981  texCoords[4] = minu;
982  texCoords[5] = maxv;
983  texCoords[6] = maxu;
984  texCoords[7] = maxv;
985 
986  data->glVertexPointer(2, GL_FLOAT, 0, vertices);
987  data->glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
988  data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
989 
990  data->glDisable(GL_TEXTURE_2D);
991 
992  return 0;
993 }
994 
995 static int
996 GLES_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
997  const SDL_Rect * srcrect, const SDL_FRect * dstrect,
998  const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
999 {
1000 
1001  GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
1002  GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata;
1003  GLfloat minx, miny, maxx, maxy;
1004  GLfloat minu, maxu, minv, maxv;
1005  GLfloat centerx, centery;
1006  GLfloat vertices[8];
1007  GLfloat texCoords[8];
1008 
1009 
1010  GLES_ActivateRenderer(renderer);
1011 
1012  data->glEnable(GL_TEXTURE_2D);
1013 
1014  data->glBindTexture(texturedata->type, texturedata->texture);
1015 
1016  if (texture->modMode) {
1017  GLES_SetColor(data, texture->r, texture->g, texture->b, texture->a);
1018  } else {
1019  GLES_SetColor(data, 255, 255, 255, 255);
1020  }
1021 
1022  GLES_SetBlendMode(data, texture->blendMode);
1023 
1024  GLES_SetTexCoords(data, SDL_TRUE);
1025 
1026  centerx = center->x;
1027  centery = center->y;
1028 
1029  /* Rotate and translate */
1030  data->glPushMatrix();
1031  data->glTranslatef(dstrect->x + centerx, dstrect->y + centery, 0.0f);
1032  data->glRotatef((GLfloat)angle, 0.0f, 0.0f, 1.0f);
1033 
1034  if (flip & SDL_FLIP_HORIZONTAL) {
1035  minx = dstrect->w - centerx;
1036  maxx = -centerx;
1037  } else {
1038  minx = -centerx;
1039  maxx = dstrect->w - centerx;
1040  }
1041 
1042  if (flip & SDL_FLIP_VERTICAL) {
1043  miny = dstrect->h - centery;
1044  maxy = -centery;
1045  } else {
1046  miny = -centery;
1047  maxy = dstrect->h - centery;
1048  }
1049 
1050  minu = (GLfloat) srcrect->x / texture->w;
1051  minu *= texturedata->texw;
1052  maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w;
1053  maxu *= texturedata->texw;
1054  minv = (GLfloat) srcrect->y / texture->h;
1055  minv *= texturedata->texh;
1056  maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h;
1057  maxv *= texturedata->texh;
1058 
1059  vertices[0] = minx;
1060  vertices[1] = miny;
1061  vertices[2] = maxx;
1062  vertices[3] = miny;
1063  vertices[4] = minx;
1064  vertices[5] = maxy;
1065  vertices[6] = maxx;
1066  vertices[7] = maxy;
1067 
1068  texCoords[0] = minu;
1069  texCoords[1] = minv;
1070  texCoords[2] = maxu;
1071  texCoords[3] = minv;
1072  texCoords[4] = minu;
1073  texCoords[5] = maxv;
1074  texCoords[6] = maxu;
1075  texCoords[7] = maxv;
1076  data->glVertexPointer(2, GL_FLOAT, 0, vertices);
1077  data->glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
1078  data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1079  data->glPopMatrix();
1080  data->glDisable(GL_TEXTURE_2D);
1081 
1082  return 0;
1083 }
1084 
1085 static int
1086 GLES_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
1087  Uint32 pixel_format, void * pixels, int pitch)
1088 {
1089  GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
1090  Uint32 temp_format = renderer->target ? renderer->target->format : SDL_PIXELFORMAT_ABGR8888;
1091  void *temp_pixels;
1092  int temp_pitch;
1093  Uint8 *src, *dst, *tmp;
1094  int w, h, length, rows;
1095  int status;
1096 
1097  GLES_ActivateRenderer(renderer);
1098 
1099  temp_pitch = rect->w * SDL_BYTESPERPIXEL(temp_format);
1100  temp_pixels = SDL_malloc(rect->h * temp_pitch);
1101  if (!temp_pixels) {
1102  return SDL_OutOfMemory();
1103  }
1104 
1105  SDL_GetRendererOutputSize(renderer, &w, &h);
1106 
1107  data->glPixelStorei(GL_PACK_ALIGNMENT, 1);
1108 
1109  data->glReadPixels(rect->x, renderer->target ? rect->y : (h-rect->y)-rect->h,
1110  rect->w, rect->h, GL_RGBA, GL_UNSIGNED_BYTE, temp_pixels);
1111 
1112  /* Flip the rows to be top-down if necessary */
1113  if (!renderer->target) {
1114  length = rect->w * SDL_BYTESPERPIXEL(temp_format);
1115  src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch;
1116  dst = (Uint8*)temp_pixels;
1117  tmp = SDL_stack_alloc(Uint8, length);
1118  rows = rect->h / 2;
1119  while (rows--) {
1120  SDL_memcpy(tmp, dst, length);
1121  SDL_memcpy(dst, src, length);
1122  SDL_memcpy(src, tmp, length);
1123  dst += temp_pitch;
1124  src -= temp_pitch;
1125  }
1126  SDL_stack_free(tmp);
1127  }
1128 
1129  status = SDL_ConvertPixels(rect->w, rect->h,
1130  temp_format, temp_pixels, temp_pitch,
1131  pixel_format, pixels, pitch);
1132  SDL_free(temp_pixels);
1133 
1134  return status;
1135 }
1136 
1137 static void
1138 GLES_RenderPresent(SDL_Renderer * renderer)
1139 {
1140  GLES_ActivateRenderer(renderer);
1141 
1142  SDL_GL_SwapWindow(renderer->window);
1143 }
1144 
1145 static void
1146 GLES_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
1147 {
1148  GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata;
1149 
1150  GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
1151 
1152  GLES_ActivateRenderer(renderer);
1153 
1154  if (!data) {
1155  return;
1156  }
1157  if (data->texture) {
1158  renderdata->glDeleteTextures(1, &data->texture);
1159  }
1160  SDL_free(data->pixels);
1161  SDL_free(data);
1162  texture->driverdata = NULL;
1163 }
1164 
1165 static void
1166 GLES_DestroyRenderer(SDL_Renderer * renderer)
1167 {
1168  GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
1169 
1170  if (data) {
1171  if (data->context) {
1172  while (data->framebuffers) {
1173  GLES_FBOList *nextnode = data->framebuffers->next;
1174  data->glDeleteFramebuffersOES(1, &data->framebuffers->FBO);
1175  SDL_free(data->framebuffers);
1176  data->framebuffers = nextnode;
1177  }
1178  SDL_GL_DeleteContext(data->context);
1179  }
1180  SDL_free(data);
1181  }
1182  SDL_free(renderer);
1183 }
1184 
1185 static int GLES_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, float *texh)
1186 {
1187  GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
1188  GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata;
1189  GLES_ActivateRenderer(renderer);
1190 
1191  data->glEnable(GL_TEXTURE_2D);
1192  data->glBindTexture(texturedata->type, texturedata->texture);
1193 
1194  if (texw) {
1195  *texw = (float)texturedata->texw;
1196  }
1197  if (texh) {
1198  *texh = (float)texturedata->texh;
1199  }
1200 
1201  return 0;
1202 }
1203 
1204 static int GLES_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture)
1205 {
1206  GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
1207  GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata;
1208  GLES_ActivateRenderer(renderer);
1209  data->glDisable(texturedata->type);
1210 
1211  return 0;
1212 }
1213 
1214 #endif /* SDL_VIDEO_RENDER_OGL_ES && !SDL_RENDER_DISABLED */
1215 
1216 /* 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_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
GLint GLint GLsizei width
Definition: SDL_opengl.h:1565
#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_PROJECTION
Definition: SDL_opengl.h:265
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
void * driverdata
int GLint
Definition: SDL_opengl.h:175
#define GL_RGBA
Definition: SDL_opengl.h:522
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1967
#define SDL_GetHint
#define SDL_GetWindowFlags
GLfloat f
#define SDL_BYTESPERPIXEL(X)
Definition: SDL_pixels.h:128
#define GL_TEXTURE_MAG_FILTER
Definition: SDL_opengl.h:667
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
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_strcasecmp
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1565
int max_texture_height
Definition: SDL_render.h:85
#define GL_ONE_MINUS_SRC_ALPHA
Definition: SDL_opengl.h:398
SDL_Window * window
SDL_RendererInfo info
int(* RenderClear)(SDL_Renderer *renderer)
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_ALIGNMENT
Definition: SDL_opengl.h:645
#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
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
#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)
void * SDL_GLContext
An opaque handle to an OpenGL context.
Definition: SDL_video.h:172
#define SDL_GL_GetSwapInterval
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
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 GL_LINE_STRIP
Definition: SDL_opengl.h:212
void SDL_free(void *mem)
#define GL_TEXTURE_WRAP_T
Definition: SDL_opengl.h:666
#define GL_LINE_LOOP
Definition: SDL_opengl.h:211
#define GL_FLOAT
Definition: SDL_opengl.h:202
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
#define GL_APIENTRY
void(* UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:99
int x
Definition: SDL_rect.h:66
int(* SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture)
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
int(* GL_UnbindTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
SDL_RendererFlip
Flip constants for SDL_RenderCopyEx.
Definition: SDL_render.h:111
GLenum GLenum GLsizei const GLuint GLboolean enabled
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
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
GLdouble GLdouble z
unsigned int GLuint
Definition: SDL_opengl.h:178
#define SDL_SetError
#define GL_OUT_OF_MEMORY
Definition: SDL_opengl.h:718
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 GL_VERTEX_ARRAY
Definition: SDL_opengl.h:221
SDL_Rect viewport
int h
Definition: SDL_rect.h:67
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 format
Definition: SDL_sysrender.h:52
#define GL_TEXTURE_COORD_ARRAY
Definition: SDL_opengl.h:225
void * driverdata
Definition: SDL_sysrender.h:69
GLbitfield flags
#define SDL_INLINE
Definition: begin_code.h:120
#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)
int(* CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:82
void(* RenderPresent)(SDL_Renderer *renderer)
#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
GLboolean GLboolean GLboolean b
int y
Definition: SDL_rect.h:66
#define SDL_GL_SwapWindow
GLfloat GLfloat GLfloat GLfloat h
SDL_bool clipping_enabled
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:64