src/render/opengl/SDL_render_gl.c
changeset 6494 309599be5c2a
parent 6449 fa00544b1374
child 6499 a34024340f54
equal deleted inserted replaced
6493:6801ced90deb 6494:309599be5c2a
   148     GLuint vtexture;
   148     GLuint vtexture;
   149     
   149     
   150     GL_FBOList *fbo;
   150     GL_FBOList *fbo;
   151 } GL_TextureData;
   151 } GL_TextureData;
   152 
   152 
   153 
   153 static inline const char*
   154 static void
   154 GL_TranslateError (GLenum error)
   155 GL_SetError(const char *prefix, GLenum result)
   155 {
   156 {
   156 #define GL_ERROR_TRANSLATE(e) case e: return #e;
   157     const char *error;
   157     switch (error) {
   158 
   158     GL_ERROR_TRANSLATE(GL_INVALID_ENUM)
   159     switch (result) {
   159     GL_ERROR_TRANSLATE(GL_INVALID_VALUE)
   160     case GL_NO_ERROR:
   160     GL_ERROR_TRANSLATE(GL_INVALID_OPERATION)
   161         error = "GL_NO_ERROR";
   161     GL_ERROR_TRANSLATE(GL_OUT_OF_MEMORY)
   162         break;
   162     GL_ERROR_TRANSLATE(GL_NO_ERROR)
   163     case GL_INVALID_ENUM:
   163     GL_ERROR_TRANSLATE(GL_STACK_OVERFLOW)
   164         error = "GL_INVALID_ENUM";
   164     GL_ERROR_TRANSLATE(GL_STACK_UNDERFLOW)
   165         break;
   165     GL_ERROR_TRANSLATE(GL_TABLE_TOO_LARGE)
   166     case GL_INVALID_VALUE:
       
   167         error = "GL_INVALID_VALUE";
       
   168         break;
       
   169     case GL_INVALID_OPERATION:
       
   170         error = "GL_INVALID_OPERATION";
       
   171         break;
       
   172     case GL_STACK_OVERFLOW:
       
   173         error = "GL_STACK_OVERFLOW";
       
   174         break;
       
   175     case GL_STACK_UNDERFLOW:
       
   176         error = "GL_STACK_UNDERFLOW";
       
   177         break;
       
   178     case GL_OUT_OF_MEMORY:
       
   179         error = "GL_OUT_OF_MEMORY";
       
   180         break;
       
   181     case GL_TABLE_TOO_LARGE:
       
   182         error = "GL_TABLE_TOO_LARGE";
       
   183         break;
       
   184     default:
   166     default:
   185         error = "UNKNOWN";
   167         return "UNKNOWN";
   186         break;
   168 }
   187     }
   169 #undef GL_ERROR_TRANSLATE
   188     SDL_SetError("%s: %s", prefix, error);
   170 }
   189 }
   171 
       
   172 static __inline__ int
       
   173 GL_CheckAllErrors (const char *prefix, SDL_Renderer * renderer, const char *file, int line, const char *function)
       
   174 {
       
   175     GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
       
   176     int ret = 0;
       
   177     /* check gl errors (can return multiple errors) */
       
   178     for (;;) {
       
   179         GLenum error = data->glGetError();
       
   180         if (error != GL_NO_ERROR) {
       
   181             if (prefix == NULL || prefix[0] == '\0') {
       
   182                 prefix = "generic";
       
   183             }
       
   184             SDL_SetError("%s: %s (%d): %s %s (0x%X)", prefix, file, line, function, GL_TranslateError(error), error);
       
   185             ret++;
       
   186         } else {
       
   187             break;
       
   188         }
       
   189     }
       
   190     return ret;
       
   191 }
       
   192 
       
   193 #if 1
       
   194 #define GL_CheckError(prefix, renderer) GL_CheckAllErrors(prefix, renderer, __FILE__, __LINE__, __PRETTY_FUNCTION__)
       
   195 #else
       
   196 #define GL_CheckError(prefix, renderer)
       
   197 #endif
   190 
   198 
   191 static int
   199 static int
   192 GL_LoadFunctions(GL_RenderData * data)
   200 GL_LoadFunctions(GL_RenderData * data)
   193 {
   201 {
   194 #ifdef __SDL_NOGETPROCADDR__
   202 #ifdef __SDL_NOGETPROCADDR__
   248     /* This ended up causing video discrepancies between OpenGL and Direct3D */
   256     /* This ended up causing video discrepancies between OpenGL and Direct3D */
   249     /*data->glEnable(GL_LINE_SMOOTH);*/
   257     /*data->glEnable(GL_LINE_SMOOTH);*/
   250 
   258 
   251     data->glMatrixMode(GL_MODELVIEW);
   259     data->glMatrixMode(GL_MODELVIEW);
   252     data->glLoadIdentity();
   260     data->glLoadIdentity();
       
   261 
       
   262     GL_CheckError("", renderer);
   253 }
   263 }
   254 
   264 
   255 
   265 
   256 GL_FBOList *
   266 GL_FBOList *
   257 GL_GetFBO(GL_RenderData *data, Uint32 w, Uint32 h)
   267 GL_GetFBO(GL_RenderData *data, Uint32 w, Uint32 h)
   481     GL_TextureData *data;
   491     GL_TextureData *data;
   482     GLint internalFormat;
   492     GLint internalFormat;
   483     GLenum format, type;
   493     GLenum format, type;
   484     int texture_w, texture_h;
   494     int texture_w, texture_h;
   485     GLenum scaleMode;
   495     GLenum scaleMode;
   486     GLenum result;
       
   487 
   496 
   488     GL_ActivateRenderer(renderer);
   497     GL_ActivateRenderer(renderer);
   489 
   498 
   490     if (!convert_format(renderdata, texture->format, &internalFormat,
   499     if (!convert_format(renderdata, texture->format, &internalFormat,
   491                         &format, &type)) {
   500                         &format, &type)) {
   523         data->fbo = GL_GetFBO(renderdata, texture->w, texture->h);
   532         data->fbo = GL_GetFBO(renderdata, texture->w, texture->h);
   524     } else {
   533     } else {
   525         data->fbo = NULL;
   534         data->fbo = NULL;
   526     }
   535     }
   527 
   536 
   528     renderdata->glGetError();
   537     GL_CheckError("", renderer);
   529     renderdata->glGenTextures(1, &data->texture);
   538     renderdata->glGenTextures(1, &data->texture);
   530     if ((renderdata->GL_ARB_texture_rectangle_supported)
   539     if ((renderdata->GL_ARB_texture_rectangle_supported)
   531         /*&& texture->access != SDL_TEXTUREACCESS_TARGET*/){
   540         /*&& texture->access != SDL_TEXTUREACCESS_TARGET*/){
   532         data->type = GL_TEXTURE_RECTANGLE_ARB;
   541         data->type = GL_TEXTURE_RECTANGLE_ARB;
   533         texture_w = texture->w;
   542         texture_w = texture->w;
   591     {
   600     {
   592         renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w,
   601         renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w,
   593                                  texture_h, 0, format, type, NULL);
   602                                  texture_h, 0, format, type, NULL);
   594     }
   603     }
   595     renderdata->glDisable(data->type);
   604     renderdata->glDisable(data->type);
   596     result = renderdata->glGetError();
   605     if (GL_CheckError("glTexImage2D()", renderer) > 0) {
   597     if (result != GL_NO_ERROR) {
       
   598         GL_SetError("glTexImage2D()", result);
       
   599         return -1;
   606         return -1;
   600     }
   607     }
   601 
   608 
   602     if (texture->format == SDL_PIXELFORMAT_YV12 ||
   609     if (texture->format == SDL_PIXELFORMAT_YV12 ||
   603         texture->format == SDL_PIXELFORMAT_IYUV) {
   610         texture->format == SDL_PIXELFORMAT_IYUV) {
   631         renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w/2,
   638         renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w/2,
   632                                  texture_h/2, 0, format, type, NULL);
   639                                  texture_h/2, 0, format, type, NULL);
   633 
   640 
   634         renderdata->glDisable(data->type);
   641         renderdata->glDisable(data->type);
   635     }
   642     }
       
   643 
       
   644     GL_CheckError("", renderer);
   636     return 0;
   645     return 0;
   637 }
   646 }
   638 
   647 
   639 static int
   648 static int
   640 GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
   649 GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
   641                  const SDL_Rect * rect, const void *pixels, int pitch)
   650                  const SDL_Rect * rect, const void *pixels, int pitch)
   642 {
   651 {
   643     GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
   652     GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
   644     GL_TextureData *data = (GL_TextureData *) texture->driverdata;
   653     GL_TextureData *data = (GL_TextureData *) texture->driverdata;
   645     GLenum result;
       
   646 
   654 
   647     GL_ActivateRenderer(renderer);
   655     GL_ActivateRenderer(renderer);
   648 
   656 
   649     renderdata->glGetError();
   657     GL_CheckError("", renderer);
   650     renderdata->glEnable(data->type);
   658     renderdata->glEnable(data->type);
   651     renderdata->glBindTexture(data->type, data->texture);
   659     renderdata->glBindTexture(data->type, data->texture);
   652     renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   660     renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   653     renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH,
   661     renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH,
   654                               (pitch / SDL_BYTESPERPIXEL(texture->format)));
   662                               (pitch / SDL_BYTESPERPIXEL(texture->format)));
   679         renderdata->glTexSubImage2D(data->type, 0, rect->x/2, rect->y/2,
   687         renderdata->glTexSubImage2D(data->type, 0, rect->x/2, rect->y/2,
   680                                     rect->w/2, rect->h/2,
   688                                     rect->w/2, rect->h/2,
   681                                     data->format, data->formattype, pixels);
   689                                     data->format, data->formattype, pixels);
   682     }
   690     }
   683     renderdata->glDisable(data->type);
   691     renderdata->glDisable(data->type);
   684     result = renderdata->glGetError();
   692     if (GL_CheckError("glTexSubImage2D()", renderer) > 0) {
   685     if (result != GL_NO_ERROR) {
       
   686         GL_SetError("glTexSubImage2D()", result);
       
   687         return -1;
   693         return -1;
   688     }
   694     }
   689     return 0;
   695     return 0;
   690 }
   696 }
   691 
   697 
   750     GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
   756     GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
   751 
   757 
   752     if (SDL_CurrentContext != data->context) {
   758     if (SDL_CurrentContext != data->context) {
   753         /* We'll update the viewport after we rebind the context */
   759         /* We'll update the viewport after we rebind the context */
   754         return 0;
   760         return 0;
       
   761     }
       
   762 
       
   763     if (!renderer->viewport.w || !renderer->viewport.h) {
       
   764         /* The viewport isn't set up yet, ignore it */
       
   765         return -1;
   755     }
   766     }
   756 
   767 
   757     data->glViewport(renderer->viewport.x, renderer->viewport.y,
   768     data->glViewport(renderer->viewport.x, renderer->viewport.y,
   758                      renderer->viewport.w, renderer->viewport.h);
   769                      renderer->viewport.w, renderer->viewport.h);
   759 
   770 
   770                       (GLdouble) renderer->viewport.w,
   781                       (GLdouble) renderer->viewport.w,
   771                       (GLdouble) renderer->viewport.h,
   782                       (GLdouble) renderer->viewport.h,
   772                       (GLdouble) 0,
   783                       (GLdouble) 0,
   773                        0.0, 1.0);
   784                        0.0, 1.0);
   774     }
   785     }
       
   786     GL_CheckError("", renderer);
   775     return 0;
   787     return 0;
   776 }
   788 }
   777 
   789 
   778 static void
   790 static void
   779 GL_SetShader(GL_RenderData * data, GL_Shader shader)
   791 GL_SetShader(GL_RenderData * data, GL_Shader shader)
   937             data->glVertex2f(0.5f + x2, 0.5f + y2);
   949             data->glVertex2f(0.5f + x2, 0.5f + y2);
   938         }
   950         }
   939 #endif
   951 #endif
   940         data->glEnd();
   952         data->glEnd();
   941     }
   953     }
       
   954     GL_CheckError("", renderer);
   942 
   955 
   943     return 0;
   956     return 0;
   944 }
   957 }
   945 
   958 
   946 static int
   959 static int
   954     for (i = 0; i < count; ++i) {
   967     for (i = 0; i < count; ++i) {
   955         const SDL_Rect *rect = &rects[i];
   968         const SDL_Rect *rect = &rects[i];
   956 
   969 
   957         data->glRecti(rect->x, rect->y, rect->x + rect->w, rect->y + rect->h);
   970         data->glRecti(rect->x, rect->y, rect->x + rect->w, rect->y + rect->h);
   958     }
   971     }
       
   972     GL_CheckError("", renderer);
   959 
   973 
   960     return 0;
   974     return 0;
   961 }
   975 }
   962 
   976 
   963 static int
   977 static int
  1021     data->glTexCoord2f(maxu, maxv);
  1035     data->glTexCoord2f(maxu, maxv);
  1022     data->glVertex2f((GLfloat) maxx, (GLfloat) maxy);
  1036     data->glVertex2f((GLfloat) maxx, (GLfloat) maxy);
  1023     data->glEnd();
  1037     data->glEnd();
  1024 
  1038 
  1025     data->glDisable(texturedata->type);
  1039     data->glDisable(texturedata->type);
       
  1040 
       
  1041     GL_CheckError("", renderer);
  1026 
  1042 
  1027     return 0;
  1043     return 0;
  1028 }
  1044 }
  1029 
  1045 
  1030 static int
  1046 static int
  1112     data->glEnd();
  1128     data->glEnd();
  1113     data->glPopMatrix();
  1129     data->glPopMatrix();
  1114     
  1130     
  1115     data->glDisable(texturedata->type);
  1131     data->glDisable(texturedata->type);
  1116 
  1132 
       
  1133     GL_CheckError("", renderer);
       
  1134 
  1117     return 0;
  1135     return 0;
  1118 }
  1136 }
  1119 
  1137 
  1120 static int
  1138 static int
  1121 GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
  1139 GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
  1149     data->glPixelStorei(GL_PACK_ROW_LENGTH,
  1167     data->glPixelStorei(GL_PACK_ROW_LENGTH,
  1150                         (temp_pitch / SDL_BYTESPERPIXEL(temp_format)));
  1168                         (temp_pitch / SDL_BYTESPERPIXEL(temp_format)));
  1151 
  1169 
  1152     data->glReadPixels(rect->x, (h-rect->y)-rect->h, rect->w, rect->h,
  1170     data->glReadPixels(rect->x, (h-rect->y)-rect->h, rect->w, rect->h,
  1153                        format, type, temp_pixels);
  1171                        format, type, temp_pixels);
       
  1172 
       
  1173     GL_CheckError("", renderer);
  1154 
  1174 
  1155     /* Flip the rows to be top-down */
  1175     /* Flip the rows to be top-down */
  1156     length = rect->w * SDL_BYTESPERPIXEL(temp_format);
  1176     length = rect->w * SDL_BYTESPERPIXEL(temp_format);
  1157     src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch;
  1177     src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch;
  1158     dst = (Uint8*)temp_pixels;
  1178     dst = (Uint8*)temp_pixels;
  1220         if (data->context) {
  1240         if (data->context) {
  1221             while (data->framebuffers) {
  1241             while (data->framebuffers) {
  1222                 GL_FBOList *nextnode = data->framebuffers->next;
  1242                 GL_FBOList *nextnode = data->framebuffers->next;
  1223                 /* delete the framebuffer object */
  1243                 /* delete the framebuffer object */
  1224                 data->glDeleteFramebuffersEXT(1, &data->framebuffers->FBO);
  1244                 data->glDeleteFramebuffersEXT(1, &data->framebuffers->FBO);
       
  1245                 GL_CheckError("", renderer);
  1225                 SDL_free(data->framebuffers);
  1246                 SDL_free(data->framebuffers);
  1226                 data->framebuffers = nextnode;
  1247                 data->framebuffers = nextnode;
  1227             }            
  1248             }            
  1228             /* SDL_GL_MakeCurrent(0, NULL); *//* doesn't do anything */
  1249             /* SDL_GL_MakeCurrent(0, NULL); *//* doesn't do anything */
  1229             SDL_GL_DeleteContext(data->context);
  1250             SDL_GL_DeleteContext(data->context);