23 #if SDL_VIDEO_RENDER_OGL_ES2 && !SDL_RENDER_DISABLED
27 #include "../SDL_sysrender.h"
58 typedef struct GLES2_FBOList GLES2_FBOList;
67 typedef struct GLES2_TextureData
78 typedef struct GLES2_ShaderCacheEntry
81 GLES2_ShaderType
type;
82 const GLES2_ShaderInstance *instance;
84 struct GLES2_ShaderCacheEntry *prev;
85 struct GLES2_ShaderCacheEntry *next;
86 } GLES2_ShaderCacheEntry;
88 typedef struct GLES2_ShaderCache
91 GLES2_ShaderCacheEntry *
head;
94 typedef struct GLES2_ProgramCacheEntry
98 GLES2_ShaderCacheEntry *vertex_shader;
99 GLES2_ShaderCacheEntry *fragment_shader;
100 GLuint uniform_locations[16];
101 struct GLES2_ProgramCacheEntry *prev;
102 struct GLES2_ProgramCacheEntry *next;
103 } GLES2_ProgramCacheEntry;
105 typedef struct GLES2_ProgramCache
108 GLES2_ProgramCacheEntry *
head;
109 GLES2_ProgramCacheEntry *
tail;
110 } GLES2_ProgramCache;
114 GLES2_ATTRIBUTE_POSITION = 0,
115 GLES2_ATTRIBUTE_TEXCOORD = 1,
116 GLES2_ATTRIBUTE_ANGLE = 2,
117 GLES2_ATTRIBUTE_CENTER = 3,
122 GLES2_UNIFORM_PROJECTION,
123 GLES2_UNIFORM_TEXTURE,
124 GLES2_UNIFORM_MODULATION,
126 GLES2_UNIFORM_COLORTABLE
131 GLES2_IMAGESOURCE_SOLID,
132 GLES2_IMAGESOURCE_TEXTURE_ABGR,
133 GLES2_IMAGESOURCE_TEXTURE_ARGB,
134 GLES2_IMAGESOURCE_TEXTURE_RGB,
135 GLES2_IMAGESOURCE_TEXTURE_BGR
138 typedef struct GLES2_DriverContext
146 #define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
150 GLuint window_framebuffer;
152 int shader_format_count;
154 GLES2_ShaderCache shader_cache;
155 GLES2_ProgramCache program_cache;
156 GLES2_ProgramCacheEntry *current_program;
157 } GLES2_DriverContext;
159 #define GLES2_MAX_CACHED_PROGRAMS 8
165 static int GLES2_ActivateRenderer(
SDL_Renderer *renderer);
168 static int GLES2_UpdateViewport(
SDL_Renderer * renderer);
169 static void GLES2_DestroyRenderer(
SDL_Renderer *renderer);
170 static int GLES2_SetOrthographicProjection(
SDL_Renderer *renderer);
175 static int GLES2_LoadFunctions(GLES2_DriverContext *
data)
177 #if SDL_VIDEO_DRIVER_UIKIT
178 #define __SDL_NOGETPROCADDR__
179 #elif SDL_VIDEO_DRIVER_ANDROID
180 #define __SDL_NOGETPROCADDR__
181 #elif SDL_VIDEO_DRIVER_PANDORA
182 #define __SDL_NOGETPROCADDR__
185 #if defined __SDL_NOGETPROCADDR__
186 #define SDL_PROC(ret,func,params) data->func=func;
188 #define SDL_PROC(ret,func,params) \
190 data->func = SDL_GL_GetProcAddress(#func); \
191 if ( ! data->func ) { \
192 return SDL_SetError("Couldn't load GLES2 function %s: %s\n", #func, SDL_GetError()); \
205 GLES2_FBOList *
result = data->framebuffers;
206 while ((result) && ((result->w != w) || (result->h != h)) )
208 result = result->next;
215 data->glGenFramebuffers(1, &result->FBO);
216 result->next = data->framebuffers;
217 data->framebuffers =
result;
225 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->
driverdata;
227 if (SDL_CurrentContext != rdata->context) {
229 rdata->current_program =
NULL;
234 SDL_CurrentContext = rdata->context;
236 GLES2_UpdateViewport(renderer);
244 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->
driverdata;
250 SDL_CurrentContext =
NULL;
262 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->
driverdata;
264 if (SDL_CurrentContext != rdata->context) {
272 if (rdata->current_program) {
273 GLES2_SetOrthographicProjection(renderer);
281 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->
driverdata;
284 if (SDL_CurrentContext != rdata->context) {
291 rdata->glScissor(rect->x, renderer->
viewport.
h - rect->y - rect->h, rect->w, rect->h);
301 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->
driverdata;
305 GLES2_ActivateRenderer(renderer);
308 GLES2_ShaderCacheEntry *entry;
309 GLES2_ShaderCacheEntry *next;
310 entry = rdata->shader_cache.head;
313 rdata->glDeleteShader(entry->id);
320 GLES2_ProgramCacheEntry *entry;
321 GLES2_ProgramCacheEntry *next;
322 entry = rdata->program_cache.head;
324 rdata->glDeleteProgram(entry->id);
330 if (rdata->context) {
331 while (rdata->framebuffers) {
332 GLES2_FBOList *nextnode = rdata->framebuffers->next;
333 rdata->glDeleteFramebuffers(1, &rdata->framebuffers->FBO);
335 rdata->framebuffers = nextnode;
352 void **
pixels,
int *pitch);
355 const void *
pixels,
int pitch);
363 if (!hint || *hint ==
'0' ||
SDL_strcasecmp(hint,
"nearest") == 0) {
373 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->
driverdata;
374 GLES2_TextureData *tdata;
379 GLES2_ActivateRenderer(renderer);
396 tdata = (GLES2_TextureData *)
SDL_calloc(1,
sizeof(GLES2_TextureData));
402 tdata->pixel_format =
format;
403 tdata->pixel_type =
type;
409 tdata->pixel_data =
SDL_calloc(1, tdata->pitch * texture->
h);
410 if (!tdata->pixel_data) {
418 rdata->glGenTextures(1, &tdata->texture);
421 return SDL_SetError(
"Texture creation failed in glGenTextures()");
424 rdata->glBindTexture(tdata->texture_type, tdata->texture);
431 rdata->glDeleteTextures(1, &tdata->texture);
438 tdata->fbo = GLES2_GetFBO(renderer->
driverdata, texture->
w, texture->
h);
449 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->
driverdata;
450 GLES2_TextureData *tdata = (GLES2_TextureData *)texture->
driverdata;
452 GLES2_ActivateRenderer(renderer);
457 rdata->glDeleteTextures(1, &tdata->texture);
466 void **
pixels,
int *pitch)
468 GLES2_TextureData *tdata = (GLES2_TextureData *)texture->
driverdata;
471 *pixels = (
Uint8 *)tdata->pixel_data +
472 (tdata->pitch * rect->
y) +
474 *pitch = tdata->pitch;
482 GLES2_TextureData *tdata = (GLES2_TextureData *)texture->
driverdata;
490 GLES2_UpdateTexture(renderer, texture, &rect, tdata->pixel_data, tdata->pitch);
495 const void *pixels,
int pitch)
497 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->
driverdata;
498 GLES2_TextureData *tdata = (GLES2_TextureData *)texture->
driverdata;
504 GLES2_ActivateRenderer(renderer);
507 if (rect->
w <= 0 || rect->
h <= 0)
512 src = (
Uint8 *)pixels;
513 if (pitch != srcPitch) {
519 for (y = 0; y < rect->
h; ++
y)
523 pixels = (
Uint8 *)pixels + pitch;
531 rdata->glBindTexture(tdata->texture_type, tdata->texture);
533 rdata->glTexSubImage2D(tdata->texture_type,
553 GLES2_DriverContext *data = (GLES2_DriverContext *) renderer->
driverdata;
554 GLES2_TextureData *texturedata =
NULL;
558 data->glBindFramebuffer(
GL_FRAMEBUFFER, data->window_framebuffer);
560 texturedata = (GLES2_TextureData *) texture->
driverdata;
577 static GLES2_ShaderCacheEntry *GLES2_CacheShader(
SDL_Renderer *renderer, GLES2_ShaderType
type,
579 static void GLES2_EvictShader(
SDL_Renderer *renderer, GLES2_ShaderCacheEntry *entry);
580 static GLES2_ProgramCacheEntry *GLES2_CacheProgram(
SDL_Renderer *renderer,
581 GLES2_ShaderCacheEntry *vertex,
582 GLES2_ShaderCacheEntry *fragment,
587 static GLES2_ProgramCacheEntry *
588 GLES2_CacheProgram(
SDL_Renderer *renderer, GLES2_ShaderCacheEntry *vertex,
591 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->
driverdata;
592 GLES2_ProgramCacheEntry *entry;
593 GLES2_ShaderCacheEntry *shaderEntry;
594 GLint linkSuccessful;
597 entry = rdata->program_cache.head;
600 if (entry->vertex_shader == vertex && entry->fragment_shader == fragment)
606 if (rdata->program_cache.head != entry)
609 entry->next->prev = entry->prev;
611 entry->prev->next = entry->next;
613 entry->next = rdata->program_cache.head;
614 rdata->program_cache.head->prev = entry;
615 rdata->program_cache.head = entry;
621 entry = (GLES2_ProgramCacheEntry *)
SDL_calloc(1,
sizeof(GLES2_ProgramCacheEntry));
627 entry->vertex_shader = vertex;
628 entry->fragment_shader = fragment;
629 entry->blend_mode = blendMode;
633 entry->id = rdata->glCreateProgram();
634 rdata->glAttachShader(entry->id, vertex->id);
635 rdata->glAttachShader(entry->id, fragment->id);
636 rdata->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_POSITION,
"a_position");
637 rdata->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_TEXCOORD,
"a_texCoord");
638 rdata->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_ANGLE,
"a_angle");
639 rdata->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_CENTER,
"a_center");
640 rdata->glLinkProgram(entry->id);
641 rdata->glGetProgramiv(entry->id,
GL_LINK_STATUS, &linkSuccessful);
642 if (rdata->glGetError() !=
GL_NO_ERROR || !linkSuccessful)
644 rdata->glDeleteProgram(entry->id);
651 entry->uniform_locations[GLES2_UNIFORM_PROJECTION] =
652 rdata->glGetUniformLocation(entry->id,
"u_projection");
653 entry->uniform_locations[GLES2_UNIFORM_TEXTURE] =
654 rdata->glGetUniformLocation(entry->id,
"u_texture");
655 entry->uniform_locations[GLES2_UNIFORM_MODULATION] =
656 rdata->glGetUniformLocation(entry->id,
"u_modulation");
657 entry->uniform_locations[GLES2_UNIFORM_COLOR] =
658 rdata->glGetUniformLocation(entry->id,
"u_color");
659 entry->uniform_locations[GLES2_UNIFORM_COLORTABLE] =
660 rdata->glGetUniformLocation(entry->id,
"u_colorTable");
663 if (rdata->program_cache.head)
665 entry->next = rdata->program_cache.head;
666 rdata->program_cache.head->prev = entry;
670 rdata->program_cache.tail = entry;
672 rdata->program_cache.head = entry;
673 ++rdata->program_cache.count;
676 ++vertex->references;
677 ++fragment->references;
680 if (rdata->program_cache.count > GLES2_MAX_CACHED_PROGRAMS)
682 shaderEntry = rdata->program_cache.tail->vertex_shader;
683 if (--shaderEntry->references <= 0)
684 GLES2_EvictShader(renderer, shaderEntry);
685 shaderEntry = rdata->program_cache.tail->fragment_shader;
686 if (--shaderEntry->references <= 0)
687 GLES2_EvictShader(renderer, shaderEntry);
688 rdata->glDeleteProgram(rdata->program_cache.tail->id);
689 rdata->program_cache.tail = rdata->program_cache.tail->prev;
690 SDL_free(rdata->program_cache.tail->next);
691 rdata->program_cache.tail->next =
NULL;
692 --rdata->program_cache.count;
697 static GLES2_ShaderCacheEntry *
700 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->
driverdata;
701 const GLES2_Shader *
shader;
702 const GLES2_ShaderInstance *instance =
NULL;
703 GLES2_ShaderCacheEntry *entry =
NULL;
708 shader = GLES2_GetShader(type, blendMode);
711 SDL_SetError(
"No shader matching the requested characteristics was found");
716 for (i = 0; i <
shader->instance_count && !instance; ++
i)
718 for (
j = 0;
j < rdata->shader_format_count && !instance; ++
j)
722 if (!
shader->instances[i])
724 if (
shader->instances[i]->format != rdata->shader_formats[
j])
726 instance =
shader->instances[
i];
731 SDL_SetError(
"The specified shader cannot be loaded on the current platform");
736 entry = rdata->shader_cache.head;
739 if (entry->instance == instance)
747 entry = (GLES2_ShaderCacheEntry *)
SDL_calloc(1,
sizeof(GLES2_ShaderCacheEntry));
754 entry->instance = instance;
758 entry->id = rdata->glCreateShader(instance->type);
759 if (instance->format == (
GLenum)-1)
761 rdata->glShaderSource(entry->id, 1, (
const char **)&instance->data,
NULL);
762 rdata->glCompileShader(entry->id);
767 rdata->glShaderBinary(1, &entry->id, instance->format, instance->data, instance->length);
770 if (rdata->glGetError() !=
GL_NO_ERROR || !compileSuccessful)
779 rdata->glGetShaderInfoLog(entry->id, length, &length, info);
788 rdata->glDeleteShader(entry->id);
794 if (rdata->shader_cache.head)
796 entry->next = rdata->shader_cache.head;
797 rdata->shader_cache.head->prev = entry;
799 rdata->shader_cache.head = entry;
800 ++rdata->shader_cache.count;
805 GLES2_EvictShader(
SDL_Renderer *renderer, GLES2_ShaderCacheEntry *entry)
807 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->
driverdata;
811 entry->next->prev = entry->prev;
813 entry->prev->next = entry->next;
814 if (rdata->shader_cache.head == entry)
815 rdata->shader_cache.head = entry->next;
816 --rdata->shader_cache.count;
819 rdata->glDeleteShader(entry->id);
826 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->
driverdata;
827 GLES2_ShaderCacheEntry *vertex =
NULL;
828 GLES2_ShaderCacheEntry *fragment =
NULL;
829 GLES2_ShaderType vtype, ftype;
830 GLES2_ProgramCacheEntry *
program;
833 vtype = GLES2_SHADER_VERTEX_DEFAULT;
836 case GLES2_IMAGESOURCE_SOLID:
837 ftype = GLES2_SHADER_FRAGMENT_SOLID_SRC;
839 case GLES2_IMAGESOURCE_TEXTURE_ABGR:
840 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_ABGR_SRC;
842 case GLES2_IMAGESOURCE_TEXTURE_ARGB:
843 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_ARGB_SRC;
845 case GLES2_IMAGESOURCE_TEXTURE_RGB:
846 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_RGB_SRC;
848 case GLES2_IMAGESOURCE_TEXTURE_BGR:
849 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_BGR_SRC;
856 vertex = GLES2_CacheShader(renderer, vtype, blendMode);
859 fragment = GLES2_CacheShader(renderer, ftype, blendMode);
864 if (rdata->current_program &&
865 rdata->current_program->vertex_shader == vertex &&
866 rdata->current_program->fragment_shader == fragment)
870 program = GLES2_CacheProgram(renderer, vertex, fragment, blendMode);
876 rdata->glUseProgram(
program->id);
884 rdata->current_program =
program;
887 if (GLES2_SetOrthographicProjection(renderer) < 0)
893 if (vertex && vertex->references <= 0)
894 GLES2_EvictShader(renderer, vertex);
895 if (fragment && fragment->references <= 0)
896 GLES2_EvictShader(renderer, fragment);
897 rdata->current_program =
NULL;
904 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->
driverdata;
913 projection[0][0] = 2.0f / renderer->
viewport.
w;
914 projection[0][1] = 0.0f;
915 projection[0][2] = 0.0f;
916 projection[0][3] = 0.0f;
917 projection[1][0] = 0.0f;
919 projection[1][1] = 2.0f / renderer->
viewport.
h;
921 projection[1][1] = -2.0f / renderer->
viewport.
h;
923 projection[1][2] = 0.0f;
924 projection[1][3] = 0.0f;
925 projection[2][0] = 0.0f;
926 projection[2][1] = 0.0f;
927 projection[2][2] = 0.0f;
928 projection[2][3] = 0.0f;
929 projection[3][0] = -1.0f;
931 projection[3][1] = -1.0f;
933 projection[3][1] = 1.0f;
935 projection[3][2] = 0.0f;
936 projection[3][3] = 1.0f;
939 locProjection = rdata->current_program->uniform_locations[GLES2_UNIFORM_PROJECTION];
941 rdata->glUniformMatrix4fv(locProjection, 1,
GL_FALSE, (
GLfloat *)projection);
943 return SDL_SetError(
"Failed to set orthographic projection");
952 static const float inv255f = 1.0f / 255.0f;
964 Uint32 pixel_format,
void * pixels,
int pitch);
965 static void GLES2_RenderPresent(
SDL_Renderer *renderer);
971 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->
driverdata;
973 GLES2_ActivateRenderer(renderer);
975 rdata->glClearColor((
GLfloat) renderer->
r * inv255f,
986 GLES2_SetBlendMode(GLES2_DriverContext *rdata,
int blendMode)
988 if (blendMode != rdata->current.blendMode) {
1007 rdata->current.blendMode = blendMode;
1014 if (enabled != rdata->current.tex_coords) {
1016 rdata->glEnableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
1018 rdata->glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
1020 rdata->current.tex_coords =
enabled;
1027 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->
driverdata;
1031 rdata->glGetError();
1033 GLES2_ActivateRenderer(renderer);
1035 GLES2_SetBlendMode(rdata, blendMode);
1040 if (GLES2_SelectProgram(renderer, GLES2_IMAGESOURCE_SOLID, blendMode) < 0)
1044 locColor = rdata->current_program->uniform_locations[GLES2_UNIFORM_COLOR];
1048 rdata->glUniform4f(locColor,
1049 renderer->
b * inv255f,
1050 renderer->
g * inv255f,
1051 renderer->
r * inv255f,
1052 renderer->
a * inv255f);
1054 rdata->glUniform4f(locColor,
1055 renderer->
r * inv255f,
1056 renderer->
g * inv255f,
1057 renderer->
b * inv255f,
1058 renderer->
a * inv255f);
1066 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->
driverdata;
1070 if (GLES2_SetDrawingState(renderer) < 0) {
1083 rdata->glGetError();
1085 rdata->glDrawArrays(
GL_POINTS, 0, count);
1096 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->
driverdata;
1100 if (GLES2_SetDrawingState(renderer) < 0) {
1113 rdata->glGetError();
1119 points[0].
x != points[count-1].
x || points[0].y != points[count-1].y) {
1120 rdata->glDrawArrays(
GL_POINTS, count-1, 1);
1132 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->
driverdata;
1136 if (GLES2_SetDrawingState(renderer) < 0) {
1141 rdata->glGetError();
1171 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->
driverdata;
1172 GLES2_TextureData *tdata = (GLES2_TextureData *)texture->
driverdata;
1173 GLES2_ImageSource sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1180 GLES2_ActivateRenderer(renderer);
1194 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1197 sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1206 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1209 sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1217 sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
1220 sourceType = GLES2_IMAGESOURCE_TEXTURE_RGB;
1223 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1231 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1234 sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
1237 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1243 else sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1249 sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1252 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1255 sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
1258 sourceType = GLES2_IMAGESOURCE_TEXTURE_RGB;
1264 if (GLES2_SelectProgram(renderer, sourceType, blendMode) < 0)
1268 locTexture = rdata->current_program->uniform_locations[GLES2_UNIFORM_TEXTURE];
1269 rdata->glGetError();
1271 rdata->glBindTexture(tdata->texture_type, tdata->texture);
1272 rdata->glUniform1i(locTexture, 0);
1275 locModulation = rdata->current_program->uniform_locations[GLES2_UNIFORM_MODULATION];
1279 rdata->glUniform4f(locModulation,
1280 texture->
b * inv255f,
1281 texture->
g * inv255f,
1282 texture->
r * inv255f,
1283 texture->
a * inv255f);
1285 rdata->glUniform4f(locModulation,
1286 texture->
r * inv255f,
1287 texture->
g * inv255f,
1288 texture->
b * inv255f,
1289 texture->
a * inv255f);
1293 GLES2_SetBlendMode(rdata, blendMode);
1295 GLES2_SetTexCoords(rdata,
SDL_TRUE);
1298 vertices[0] = dstrect->
x;
1299 vertices[1] = dstrect->
y;
1300 vertices[2] = (dstrect->
x + dstrect->
w);
1301 vertices[3] = dstrect->
y;
1302 vertices[4] = dstrect->
x;
1303 vertices[5] = (dstrect->
y + dstrect->
h);
1304 vertices[6] = (dstrect->
x + dstrect->
w);
1305 vertices[7] = (dstrect->
y + dstrect->
h);
1306 rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2,
GL_FLOAT,
GL_FALSE, 0, vertices);
1307 texCoords[0] = srcrect->
x / (
GLfloat)texture->
w;
1308 texCoords[1] = srcrect->
y / (
GLfloat)texture->
h;
1309 texCoords[2] = (srcrect->
x + srcrect->
w) / (
GLfloat)texture->
w;
1310 texCoords[3] = srcrect->
y / (
GLfloat)texture->
h;
1311 texCoords[4] = srcrect->
x / (
GLfloat)texture->
w;
1312 texCoords[5] = (srcrect->
y + srcrect->
h) / (
GLfloat)texture->
h;
1313 texCoords[6] = (srcrect->
x + srcrect->
w) / (
GLfloat)texture->
w;
1314 texCoords[7] = (srcrect->
y + srcrect->
h) / (
GLfloat)texture->
h;
1315 rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2,
GL_FLOAT,
GL_FALSE, 0, texCoords);
1327 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->
driverdata;
1328 GLES2_TextureData *tdata = (GLES2_TextureData *)texture->
driverdata;
1329 GLES2_ImageSource sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1339 GLES2_ActivateRenderer(renderer);
1341 rdata->glEnableVertexAttribArray(GLES2_ATTRIBUTE_CENTER);
1342 rdata->glEnableVertexAttribArray(GLES2_ATTRIBUTE_ANGLE);
1343 fAngle[0] = fAngle[1] = fAngle[2] = fAngle[3] = (
GLfloat)(360.0
f - angle);
1345 translate[0] = translate[2] = translate[4] = translate[6] = (center->
x + dstrect->
x);
1346 translate[1] = translate[3] = translate[5] = translate[7] = (center->
y + dstrect->
y);
1360 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1363 sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1372 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1375 sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1383 sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
1386 sourceType = GLES2_IMAGESOURCE_TEXTURE_RGB;
1389 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1397 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1400 sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
1403 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1409 else sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1415 sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1418 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1421 sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
1424 sourceType = GLES2_IMAGESOURCE_TEXTURE_RGB;
1430 if (GLES2_SelectProgram(renderer, sourceType, blendMode) < 0)
1434 locTexture = rdata->current_program->uniform_locations[GLES2_UNIFORM_TEXTURE];
1435 rdata->glGetError();
1437 rdata->glBindTexture(tdata->texture_type, tdata->texture);
1438 rdata->glUniform1i(locTexture, 0);
1441 locModulation = rdata->current_program->uniform_locations[GLES2_UNIFORM_MODULATION];
1445 rdata->glUniform4f(locModulation,
1446 texture->
b * inv255f,
1447 texture->
g * inv255f,
1448 texture->
r * inv255f,
1449 texture->
a * inv255f);
1451 rdata->glUniform4f(locModulation,
1452 texture->
r * inv255f,
1453 texture->
g * inv255f,
1454 texture->
b * inv255f,
1455 texture->
a * inv255f);
1459 GLES2_SetBlendMode(rdata, blendMode);
1461 GLES2_SetTexCoords(rdata,
SDL_TRUE);
1464 vertices[0] = dstrect->
x;
1465 vertices[1] = dstrect->
y;
1466 vertices[2] = (dstrect->
x + dstrect->
w);
1467 vertices[3] = dstrect->
y;
1468 vertices[4] = dstrect->
x;
1469 vertices[5] = (dstrect->
y + dstrect->
h);
1470 vertices[6] = (dstrect->
x + dstrect->
w);
1471 vertices[7] = (dstrect->
y + dstrect->
h);
1474 vertices[0] = vertices[4] = vertices[2];
1475 vertices[2] = vertices[6] = tmp;
1479 vertices[1] = vertices[3] = vertices[5];
1480 vertices[5] = vertices[7] = tmp;
1483 rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_ANGLE, 1,
GL_FLOAT,
GL_FALSE, 0, &fAngle);
1484 rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_CENTER, 2,
GL_FLOAT,
GL_FALSE, 0, translate);
1485 rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2,
GL_FLOAT,
GL_FALSE, 0, vertices);
1487 texCoords[0] = srcrect->
x / (
GLfloat)texture->
w;
1488 texCoords[1] = srcrect->
y / (
GLfloat)texture->
h;
1489 texCoords[2] = (srcrect->
x + srcrect->
w) / (
GLfloat)texture->
w;
1490 texCoords[3] = srcrect->
y / (
GLfloat)texture->
h;
1491 texCoords[4] = srcrect->
x / (
GLfloat)texture->
w;
1492 texCoords[5] = (srcrect->
y + srcrect->
h) / (
GLfloat)texture->
h;
1493 texCoords[6] = (srcrect->
x + srcrect->
w) / (
GLfloat)texture->
w;
1494 texCoords[7] = (srcrect->
y + srcrect->
h) / (
GLfloat)texture->
h;
1495 rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2,
GL_FLOAT,
GL_FALSE, 0, texCoords);
1497 rdata->glDisableVertexAttribArray(GLES2_ATTRIBUTE_CENTER);
1498 rdata->glDisableVertexAttribArray(GLES2_ATTRIBUTE_ANGLE);
1507 Uint32 pixel_format,
void * pixels,
int pitch)
1509 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->
driverdata;
1514 int w, h, length, rows;
1517 GLES2_ActivateRenderer(renderer);
1529 rdata->glReadPixels(rect->
x, (h-rect->
y)-rect->
h, rect->
w, rect->
h,
1534 src = (
Uint8*)temp_pixels + (rect->
h-1)*temp_pitch;
1548 temp_format, temp_pixels, temp_pitch,
1549 pixel_format, pixels, pitch);
1558 GLES2_ActivateRenderer(renderer);
1572 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
1573 GLES2_TextureData *texturedata = (GLES2_TextureData *)texture->
driverdata;
1574 GLES2_ActivateRenderer(renderer);
1576 data->glBindTexture(texturedata->texture_type, texturedata->texture);
1578 if(texw) *texw = 1.0;
1579 if(texh) *texh = 1.0;
1585 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
1586 GLES2_TextureData *texturedata = (GLES2_TextureData *)texture->
driverdata;
1587 GLES2_ActivateRenderer(renderer);
1589 data->glBindTexture(texturedata->texture_type, 0);
1599 #define GL_NVIDIA_PLATFORM_BINARY_NV 0x890B
1604 GLES2_DriverContext *rdata = (GLES2_DriverContext *) renderer->
driverdata;
1606 if (SDL_CurrentContext == rdata->context) {
1607 GLES2_UpdateViewport(renderer);
1609 GLES2_ActivateRenderer(renderer);
1612 rdata->current.blendMode = -1;
1615 rdata->glEnableVertexAttribArray(GLES2_ATTRIBUTE_POSITION);
1616 rdata->glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
1623 GLES2_DriverContext *rdata;
1629 GLint window_framebuffer;
1651 rdata = (GLES2_DriverContext *)
SDL_calloc(1,
sizeof(GLES2_DriverContext));
1653 GLES2_DestroyRenderer(renderer);
1657 renderer->
info = GLES2_RenderDriver.
info;
1660 renderer->
window = window;
1664 if (!rdata->context)
1666 GLES2_DestroyRenderer(renderer);
1670 GLES2_DestroyRenderer(renderer);
1674 if (GLES2_LoadFunctions(rdata) < 0) {
1675 GLES2_DestroyRenderer(renderer);
1690 rdata->glGetError();
1700 if (!rdata->shader_formats)
1702 GLES2_DestroyRenderer(renderer);
1706 rdata->shader_format_count = nFormats;
1708 rdata->shader_formats[0] = GL_NVIDIA_PLATFORM_BINARY_NV;
1713 GLES2_DestroyRenderer(renderer);
1714 SDL_SetError(
"Failed to query supported shader formats");
1718 rdata->shader_formats[nFormats - 1] = (
GLenum)-1;
1721 rdata->framebuffers =
NULL;
1723 rdata->window_framebuffer = (
GLuint)window_framebuffer;
1747 GLES2_ResetState(renderer);
int(* UpdateClipRect)(SDL_Renderer *renderer)
GLfloat GLfloat GLfloat GLfloat h
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum type
DECLSPEC void *SDLCALL SDL_calloc(size_t nmemb, size_t size)
void(* WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event)
SDL_BlendMode
The blend mode used in SDL_RenderCopy() and drawing operations.
DECLSPEC int SDLCALL SDL_GL_GetSwapInterval(void)
Get the swap interval for the current OpenGL context.
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.
#define GL_NUM_SHADER_BINARY_FORMATS
int(* RenderClear)(SDL_Renderer *renderer)
#define GL_COLOR_ATTACHMENT0
#define SDL_stack_free(data)
DECLSPEC SDL_GLContext SDLCALL SDL_GL_CreateContext(SDL_Window *window)
Create an OpenGL context for use with an OpenGL window, and make it current.
int(* RenderDrawPoints)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
GLenum GLsizei const GLuint GLboolean enabled
int(* SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
#define SDL_HINT_RENDER_SCALE_QUALITY
A variable controlling the scaling quality.
#define GL_FRAMEBUFFER_COMPLETE
DECLSPEC void SDLCALL SDL_free(void *mem)
#define GL_INFO_LOG_LENGTH
void * SDL_GLContext
An opaque handle to an OpenGL context.
#define SDL_BYTESPERPIXEL(X)
void(* UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
#define GL_TEXTURE_MAG_FILTER
DECLSPEC int SDLCALL SDL_GetRendererOutputSize(SDL_Renderer *renderer, int *w, int *h)
Get the output size of a rendering context.
#define GL_SHADER_COMPILER
#define GL_TRIANGLE_STRIP
SDL_FORCE_INLINE SDL_bool SDL_RectEmpty(const SDL_Rect *r)
Returns true if the rectangle has no area.
uint32_t Uint32
An unsigned 32-bit integer type.
const GLuint * framebuffers
DECLSPEC int SDLCALL SDL_GL_MakeCurrent(SDL_Window *window, SDL_GLContext context)
Set up an OpenGL context for rendering into an OpenGL window.
int(* LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
DECLSPEC int SDLCALL SDL_GL_SetAttribute(SDL_GLattr attr, int value)
Set an OpenGL window attribute before window creation.
#define GL_COLOR_BUFFER_BIT
#define GL_TEXTURE_MIN_FILTER
DECLSPEC int SDLCALL SDL_GL_SetSwapInterval(int interval)
Set the swap interval for the current OpenGL context.
int(* UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
int SDL_RecreateWindow(SDL_Window *window, Uint32 flags)
static int GetScaleQuality(void)
DECLSPEC void SDLCALL SDL_GL_DeleteContext(SDL_GLContext context)
Delete an OpenGL context.
int(* RenderDrawLines)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
#define GL_PACK_ALIGNMENT
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum format
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
DECLSPEC void *SDLCALL SDL_malloc(size_t size)
DECLSPEC Uint32 SDLCALL SDL_GetWindowFlags(SDL_Window *window)
Get the window flags.
DECLSPEC const char *SDLCALL SDL_GetHint(const char *name)
Get a hint.
void(* DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
GLbitfield GLuint program
int(* RenderCopy)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect)
SDL_RendererFlip
Flip constants for SDL_RenderCopyEx.
#define GL_COMPILE_STATUS
Window state change event data (event.window.*)
EGLSurface EGLint EGLint y
#define SDL_OutOfMemory()
GLenum GLenum GLuint texture
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
int(* GL_BindTexture)(SDL_Renderer *renderer, SDL_Texture *texture, float *texw, float *texh)
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)
GLenum GLsizei GLsizei GLsizei GLsizei GLbitfield flags
#define GL_FRAMEBUFFER_BINDING
int(* GL_UnbindTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
#define GL_TEXTURE_WRAP_T
int(* RenderFillRects)(SDL_Renderer *renderer, const SDL_FRect *rects, int count)
uint8_t Uint8
An unsigned 8-bit integer type.
#define GL_TEXTURE_WRAP_S
#define GL_ONE_MINUS_SRC_ALPHA
GLint GLint GLint GLint GLint w
#define SDL_stack_alloc(type, count)
#define GL_UNPACK_ALIGNMENT
int(* UpdateViewport)(SDL_Renderer *renderer)
GLuint GLdouble GLdouble GLint GLint const GLdouble * points
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)
#define GL_SHADER_BINARY_FORMATS
void(* DestroyRenderer)(SDL_Renderer *renderer)
GLsizei GLsizei GLchar * source
DECLSPEC int SDLCALL SDL_strcasecmp(const char *str1, const char *str2)
A rectangle, with the origin at the upper left.
DECLSPEC void SDLCALL SDL_GL_SwapWindow(SDL_Window *window)
Swap the OpenGL buffers for a window, if double-buffering is supported.