ecere/gfx/drivers/OpenGL: Shaders support improvements
authorJerome St-Louis <jerome@ecere.com>
Tue, 8 Sep 2015 11:38:27 +0000 (19:38 +0800)
committerJerome St-Louis <jerome@ecere.com>
Sun, 3 Jul 2016 08:07:06 +0000 (04:07 -0400)
- Fixed 3D issues (including incomplete Matrix multiplication biting again)
- Added texture_matrix and texturingOn uniforms
- Fixed color on no texturing
- Removed deprecated lighting & material calls when SHADERS is defined
- Added Shaders to drivers/gl3 in project in addition to res/shaders/
   (Allows linking project with F7 while they're the active editor)

ecere/ecere.epj
ecere/src/gfx/3D/Matrix.ec
ecere/src/gfx/drivers/OpenGLDisplayDriver.ec
ecere/src/gfx/drivers/gl3/fixed.frag
ecere/src/gfx/drivers/gl3/shading.ec

index 4097eeb..10b4971 100644 (file)
@@ -1055,7 +1055,9 @@ if distributed with the Ecere SDK Windows installer.
                                     }
                                  ]
                               },
-                              "gl_compat_4_4.h"
+                              "gl_compat_4_4.h",
+                              "fixed.frag",
+                              "fixed.vertex"
                            ]
                         },
                         {
index a36720b..53a2ed6 100644 (file)
@@ -45,7 +45,7 @@ public union Matrix
 
    void Multiply(Matrix a, Matrix b)
    {
-#if 1
+#if 1 // defined(_GLES) || defined(SHADERS)
       // We need a full matrix multiplication for the Projection matrix
       m[0][0]=a.m[0][0]*b.m[0][0] + a.m[0][1]*b.m[1][0] + a.m[0][2]*b.m[2][0] + a.m[0][3]*b.m[3][0];
       m[0][1]=a.m[0][0]*b.m[0][1] + a.m[0][1]*b.m[1][1] + a.m[0][2]*b.m[2][1] + a.m[0][3]*b.m[3][1];
index a28ae8d..dd97e2b 100644 (file)
@@ -9,7 +9,7 @@ namespace gfx::drivers;
 #define GL_BGRA_EXT  0x80E1
 
 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
-#  if 0 //defined(SHADERS)
+#  if defined(SHADERS)
 #     include "gl_core_3_3.h"
 #  else
 #     include "gl_compat_4_4.h"
@@ -397,7 +397,9 @@ public void glesLineStipple( int i, unsigned short j )
       glGenTextures(1, &stippleTexture);
    glBindTexture(GL_TEXTURE_2D, stippleTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
-   glEnable(GL_TEXTURE_2D);
+
+   // TOOD: Special shading code for stippling?
+   GLSetupTexturing(true);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
@@ -412,7 +414,7 @@ public void glesLineStipple( int i, unsigned short j )
 
 public void glesLightModeli( unsigned int pname, int param )
 {
-#if !defined(EM_MODE)
+#if !defined(EM_MODE) && !defined(SHADERS)
    if(pname == GL_LIGHT_MODEL_TWO_SIDE)
       glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, param);
 #endif
@@ -449,6 +451,15 @@ static int primitiveTypes[RenderPrimitiveType] =
 };
 #endif
 
+public void GLSetupTexturing(bool enable)
+{
+#ifdef SHADERS
+   shader_texturing(enable);
+#else
+   (enable ? glEnable : glDisable)(GL_TEXTURE_2D);
+#endif
+}
+
 
 // Non OpenGL ES friendly stuff
 
@@ -1017,19 +1028,6 @@ class OpenGLDisplayDriver : DisplayDriver
          {
             wglShareLists(oglSystem.glrc, oglDisplay.glrc);
             wglMakeCurrent(oglDisplay.hdc, oglDisplay.glrc);
-
-            // Had to recreate the context here ? (Alpha blending visual)
-
-            ogl_LoadFunctions();
-            CheckExtensions(oglSystem);
-            vboAvailable = glBindBuffer != null;
-
-            setupDebugging();
-            #ifdef SHADERS
-            loadShaders("<:ecere>shaders/fixed.vertex", "<:ecere>shaders/fixed.frag");
-            #endif
-            glEnableClientState(GL_VERTEX_ARRAY);
-
             result = true;
          }
          else
@@ -1107,15 +1105,15 @@ class OpenGLDisplayDriver : DisplayDriver
          // glTranslatef(0.375f, 0.375f, 0.0f);
          // glTranslatef(-0.625f, -0.625f, 0.0f);
          glMatrixMode(MatrixMode::projection);
+#if !defined(EM_MODE) && !defined(SHADERS)
          glShadeModel(GL_FLAT);
 
          // glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, true);
-#if !defined(EM_MODE)
          glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
-#endif
          glFogi(GL_FOG_MODE, GL_EXP);
          glFogf(GL_FOG_DENSITY, 0);
          glEnable(GL_NORMALIZE);
+#endif
          glDepthFunc(GL_LESS);
          glClearDepth(1.0);
          glDisable(GL_MULTISAMPLE_ARB);
@@ -1698,7 +1696,9 @@ class OpenGLDisplayDriver : DisplayDriver
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 
+#if !defined(SHADERS)
       glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+#endif
 
       mipMap.Allocate(null, w, h, w, pixelFormatRGBA, false);
 
@@ -1785,7 +1785,9 @@ class OpenGLDisplayDriver : DisplayDriver
          glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0 );
 #endif
 
+#if !defined(SHADERS)
          glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+#endif
 
          result = true;
 
@@ -2174,7 +2176,7 @@ class OpenGLDisplayDriver : DisplayDriver
       if(!oglSurface.writingText)
       {
          // glTranslatef(-0.375f, -0.375f, 0.0f);
-         glEnable(GL_TEXTURE_2D);
+         GLSetupTexturing(true);
          glColor4fv(oglSurface.bitmapMult);
       }
       else if(oglSurface.xOffset)
@@ -2220,7 +2222,7 @@ class OpenGLDisplayDriver : DisplayDriver
 
       if(!oglSurface.writingText)
       {
-         glDisable(GL_TEXTURE_2D);
+         GLSetupTexturing(false);
 
          //glTranslate(0.375, 0.375, 0.0);
       }
@@ -2234,7 +2236,7 @@ class OpenGLDisplayDriver : DisplayDriver
 
       //glTranslate(-0.375, -0.375, 0.0);
 
-      glEnable(GL_TEXTURE_2D);
+      GLSetupTexturing(true);
       glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)bitmap.driverData);
 
       glColor4fv(oglSurface.bitmapMult);
