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