src/render/opengl/SDL_render_gl.c
changeset 6246 c70ec935a4bb
parent 6237 240f1bced46b
child 6247 b6212690f78d
equal deleted inserted replaced
6245:9d15de67bff9 6246:c70ec935a4bb
    52                             const SDL_Rect * rect, const void *pixels,
    52                             const SDL_Rect * rect, const void *pixels,
    53                             int pitch);
    53                             int pitch);
    54 static int GL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
    54 static int GL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
    55                           const SDL_Rect * rect, void **pixels, int *pitch);
    55                           const SDL_Rect * rect, void **pixels, int *pitch);
    56 static void GL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
    56 static void GL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
       
    57 static int GL_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture);
    57 static int GL_UpdateViewport(SDL_Renderer * renderer);
    58 static int GL_UpdateViewport(SDL_Renderer * renderer);
    58 static int GL_RenderClear(SDL_Renderer * renderer);
    59 static int GL_RenderClear(SDL_Renderer * renderer);
    59 static int GL_RenderDrawPoints(SDL_Renderer * renderer,
    60 static int GL_RenderDrawPoints(SDL_Renderer * renderer,
    60                                const SDL_Point * points, int count);
    61                                const SDL_Point * points, int count);
    61 static int GL_RenderDrawLines(SDL_Renderer * renderer,
    62 static int GL_RenderDrawLines(SDL_Renderer * renderer,
    64                               const SDL_Rect * rects, int count);
    65                               const SDL_Rect * rects, int count);
    65 static int GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
    66 static int GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
    66                          const SDL_Rect * srcrect, const SDL_Rect * dstrect);
    67                          const SDL_Rect * srcrect, const SDL_Rect * dstrect);
    67 static int GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
    68 static int GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
    68                                Uint32 pixel_format, void * pixels, int pitch);
    69                                Uint32 pixel_format, void * pixels, int pitch);
    69 static int GL_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture);
       
    70 static void GL_RenderPresent(SDL_Renderer * renderer);
    70 static void GL_RenderPresent(SDL_Renderer * renderer);
    71 static void GL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture);
    71 static void GL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture);
    72 static void GL_DestroyRenderer(SDL_Renderer * renderer);
    72 static void GL_DestroyRenderer(SDL_Renderer * renderer);
    73 
    73 
    74 
    74 
   102         int blendMode;
   102         int blendMode;
   103     } current;
   103     } current;
   104     
   104     
   105     SDL_bool GL_EXT_framebuffer_object_supported;
   105     SDL_bool GL_EXT_framebuffer_object_supported;
   106     GL_FBOList *framebuffers;
   106     GL_FBOList *framebuffers;
   107     SDL_Texture *renderTarget;
       
   108     SDL_Rect viewport_copy;
       
   109 
   107 
   110     /* OpenGL functions */
   108     /* OpenGL functions */
   111 #define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
   109 #define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
   112 #include "SDL_glfuncs.h"
   110 #include "SDL_glfuncs.h"
   113 #undef SDL_PROC
   111 #undef SDL_PROC
   307     renderer->WindowEvent = GL_WindowEvent;
   305     renderer->WindowEvent = GL_WindowEvent;
   308     renderer->CreateTexture = GL_CreateTexture;
   306     renderer->CreateTexture = GL_CreateTexture;
   309     renderer->UpdateTexture = GL_UpdateTexture;
   307     renderer->UpdateTexture = GL_UpdateTexture;
   310     renderer->LockTexture = GL_LockTexture;
   308     renderer->LockTexture = GL_LockTexture;
   311     renderer->UnlockTexture = GL_UnlockTexture;
   309     renderer->UnlockTexture = GL_UnlockTexture;
       
   310     renderer->SetTargetTexture = GL_SetTargetTexture;
   312     renderer->UpdateViewport = GL_UpdateViewport;
   311     renderer->UpdateViewport = GL_UpdateViewport;
   313     renderer->RenderClear = GL_RenderClear;
   312     renderer->RenderClear = GL_RenderClear;
   314     renderer->RenderDrawPoints = GL_RenderDrawPoints;
   313     renderer->RenderDrawPoints = GL_RenderDrawPoints;
   315     renderer->RenderDrawLines = GL_RenderDrawLines;
   314     renderer->RenderDrawLines = GL_RenderDrawLines;
   316     renderer->RenderFillRects = GL_RenderFillRects;
   315     renderer->RenderFillRects = GL_RenderFillRects;
   317     renderer->RenderCopy = GL_RenderCopy;
   316     renderer->RenderCopy = GL_RenderCopy;
   318     renderer->SetTargetTexture = GL_SetTargetTexture;
       
   319     renderer->RenderReadPixels = GL_RenderReadPixels;
   317     renderer->RenderReadPixels = GL_RenderReadPixels;
   320     renderer->RenderPresent = GL_RenderPresent;
   318     renderer->RenderPresent = GL_RenderPresent;
   321     renderer->DestroyTexture = GL_DestroyTexture;
   319     renderer->DestroyTexture = GL_DestroyTexture;
   322     renderer->DestroyRenderer = GL_DestroyRenderer;
   320     renderer->DestroyRenderer = GL_DestroyRenderer;
   323     renderer->info = GL_RenderDriver.info;
   321     renderer->info = GL_RenderDriver.info;
   324     renderer->info.flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE;
   322     renderer->info.flags = SDL_RENDERER_ACCELERATED;
   325     renderer->driverdata = data;
   323     renderer->driverdata = data;
   326     renderer->window = window;
   324     renderer->window = window;
   327 
   325 
   328     data->context = SDL_GL_CreateContext(window);
   326     data->context = SDL_GL_CreateContext(window);
   329     if (!data->context) {
   327     if (!data->context) {
   397             SDL_GL_GetProcAddress("glDeleteFramebuffersEXT");
   395             SDL_GL_GetProcAddress("glDeleteFramebuffersEXT");
   398         data->glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)
   396         data->glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)
   399             SDL_GL_GetProcAddress("glFramebufferTexture2DEXT");
   397             SDL_GL_GetProcAddress("glFramebufferTexture2DEXT");
   400         data->glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)
   398         data->glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)
   401             SDL_GL_GetProcAddress("glBindFramebufferEXT");
   399             SDL_GL_GetProcAddress("glBindFramebufferEXT");
   402        data->glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)
   400         data->glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)
   403             SDL_GL_GetProcAddress("glCheckFramebufferStatusEXT");
   401             SDL_GL_GetProcAddress("glCheckFramebufferStatusEXT");
       
   402         renderer->info.flags |= SDL_RENDERER_TARGETTEXTURE;
   404     }
   403     }
   405     data->framebuffers = NULL;
   404     data->framebuffers = NULL;
   406     data->renderTarget = NULL;
       
   407 
   405 
   408     /* Set up parameters for rendering */
   406     /* Set up parameters for rendering */
   409     GL_ResetState(renderer);
   407     GL_ResetState(renderer);
   410 
   408 
   411     return renderer;
   409     return renderer;
   461     if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
   459     if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
   462         return GL_NEAREST;
   460         return GL_NEAREST;
   463     } else {
   461     } else {
   464         return GL_LINEAR;
   462         return GL_LINEAR;
   465     }
   463     }
   466 }
       
   467 
       
   468 static int
       
   469 GL_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture)
       
   470 {
       
   471     GL_RenderData *data = (GL_RenderData *) renderer->driverdata;    
       
   472     
       
   473     GL_TextureData *texturedata;
       
   474     GLenum status;
       
   475 
       
   476     if (!renderer) return -1;
       
   477     GL_ActivateRenderer(renderer);
       
   478     
       
   479     if (! data->GL_EXT_framebuffer_object_supported) {
       
   480         SDL_Unsupported();
       
   481         return -1;
       
   482     }
       
   483     
       
   484     if (texture == NULL) {
       
   485         if (data->renderTarget != NULL) {
       
   486             data->renderTarget = NULL;
       
   487             renderer->viewport = data->viewport_copy;
       
   488             data->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
       
   489             data->glMatrixMode(GL_PROJECTION);
       
   490             data->glLoadIdentity();
       
   491             data->glMatrixMode(GL_MODELVIEW);
       
   492             data->glLoadIdentity();
       
   493             data->glViewport(renderer->viewport.x, renderer->viewport.y, renderer->viewport.w, renderer->viewport.h);
       
   494             data->glOrtho(0.0, (GLdouble) renderer->viewport.w, (GLdouble) renderer->viewport.h, 0.0, 0.0, 1.0);
       
   495         }
       
   496         return 0;
       
   497     }
       
   498     if (renderer != texture->renderer) return -1;
       
   499     if (data->renderTarget==NULL) {
       
   500         // Keep a copy of the default viewport to restore when texture==NULL
       
   501         data->viewport_copy = renderer->viewport;
       
   502     }
       
   503     
       
   504     
       
   505     texturedata = (GL_TextureData *) texture->driverdata;
       
   506     if (!texturedata) {
       
   507         if (texture->native && texture->native->driverdata) {
       
   508             texture = texture->native;
       
   509             texturedata = texture->driverdata;
       
   510         }
       
   511         else return -1;
       
   512     }
       
   513     data->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, texturedata->fbo->FBO);
       
   514     /* TODO: check if texture pixel format allows this operation */
       
   515     data->glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, texturedata->type, texturedata->texture, 0);
       
   516     /* Check FBO status */
       
   517     status = data->glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
       
   518     if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
       
   519         return -1;
       
   520     }
       
   521 
       
   522     data->renderTarget = texture;
       
   523     renderer->viewport.x = 0;
       
   524     renderer->viewport.y = 0;
       
   525     renderer->viewport.w = texture->w;
       
   526     renderer->viewport.h = texture->h;
       
   527     data->glMatrixMode(GL_PROJECTION);
       
   528     data->glLoadIdentity();
       
   529     data->glOrtho(0.0, (GLdouble) texture->w, 0.0, (GLdouble) texture->h, 0.0, 1.0);
       
   530     data->glMatrixMode(GL_MODELVIEW);
       
   531     data->glLoadIdentity();
       
   532     data->glViewport(0, 0, texture->w, texture->h);    
       
   533     return 0;
       
   534 }
   464 }
   535 
   465 
   536 static int
   466 static int
   537 GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
   467 GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
   538 {
   468 {
   775                   rect->x * SDL_BYTESPERPIXEL(texture->format));
   705                   rect->x * SDL_BYTESPERPIXEL(texture->format));
   776     GL_UpdateTexture(renderer, texture, rect, pixels, data->pitch);
   706     GL_UpdateTexture(renderer, texture, rect, pixels, data->pitch);
   777 }
   707 }
   778 
   708 
   779 static int
   709 static int
       
   710 GL_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture)
       
   711 {
       
   712     GL_RenderData *data = (GL_RenderData *) renderer->driverdata;    
       
   713     GL_TextureData *texturedata;
       
   714     GLenum status;
       
   715 
       
   716     GL_ActivateRenderer(renderer);
       
   717     
       
   718     if (texture == NULL) {
       
   719         data->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
       
   720         return 0;
       
   721     }
       
   722 
       
   723     texturedata = (GL_TextureData *) texture->driverdata;
       
   724     data->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, texturedata->fbo->FBO);
       
   725     /* TODO: check if texture pixel format allows this operation */
       
   726     data->glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, texturedata->type, texturedata->texture, 0);
       
   727     /* Check FBO status */
       
   728     status = data->glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
       
   729     if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
       
   730         SDL_SetError("glFramebufferTexture2DEXT() failed");
       
   731         return -1;
       
   732     }
       
   733     return 0;
       
   734 }
       
   735 
       
   736 static int
   780 GL_UpdateViewport(SDL_Renderer * renderer)
   737 GL_UpdateViewport(SDL_Renderer * renderer)
   781 {
   738 {
   782     GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
   739     GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
   783 
   740 
   784     if (SDL_CurrentContext != data->context) {
   741     if (SDL_CurrentContext != data->context) {
   789     data->glViewport(renderer->viewport.x, renderer->viewport.y,
   746     data->glViewport(renderer->viewport.x, renderer->viewport.y,
   790                      renderer->viewport.w, renderer->viewport.h);
   747                      renderer->viewport.w, renderer->viewport.h);
   791 
   748 
   792     data->glMatrixMode(GL_PROJECTION);
   749     data->glMatrixMode(GL_PROJECTION);
   793     data->glLoadIdentity();
   750     data->glLoadIdentity();
   794     data->glOrtho((GLdouble) 0,
   751     if (renderer->target) {
   795                   (GLdouble) renderer->viewport.w,
   752         data->glOrtho((GLdouble) 0,
   796                   (GLdouble) renderer->viewport.h,
   753                       (GLdouble) renderer->viewport.w,
   797                   (GLdouble) 0, 0.0, 1.0);
   754                       (GLdouble) 0,
       
   755                       (GLdouble) renderer->viewport.h,
       
   756                        0.0, 1.0);
       
   757     } else {
       
   758         data->glOrtho((GLdouble) 0,
       
   759                       (GLdouble) renderer->viewport.w,
       
   760                       (GLdouble) renderer->viewport.h,
       
   761                       (GLdouble) 0,
       
   762                        0.0, 1.0);
       
   763     }
   798     return 0;
   764     return 0;
   799 }
   765 }
   800 
   766 
   801 static void
   767 static void
   802 GL_SetShader(GL_RenderData * data, GL_Shader shader)
   768 GL_SetShader(GL_RenderData * data, GL_Shader shader)