@@ -2272,7 +2274,7 @@ class OpenGLDisplayDriver : DisplayDriver
 
       glEnd();
 
-      glDisable(GL_TEXTURE_2D);
+      GLSetupTexturing(false);
 
       //glTranslate(0.375, 0.375, 0.0);
    }
@@ -2372,10 +2374,12 @@ class OpenGLDisplayDriver : DisplayDriver
          glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
          glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
          glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
+#if !defined(SHADERS)
          glRasterPos2d(dx,dy);
          //glPixelZoom(flipX ? -s2dw : s2dw, flipY ? s2dh : -s2dh);
          glPixelZoom(s2dw, -s2dh);
          glDrawPixels(sw,sh,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
+#endif
          glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
          glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
          glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
@@ -2439,9 +2443,11 @@ class OpenGLDisplayDriver : DisplayDriver
          glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
          glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
          glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
+#if !defined(SHADERS)
          glRasterPos2d(dx,dy);
          glPixelZoom(1,-1);
          glDrawPixels(w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
+#endif
          glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
          glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
          glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
@@ -2494,7 +2500,8 @@ class OpenGLDisplayDriver : DisplayDriver
 
       oglSurface.writingText = true;
 
-      glEnable(GL_TEXTURE_2D);
+      GLSetupTexturing(true);
+
       if(surface.font.outlineSize)
       {
          ColorAlpha outlineColor = surface.outlineColor;
@@ -2509,7 +2516,7 @@ class OpenGLDisplayDriver : DisplayDriver
       oglSurface.writingText = false;
       oglSystem.loadingFont = false;
 
-      glDisable(GL_TEXTURE_2D);
+      GLSetupTexturing(false);
 
       //glTranslated(0.375, 0.375, 0.0);
    }
@@ -2555,12 +2562,12 @@ class OpenGLDisplayDriver : DisplayDriver
       }
       else
       {
-#if defined(ES1_1) || defined(EM_MODE)
+#if defined(ES1_1) || defined(EM_MODE) || defined(SHADERS)
          stippleEnabled = false;
          glMatrixMode(GL_TEXTURE);
          glLoadIdentity();
          glMatrixMode(MatrixMode::projection);
-         glDisable(GL_TEXTURE_2D);
+         GLSetupTexturing(false);   // TODO: Special shading code for stipple?
 #else
          glDisable(GL_LINE_STIPPLE);
 #endif
@@ -2594,19 +2601,23 @@ class OpenGLDisplayDriver : DisplayDriver
             break;
          case fogColor:
          {
+#if !defined(SHADERS)
             float color[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
             glFogfv(GL_FOG_COLOR, (float *)&color);
+#endif
             break;
          }
          case fogDensity:
+#if !defined(SHADERS)
             glFogf(GL_FOG_DENSITY, (float)(RenderStateFloat { ui = value }.f * nearPlane));
+#endif
             break;
          case blend:
             if(value) glEnable(GL_BLEND); else glDisable(GL_BLEND);
             break;
          case ambient:
          {
-#if !defined(EM_MODE)
+#if !defined(EM_MODE) && !defined(SHADERS)
             float ambient[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
             glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
 #endif
@@ -2629,7 +2640,7 @@ class OpenGLDisplayDriver : DisplayDriver
 
    void SetLight(Display display, int id, Light light)
    {
-#if !defined(EM_MODE)
+#if !defined(EM_MODE) && !defined(SHADERS)
       //Logf("SetLight\n");
 
       if(light != null)
@@ -2853,7 +2864,8 @@ class OpenGLDisplayDriver : DisplayDriver
          // ...
 
          glEnable(GL_DEPTH_TEST);
-#if !defined(EM_MODE)
+
+#if !defined(EM_MODE) && !defined(SHADERS)
          glEnable(GL_LIGHTING);
          glShadeModel(GL_SMOOTH);
 #endif
@@ -2869,10 +2881,10 @@ class OpenGLDisplayDriver : DisplayDriver
 
          glDisable(GL_CULL_FACE);
          glDisable(GL_DEPTH_TEST);
+         GLSetupTexturing(false);
+#if !defined(EM_MODE) && !defined(SHADERS)
          glDisable(GL_LIGHTING);
          glDisable(GL_FOG);
-         glDisable(GL_TEXTURE_2D);
-#if !defined(EM_MODE)
          glShadeModel(GL_FLAT);
 #endif
          glEnable(GL_BLEND);
@@ -2895,30 +2907,32 @@ class OpenGLDisplayDriver : DisplayDriver
       // Basic Properties
       if(material.flags.doubleSided)
       {
-#if !defined(EM_MODE)
+#if !defined(EM_MODE) && !defined(SHADERS)
          glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, !material.flags.singleSideLight);
 #endif
          glDisable(GL_CULL_FACE);
       }
       else
       {
-#if !defined(EM_MODE)
+#if !defined(EM_MODE) && !defined(SHADERS)
          glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, bool::false);
 #endif
          glEnable(GL_CULL_FACE);
       }
 
+#if !defined(SHADERS)
       // Fog
       if(material.flags.noFog)
          glDisable(GL_FOG);
       else
          glEnable(GL_FOG);
+#endif
 
       // Maps
       if(material.baseMap && (mesh.texCoords || mesh.flags.texCoords1))
       {
          Bitmap map = material.baseMap;
-         glEnable(GL_TEXTURE_2D);
+         GLSetupTexturing(true);
          glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr)map.driverData);
 
          glMatrixMode(GL_TEXTURE);
@@ -2939,10 +2953,10 @@ class OpenGLDisplayDriver : DisplayDriver
          }
       }
       else
-         glDisable(GL_TEXTURE_2D);
+         GLSetupTexturing(false);
 
-#ifdef EM_MODE
-      glColor4f(material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity);
+#if defined(EM_MODE) || defined(SHADERS)
+      glimtkColor4f(material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity);
 #else
       if(mesh.flags.colors)
       {
@@ -3272,7 +3286,7 @@ class OpenGLDisplayDriver : DisplayDriver
          if(primitive->nIndices < (mesh.nVertices >> 2) && !primitive->type.indices32bit)
          {
             int c;
-            glBegin(primitiveTypes[primitive->type.primitiveType]);
+            glBegin((GLIMTKMode)primitiveTypes[primitive->type.primitiveType]);
             if(primitive->data)
             {
                OGLIndices oglIndices = primitive->data;
index 27223d9..5d11323 100644 (file)
@@ -1,6 +1,8 @@
 #version 150
 
 uniform sampler2D diffuseTex;
+uniform bool texturingOn;
+uniform mat4 texture_matrix;
 
 in vec2 fTexCoord;
 in vec4 fColor;
@@ -9,5 +11,5 @@ out vec4 fragColor;
 
 void main(void)
 {
-   fragColor = fColor * texture(diffuseTex, fTexCoord);
+   fragColor = texturingOn ? fColor * texture(diffuseTex, (vec4(fTexCoord, 0, 1) * texture_matrix).xy) : fColor;
 }
index 4f1c6ae..02efae9 100644 (file)
@@ -13,11 +13,15 @@ int shadingProgram;
 // Uniforms
 int uPrjMatrix;
 int uMVMatrix;
+int uTextureMatrix;
 int uColor;
+int uTexturingOn;
 
 void shader_LoadMatrixf(MatrixMode mode, float * m)
 {
-   if(mode == projection)
+   if(mode == texture)
+      glUniformMatrix4fv(uTextureMatrix, 1, GL_FALSE, m);
+   else if(mode == projection)
       glUniformMatrix4fv(uPrjMatrix, 1, GL_FALSE, m);
    else
       glUniformMatrix4fv(uMVMatrix, 1, GL_FALSE, m);
@@ -28,6 +32,11 @@ void shader_color(float r, float g, float b, float a)
    glUniform4f(uColor, r, g, b, a);
 }
 
+void shader_texturing(bool on)
+{
+   glUniform1ui(uTexturingOn, on);
+}
+
 void loadShaders(const String vertexShaderFile, const String fragmentShaderFile)
 {
    static char compileLog[65536];
@@ -124,12 +133,23 @@ void loadShaders(const String vertexShaderFile, const String fragmentShaderFile)
       puts("--------------------------");
       puts(compileLog[0] ? compileLog : "Success.");
 
-      uPrjMatrix = glGetUniformLocation(program, "projection_matrix");
-      uMVMatrix  = glGetUniformLocation(program, "modelview_matrix");
-      uColor     = glGetUniformLocation(program, "current_color");
+      uPrjMatrix     = glGetUniformLocation(program, "projection_matrix");
+      uMVMatrix      = glGetUniformLocation(program, "modelview_matrix");
+      uTextureMatrix = glGetUniformLocation(program, "texture_matrix");
+      uColor         = glGetUniformLocation(program, "current_color");
+      uTexturingOn   = glGetUniformLocation(program, "texturingOn");
 
       shadingProgram = program;
 
       glUseProgram(shadingProgram);
+
+      // Initialize uniforms to defaults
+      glmsMatrixMode(texture);
+      glmsLoadIdentity();
+      glmsMatrixMode(projection);
+      glmsLoadIdentity();
+      glmsMatrixMode(modelView);
+      glmsLoadIdentity();
+      shader_color(1.0, 1.0, 1.0, 1.0);
    }
 }