Fixed bug 1335 - Added support for different pixel formats in OpenGL ES 2 renderer
authorSam Lantinga <slouken@libsdl.org>
Thu, 29 Dec 2011 05:11:33 -0500
changeset 6113 64742b8c8eb3
parent 6108 f3c34d321289
child 6114 d166819bf2b3
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
src/render/opengles2/SDL_shaders_gles2.c
src/render/opengles2/SDL_shaders_gles2.h
--- a/src/render/opengles2/SDL_render_gles2.c	Fri Dec 09 02:32:21 2011 -0500
+++ b/src/render/opengles2/SDL_render_gles2.c	Thu Dec 29 05:11:33 2011 -0500
@@ -38,8 +38,11 @@
     {
         "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
 {
     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 @@
     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 @@
     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 @@
     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 @@
 
     /* 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;
 
--- a/src/render/opengles2/SDL_shaders_gles2.c	Fri Dec 09 02:32:21 2011 -0500
+++ b/src/render/opengles2/SDL_shaders_gles2.c	Thu Dec 29 05:11:33 2011 -0500
@@ -55,7 +55,7 @@
     } \
 ";
 
-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 @@
     } \
 ";
 
+// 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 @@
     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_TextureABGRSrc_),
+    GLES2_FragmentSrc_TextureABGRSrc_
+};
+
+static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureARGBSrc = {
     GL_FRAGMENT_SHADER,
     GLES2_SOURCE_SHADER,
-    sizeof(GLES2_FragmentSrc_TextureSrc_),
-    GLES2_FragmentSrc_TextureSrc_
+    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 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_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_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_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_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_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 @@
     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_SolidSrc;
+            return &GLES2_FragmentShader_None_TextureABGRSrc;
         case SDL_BLENDMODE_BLEND:
-            return &GLES2_FragmentShader_Alpha_SolidSrc;
+            return &GLES2_FragmentShader_Alpha_TextureABGRSrc;
         case SDL_BLENDMODE_ADD:
-            return &GLES2_FragmentShader_Additive_SolidSrc;
+            return &GLES2_FragmentShader_Additive_TextureABGRSrc;
         case SDL_BLENDMODE_MOD:
-            return &GLES2_FragmentShader_Modulated_SolidSrc;
+            return &GLES2_FragmentShader_Modulated_TextureABGRSrc;
         default:
             return NULL;
-        }
-    case GLES2_SHADER_FRAGMENT_TEXTURE_SRC:
+    }
+    case GLES2_SHADER_FRAGMENT_TEXTURE_ARGB_SRC:
         switch (blendMode)
-        {
+    {
         case SDL_BLENDMODE_NONE:
-            return &GLES2_FragmentShader_None_TextureSrc;
+            return &GLES2_FragmentShader_None_TextureARGBSrc;
         case SDL_BLENDMODE_BLEND:
-            return &GLES2_FragmentShader_Alpha_TextureSrc;
+            return &GLES2_FragmentShader_Alpha_TextureARGBSrc;
         case SDL_BLENDMODE_ADD:
-            return &GLES2_FragmentShader_Additive_TextureSrc;
+            return &GLES2_FragmentShader_Additive_TextureARGBSrc;
         case SDL_BLENDMODE_MOD:
-            return &GLES2_FragmentShader_Modulated_TextureSrc;
+            return &GLES2_FragmentShader_Modulated_TextureARGBSrc;
         default:
             return NULL;
-        }
+    }
+        
+    case GLES2_SHADER_FRAGMENT_TEXTURE_RGB_SRC:
+        switch (blendMode)
+    {
+        case SDL_BLENDMODE_NONE:
+            return &GLES2_FragmentShader_None_TextureRGBSrc;
+        case SDL_BLENDMODE_BLEND:
+            return &GLES2_FragmentShader_Alpha_TextureRGBSrc;
+        case SDL_BLENDMODE_ADD:
+            return &GLES2_FragmentShader_Additive_TextureRGBSrc;
+        case SDL_BLENDMODE_MOD:
+            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;
     }
--- a/src/render/opengles2/SDL_shaders_gles2.h	Fri Dec 09 02:32:21 2011 -0500
+++ b/src/render/opengles2/SDL_shaders_gles2.h	Thu Dec 29 05:11:33 2011 -0500
@@ -43,7 +43,10 @@
 {
     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