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>
Thu, 15 Oct 2015 00:26:37 +0000 (20:26 -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 f76420e..9ba3a35 100644 (file)
@@ -1075,7 +1075,9 @@ from wherever you obtained them.
                                     }
                                  ]
                               },
-                              "gl_compat_4_4.h"
+                              "gl_compat_4_4.h",
+                              "fixed.frag",
+                              "fixed.vertex"
                            ]
                         },
                         {
index ab1282f..53a2ed6 100644 (file)
@@ -45,7 +45,7 @@ public union Matrix
 
    void Multiply(Matrix a, Matrix b)
    {
-#ifdef _GLES
+#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 b3b4a31..0f58cad 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"
@@ -399,7 +399,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);
@@ -414,7 +416,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
@@ -451,6 +453,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
 
@@ -1015,19 +1026,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
@@ -1102,15 +1100,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);
@@ -1693,7 +1691,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);
 
@@ -1776,11 +1776,13 @@ 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);
-#ifndef __ANDROID__
+#if !defined(__ANDROID__) && !defined(SHADERS)
          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;
 
@@ -2169,7 +2171,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)
@@ -2215,7 +2217,7 @@ class OpenGLDisplayDriver : DisplayDriver
 
       if(!oglSurface.writingText)
       {
-         glDisable(GL_TEXTURE_2D);
+         GLSetupTexturing(false);
 
          //glTranslate(0.375, 0.375, 0.0);
       }
@@ -2229,7 +2231,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);
@@ -2267,7 +2269,7 @@ class OpenGLDisplayDriver : DisplayDriver
 
       glEnd();
 
-      glDisable(GL_TEXTURE_2D);
+      GLSetupTexturing(false);
 
       //glTranslate(0.375, 0.375, 0.0);
    }
@@ -2367,10 +2369,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);
@@ -2434,9 +2438,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);
@@ -2488,7 +2494,7 @@ class OpenGLDisplayDriver : DisplayDriver
 
       oglSurface.writingText = true;
 
-      glEnable(GL_TEXTURE_2D);
+      GLSetupTexturing(true);
 
       if(surface.outline.size)
       {
@@ -2507,7 +2513,7 @@ class OpenGLDisplayDriver : DisplayDriver
       oglSurface.writingText = false;
       oglSystem.loadingFont = false;
 
-      glDisable(GL_TEXTURE_2D);
+      GLSetupTexturing(false);
 
       //glTranslated(0.375, 0.375, 0.0);
    }
@@ -2553,12 +2559,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
@@ -2592,19 +2598,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
@@ -2627,7 +2637,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)
@@ -2851,10 +2861,11 @@ class OpenGLDisplayDriver : DisplayDriver
          // ...
 
          glEnable(GL_DEPTH_TEST);
-//#if !defined(EM_MODE)
+
+#if !defined(EM_MODE) && !defined(SHADERS)
          glEnable(GL_LIGHTING);
          glShadeModel(GL_SMOOTH);
-//#endif
+#endif
          glDepthMask((byte)bool::true);
          oglDisplay.depthWrite = true;
 
@@ -2867,12 +2878,12 @@ 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
+#endif
          glEnable(GL_BLEND);
          glDisable(GL_MULTISAMPLE_ARB);
 
@@ -2893,30 +2904,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);
@@ -2937,10 +2950,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)
       {
@@ -3270,7 +3283,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);
    }
 }