src/render/opengl/SDL_render_gl.c
changeset 5264 7ace5f8f432f
parent 5262 b530ef003506
child 5265 48724afcdc6e
equal deleted inserted replaced
5263:e1122f31fec5 5264:7ace5f8f432f
   117     GLenum format;
   117     GLenum format;
   118     GLenum formattype;
   118     GLenum formattype;
   119     void *pixels;
   119     void *pixels;
   120     int pitch;
   120     int pitch;
   121     SDL_Rect locked_rect;
   121     SDL_Rect locked_rect;
       
   122 
       
   123     /* YV12 texture support */
       
   124     SDL_bool yuv;
       
   125     GLuint utexture;
       
   126     GLuint vtexture;
   122 } GL_TextureData;
   127 } GL_TextureData;
   123 
   128 
   124 
   129 
   125 static void
   130 static void
   126 GL_SetError(const char *prefix, GLenum result)
   131 GL_SetError(const char *prefix, GLenum result)
   290         data->shaders = GL_CreateShaderContext();
   295         data->shaders = GL_CreateShaderContext();
   291     }
   296     }
   292     SDL_LogInfo(SDL_LOG_CATEGORY_RENDER, "OpenGL shaders: %s",
   297     SDL_LogInfo(SDL_LOG_CATEGORY_RENDER, "OpenGL shaders: %s",
   293                 data->shaders ? "ENABLED" : "DISABLED");
   298                 data->shaders ? "ENABLED" : "DISABLED");
   294 
   299 
   295 #if 0
       
   296     /* We support YV12 textures using 3 textures and a shader */
   300     /* We support YV12 textures using 3 textures and a shader */
   297     if (data->shaders && data->num_texture_units >= 3) {
   301     if (data->shaders && data->num_texture_units >= 3) {
   298         renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_YV12;
   302         renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_YV12;
   299     }
   303         renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_IYUV;
   300 #endif
   304     }
   301 
   305 
   302     /* Set up parameters for rendering */
   306     /* Set up parameters for rendering */
   303     data->blendMode = -1;
   307     data->blendMode = -1;
   304     data->glDisable(GL_DEPTH_TEST);
   308     data->glDisable(GL_DEPTH_TEST);
   305     data->glDisable(GL_CULL_FACE);
   309     data->glDisable(GL_CULL_FACE);
   370     case SDL_PIXELFORMAT_ARGB8888:
   374     case SDL_PIXELFORMAT_ARGB8888:
   371         *internalFormat = GL_RGBA8;
   375         *internalFormat = GL_RGBA8;
   372         *format = GL_BGRA;
   376         *format = GL_BGRA;
   373         *type = GL_UNSIGNED_INT_8_8_8_8_REV;
   377         *type = GL_UNSIGNED_INT_8_8_8_8_REV;
   374         break;
   378         break;
       
   379     case SDL_PIXELFORMAT_YV12:
       
   380     case SDL_PIXELFORMAT_IYUV:
       
   381         *internalFormat = GL_LUMINANCE;
       
   382         *format = GL_LUMINANCE;
       
   383         *type = GL_UNSIGNED_BYTE;
       
   384         break;
   375     default:
   385     default:
   376         return SDL_FALSE;
   386         return SDL_FALSE;
   377     }
   387     }
   378     return SDL_TRUE;
   388     return SDL_TRUE;
   379 }
   389 }
   402         SDL_OutOfMemory();
   412         SDL_OutOfMemory();
   403         return -1;
   413         return -1;
   404     }
   414     }
   405 
   415 
   406     if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
   416     if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
       
   417         size_t size;
   407         data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
   418         data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
   408         data->pixels = SDL_malloc(texture->h * data->pitch);
   419         size = texture->h * data->pitch;
       
   420         if (texture->format == SDL_PIXELFORMAT_YV12 ||
       
   421             texture->format == SDL_PIXELFORMAT_IYUV) {
       
   422             /* Need to add size for the U and V planes */
       
   423             size += (2 * (texture->h * data->pitch) / 4);
       
   424         }
       
   425         data->pixels = SDL_malloc(size);
   409         if (!data->pixels) {
   426         if (!data->pixels) {
   410             SDL_OutOfMemory();
   427             SDL_OutOfMemory();
   411             SDL_free(data);
   428             SDL_free(data);
   412             return -1;
   429             return -1;
   413         }
   430         }
   476     result = renderdata->glGetError();
   493     result = renderdata->glGetError();
   477     if (result != GL_NO_ERROR) {
   494     if (result != GL_NO_ERROR) {
   478         GL_SetError("glTexImage2D()", result);
   495         GL_SetError("glTexImage2D()", result);
   479         return -1;
   496         return -1;
   480     }
   497     }
       
   498 
       
   499     if (texture->format == SDL_PIXELFORMAT_YV12 ||
       
   500         texture->format == SDL_PIXELFORMAT_IYUV) {
       
   501         data->yuv = SDL_TRUE;
       
   502 
       
   503         renderdata->glGenTextures(1, &data->utexture);
       
   504         renderdata->glGenTextures(1, &data->vtexture);
       
   505         renderdata->glEnable(data->type);
       
   506 
       
   507         renderdata->glBindTexture(data->type, data->utexture);
       
   508         renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER,
       
   509                                     GL_LINEAR);
       
   510         renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER,
       
   511                                     GL_LINEAR);
       
   512         renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S,
       
   513                                     GL_CLAMP_TO_EDGE);
       
   514         renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T,
       
   515                                     GL_CLAMP_TO_EDGE);
       
   516         renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w/2,
       
   517                                  texture_h/2, 0, format, type, NULL);
       
   518 
       
   519         renderdata->glBindTexture(data->type, data->vtexture);
       
   520         renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER,
       
   521                                     GL_LINEAR);
       
   522         renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER,
       
   523                                     GL_LINEAR);
       
   524         renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S,
       
   525                                     GL_CLAMP_TO_EDGE);
       
   526         renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T,
       
   527                                     GL_CLAMP_TO_EDGE);
       
   528         renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w/2,
       
   529                                  texture_h/2, 0, format, type, NULL);
       
   530 
       
   531         renderdata->glDisable(data->type);
       
   532     }
   481     return 0;
   533     return 0;
   482 }
   534 }
   483 
   535 
   484 static int
   536 static int
   485 GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
   537 GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
   498     renderdata->glEnable(data->type);
   550     renderdata->glEnable(data->type);
   499     renderdata->glBindTexture(data->type, data->texture);
   551     renderdata->glBindTexture(data->type, data->texture);
   500     renderdata->glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w,
   552     renderdata->glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w,
   501                                 rect->h, data->format, data->formattype,
   553                                 rect->h, data->format, data->formattype,
   502                                 pixels);
   554                                 pixels);
       
   555     if (data->yuv) {
       
   556         /* Skip to the top of the next texture */
       
   557         const void *top = (const void*)((const Uint8*)pixels + (texture->h-rect->y) * pitch - rect->x);
       
   558 
       
   559         /* Skip to the correct offset into the next texture */
       
   560         pixels = (const void*)((const Uint8*)top + (rect->y / 2) * pitch + rect->x / 2);
       
   561         if (texture->format == SDL_PIXELFORMAT_YV12) {
       
   562             renderdata->glBindTexture(data->type, data->vtexture);
       
   563         } else {
       
   564             renderdata->glBindTexture(data->type, data->utexture);
       
   565         }
       
   566         renderdata->glTexSubImage2D(data->type, 0, rect->x/2, rect->y/2,
       
   567                                     rect->w/2, rect->h/2,
       
   568                                     data->format, data->formattype, pixels);
       
   569 
       
   570         /* Skip to the top of the next texture */
       
   571         top = (const void*)((const Uint8*)top + (texture->h * pitch)/4);
       
   572 
       
   573         /* Skip to the correct offset into the next texture */
       
   574         pixels = (const void*)((const Uint8*)top + (rect->y / 2) * pitch + rect->x / 2);
       
   575         if (texture->format == SDL_PIXELFORMAT_YV12) {
       
   576             renderdata->glBindTexture(data->type, data->utexture);
       
   577         } else {
       
   578             renderdata->glBindTexture(data->type, data->vtexture);
       
   579         }
       
   580         renderdata->glTexSubImage2D(data->type, 0, rect->x/2, rect->y/2,
       
   581                                     rect->w/2, rect->h/2,
       
   582                                     data->format, data->formattype, pixels);
       
   583     }
   503     renderdata->glDisable(data->type);
   584     renderdata->glDisable(data->type);
   504     result = renderdata->glGetError();
   585     result = renderdata->glGetError();
   505     if (result != GL_NO_ERROR) {
   586     if (result != GL_NO_ERROR) {
   506         GL_SetError("glTexSubImage2D()", result);
   587         GL_SetError("glTexSubImage2D()", result);
   507         return -1;
   588         return -1;
   748     minv *= texturedata->texh;
   829     minv *= texturedata->texh;
   749     maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h;
   830     maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h;
   750     maxv *= texturedata->texh;
   831     maxv *= texturedata->texh;
   751 
   832 
   752     data->glEnable(texturedata->type);
   833     data->glEnable(texturedata->type);
       
   834     if (texturedata->yuv) {
       
   835         data->glActiveTextureARB(GL_TEXTURE2_ARB);
       
   836         data->glBindTexture(texturedata->type, texturedata->vtexture);
       
   837         data->glActiveTextureARB(GL_TEXTURE1_ARB);
       
   838         data->glBindTexture(texturedata->type, texturedata->utexture);
       
   839         data->glActiveTextureARB(GL_TEXTURE0_ARB);
       
   840     }
   753     data->glBindTexture(texturedata->type, texturedata->texture);
   841     data->glBindTexture(texturedata->type, texturedata->texture);
   754 
   842 
   755     if (texture->modMode) {
   843     if (texture->modMode) {
   756         data->glColor4f((GLfloat) texture->r * inv255f,
   844         data->glColor4f((GLfloat) texture->r * inv255f,
   757                         (GLfloat) texture->g * inv255f,
   845                         (GLfloat) texture->g * inv255f,
   760     } else {
   848     } else {
   761         data->glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
   849         data->glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
   762     }
   850     }
   763 
   851 
   764     GL_SetBlendMode(data, texture->blendMode);
   852     GL_SetBlendMode(data, texture->blendMode);
   765     GL_SelectShader(data->shaders, SHADER_RGB);
   853     if (texturedata->yuv) {
       
   854         GL_SelectShader(data->shaders, SHADER_YV12);
       
   855     } else {
       
   856         GL_SelectShader(data->shaders, SHADER_RGB);
       
   857     }
   766 
   858 
   767     data->glBegin(GL_TRIANGLE_STRIP);
   859     data->glBegin(GL_TRIANGLE_STRIP);
   768     data->glTexCoord2f(minu, minv);
   860     data->glTexCoord2f(minu, minv);
   769     data->glVertex2f((GLfloat) minx, (GLfloat) miny);
   861     data->glVertex2f((GLfloat) minx, (GLfloat) miny);
   770     data->glTexCoord2f(maxu, minv);
   862     data->glTexCoord2f(maxu, minv);
   846         return;
   938         return;
   847     }
   939     }
   848     if (data->texture) {
   940     if (data->texture) {
   849         renderdata->glDeleteTextures(1, &data->texture);
   941         renderdata->glDeleteTextures(1, &data->texture);
   850     }
   942     }
       
   943     if (data->yuv) {
       
   944         renderdata->glDeleteTextures(1, &data->utexture);
       
   945         renderdata->glDeleteTextures(1, &data->vtexture);
       
   946     }
   851     if (data->pixels) {
   947     if (data->pixels) {
   852         SDL_free(data->pixels);
   948         SDL_free(data->pixels);
   853     }
   949     }
   854     SDL_free(data);
   950     SDL_free(data);
   855     texture->driverdata = NULL;
   951     texture->driverdata = NULL;