src/render/opengles2/SDL_render_gles2.c
changeset 6246 c70ec935a4bb
parent 6237 240f1bced46b
child 6247 b6212690f78d
equal deleted inserted replaced
6245:9d15de67bff9 6246:c70ec935a4bb
   143 
   143 
   144 #define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
   144 #define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
   145 #include "SDL_gles2funcs.h"
   145 #include "SDL_gles2funcs.h"
   146 #undef SDL_PROC
   146 #undef SDL_PROC
   147     GLES2_FBOList *framebuffers;
   147     GLES2_FBOList *framebuffers;
   148     SDL_Texture *renderTarget;
       
   149     SDL_Rect viewport_copy;
       
   150 
   148 
   151     int shader_format_count;
   149     int shader_format_count;
   152     GLenum *shader_formats;
   150     GLenum *shader_formats;
   153     GLES2_ShaderCache shader_cache;
   151     GLES2_ShaderCache shader_cache;
   154     GLES2_ProgramCache program_cache;
   152     GLES2_ProgramCache program_cache;
   164 static int GLES2_ActivateRenderer(SDL_Renderer *renderer);
   162 static int GLES2_ActivateRenderer(SDL_Renderer *renderer);
   165 static void GLES2_WindowEvent(SDL_Renderer * renderer,
   163 static void GLES2_WindowEvent(SDL_Renderer * renderer,
   166                               const SDL_WindowEvent *event);
   164                               const SDL_WindowEvent *event);
   167 static int GLES2_UpdateViewport(SDL_Renderer * renderer);
   165 static int GLES2_UpdateViewport(SDL_Renderer * renderer);
   168 static void GLES2_DestroyRenderer(SDL_Renderer *renderer);
   166 static void GLES2_DestroyRenderer(SDL_Renderer *renderer);
   169 
   167 static int GLES2_SetOrthographicProjection(SDL_Renderer *renderer);
   170 static int GLES2_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture);
   168 
   171 
   169 
   172 static SDL_GLContext SDL_CurrentContext = NULL;
   170 static SDL_GLContext SDL_CurrentContext = NULL;
   173 
   171 
   174 static int GLES2_LoadFunctions(GLES2_DriverContext * data)
   172 static int GLES2_LoadFunctions(GLES2_DriverContext * data)
   175 {
   173 {
   327 static int GLES2_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect,
   325 static int GLES2_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect,
   328                              void **pixels, int *pitch);
   326                              void **pixels, int *pitch);
   329 static void GLES2_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture);
   327 static void GLES2_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture);
   330 static int GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect,
   328 static int GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect,
   331                                const void *pixels, int pitch);
   329                                const void *pixels, int pitch);
       
   330 static int GLES2_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture);
   332 
   331 
   333 static GLenum
   332 static GLenum
   334 GetScaleQuality(void)
   333 GetScaleQuality(void)
   335 {
   334 {
   336     const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
   335     const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
   531         return -1;
   530         return -1;
   532     }
   531     }
   533     return 0;
   532     return 0;
   534 }
   533 }
   535 
   534 
       
   535 static int
       
   536 GLES2_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture)
       
   537 {
       
   538     GLES2_DriverContext *data = (GLES2_DriverContext *) renderer->driverdata;
       
   539     GLES2_TextureData *texturedata = NULL;
       
   540     GLenum status;
       
   541 
       
   542     if (texture == NULL) {
       
   543         data->glBindFramebuffer(GL_FRAMEBUFFER, 0);
       
   544     } else {
       
   545         texturedata = (GLES2_TextureData *) texture->driverdata;
       
   546         data->glBindFramebuffer(GL_FRAMEBUFFER, texturedata->fbo->FBO);
       
   547         /* TODO: check if texture pixel format allows this operation */
       
   548         data->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texturedata->texture_type, texturedata->texture, 0);
       
   549         /* Check FBO status */
       
   550         status = data->glCheckFramebufferStatus(GL_FRAMEBUFFER);
       
   551         if (status != GL_FRAMEBUFFER_COMPLETE) {
       
   552             SDL_SetError("glFramebufferTexture2D() failed");
       
   553             return -1;
       
   554         }
       
   555     }
       
   556     if (data->current_program) {
       
   557         GLES2_SetOrthographicProjection(renderer);
       
   558     }
       
   559     return 0;
       
   560 }
       
   561 
   536 /*************************************************************************************************
   562 /*************************************************************************************************
   537  * Shader management functions                                                                   *
   563  * Shader management functions                                                                   *
   538  *************************************************************************************************/
   564  *************************************************************************************************/
   539 
   565 
   540 static GLES2_ShaderCacheEntry *GLES2_CacheShader(SDL_Renderer *renderer, GLES2_ShaderType type,
   566 static GLES2_ShaderCacheEntry *GLES2_CacheShader(SDL_Renderer *renderer, GLES2_ShaderType type,
   544                                                    GLES2_ShaderCacheEntry *vertex,
   570                                                    GLES2_ShaderCacheEntry *vertex,
   545                                                    GLES2_ShaderCacheEntry *fragment,
   571                                                    GLES2_ShaderCacheEntry *fragment,
   546                                                    SDL_BlendMode blendMode);
   572                                                    SDL_BlendMode blendMode);
   547 static int GLES2_SelectProgram(SDL_Renderer *renderer, GLES2_ImageSource source,
   573 static int GLES2_SelectProgram(SDL_Renderer *renderer, GLES2_ImageSource source,
   548                                SDL_BlendMode blendMode);
   574                                SDL_BlendMode blendMode);
   549 static int GLES2_SetOrthographicProjection(SDL_Renderer *renderer);
       
   550 
   575 
   551 static GLES2_ProgramCacheEntry *
   576 static GLES2_ProgramCacheEntry *
   552 GLES2_CacheProgram(SDL_Renderer *renderer, GLES2_ShaderCacheEntry *vertex,
   577 GLES2_CacheProgram(SDL_Renderer *renderer, GLES2_ShaderCacheEntry *vertex,
   553                    GLES2_ShaderCacheEntry *fragment, SDL_BlendMode blendMode)
   578                    GLES2_ShaderCacheEntry *fragment, SDL_BlendMode blendMode)
   554 {
   579 {
  1126 
  1151 
  1127     GLES2_ActivateRenderer(renderer);
  1152     GLES2_ActivateRenderer(renderer);
  1128 
  1153 
  1129     /* Activate an appropriate shader and set the projection matrix */
  1154     /* Activate an appropriate shader and set the projection matrix */
  1130     blendMode = texture->blendMode;
  1155     blendMode = texture->blendMode;
  1131     if (rdata->renderTarget!=NULL) {
  1156     if (renderer->target) {
  1132         /* Check if we need to do color mapping between the source and render target textures */
  1157         /* Check if we need to do color mapping between the source and render target textures */
  1133         if (rdata->renderTarget->format != texture->format) {
  1158         if (renderer->target->format != texture->format) {
  1134             switch (texture->format)
  1159             switch (texture->format)
  1135             {
  1160             {
  1136             case SDL_PIXELFORMAT_ABGR8888:
  1161             case SDL_PIXELFORMAT_ABGR8888:
  1137                 switch (rdata->renderTarget->format)
  1162                 switch (renderer->target->format)
  1138                 {
  1163                 {
  1139                     case SDL_PIXELFORMAT_ARGB8888:
  1164                     case SDL_PIXELFORMAT_ARGB8888:
  1140                     case SDL_PIXELFORMAT_RGB888:
  1165                     case SDL_PIXELFORMAT_RGB888:
  1141                         sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
  1166                         sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
  1142                         break;
  1167                         break;
  1144                         sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
  1169                         sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
  1145                         break;
  1170                         break;
  1146                 }
  1171                 }
  1147                 break;
  1172                 break;
  1148             case SDL_PIXELFORMAT_ARGB8888:
  1173             case SDL_PIXELFORMAT_ARGB8888:
  1149                 switch (rdata->renderTarget->format)
  1174                 switch (renderer->target->format)
  1150                 {
  1175                 {
  1151                     case SDL_PIXELFORMAT_ABGR8888:
  1176                     case SDL_PIXELFORMAT_ABGR8888:
  1152                     case SDL_PIXELFORMAT_BGR888:
  1177                     case SDL_PIXELFORMAT_BGR888:
  1153                         sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
  1178                         sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
  1154                         break;
  1179                         break;
  1156                         sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
  1181                         sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
  1157                         break;
  1182                         break;
  1158                 }
  1183                 }
  1159                 break;
  1184                 break;
  1160             case SDL_PIXELFORMAT_BGR888:
  1185             case SDL_PIXELFORMAT_BGR888:
  1161                 switch (rdata->renderTarget->format)
  1186                 switch (renderer->target->format)
  1162                 {
  1187                 {
  1163                     case SDL_PIXELFORMAT_ABGR8888:
  1188                     case SDL_PIXELFORMAT_ABGR8888:
  1164                         sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
  1189                         sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
  1165                         break;
  1190                         break;
  1166                     case SDL_PIXELFORMAT_ARGB8888:
  1191                     case SDL_PIXELFORMAT_ARGB8888:
  1170                         sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
  1195                         sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
  1171                         break;
  1196                         break;
  1172                 }
  1197                 }
  1173                 break;
  1198                 break;
  1174             case SDL_PIXELFORMAT_RGB888:
  1199             case SDL_PIXELFORMAT_RGB888:
  1175                 switch (rdata->renderTarget->format)
  1200                 switch (renderer->target->format)
  1176                 {
  1201                 {
  1177                     case SDL_PIXELFORMAT_ABGR8888:
  1202                     case SDL_PIXELFORMAT_ABGR8888:
  1178                         sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
  1203                         sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
  1179                         break;
  1204                         break;
  1180                     case SDL_PIXELFORMAT_ARGB8888:
  1205                     case SDL_PIXELFORMAT_ARGB8888:
  1228     GLES2_SetBlendMode(rdata, blendMode);
  1253     GLES2_SetBlendMode(rdata, blendMode);
  1229 
  1254 
  1230     GLES2_SetTexCoords(rdata, SDL_TRUE);
  1255     GLES2_SetTexCoords(rdata, SDL_TRUE);
  1231 
  1256 
  1232     /* Emit the textured quad */
  1257     /* Emit the textured quad */
  1233     if (rdata->renderTarget!=NULL) {
  1258     if (renderer->target) {
  1234         // Flip the texture vertically to compensate for the inversion it'll be subjected to later when it's rendered to the screen
  1259         // Flip the texture vertically to compensate for the inversion it'll be subjected to later when it's rendered to the screen
  1235         vertices[0] = (GLfloat)dstrect->x;
  1260         vertices[0] = (GLfloat)dstrect->x;
  1236         vertices[1] = (GLfloat)renderer->viewport.h-dstrect->y;
  1261         vertices[1] = (GLfloat)renderer->viewport.h-dstrect->y;
  1237         vertices[2] = (GLfloat)(dstrect->x + dstrect->w);
  1262         vertices[2] = (GLfloat)(dstrect->x + dstrect->w);
  1238         vertices[3] = (GLfloat)renderer->viewport.h-dstrect->y;
  1263         vertices[3] = (GLfloat)renderer->viewport.h-dstrect->y;
  1352     rdata->current.blendMode = -1;
  1377     rdata->current.blendMode = -1;
  1353     rdata->current.tex_coords = SDL_FALSE;
  1378     rdata->current.tex_coords = SDL_FALSE;
  1354 
  1379 
  1355     rdata->glEnableVertexAttribArray(GLES2_ATTRIBUTE_POSITION);
  1380     rdata->glEnableVertexAttribArray(GLES2_ATTRIBUTE_POSITION);
  1356     rdata->glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
  1381     rdata->glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
  1357 }
       
  1358 
       
  1359 static int
       
  1360 GLES2_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture)
       
  1361 {
       
  1362     GLES2_DriverContext *data = (GLES2_DriverContext *) renderer->driverdata;
       
  1363     GLES2_TextureData *texturedata = NULL;
       
  1364     GLenum status;
       
  1365     SDL_BlendMode blendMode;
       
  1366 
       
  1367     if (!renderer) return -1;
       
  1368 
       
  1369     blendMode = texture->blendMode;
       
  1370     if (texture == NULL) {
       
  1371         if (data->renderTarget!=NULL) {
       
  1372             data->glBindFramebuffer(GL_FRAMEBUFFER, 0);
       
  1373             renderer->viewport = data->viewport_copy;
       
  1374             data->renderTarget = NULL;
       
  1375             data->glViewport(renderer->viewport.x, renderer->viewport.y, renderer->viewport.w, renderer->viewport.h);
       
  1376             if(data->current_program) GLES2_SetOrthographicProjection(renderer);
       
  1377         }
       
  1378         return 0;
       
  1379     }
       
  1380     if (renderer != texture->renderer) return -1;
       
  1381     if (data->renderTarget==NULL) {
       
  1382         // Keep a copy of the default viewport to restore when texture==NULL
       
  1383         data->viewport_copy = renderer->viewport;
       
  1384     }
       
  1385 
       
  1386     texturedata = (GLES2_TextureData *) texture->driverdata;
       
  1387     if (!texturedata) {
       
  1388         if (texture->native && texture->native->driverdata) {
       
  1389             texture = texture->native;
       
  1390             texturedata = texture->driverdata;
       
  1391         }
       
  1392         else return -1;
       
  1393     }
       
  1394     data->glBindFramebuffer(GL_FRAMEBUFFER, texturedata->fbo->FBO);
       
  1395     /* TODO: check if texture pixel format allows this operation */
       
  1396     data->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texturedata->texture_type, texturedata->texture, 0);
       
  1397     /* Check FBO status */
       
  1398     status = data->glCheckFramebufferStatus(GL_FRAMEBUFFER);
       
  1399     if (status != GL_FRAMEBUFFER_COMPLETE) {
       
  1400         return -1;
       
  1401     }
       
  1402     
       
  1403     renderer->viewport.x = 0;
       
  1404     renderer->viewport.y = 0;
       
  1405     renderer->viewport.w = texture->w;
       
  1406     renderer->viewport.h = texture->h;
       
  1407     data->renderTarget = texture;
       
  1408     data->glViewport(0, 0, texture->w, texture->h);
       
  1409     if(data->current_program) GLES2_SetOrthographicProjection(renderer);
       
  1410     return 0;
       
  1411 }
  1382 }
  1412 
  1383 
  1413 static SDL_Renderer *
  1384 static SDL_Renderer *
  1414 GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
  1385 GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
  1415 {
  1386 {
  1509     if (hasCompiler)
  1480     if (hasCompiler)
  1510         rdata->shader_formats[nFormats - 1] = (GLenum)-1;
  1481         rdata->shader_formats[nFormats - 1] = (GLenum)-1;
  1511 #endif /* ZUNE_HD */
  1482 #endif /* ZUNE_HD */
  1512 
  1483 
  1513     rdata->framebuffers = NULL;
  1484     rdata->framebuffers = NULL;
  1514     rdata->renderTarget = NULL;
       
  1515 
  1485 
  1516     /* Populate the function pointers for the module */
  1486     /* Populate the function pointers for the module */
  1517     renderer->WindowEvent         = &GLES2_WindowEvent;
  1487     renderer->WindowEvent         = &GLES2_WindowEvent;
  1518     renderer->CreateTexture       = &GLES2_CreateTexture;
  1488     renderer->CreateTexture       = &GLES2_CreateTexture;
  1519     renderer->UpdateTexture       = &GLES2_UpdateTexture;
  1489     renderer->UpdateTexture       = &GLES2_UpdateTexture;
  1520     renderer->LockTexture         = &GLES2_LockTexture;
  1490     renderer->LockTexture         = &GLES2_LockTexture;
  1521     renderer->UnlockTexture       = &GLES2_UnlockTexture;
  1491     renderer->UnlockTexture       = &GLES2_UnlockTexture;
       
  1492     renderer->SetTargetTexture    = &GLES2_SetTargetTexture;
  1522     renderer->UpdateViewport      = &GLES2_UpdateViewport;
  1493     renderer->UpdateViewport      = &GLES2_UpdateViewport;
  1523     renderer->RenderClear         = &GLES2_RenderClear;
  1494     renderer->RenderClear         = &GLES2_RenderClear;
  1524     renderer->RenderDrawPoints    = &GLES2_RenderDrawPoints;
  1495     renderer->RenderDrawPoints    = &GLES2_RenderDrawPoints;
  1525     renderer->RenderDrawLines     = &GLES2_RenderDrawLines;
  1496     renderer->RenderDrawLines     = &GLES2_RenderDrawLines;
  1526     renderer->RenderFillRects     = &GLES2_RenderFillRects;
  1497     renderer->RenderFillRects     = &GLES2_RenderFillRects;
  1527     renderer->RenderCopy          = &GLES2_RenderCopy;
  1498     renderer->RenderCopy          = &GLES2_RenderCopy;
  1528     renderer->RenderReadPixels    = &GLES2_RenderReadPixels;
  1499     renderer->RenderReadPixels    = &GLES2_RenderReadPixels;
  1529     renderer->RenderPresent       = &GLES2_RenderPresent;
  1500     renderer->RenderPresent       = &GLES2_RenderPresent;
  1530     renderer->DestroyTexture      = &GLES2_DestroyTexture;
  1501     renderer->DestroyTexture      = &GLES2_DestroyTexture;
  1531     renderer->DestroyRenderer     = &GLES2_DestroyRenderer;
  1502     renderer->DestroyRenderer     = &GLES2_DestroyRenderer;
  1532     renderer->SetTargetTexture    = &GLES2_SetTargetTexture;
       
  1533 
  1503 
  1534     GLES2_ResetState(renderer);
  1504     GLES2_ResetState(renderer);
  1535 
  1505 
  1536     return renderer;
  1506     return renderer;
  1537 }
  1507 }