SDL 2.0
SDL_render_gles.c
Go to the documentation of this file.
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2019 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 */
40GL_API void GL_APIENTRY
41glDrawTexiOES(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
53static const float inv255f = 1.0f / 255.0f;
54
55typedef struct GLES_FBOList GLES_FBOList;
56
57struct GLES_FBOList
58{
59 Uint32 w, h;
60 GLuint FBO;
61 GLES_FBOList *next;
62};
63
64typedef struct
65{
67 SDL_bool viewport_dirty;
70 int drawablew;
71 int drawableh;
72 SDL_BlendMode blend;
73 SDL_bool cliprect_enabled_dirty;
74 SDL_bool cliprect_enabled;
75 SDL_bool cliprect_dirty;
76 SDL_Rect cliprect;
77 SDL_bool texturing;
79 Uint32 clear_color;
80} GLES_DrawStateCache;
81
82typedef struct
83{
85
86#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
87#define SDL_PROC_OES SDL_PROC
88#include "SDL_glesfuncs.h"
89#undef SDL_PROC
90#undef SDL_PROC_OES
91 SDL_bool GL_OES_framebuffer_object_supported;
92 GLES_FBOList *framebuffers;
93 GLuint window_framebuffer;
94
95 SDL_bool GL_OES_blend_func_separate_supported;
96 SDL_bool GL_OES_blend_equation_separate_supported;
97 SDL_bool GL_OES_blend_subtract_supported;
98
99 GLES_DrawStateCache drawstate;
100} GLES_RenderData;
101
102typedef struct
103{
105 GLenum type;
106 GLfloat texw;
107 GLfloat texh;
109 GLenum formattype;
110 void *pixels;
111 int pitch;
112 GLES_FBOList *fbo;
113} GLES_TextureData;
114
115static int
116GLES_SetError(const char *prefix, GLenum result)
117{
118 const char *error;
119
120 switch (result) {
121 case GL_NO_ERROR:
122 error = "GL_NO_ERROR";
123 break;
124 case GL_INVALID_ENUM:
125 error = "GL_INVALID_ENUM";
126 break;
127 case GL_INVALID_VALUE:
128 error = "GL_INVALID_VALUE";
129 break;
131 error = "GL_INVALID_OPERATION";
132 break;
134 error = "GL_STACK_OVERFLOW";
135 break;
137 error = "GL_STACK_UNDERFLOW";
138 break;
139 case GL_OUT_OF_MEMORY:
140 error = "GL_OUT_OF_MEMORY";
141 break;
142 default:
143 error = "UNKNOWN";
144 break;
145 }
146 return SDL_SetError("%s: %s", prefix, error);
147}
148
149static int GLES_LoadFunctions(GLES_RenderData * data)
150{
151#if SDL_VIDEO_DRIVER_UIKIT
152#define __SDL_NOGETPROCADDR__
153#elif SDL_VIDEO_DRIVER_ANDROID
154#define __SDL_NOGETPROCADDR__
155#elif SDL_VIDEO_DRIVER_PANDORA
156#define __SDL_NOGETPROCADDR__
157#endif
158
159#ifdef __SDL_NOGETPROCADDR__
160#define SDL_PROC(ret,func,params) data->func=func;
161#define SDL_PROC_OES(ret,func,params) data->func=func;
162#else
163#define SDL_PROC(ret,func,params) \
164 do { \
165 data->func = SDL_GL_GetProcAddress(#func); \
166 if ( ! data->func ) { \
167 return SDL_SetError("Couldn't load GLES function %s: %s", #func, SDL_GetError()); \
168 } \
169 } while ( 0 );
170#define SDL_PROC_OES(ret,func,params) \
171 do { \
172 data->func = SDL_GL_GetProcAddress(#func); \
173 } while ( 0 );
174#endif /* __SDL_NOGETPROCADDR__ */
175
176#include "SDL_glesfuncs.h"
177#undef SDL_PROC
178#undef SDL_PROC_OES
179 return 0;
180}
181
182static GLES_FBOList *
183GLES_GetFBO(GLES_RenderData *data, Uint32 w, Uint32 h)
184{
185 GLES_FBOList *result = data->framebuffers;
186 while ((result) && ((result->w != w) || (result->h != h)) ) {
187 result = result->next;
188 }
189 if (result == NULL) {
190 result = SDL_malloc(sizeof(GLES_FBOList));
191 result->w = w;
192 result->h = h;
193 data->glGenFramebuffersOES(1, &result->FBO);
194 result->next = data->framebuffers;
195 data->framebuffers = result;
196 }
197 return result;
198}
199
200
201static int
202GLES_ActivateRenderer(SDL_Renderer * renderer)
203{
204 GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
205
206 if (SDL_GL_GetCurrentContext() != data->context) {
207 if (SDL_GL_MakeCurrent(renderer->window, data->context) < 0) {
208 return -1;
209 }
210 }
211
212 return 0;
213}
214
215static void
216GLES_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
217{
218 GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
219
220 if (event->event == SDL_WINDOWEVENT_MINIMIZED) {
221 /* According to Apple documentation, we need to finish drawing NOW! */
222 data->glFinish();
223 }
224}
225
226static int
227GLES_GetOutputSize(SDL_Renderer * renderer, int *w, int *h)
228{
230 return 0;
231}
232
233static GLenum GetBlendFunc(SDL_BlendFactor factor)
234{
235 switch (factor) {
237 return GL_ZERO;
239 return GL_ONE;
241 return GL_SRC_COLOR;
245 return GL_SRC_ALPHA;
249 return GL_DST_COLOR;
253 return GL_DST_ALPHA;
256 default:
257 return GL_INVALID_ENUM;
258 }
259}
260
261static GLenum GetBlendEquation(SDL_BlendOperation operation)
262{
263 switch (operation) {
265 return GL_FUNC_ADD_OES;
267 return GL_FUNC_SUBTRACT_OES;
269 return GL_FUNC_REVERSE_SUBTRACT_OES;
270 default:
271 return GL_INVALID_ENUM;
272 }
273}
274
275static SDL_bool
276GLES_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode)
277{
278 GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
285
286 if (GetBlendFunc(srcColorFactor) == GL_INVALID_ENUM ||
287 GetBlendFunc(srcAlphaFactor) == GL_INVALID_ENUM ||
288 GetBlendEquation(colorOperation) == GL_INVALID_ENUM ||
289 GetBlendFunc(dstColorFactor) == GL_INVALID_ENUM ||
290 GetBlendFunc(dstAlphaFactor) == GL_INVALID_ENUM ||
291 GetBlendEquation(alphaOperation) == GL_INVALID_ENUM) {
292 return SDL_FALSE;
293 }
294 if ((srcColorFactor != srcAlphaFactor || dstColorFactor != dstAlphaFactor) && !data->GL_OES_blend_func_separate_supported) {
295 return SDL_FALSE;
296 }
297 if (colorOperation != alphaOperation && !data->GL_OES_blend_equation_separate_supported) {
298 return SDL_FALSE;
299 }
300 if (colorOperation != SDL_BLENDOPERATION_ADD && !data->GL_OES_blend_subtract_supported) {
301 return SDL_FALSE;
302 }
303 return SDL_TRUE;
304}
305
306static SDL_INLINE int
307power_of_2(int input)
308{
309 int value = 1;
310
311 while (value < input) {
312 value <<= 1;
313 }
314 return value;
315}
316
317static int
318GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
319{
320 GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata;
321 GLES_TextureData *data;
324 int texture_w, texture_h;
325 GLenum scaleMode;
327
328 GLES_ActivateRenderer(renderer);
329
330 switch (texture->format) {
333 format = GL_RGBA;
335 break;
336 default:
337 return SDL_SetError("Texture format not supported");
338 }
339
340 data = (GLES_TextureData *) SDL_calloc(1, sizeof(*data));
341 if (!data) {
342 return SDL_OutOfMemory();
343 }
344
345 if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
346 data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
347 data->pixels = SDL_calloc(1, texture->h * data->pitch);
348 if (!data->pixels) {
349 SDL_free(data);
350 return SDL_OutOfMemory();
351 }
352 }
353
354
355 if (texture->access == SDL_TEXTUREACCESS_TARGET) {
356 if (!renderdata->GL_OES_framebuffer_object_supported) {
357 SDL_free(data);
358 return SDL_SetError("GL_OES_framebuffer_object not supported");
359 }
360 data->fbo = GLES_GetFBO(renderer->driverdata, texture->w, texture->h);
361 } else {
362 data->fbo = NULL;
363 }
364
365
366 renderdata->glGetError();
367 renderdata->glEnable(GL_TEXTURE_2D);
368 renderdata->glGenTextures(1, &data->texture);
369 result = renderdata->glGetError();
370 if (result != GL_NO_ERROR) {
371 SDL_free(data);
372 return GLES_SetError("glGenTextures()", result);
373 }
374
375 data->type = GL_TEXTURE_2D;
376 /* no NPOV textures allowed in OpenGL ES (yet) */
377 texture_w = power_of_2(texture->w);
378 texture_h = power_of_2(texture->h);
379 data->texw = (GLfloat) texture->w / texture_w;
380 data->texh = (GLfloat) texture->h / texture_h;
381
382 data->format = format;
383 data->formattype = type;
384 scaleMode = (texture->scaleMode == SDL_ScaleModeNearest) ? GL_NEAREST : GL_LINEAR;
385 renderdata->glBindTexture(data->type, data->texture);
386 renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER, scaleMode);
387 renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER, scaleMode);
388 renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
389 renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
390
391 renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w,
392 texture_h, 0, format, type, NULL);
393 renderdata->glDisable(GL_TEXTURE_2D);
394 renderdata->drawstate.texture = texture;
395 renderdata->drawstate.texturing = SDL_FALSE;
396
397 result = renderdata->glGetError();
398 if (result != GL_NO_ERROR) {
399 SDL_free(data);
400 return GLES_SetError("glTexImage2D()", result);
401 }
402
403 texture->driverdata = data;
404 return 0;
405}
406
407static int
408GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
409 const SDL_Rect * rect, const void *pixels, int pitch)
410{
411 GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata;
412 GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
413 Uint8 *blob = NULL;
414 Uint8 *src;
415 int srcPitch;
416 int y;
417
418 GLES_ActivateRenderer(renderer);
419
420 /* Bail out if we're supposed to update an empty rectangle */
421 if (rect->w <= 0 || rect->h <= 0) {
422 return 0;
423 }
424
425 /* Reformat the texture data into a tightly packed array */
426 srcPitch = rect->w * SDL_BYTESPERPIXEL(texture->format);
427 src = (Uint8 *)pixels;
428 if (pitch != srcPitch) {
429 blob = (Uint8 *)SDL_malloc(srcPitch * rect->h);
430 if (!blob) {
431 return SDL_OutOfMemory();
432 }
433 src = blob;
434 for (y = 0; y < rect->h; ++y) {
435 SDL_memcpy(src, pixels, srcPitch);
436 src += srcPitch;
437 pixels = (Uint8 *)pixels + pitch;
438 }
439 src = blob;
440 }
441
442 /* Create a texture subimage with the supplied data */
443 renderdata->glGetError();
444 renderdata->glEnable(data->type);
445 renderdata->glBindTexture(data->type, data->texture);
446 renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
447 renderdata->glTexSubImage2D(data->type,
448 0,
449 rect->x,
450 rect->y,
451 rect->w,
452 rect->h,
453 data->format,
454 data->formattype,
455 src);
456 renderdata->glDisable(data->type);
457 SDL_free(blob);
458
459 renderdata->drawstate.texture = texture;
460 renderdata->drawstate.texturing = SDL_FALSE;
461
462 if (renderdata->glGetError() != GL_NO_ERROR) {
463 return SDL_SetError("Failed to update texture");
464 }
465 return 0;
466}
467
468static int
469GLES_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
470 const SDL_Rect * rect, void **pixels, int *pitch)
471{
472 GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
473
474 *pixels =
475 (void *) ((Uint8 *) data->pixels + rect->y * data->pitch +
476 rect->x * SDL_BYTESPERPIXEL(texture->format));
477 *pitch = data->pitch;
478 return 0;
479}
480
481static void
482GLES_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
483{
484 GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
486
487 /* We do whole texture updates, at least for now */
488 rect.x = 0;
489 rect.y = 0;
490 rect.w = texture->w;
491 rect.h = texture->h;
492 GLES_UpdateTexture(renderer, texture, &rect, data->pixels, data->pitch);
493}
494
495static int
496GLES_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
497{
498 GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
499 GLES_TextureData *texturedata = NULL;
500 GLenum status;
501
502 if (!data->GL_OES_framebuffer_object_supported) {
503 return SDL_SetError("Can't enable render target support in this renderer");
504 }
505
506 data->drawstate.viewport_dirty = SDL_TRUE;
507
508 if (texture == NULL) {
509 data->glBindFramebufferOES(GL_FRAMEBUFFER_OES, data->window_framebuffer);
510 return 0;
511 }
512
513 texturedata = (GLES_TextureData *) texture->driverdata;
514 data->glBindFramebufferOES(GL_FRAMEBUFFER_OES, texturedata->fbo->FBO);
515 /* TODO: check if texture pixel format allows this operation */
516 data->glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, texturedata->type, texturedata->texture, 0);
517 /* Check FBO status */
518 status = data->glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
519 if (status != GL_FRAMEBUFFER_COMPLETE_OES) {
520 return SDL_SetError("glFramebufferTexture2DOES() failed");
521 }
522 return 0;
523}
524
525
526static int
527GLES_QueueSetViewport(SDL_Renderer * renderer, SDL_RenderCommand *cmd)
528{
529 return 0; /* nothing to do in this backend. */
530}
531
532static int
533GLES_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count)
534{
535 GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, count * 2 * sizeof (GLfloat), 0, &cmd->data.draw.first);
536 int i;
537
538 if (!verts) {
539 return -1;
540 }
541
542 cmd->data.draw.count = count;
543 for (i = 0; i < count; i++) {
544 *(verts++) = 0.5f + points[i].x;
545 *(verts++) = 0.5f + points[i].y;
546 }
547
548 return 0;
549}
550
551static int
552GLES_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count)
553{
554 GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, count * 8 * sizeof (GLfloat), 0, &cmd->data.draw.first);
555 int i;
556
557 if (!verts) {
558 return -1;
559 }
560
561 cmd->data.draw.count = count;
562
563 for (i = 0; i < count; i++) {
564 const SDL_FRect *rect = &rects[i];
565 const GLfloat minx = rect->x;
566 const GLfloat maxx = rect->x + rect->w;
567 const GLfloat miny = rect->y;
568 const GLfloat maxy = rect->y + rect->h;
569 *(verts++) = minx;
570 *(verts++) = miny;
571 *(verts++) = maxx;
572 *(verts++) = miny;
573 *(verts++) = minx;
574 *(verts++) = maxy;
575 *(verts++) = maxx;
576 *(verts++) = maxy;
577 }
578
579 return 0;
580}
581
582static int
584 const SDL_Rect * srcrect, const SDL_FRect * dstrect)
585{
586 GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata;
587 GLfloat minx, miny, maxx, maxy;
588 GLfloat minu, maxu, minv, maxv;
589 GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, 16 * sizeof (GLfloat), 0, &cmd->data.draw.first);
590
591 if (!verts) {
592 return -1;
593 }
594
595 cmd->data.draw.count = 1;
596
597 minx = dstrect->x;
598 miny = dstrect->y;
599 maxx = dstrect->x + dstrect->w;
600 maxy = dstrect->y + dstrect->h;
601
602 minu = (GLfloat) srcrect->x / texture->w;
603 minu *= texturedata->texw;
604 maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w;
605 maxu *= texturedata->texw;
606 minv = (GLfloat) srcrect->y / texture->h;
607 minv *= texturedata->texh;
608 maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h;
609 maxv *= texturedata->texh;
610
611 *(verts++) = minx;
612 *(verts++) = miny;
613 *(verts++) = maxx;
614 *(verts++) = miny;
615 *(verts++) = minx;
616 *(verts++) = maxy;
617 *(verts++) = maxx;
618 *(verts++) = maxy;
619
620 *(verts++) = minu;
621 *(verts++) = minv;
622 *(verts++) = maxu;
623 *(verts++) = minv;
624 *(verts++) = minu;
625 *(verts++) = maxv;
626 *(verts++) = maxu;
627 *(verts++) = maxv;
628
629 return 0;
630}
631
632static int
633GLES_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
634 const SDL_Rect * srcquad, const SDL_FRect * dstrect,
635 const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
636{
637 GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata;
638 GLfloat minx, miny, maxx, maxy;
639 GLfloat centerx, centery;
640 GLfloat minu, maxu, minv, maxv;
641 GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, 19 * sizeof (GLfloat), 0, &cmd->data.draw.first);
642
643 if (!verts) {
644 return -1;
645 }
646
647 centerx = center->x;
648 centery = center->y;
649
650 if (flip & SDL_FLIP_HORIZONTAL) {
651 minx = dstrect->w - centerx;
652 maxx = -centerx;
653 }
654 else {
655 minx = -centerx;
656 maxx = dstrect->w - centerx;
657 }
658
659 if (flip & SDL_FLIP_VERTICAL) {
660 miny = dstrect->h - centery;
661 maxy = -centery;
662 }
663 else {
664 miny = -centery;
665 maxy = dstrect->h - centery;
666 }
667
668 minu = (GLfloat) srcquad->x / texture->w;
669 minu *= texturedata->texw;
670 maxu = (GLfloat) (srcquad->x + srcquad->w) / texture->w;
671 maxu *= texturedata->texw;
672 minv = (GLfloat) srcquad->y / texture->h;
673 minv *= texturedata->texh;
674 maxv = (GLfloat) (srcquad->y + srcquad->h) / texture->h;
675 maxv *= texturedata->texh;
676
677 cmd->data.draw.count = 1;
678
679 *(verts++) = minx;
680 *(verts++) = miny;
681 *(verts++) = maxx;
682 *(verts++) = miny;
683 *(verts++) = minx;
684 *(verts++) = maxy;
685 *(verts++) = maxx;
686 *(verts++) = maxy;
687
688 *(verts++) = minu;
689 *(verts++) = minv;
690 *(verts++) = maxu;
691 *(verts++) = minv;
692 *(verts++) = minu;
693 *(verts++) = maxv;
694 *(verts++) = maxu;
695 *(verts++) = maxv;
696
697 *(verts++) = (GLfloat) dstrect->x + centerx;
698 *(verts++) = (GLfloat) dstrect->y + centery;
699 *(verts++) = (GLfloat) angle;
700
701 return 0;
702}
703
704static void
705SetDrawState(GLES_RenderData *data, const SDL_RenderCommand *cmd)
706{
707 const SDL_BlendMode blend = cmd->data.draw.blend;
708 const Uint8 r = cmd->data.draw.r;
709 const Uint8 g = cmd->data.draw.g;
710 const Uint8 b = cmd->data.draw.b;
711 const Uint8 a = cmd->data.draw.a;
712 const Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b);
713
714 if (color != data->drawstate.color) {
715 const GLfloat fr = ((GLfloat) r) * inv255f;
716 const GLfloat fg = ((GLfloat) g) * inv255f;
717 const GLfloat fb = ((GLfloat) b) * inv255f;
718 const GLfloat fa = ((GLfloat) a) * inv255f;
719 data->glColor4f(fr, fg, fb, fa);
720 data->drawstate.color = color;
721 }
722
723 if (data->drawstate.viewport_dirty) {
724 const SDL_Rect *viewport = &data->drawstate.viewport;
725 const SDL_bool istarget = (data->drawstate.target != NULL);
726 data->glMatrixMode(GL_PROJECTION);
727 data->glLoadIdentity();
728 data->glViewport(viewport->x,
729 istarget ? viewport->y : (data->drawstate.drawableh - viewport->y - viewport->h),
730 viewport->w, viewport->h);
731 if (viewport->w && viewport->h) {
732 data->glOrthof((GLfloat) 0, (GLfloat) viewport->w,
733 (GLfloat) (istarget ? 0 : viewport->h),
734 (GLfloat) (istarget ? viewport->h : 0),
735 0.0, 1.0);
736 }
737 data->glMatrixMode(GL_MODELVIEW);
738 data->drawstate.viewport_dirty = SDL_FALSE;
739 }
740
741 if (data->drawstate.cliprect_enabled_dirty) {
742 if (data->drawstate.cliprect_enabled) {
743 data->glEnable(GL_SCISSOR_TEST);
744 } else {
745 data->glDisable(GL_SCISSOR_TEST);
746 }
747 data->drawstate.cliprect_enabled_dirty = SDL_FALSE;
748 }
749
750 if (data->drawstate.cliprect_enabled && data->drawstate.cliprect_dirty) {
751 const SDL_Rect *viewport = &data->drawstate.viewport;
752 const SDL_Rect *rect = &data->drawstate.cliprect;
753 const SDL_bool istarget = (data->drawstate.target != NULL);
754 data->glScissor(viewport->x + rect->x,
755 istarget ? viewport->y + rect->y : data->drawstate.drawableh - viewport->y - rect->y - rect->h,
756 rect->w, rect->h);
757 data->drawstate.cliprect_dirty = SDL_FALSE;
758 }
759
760 if (blend != data->drawstate.blend) {
761 if (blend == SDL_BLENDMODE_NONE) {
762 data->glDisable(GL_BLEND);
763 } else {
764 data->glEnable(GL_BLEND);
765 if (data->GL_OES_blend_func_separate_supported) {
766 data->glBlendFuncSeparateOES(GetBlendFunc(SDL_GetBlendModeSrcColorFactor(blend)),
767 GetBlendFunc(SDL_GetBlendModeDstColorFactor(blend)),
768 GetBlendFunc(SDL_GetBlendModeSrcAlphaFactor(blend)),
769 GetBlendFunc(SDL_GetBlendModeDstAlphaFactor(blend)));
770 } else {
771 data->glBlendFunc(GetBlendFunc(SDL_GetBlendModeSrcColorFactor(blend)),
772 GetBlendFunc(SDL_GetBlendModeDstColorFactor(blend)));
773 }
774 if (data->GL_OES_blend_equation_separate_supported) {
775 data->glBlendEquationSeparateOES(GetBlendEquation(SDL_GetBlendModeColorOperation(blend)),
776 GetBlendEquation(SDL_GetBlendModeAlphaOperation(blend)));
777 } else if (data->GL_OES_blend_subtract_supported) {
778 data->glBlendEquationOES(GetBlendEquation(SDL_GetBlendModeColorOperation(blend)));
779 }
780 }
781 data->drawstate.blend = blend;
782 }
783
784 if ((cmd->data.draw.texture != NULL) != data->drawstate.texturing) {
785 if (cmd->data.draw.texture == NULL) {
786 data->glDisable(GL_TEXTURE_2D);
787 data->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
788 data->drawstate.texturing = SDL_FALSE;
789 } else {
790 data->glEnable(GL_TEXTURE_2D);
791 data->glEnableClientState(GL_TEXTURE_COORD_ARRAY);
792 data->drawstate.texturing = SDL_TRUE;
793 }
794 }
795}
796
797static void
798SetCopyState(GLES_RenderData *data, const SDL_RenderCommand *cmd)
799{
801 SetDrawState(data, cmd);
802
803 if (texture != data->drawstate.texture) {
804 GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata;
805 data->glBindTexture(GL_TEXTURE_2D, texturedata->texture);
806 data->drawstate.texture = texture;
807 }
808}
809
810static int
811GLES_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
812{
813 GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
814 size_t i;
815
816 if (GLES_ActivateRenderer(renderer) < 0) {
817 return -1;
818 }
819
820 data->drawstate.target = renderer->target;
821
822 if (!renderer->target) {
823 SDL_GL_GetDrawableSize(renderer->window, &data->drawstate.drawablew, &data->drawstate.drawableh);
824 }
825
826 while (cmd) {
827 switch (cmd->command) {
829 break; /* not used in this render backend. */
830 }
831
833 SDL_Rect *viewport = &data->drawstate.viewport;
834 if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)) != 0) {
835 SDL_memcpy(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect));
836 data->drawstate.viewport_dirty = SDL_TRUE;
837 }
838 break;
839 }
840
842 const SDL_Rect *rect = &cmd->data.cliprect.rect;
843 if (data->drawstate.cliprect_enabled != cmd->data.cliprect.enabled) {
844 data->drawstate.cliprect_enabled = cmd->data.cliprect.enabled;
845 data->drawstate.cliprect_enabled_dirty = SDL_TRUE;
846 }
847 if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)) != 0) {
848 SDL_memcpy(&data->drawstate.cliprect, rect, sizeof (SDL_Rect));
849 data->drawstate.cliprect_dirty = SDL_TRUE;
850 }
851 break;
852 }
853
854 case SDL_RENDERCMD_CLEAR: {
855 const Uint8 r = cmd->data.color.r;
856 const Uint8 g = cmd->data.color.g;
857 const Uint8 b = cmd->data.color.b;
858 const Uint8 a = cmd->data.color.a;
859 const Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b);
860 if (color != data->drawstate.clear_color) {
861 const GLfloat fr = ((GLfloat) r) * inv255f;
862 const GLfloat fg = ((GLfloat) g) * inv255f;
863 const GLfloat fb = ((GLfloat) b) * inv255f;
864 const GLfloat fa = ((GLfloat) a) * inv255f;
865 data->glClearColor(fr, fg, fb, fa);
866 data->drawstate.clear_color = color;
867 }
868
869 if (data->drawstate.cliprect_enabled) {
870 data->glDisable(GL_SCISSOR_TEST);
871 data->drawstate.cliprect_enabled_dirty = SDL_TRUE;
872 }
873
874 data->glClear(GL_COLOR_BUFFER_BIT);
875
876 break;
877 }
878
880 const size_t count = cmd->data.draw.count;
881 const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
882 SetDrawState(data, cmd);
883 data->glVertexPointer(2, GL_FLOAT, 0, verts);
884 data->glDrawArrays(GL_POINTS, 0, (GLsizei) count);
885 break;
886 }
887
889 const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
890 const size_t count = cmd->data.draw.count;
891 SetDrawState(data, cmd);
892 data->glVertexPointer(2, GL_FLOAT, 0, verts);
893 if (count > 2 && (verts[0] == verts[(count-1)*2]) && (verts[1] == verts[(count*2)-1])) {
894 /* GL_LINE_LOOP takes care of the final segment */
895 data->glDrawArrays(GL_LINE_LOOP, 0, (GLsizei) (count - 1));
896 } else {
897 data->glDrawArrays(GL_LINE_STRIP, 0, (GLsizei) count);
898 /* We need to close the endpoint of the line */
899 data->glDrawArrays(GL_POINTS, (GLsizei) (count - 1), 1);
900 }
901 break;
902 }
903
905 const size_t count = cmd->data.draw.count;
906 const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
907 GLsizei offset = 0;
908 SetDrawState(data, cmd);
909 data->glVertexPointer(2, GL_FLOAT, 0, verts);
910 for (i = 0; i < count; ++i, offset += 4) {
911 data->glDrawArrays(GL_TRIANGLE_STRIP, offset, 4);
912 }
913 break;
914 }
915
916 case SDL_RENDERCMD_COPY: {
917 const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
918 SetCopyState(data, cmd);
919 data->glVertexPointer(2, GL_FLOAT, 0, verts);
920 data->glTexCoordPointer(2, GL_FLOAT, 0, verts + 8);
921 data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
922 break;
923 }
924
926 const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
927 const GLfloat translatex = verts[16];
928 const GLfloat translatey = verts[17];
929 const GLfloat angle = verts[18];
930 SetCopyState(data, cmd);
931 data->glVertexPointer(2, GL_FLOAT, 0, verts);
932 data->glTexCoordPointer(2, GL_FLOAT, 0, verts + 8);
933
934 /* Translate to flip, rotate, translate to position */
935 data->glPushMatrix();
936 data->glTranslatef(translatex, translatey, 0.0f);
937 data->glRotatef(angle, 0.0, 0.0, 1.0);
938 data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
939 data->glPopMatrix();
940 break;
941 }
942
944 break;
945 }
946
947 cmd = cmd->next;
948 }
949
950 return 0;
951}
952
953static int
954GLES_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
955 Uint32 pixel_format, void * pixels, int pitch)
956{
957 GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
959 void *temp_pixels;
960 int temp_pitch;
961 Uint8 *src, *dst, *tmp;
962 int w, h, length, rows;
963 int status;
964
965 GLES_ActivateRenderer(renderer);
966
967 temp_pitch = rect->w * SDL_BYTESPERPIXEL(temp_format);
968 temp_pixels = SDL_malloc(rect->h * temp_pitch);
969 if (!temp_pixels) {
970 return SDL_OutOfMemory();
971 }
972
974
975 data->glPixelStorei(GL_PACK_ALIGNMENT, 1);
976
977 data->glReadPixels(rect->x, renderer->target ? rect->y : (h-rect->y)-rect->h,
978 rect->w, rect->h, GL_RGBA, GL_UNSIGNED_BYTE, temp_pixels);
979
980 /* Flip the rows to be top-down if necessary */
981 if (!renderer->target) {
982 SDL_bool isstack;
983 length = rect->w * SDL_BYTESPERPIXEL(temp_format);
984 src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch;
985 dst = (Uint8*)temp_pixels;
986 tmp = SDL_small_alloc(Uint8, length, &isstack);
987 rows = rect->h / 2;
988 while (rows--) {
989 SDL_memcpy(tmp, dst, length);
991 SDL_memcpy(src, tmp, length);
992 dst += temp_pitch;
993 src -= temp_pitch;
994 }
995 SDL_small_free(tmp, isstack);
996 }
997
998 status = SDL_ConvertPixels(rect->w, rect->h,
999 temp_format, temp_pixels, temp_pitch,
1000 pixel_format, pixels, pitch);
1001 SDL_free(temp_pixels);
1002
1003 return status;
1004}
1005
1006static void
1007GLES_RenderPresent(SDL_Renderer * renderer)
1008{
1009 GLES_ActivateRenderer(renderer);
1010
1012}
1013
1014static void
1015GLES_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
1016{
1017 GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata;
1018
1019 GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
1020
1021 GLES_ActivateRenderer(renderer);
1022
1023 if (renderdata->drawstate.texture == texture) {
1024 renderdata->drawstate.texture = NULL;
1025 }
1026 if (renderdata->drawstate.target == texture) {
1027 renderdata->drawstate.target = NULL;
1028 }
1029
1030 if (!data) {
1031 return;
1032 }
1033 if (data->texture) {
1034 renderdata->glDeleteTextures(1, &data->texture);
1035 }
1036 SDL_free(data->pixels);
1037 SDL_free(data);
1038 texture->driverdata = NULL;
1039}
1040
1041static void
1042GLES_DestroyRenderer(SDL_Renderer * renderer)
1043{
1044 GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
1045
1046 if (data) {
1047 if (data->context) {
1048 while (data->framebuffers) {
1049 GLES_FBOList *nextnode = data->framebuffers->next;
1050 data->glDeleteFramebuffersOES(1, &data->framebuffers->FBO);
1051 SDL_free(data->framebuffers);
1052 data->framebuffers = nextnode;
1053 }
1054 SDL_GL_DeleteContext(data->context);
1055 }
1056 SDL_free(data);
1057 }
1059}
1060
1061static int GLES_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, float *texh)
1062{
1063 GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
1064 GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata;
1065 GLES_ActivateRenderer(renderer);
1066
1067 data->glEnable(GL_TEXTURE_2D);
1068 data->glBindTexture(texturedata->type, texturedata->texture);
1069
1070 data->drawstate.texture = texture;
1071 data->drawstate.texturing = SDL_TRUE;
1072
1073 if (texw) {
1074 *texw = (float)texturedata->texw;
1075 }
1076 if (texh) {
1077 *texh = (float)texturedata->texh;
1078 }
1079
1080 return 0;
1081}
1082
1083static int GLES_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture)
1084{
1085 GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
1086 GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata;
1087 GLES_ActivateRenderer(renderer);
1088 data->glDisable(texturedata->type);
1089
1090 data->drawstate.texture = NULL;
1091 data->drawstate.texturing = SDL_FALSE;
1092
1093 return 0;
1094}
1095
1096static SDL_Renderer *
1097GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
1098{
1100 GLES_RenderData *data;
1101 GLint value;
1102 Uint32 window_flags;
1103 int profile_mask = 0, major = 0, minor = 0;
1104 SDL_bool changed_window = SDL_FALSE;
1105
1109
1110 window_flags = SDL_GetWindowFlags(window);
1111 if (!(window_flags & SDL_WINDOW_OPENGL) ||
1112 profile_mask != SDL_GL_CONTEXT_PROFILE_ES || major != RENDERER_CONTEXT_MAJOR || minor != RENDERER_CONTEXT_MINOR) {
1113
1114 changed_window = SDL_TRUE;
1116 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, RENDERER_CONTEXT_MAJOR);
1117 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, RENDERER_CONTEXT_MINOR);
1118
1119 if (SDL_RecreateWindow(window, window_flags | SDL_WINDOW_OPENGL) < 0) {
1120 goto error;
1121 }
1122 }
1123
1124 renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
1125 if (!renderer) {
1127 goto error;
1128 }
1129
1130 data = (GLES_RenderData *) SDL_calloc(1, sizeof(*data));
1131 if (!data) {
1132 GLES_DestroyRenderer(renderer);
1134 goto error;
1135 }
1136
1137 renderer->WindowEvent = GLES_WindowEvent;
1138 renderer->GetOutputSize = GLES_GetOutputSize;
1139 renderer->SupportsBlendMode = GLES_SupportsBlendMode;
1140 renderer->CreateTexture = GLES_CreateTexture;
1141 renderer->UpdateTexture = GLES_UpdateTexture;
1142 renderer->LockTexture = GLES_LockTexture;
1143 renderer->UnlockTexture = GLES_UnlockTexture;
1144 renderer->SetRenderTarget = GLES_SetRenderTarget;
1145 renderer->QueueSetViewport = GLES_QueueSetViewport;
1146 renderer->QueueSetDrawColor = GLES_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */
1147 renderer->QueueDrawPoints = GLES_QueueDrawPoints;
1148 renderer->QueueDrawLines = GLES_QueueDrawPoints; /* lines and points queue vertices the same way. */
1149 renderer->QueueFillRects = GLES_QueueFillRects;
1150 renderer->QueueCopy = GLES_QueueCopy;
1151 renderer->QueueCopyEx = GLES_QueueCopyEx;
1152 renderer->RunCommandQueue = GLES_RunCommandQueue;
1153 renderer->RenderReadPixels = GLES_RenderReadPixels;
1154 renderer->RenderPresent = GLES_RenderPresent;
1155 renderer->DestroyTexture = GLES_DestroyTexture;
1156 renderer->DestroyRenderer = GLES_DestroyRenderer;
1157 renderer->GL_BindTexture = GLES_BindTexture;
1158 renderer->GL_UnbindTexture = GLES_UnbindTexture;
1163
1164 data->context = SDL_GL_CreateContext(window);
1165 if (!data->context) {
1166 GLES_DestroyRenderer(renderer);
1167 goto error;
1168 }
1169 if (SDL_GL_MakeCurrent(window, data->context) < 0) {
1170 GLES_DestroyRenderer(renderer);
1171 goto error;
1172 }
1173
1174 if (GLES_LoadFunctions(data) < 0) {
1175 GLES_DestroyRenderer(renderer);
1176 goto error;
1177 }
1178
1181 } else {
1183 }
1184 if (SDL_GL_GetSwapInterval() > 0) {
1186 }
1187
1188 value = 0;
1189 data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
1191 value = 0;
1192 data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
1194
1195 /* Android does not report GL_OES_framebuffer_object but the functionality seems to be there anyway */
1196 if (SDL_GL_ExtensionSupported("GL_OES_framebuffer_object") || data->glGenFramebuffersOES) {
1197 data->GL_OES_framebuffer_object_supported = SDL_TRUE;
1199
1200 value = 0;
1201 data->glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &value);
1202 data->window_framebuffer = (GLuint)value;
1203 }
1204 data->framebuffers = NULL;
1205
1206 if (SDL_GL_ExtensionSupported("GL_OES_blend_func_separate")) {
1207 data->GL_OES_blend_func_separate_supported = SDL_TRUE;
1208 }
1209 if (SDL_GL_ExtensionSupported("GL_OES_blend_equation_separate")) {
1210 data->GL_OES_blend_equation_separate_supported = SDL_TRUE;
1211 }
1212 if (SDL_GL_ExtensionSupported("GL_OES_blend_subtract")) {
1213 data->GL_OES_blend_subtract_supported = SDL_TRUE;
1214 }
1215
1216 /* Set up parameters for rendering */
1217 data->glDisable(GL_DEPTH_TEST);
1218 data->glDisable(GL_CULL_FACE);
1219
1220 data->glMatrixMode(GL_MODELVIEW);
1221 data->glLoadIdentity();
1222
1223 data->glEnableClientState(GL_VERTEX_ARRAY);
1224 data->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1225
1226 data->glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
1227
1228 data->drawstate.blend = SDL_BLENDMODE_INVALID;
1229 data->drawstate.color = 0xFFFFFFFF;
1230 data->drawstate.clear_color = 0xFFFFFFFF;
1231
1232 return renderer;
1233
1234error:
1235 if (changed_window) {
1236 /* Uh oh, better try to put it back... */
1240 SDL_RecreateWindow(window, window_flags);
1241 }
1242 return NULL;
1243}
1244
1246 GLES_CreateRenderer,
1247 {
1248 "opengles",
1250 1,
1252 0,
1253 0
1254 }
1255};
1256
1257#endif /* SDL_VIDEO_RENDER_OGL_ES && !SDL_RENDER_DISABLED */
1258
1259/* vi: set ts=4 sw=4 expandtab: */
SDL_BlendOperation
The blend operation used when combining source and destination pixel components.
Definition: SDL_blendmode.h:63
@ SDL_BLENDOPERATION_REV_SUBTRACT
Definition: SDL_blendmode.h:66
@ SDL_BLENDOPERATION_ADD
Definition: SDL_blendmode.h:64
@ SDL_BLENDOPERATION_SUBTRACT
Definition: SDL_blendmode.h:65
SDL_BlendFactor
The normalized factor used to multiply pixel components.
Definition: SDL_blendmode.h:76
@ SDL_BLENDFACTOR_ONE_MINUS_SRC_COLOR
Definition: SDL_blendmode.h:80
@ SDL_BLENDFACTOR_ZERO
Definition: SDL_blendmode.h:77
@ SDL_BLENDFACTOR_SRC_COLOR
Definition: SDL_blendmode.h:79
@ SDL_BLENDFACTOR_SRC_ALPHA
Definition: SDL_blendmode.h:81
@ SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR
Definition: SDL_blendmode.h:84
@ SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA
Definition: SDL_blendmode.h:86
@ SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA
Definition: SDL_blendmode.h:82
@ SDL_BLENDFACTOR_DST_ALPHA
Definition: SDL_blendmode.h:85
@ SDL_BLENDFACTOR_DST_COLOR
Definition: SDL_blendmode.h:83
@ SDL_BLENDFACTOR_ONE
Definition: SDL_blendmode.h:78
SDL_BlendMode
The blend mode used in SDL_RenderCopy() and drawing operations.
Definition: SDL_blendmode.h:41
@ SDL_BLENDMODE_NONE
Definition: SDL_blendmode.h:42
@ SDL_BLENDMODE_INVALID
Definition: SDL_blendmode.h:53
#define SDL_SetError
#define SDL_GL_SwapWindow
#define SDL_GetWindowFlags
#define SDL_GL_GetAttribute
#define SDL_GL_SetSwapInterval
#define SDL_GL_MakeCurrent
#define SDL_GetRendererOutputSize
#define SDL_malloc
#define SDL_GL_SetAttribute
#define SDL_free
#define SDL_memcmp
#define SDL_GL_GetSwapInterval
#define SDL_GL_DeleteContext
#define SDL_memcpy
#define SDL_GL_CreateContext
#define SDL_GL_ExtensionSupported
#define SDL_GL_GetDrawableSize
#define SDL_calloc
#define SDL_ConvertPixels
#define SDL_GL_GetCurrentContext
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
#define SDL_small_alloc(type, count, pisstack)
Definition: SDL_internal.h:39
#define SDL_small_free(ptr, isstack)
Definition: SDL_internal.h:40
#define GL_TEXTURE_COORD_ARRAY
Definition: SDL_opengl.h:232
#define GL_INVALID_VALUE
Definition: SDL_opengl.h:721
#define GL_MAX_TEXTURE_SIZE
Definition: SDL_opengl.h:536
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
#define GL_TEXTURE_MIN_FILTER
Definition: SDL_opengl.h:675
#define GL_TEXTURE_WRAP_S
Definition: SDL_opengl.h:672
float GLfloat
Definition: SDL_opengl.h:187
#define GL_ONE_MINUS_DST_ALPHA
Definition: SDL_opengl.h:407
#define GL_PACK_ALIGNMENT
Definition: SDL_opengl.h:652
#define GL_ONE_MINUS_DST_COLOR
Definition: SDL_opengl.h:409
#define GL_DEPTH_TEST
Definition: SDL_opengl.h:327
#define GL_LINEAR
Definition: SDL_opengl.h:447
#define GL_LINE_STRIP
Definition: SDL_opengl.h:219
#define GL_SRC_ALPHA
Definition: SDL_opengl.h:404
#define GL_INVALID_OPERATION
Definition: SDL_opengl.h:722
unsigned int GLenum
Definition: SDL_opengl.h:176
GLuint GLuint GLsizei count
Definition: SDL_opengl.h:1571
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: SDL_opengl.h:1572
#define GL_STACK_OVERFLOW
Definition: SDL_opengl.h:723
unsigned int GLuint
Definition: SDL_opengl.h:185
#define GL_SRC_COLOR
Definition: SDL_opengl.h:402
#define GL_FLOAT
Definition: SDL_opengl.h:209
#define GL_ZERO
Definition: SDL_opengl.h:400
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
#define GL_VERTEX_ARRAY
Definition: SDL_opengl.h:228
#define GL_NEAREST
Definition: SDL_opengl.h:704
#define GL_UNSIGNED_BYTE
Definition: SDL_opengl.h:204
#define GL_PROJECTION
Definition: SDL_opengl.h:272
#define GL_NO_ERROR
Definition: SDL_opengl.h:719
#define GL_MODELVIEW
Definition: SDL_opengl.h:271
#define GL_POINTS
Definition: SDL_opengl.h:216
#define GL_CULL_FACE
Definition: SDL_opengl.h:302
#define GL_UNPACK_ALIGNMENT
Definition: SDL_opengl.h:658
int GLsizei
Definition: SDL_opengl.h:186
#define GL_COLOR_BUFFER_BIT
Definition: SDL_opengl.h:742
GLint GLint GLsizei width
Definition: SDL_opengl.h:1572
#define GL_RGBA
Definition: SDL_opengl.h:529
#define GL_BLEND
Definition: SDL_opengl.h:397
#define GL_ONE_MINUS_SRC_ALPHA
Definition: SDL_opengl.h:405
#define GL_ONE
Definition: SDL_opengl.h:401
#define GL_DST_ALPHA
Definition: SDL_opengl.h:406
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2079
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
#define GL_SCISSOR_TEST
Definition: SDL_opengl.h:615
#define GL_TEXTURE_WRAP_T
Definition: SDL_opengl.h:673
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1572
#define GL_TEXTURE_MAG_FILTER
Definition: SDL_opengl.h:674
#define GL_LINE_LOOP
Definition: SDL_opengl.h:218
#define GL_DST_COLOR
Definition: SDL_opengl.h:408
int GLint
Definition: SDL_opengl.h:182
#define GL_OUT_OF_MEMORY
Definition: SDL_opengl.h:725
#define GL_TRIANGLE_STRIP
Definition: SDL_opengl.h:221
#define GL_TEXTURE_2D
Definition: SDL_opengl.h:671
GLuint GLuint GLsizei GLenum type
Definition: SDL_opengl.h:1571
#define GL_CLAMP_TO_EDGE
Definition: SDL_opengl.h:1507
#define GL_INVALID_ENUM
Definition: SDL_opengl.h:720
#define GL_STACK_UNDERFLOW
Definition: SDL_opengl.h:724
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1572
#define GL_ONE_MINUS_SRC_COLOR
Definition: SDL_opengl.h:403
GLboolean GLboolean GLboolean b
struct _cl_event * event
GLfixed GLfixed GLint GLint GLfixed points
GLenum src
GLuint64EXT * result
GLuint color
GLintptr offset
GLenum internalFormat
GLboolean GLboolean GLboolean GLboolean a
GLenum GLenum dst
const GLuint * framebuffers
GLdouble GLdouble z
GLboolean GLboolean g
GLfloat angle
GLbitfield flags
GLenum GLenum GLuint texture
GLuint GLsizei GLsizei * length
GLsizei const GLfloat * value
GLenum GLenum GLenum input
GLenum target
GLfloat GLfloat GLfloat GLfloat h
GLubyte GLubyte GLubyte GLubyte w
#define GL_APIENTRY
#define SDL_BYTESPERPIXEL(X)
Definition: SDL_pixels.h:128
@ SDL_PIXELFORMAT_ABGR8888
Definition: SDL_pixels.h:254
SDL_BlendFactor SDL_GetBlendModeDstColorFactor(SDL_BlendMode blendMode)
Definition: SDL_render.c:3349
SDL_BlendFactor SDL_GetBlendModeSrcColorFactor(SDL_BlendMode blendMode)
Definition: SDL_render.c:3342
SDL_BlendFactor SDL_GetBlendModeDstAlphaFactor(SDL_BlendMode blendMode)
Definition: SDL_render.c:3370
SDL_BlendFactor SDL_GetBlendModeSrcAlphaFactor(SDL_BlendMode blendMode)
Definition: SDL_render.c:3363
SDL_BlendOperation SDL_GetBlendModeAlphaOperation(SDL_BlendMode blendMode)
Definition: SDL_render.c:3377
SDL_BlendOperation SDL_GetBlendModeColorOperation(SDL_BlendMode blendMode)
Definition: SDL_render.c:3356
void * SDL_AllocateRenderVertices(SDL_Renderer *renderer, const size_t numbytes, const size_t alignment, size_t *offset)
Definition: SDL_render.c:284
@ SDL_RENDERER_ACCELERATED
Definition: SDL_render.h:67
@ SDL_RENDERER_PRESENTVSYNC
Definition: SDL_render.h:69
@ SDL_RENDERER_TARGETTEXTURE
Definition: SDL_render.h:71
SDL_RendererFlip
Flip constants for SDL_RenderCopyEx.
Definition: SDL_render.h:112
@ SDL_FLIP_VERTICAL
Definition: SDL_render.h:115
@ SDL_FLIP_HORIZONTAL
Definition: SDL_render.h:114
@ SDL_TEXTUREACCESS_STREAMING
Definition: SDL_render.h:94
@ SDL_TEXTUREACCESS_TARGET
Definition: SDL_render.h:95
static void SetDrawState(SDL_Surface *surface, SW_DrawStateCache *drawstate)
SDL_bool
Definition: SDL_stdinc.h:162
@ SDL_TRUE
Definition: SDL_stdinc.h:164
@ SDL_FALSE
Definition: SDL_stdinc.h:163
uint32_t Uint32
Definition: SDL_stdinc.h:203
uint8_t Uint8
Definition: SDL_stdinc.h:179
@ SDL_ScaleModeNearest
Definition: SDL_sysrender.h:37
SDL_RenderDriver GLES_RenderDriver
@ SDL_RENDERCMD_SETCLIPRECT
Definition: SDL_sysrender.h:76
@ SDL_RENDERCMD_DRAW_LINES
Definition: SDL_sysrender.h:80
@ SDL_RENDERCMD_SETVIEWPORT
Definition: SDL_sysrender.h:75
@ SDL_RENDERCMD_DRAW_POINTS
Definition: SDL_sysrender.h:79
@ SDL_RENDERCMD_NO_OP
Definition: SDL_sysrender.h:74
@ SDL_RENDERCMD_FILL_RECTS
Definition: SDL_sysrender.h:81
@ SDL_RENDERCMD_COPY
Definition: SDL_sysrender.h:82
@ SDL_RENDERCMD_CLEAR
Definition: SDL_sysrender.h:78
@ SDL_RENDERCMD_SETDRAWCOLOR
Definition: SDL_sysrender.h:77
@ SDL_RENDERCMD_COPY_EX
Definition: SDL_sysrender.h:83
int SDL_RecreateWindow(SDL_Window *window, Uint32 flags)
Definition: SDL_video.c:1614
@ SDL_GL_CONTEXT_MAJOR_VERSION
Definition: SDL_video.h:217
@ SDL_GL_CONTEXT_MINOR_VERSION
Definition: SDL_video.h:218
@ SDL_GL_CONTEXT_PROFILE_MASK
Definition: SDL_video.h:221
@ SDL_WINDOW_OPENGL
Definition: SDL_video.h:101
void * SDL_GLContext
An opaque handle to an OpenGL context.
Definition: SDL_video.h:193
@ SDL_WINDOWEVENT_MINIMIZED
Definition: SDL_video.h:159
@ SDL_GL_CONTEXT_PROFILE_ES
Definition: SDL_video.h:233
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
#define NULL
Definition: begin_code.h:167
#define SDL_INLINE
Definition: begin_code.h:134
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
EGLSurface EGLint * rects
Definition: eglext.h:282
The structure that defines a point (floating point)
Definition: SDL_rect.h:61
float x
Definition: SDL_rect.h:62
float y
Definition: SDL_rect.h:63
A rectangle, with the origin at the upper left (floating point).
Definition: SDL_rect.h:88
float h
Definition: SDL_rect.h:92
float x
Definition: SDL_rect.h:89
float w
Definition: SDL_rect.h:91
float y
Definition: SDL_rect.h:90
A rectangle, with the origin at the upper left (integer).
Definition: SDL_rect.h:78
int h
Definition: SDL_rect.h:80
int w
Definition: SDL_rect.h:80
int y
Definition: SDL_rect.h:79
int x
Definition: SDL_rect.h:79
union SDL_RenderCommand::@30 data
struct SDL_RenderCommand * next
struct SDL_RenderCommand::@30::@33 draw
struct SDL_RenderCommand::@30::@31 viewport
SDL_BlendMode blend
SDL_RenderCommandType command
Definition: SDL_sysrender.h:88
struct SDL_RenderCommand::@30::@32 cliprect
SDL_Texture * texture
struct SDL_RenderCommand::@30::@34 color
SDL_RendererInfo info
int(* QueueCopy)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect)
int(* LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
SDL_Window * window
int(* QueueDrawLines)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
void(* UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
int(* SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture)
void(* DestroyRenderer)(SDL_Renderer *renderer)
void(* DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* GL_BindTexture)(SDL_Renderer *renderer, SDL_Texture *texture, float *texw, float *texh)
int(* GetOutputSize)(SDL_Renderer *renderer, int *w, int *h)
SDL_bool(* SupportsBlendMode)(SDL_Renderer *renderer, SDL_BlendMode blendMode)
void(* RenderPresent)(SDL_Renderer *renderer)
int(* RenderReadPixels)(SDL_Renderer *renderer, const SDL_Rect *rect, Uint32 format, void *pixels, int pitch)
int(* QueueDrawPoints)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
int(* QueueFillRects)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FRect *rects, int count)
void(* WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event)
int(* RunCommandQueue)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
int(* QueueCopyEx)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, const SDL_Rect *srcquad, const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
int(* CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* QueueSetViewport)(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
SDL_RendererInfo info
void * driverdata
int(* GL_UnbindTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
SDL_Texture * target
int(* QueueSetDrawColor)(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
int max_texture_height
Definition: SDL_render.h:85
Uint32 format
Definition: SDL_sysrender.h:46
Window state change event data (event.window.*)
Definition: SDL_events.h:196
The type used to identify a window.
Definition: SDL_sysvideo.h:74
static SDL_Renderer * renderer
static SDL_BlendMode blendMode
Definition: testdraw2.c:34
SDL_Rect rect
Definition: testrelative.c:27
SDL_Rect viewport
Definition: testviewport.c:28
static screen_context_t context
Definition: video.c:25