From 5aef89b163cd608719de22b57f51f22e6350087a Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 29 Dec 2011 05:11:33 -0500 Subject: [PATCH] Fixed bug 1335 - Added support for different pixel formats in OpenGL ES 2 renderer Gueniffey 2011-11-23 04:06:31 PST The attached patch adds native support for SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_RGB888, SDL_PIXELFORMAT_BGR888 --- src/render/opengles2/SDL_render_gles2.c | 48 +++- src/render/opengles2/SDL_shaders_gles2.c | 287 +++++++++++++++++++++-- src/render/opengles2/SDL_shaders_gles2.h | 5 +- 3 files changed, 307 insertions(+), 33 deletions(-) diff --git a/src/render/opengles2/SDL_render_gles2.c b/src/render/opengles2/SDL_render_gles2.c index 0122a298d..54002e397 100644 --- a/src/render/opengles2/SDL_render_gles2.c +++ b/src/render/opengles2/SDL_render_gles2.c @@ -38,8 +38,11 @@ SDL_RenderDriver GLES2_RenderDriver = { { "opengles2", (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC), - 1, - {SDL_PIXELFORMAT_ABGR8888}, + 4, + {SDL_PIXELFORMAT_ABGR8888, + SDL_PIXELFORMAT_ARGB8888, + SDL_PIXELFORMAT_RGB888, + SDL_PIXELFORMAT_BGR888}, 0, 0 } @@ -111,7 +114,10 @@ typedef enum typedef enum { GLES2_IMAGESOURCE_SOLID, - GLES2_IMAGESOURCE_TEXTURE + GLES2_IMAGESOURCE_TEXTURE_ABGR, + GLES2_IMAGESOURCE_TEXTURE_ARGB, + GLES2_IMAGESOURCE_TEXTURE_RGB, + GLES2_IMAGESOURCE_TEXTURE_BGR } GLES2_ImageSource; typedef struct GLES2_DriverContext @@ -272,6 +278,9 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) switch (texture->format) { case SDL_PIXELFORMAT_ABGR8888: + case SDL_PIXELFORMAT_ARGB8888: + case SDL_PIXELFORMAT_BGR888: + case SDL_PIXELFORMAT_RGB888: format = GL_RGBA; type = GL_UNSIGNED_BYTE; break; @@ -635,7 +644,7 @@ GLES2_CacheShader(SDL_Renderer *renderer, GLES2_ShaderType type, SDL_BlendMode b if (glGetError() != GL_NO_ERROR || !compileSuccessful) { char *info = NULL; - int length; + int length = 0; glGetShaderiv(entry->id, GL_INFO_LOG_LENGTH, &length); if (length > 0) { @@ -701,9 +710,20 @@ GLES2_SelectProgram(SDL_Renderer *renderer, GLES2_ImageSource source, SDL_BlendM case GLES2_IMAGESOURCE_SOLID: ftype = GLES2_SHADER_FRAGMENT_SOLID_SRC; break; - case GLES2_IMAGESOURCE_TEXTURE: - ftype = GLES2_SHADER_FRAGMENT_TEXTURE_SRC; + case GLES2_IMAGESOURCE_TEXTURE_ABGR: + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_ABGR_SRC; + break; + case GLES2_IMAGESOURCE_TEXTURE_ARGB: + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_ARGB_SRC; + break; + case GLES2_IMAGESOURCE_TEXTURE_RGB: + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_RGB_SRC; + break; + case GLES2_IMAGESOURCE_TEXTURE_BGR: + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_BGR_SRC; break; + default: + goto fault; } /* Load the requested shaders */ @@ -1015,7 +1035,21 @@ GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *s /* Activate an appropriate shader and set the projection matrix */ blendMode = texture->blendMode; - sourceType = GLES2_IMAGESOURCE_TEXTURE; + switch (texture->format) + { + case SDL_PIXELFORMAT_ABGR8888: + sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR; + break; + case SDL_PIXELFORMAT_ARGB8888: + sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB; + break; + case SDL_PIXELFORMAT_BGR888: + sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR; + break; + case SDL_PIXELFORMAT_RGB888: + sourceType = GLES2_IMAGESOURCE_TEXTURE_RGB; + break; + } if (GLES2_SelectProgram(renderer, sourceType, blendMode) < 0) return -1; diff --git a/src/render/opengles2/SDL_shaders_gles2.c b/src/render/opengles2/SDL_shaders_gles2.c index e82716b14..b7b323037 100644 --- a/src/render/opengles2/SDL_shaders_gles2.c +++ b/src/render/opengles2/SDL_shaders_gles2.c @@ -55,7 +55,7 @@ static const Uint8 GLES2_FragmentSrc_SolidSrc_[] = " \ } \ "; -static const Uint8 GLES2_FragmentSrc_TextureSrc_[] = " \ +static const Uint8 GLES2_FragmentSrc_TextureABGRSrc_[] = " \ precision mediump float; \ uniform sampler2D u_texture; \ uniform vec4 u_modulation; \ @@ -68,6 +68,57 @@ static const Uint8 GLES2_FragmentSrc_TextureSrc_[] = " \ } \ "; +// ARGB to ABGR conversion +static const Uint8 GLES2_FragmentSrc_TextureARGBSrc_[] = " \ + precision mediump float; \ + uniform sampler2D u_texture; \ + uniform vec4 u_modulation; \ + varying vec2 v_texCoord; \ + \ + void main() \ + { \ + vec4 abgr = texture2D(u_texture, v_texCoord); \ + gl_FragColor = abgr; \ + gl_FragColor.r = abgr.b; \ + gl_FragColor.b = abgr.r; \ + gl_FragColor *= u_modulation; \ + } \ +"; + +// RGB to ABGR conversion +static const Uint8 GLES2_FragmentSrc_TextureRGBSrc_[] = " \ + precision mediump float; \ + uniform sampler2D u_texture; \ + uniform vec4 u_modulation; \ + varying vec2 v_texCoord; \ + \ + void main() \ + { \ + vec4 abgr = texture2D(u_texture, v_texCoord); \ + gl_FragColor = abgr; \ + gl_FragColor.r = abgr.b; \ + gl_FragColor.b = abgr.r; \ + gl_FragColor.a = 1.0; \ + gl_FragColor *= u_modulation; \ + } \ +"; + +// BGR to ABGR conversion +static const Uint8 GLES2_FragmentSrc_TextureBGRSrc_[] = " \ + precision mediump float; \ + uniform sampler2D u_texture; \ + uniform vec4 u_modulation; \ + varying vec2 v_texCoord; \ + \ + void main() \ + { \ + vec4 abgr = texture2D(u_texture, v_texCoord); \ + gl_FragColor = abgr; \ + gl_FragColor.a = 1.0; \ + gl_FragColor *= u_modulation; \ + } \ +"; + static const GLES2_ShaderInstance GLES2_VertexSrc_Default = { GL_VERTEX_SHADER, GLES2_SOURCE_SHADER, @@ -82,11 +133,32 @@ static const GLES2_ShaderInstance GLES2_FragmentSrc_SolidSrc = { GLES2_FragmentSrc_SolidSrc_ }; -static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureSrc = { +static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureABGRSrc = { GL_FRAGMENT_SHADER, GLES2_SOURCE_SHADER, - sizeof(GLES2_FragmentSrc_TextureSrc_), - GLES2_FragmentSrc_TextureSrc_ + sizeof(GLES2_FragmentSrc_TextureABGRSrc_), + GLES2_FragmentSrc_TextureABGRSrc_ +}; + +static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureARGBSrc = { + GL_FRAGMENT_SHADER, + GLES2_SOURCE_SHADER, + sizeof(GLES2_FragmentSrc_TextureARGBSrc_), + GLES2_FragmentSrc_TextureARGBSrc_ +}; + +static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureRGBSrc = { + GL_FRAGMENT_SHADER, + GLES2_SOURCE_SHADER, + sizeof(GLES2_FragmentSrc_TextureRGBSrc_), + GLES2_FragmentSrc_TextureRGBSrc_ +}; + +static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureBGRSrc = { + GL_FRAGMENT_SHADER, + GLES2_SOURCE_SHADER, + sizeof(GLES2_FragmentSrc_TextureBGRSrc_), + GLES2_FragmentSrc_TextureBGRSrc_ }; /************************************************************************************************* @@ -404,7 +476,11 @@ static const GLES2_ShaderInstance GLES2_FragmentTegra_Modulated_TextureSrc = { *************************************************************************************************/ static GLES2_Shader GLES2_VertexShader_Default = { +#if GLES2_INCLUDE_NVIDIA_SHADERS 2, +#else + 1, +#endif { #if GLES2_INCLUDE_NVIDIA_SHADERS &GLES2_VertexTegra_Default, @@ -414,7 +490,11 @@ static GLES2_Shader GLES2_VertexShader_Default = { }; static GLES2_Shader GLES2_FragmentShader_None_SolidSrc = { +#if GLES2_INCLUDE_NVIDIA_SHADERS 2, +#else + 1, +#endif { #if GLES2_INCLUDE_NVIDIA_SHADERS &GLES2_FragmentTegra_None_SolidSrc, @@ -424,7 +504,11 @@ static GLES2_Shader GLES2_FragmentShader_None_SolidSrc = { }; static GLES2_Shader GLES2_FragmentShader_Alpha_SolidSrc = { +#if GLES2_INCLUDE_NVIDIA_SHADERS 2, +#else + 1, +#endif { #if GLES2_INCLUDE_NVIDIA_SHADERS &GLES2_FragmentTegra_Alpha_SolidSrc, @@ -434,7 +518,11 @@ static GLES2_Shader GLES2_FragmentShader_Alpha_SolidSrc = { }; static GLES2_Shader GLES2_FragmentShader_Additive_SolidSrc = { +#if GLES2_INCLUDE_NVIDIA_SHADERS 2, +#else + 1, +#endif { #if GLES2_INCLUDE_NVIDIA_SHADERS &GLES2_FragmentTegra_Additive_SolidSrc, @@ -444,7 +532,11 @@ static GLES2_Shader GLES2_FragmentShader_Additive_SolidSrc = { }; static GLES2_Shader GLES2_FragmentShader_Modulated_SolidSrc = { +#if GLES2_INCLUDE_NVIDIA_SHADERS 2, +#else + 1, +#endif { #if GLES2_INCLUDE_NVIDIA_SHADERS &GLES2_FragmentTegra_Modulated_SolidSrc, @@ -453,43 +545,143 @@ static GLES2_Shader GLES2_FragmentShader_Modulated_SolidSrc = { } }; -static GLES2_Shader GLES2_FragmentShader_None_TextureSrc = { +static GLES2_Shader GLES2_FragmentShader_None_TextureABGRSrc = { +#if GLES2_INCLUDE_NVIDIA_SHADERS 2, +#else + 1, +#endif { #if GLES2_INCLUDE_NVIDIA_SHADERS &GLES2_FragmentTegra_None_TextureSrc, #endif - &GLES2_FragmentSrc_TextureSrc + &GLES2_FragmentSrc_TextureABGRSrc } }; -static GLES2_Shader GLES2_FragmentShader_Alpha_TextureSrc = { +static GLES2_Shader GLES2_FragmentShader_Alpha_TextureABGRSrc = { +#if GLES2_INCLUDE_NVIDIA_SHADERS 2, +#else + 1, +#endif { #if GLES2_INCLUDE_NVIDIA_SHADERS &GLES2_FragmentTegra_Alpha_TextureSrc, #endif - &GLES2_FragmentSrc_TextureSrc + &GLES2_FragmentSrc_TextureABGRSrc } }; -static GLES2_Shader GLES2_FragmentShader_Additive_TextureSrc = { +static GLES2_Shader GLES2_FragmentShader_Additive_TextureABGRSrc = { +#if GLES2_INCLUDE_NVIDIA_SHADERS 2, +#else + 1, +#endif { #if GLES2_INCLUDE_NVIDIA_SHADERS &GLES2_FragmentTegra_Additive_TextureSrc, #endif - &GLES2_FragmentSrc_TextureSrc + &GLES2_FragmentSrc_TextureABGRSrc } }; -static GLES2_Shader GLES2_FragmentShader_Modulated_TextureSrc = { +static GLES2_Shader GLES2_FragmentShader_Modulated_TextureABGRSrc = { +#if GLES2_INCLUDE_NVIDIA_SHADERS 2, +#else + 1, +#endif { #if GLES2_INCLUDE_NVIDIA_SHADERS &GLES2_FragmentTegra_Modulated_TextureSrc, #endif - &GLES2_FragmentSrc_TextureSrc + &GLES2_FragmentSrc_TextureABGRSrc + } +}; + +static GLES2_Shader GLES2_FragmentShader_None_TextureARGBSrc = { + 1, + { + &GLES2_FragmentSrc_TextureARGBSrc + } +}; + +static GLES2_Shader GLES2_FragmentShader_Alpha_TextureARGBSrc = { + 1, + { + &GLES2_FragmentSrc_TextureARGBSrc + } +}; + +static GLES2_Shader GLES2_FragmentShader_Additive_TextureARGBSrc = { + 1, + { + &GLES2_FragmentSrc_TextureARGBSrc + } +}; + +static GLES2_Shader GLES2_FragmentShader_Modulated_TextureARGBSrc = { + 1, + { + &GLES2_FragmentSrc_TextureARGBSrc + } +}; + +static GLES2_Shader GLES2_FragmentShader_None_TextureRGBSrc = { + 1, + { + &GLES2_FragmentSrc_TextureRGBSrc + } +}; + +static GLES2_Shader GLES2_FragmentShader_Alpha_TextureRGBSrc = { + 1, + { + &GLES2_FragmentSrc_TextureRGBSrc + } +}; + +static GLES2_Shader GLES2_FragmentShader_Additive_TextureRGBSrc = { + 1, + { + &GLES2_FragmentSrc_TextureRGBSrc + } +}; + +static GLES2_Shader GLES2_FragmentShader_Modulated_TextureRGBSrc = { + 1, + { + &GLES2_FragmentSrc_TextureRGBSrc + } +}; + +static GLES2_Shader GLES2_FragmentShader_None_TextureBGRSrc = { + 1, + { + &GLES2_FragmentSrc_TextureBGRSrc + } +}; + +static GLES2_Shader GLES2_FragmentShader_Alpha_TextureBGRSrc = { + 1, + { + &GLES2_FragmentSrc_TextureBGRSrc + } +}; + +static GLES2_Shader GLES2_FragmentShader_Additive_TextureBGRSrc = { + 1, + { + &GLES2_FragmentSrc_TextureBGRSrc + } +}; + +static GLES2_Shader GLES2_FragmentShader_Modulated_TextureBGRSrc = { + 1, + { + &GLES2_FragmentSrc_TextureBGRSrc } }; @@ -504,33 +696,78 @@ const GLES2_Shader *GLES2_GetShader(GLES2_ShaderType type, SDL_BlendMode blendMo case GLES2_SHADER_VERTEX_DEFAULT: return &GLES2_VertexShader_Default; case GLES2_SHADER_FRAGMENT_SOLID_SRC: + switch (blendMode) + { + case SDL_BLENDMODE_NONE: + return &GLES2_FragmentShader_None_SolidSrc; + case SDL_BLENDMODE_BLEND: + return &GLES2_FragmentShader_Alpha_SolidSrc; + case SDL_BLENDMODE_ADD: + return &GLES2_FragmentShader_Additive_SolidSrc; + case SDL_BLENDMODE_MOD: + return &GLES2_FragmentShader_Modulated_SolidSrc; + default: + return NULL; + } + case GLES2_SHADER_FRAGMENT_TEXTURE_ABGR_SRC: + switch (blendMode) + { + case SDL_BLENDMODE_NONE: + return &GLES2_FragmentShader_None_TextureABGRSrc; + case SDL_BLENDMODE_BLEND: + return &GLES2_FragmentShader_Alpha_TextureABGRSrc; + case SDL_BLENDMODE_ADD: + return &GLES2_FragmentShader_Additive_TextureABGRSrc; + case SDL_BLENDMODE_MOD: + return &GLES2_FragmentShader_Modulated_TextureABGRSrc; + default: + return NULL; + } + case GLES2_SHADER_FRAGMENT_TEXTURE_ARGB_SRC: switch (blendMode) - { + { case SDL_BLENDMODE_NONE: - return &GLES2_FragmentShader_None_SolidSrc; + return &GLES2_FragmentShader_None_TextureARGBSrc; case SDL_BLENDMODE_BLEND: - return &GLES2_FragmentShader_Alpha_SolidSrc; + return &GLES2_FragmentShader_Alpha_TextureARGBSrc; case SDL_BLENDMODE_ADD: - return &GLES2_FragmentShader_Additive_SolidSrc; + return &GLES2_FragmentShader_Additive_TextureARGBSrc; case SDL_BLENDMODE_MOD: - return &GLES2_FragmentShader_Modulated_SolidSrc; + return &GLES2_FragmentShader_Modulated_TextureARGBSrc; default: return NULL; - } - case GLES2_SHADER_FRAGMENT_TEXTURE_SRC: + } + + case GLES2_SHADER_FRAGMENT_TEXTURE_RGB_SRC: switch (blendMode) - { + { case SDL_BLENDMODE_NONE: - return &GLES2_FragmentShader_None_TextureSrc; + return &GLES2_FragmentShader_None_TextureRGBSrc; case SDL_BLENDMODE_BLEND: - return &GLES2_FragmentShader_Alpha_TextureSrc; + return &GLES2_FragmentShader_Alpha_TextureRGBSrc; case SDL_BLENDMODE_ADD: - return &GLES2_FragmentShader_Additive_TextureSrc; + return &GLES2_FragmentShader_Additive_TextureRGBSrc; case SDL_BLENDMODE_MOD: - return &GLES2_FragmentShader_Modulated_TextureSrc; + return &GLES2_FragmentShader_Modulated_TextureRGBSrc; default: return NULL; - } + } + + case GLES2_SHADER_FRAGMENT_TEXTURE_BGR_SRC: + switch (blendMode) + { + case SDL_BLENDMODE_NONE: + return &GLES2_FragmentShader_None_TextureBGRSrc; + case SDL_BLENDMODE_BLEND: + return &GLES2_FragmentShader_Alpha_TextureBGRSrc; + case SDL_BLENDMODE_ADD: + return &GLES2_FragmentShader_Additive_TextureBGRSrc; + case SDL_BLENDMODE_MOD: + return &GLES2_FragmentShader_Modulated_TextureBGRSrc; + default: + return NULL; + } + default: return NULL; } diff --git a/src/render/opengles2/SDL_shaders_gles2.h b/src/render/opengles2/SDL_shaders_gles2.h index c34d7e587..ef482c4a0 100644 --- a/src/render/opengles2/SDL_shaders_gles2.h +++ b/src/render/opengles2/SDL_shaders_gles2.h @@ -43,7 +43,10 @@ typedef enum { GLES2_SHADER_VERTEX_DEFAULT, GLES2_SHADER_FRAGMENT_SOLID_SRC, - GLES2_SHADER_FRAGMENT_TEXTURE_SRC + GLES2_SHADER_FRAGMENT_TEXTURE_ABGR_SRC, + GLES2_SHADER_FRAGMENT_TEXTURE_ARGB_SRC, + GLES2_SHADER_FRAGMENT_TEXTURE_BGR_SRC, + GLES2_SHADER_FRAGMENT_TEXTURE_RGB_SRC } GLES2_ShaderType; #define GLES2_SOURCE_SHADER (GLenum)-1