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