ecere/gfx/OpenGLDispalyDriver: Fixed setting initial projection matrix; Emscripten...
[sdk] / ecere / src / gfx / drivers / OpenGLDisplayDriver.ec
index 829dc41..4c06cf0 100644 (file)
@@ -86,7 +86,6 @@ namespace gfx::drivers;
    #define uint _uint
 
    #include <GL/gl.h>
-   #include <GL/glut.h>
 
    //#include <GLES/gl.h>
    //#include <EGL/egl.h>
@@ -108,6 +107,12 @@ namespace gfx::drivers;
 
 #endif
 
+#if defined(__EMSCRIPTEN__)
+#define EM_MODE
+#endif
+
+#define EM_MODE
+
 #undef pointer
 
 import "Display"
@@ -122,6 +127,16 @@ import "Display"
 
 static double nearPlane = 1;
 
+public double glesGetNearPlane()
+{
+   return nearPlane;
+}
+
+public void glesSetNearPlane(double value)
+{
+   nearPlane = value;
+}
+
 #define glLoadMatrix glLoadMatrixd
 #define glMultMatrix glMultMatrixd
 #define glGetMatrix  glGetDoublev
@@ -645,9 +660,12 @@ static int vertexCount;
 static int normalCount;
 static float *vertexPointer;
 static float *normalPointer;
-static GLenum beginMode;
-static unsigned int beginBufferSize, normalBufferSize;
+static GLenum beginMode = -1;
+static uint beginBufferSize, normalBufferSize;
 static int numVertexCoords = 2;
+static bool vertexColorValues = false;
+static int vertexStride = 4;
+static int vertexOffset = 2;
 
 public void glesRecti(int a, int b, int c, int d)
 {
@@ -664,10 +682,15 @@ public void glesBegin(GLenum mode)
    beginMode = mode;
    beginCount = 0;
    vertexCount = 0;
+   vertexColorValues = false;
+   vertexOffset = 2;
+   vertexStride = 4;
+   numVertexCoords = 2;
+
    if(!vertexPointer)
    {
       normalBufferSize = beginBufferSize = 1024;  // default number of vertices
-      vertexPointer = new float[beginBufferSize * 5];
+      vertexPointer = new float[beginBufferSize * vertexStride];
       normalPointer = new float[normalBufferSize * 3];
    }
 }
@@ -679,20 +702,20 @@ public void glesTexCoord2f(float x, float y)
    if(vertexCount + numVertexCoords > beginBufferSize)
    {
       beginBufferSize = beginBufferSize + beginBufferSize/2;
-      vertexPointer = renew vertexPointer float[beginBufferSize * 5];
+      vertexPointer = renew vertexPointer float[beginBufferSize * vertexStride];
    }
 
-   vertexPointer[count*(2+numVertexCoords)  ] = x;
-   vertexPointer[count*(2+numVertexCoords)+1] = y;
+   vertexPointer[count*vertexStride  ] = x;
+   vertexPointer[count*vertexStride+1] = y;
    count++;
 
    if(beginMode == GL_QUADS && ((beginCount % 4) == 3))
    {
-      vertexPointer[count*(2+numVertexCoords)  ] = vertexPointer[(count-4)*(2+numVertexCoords)];
-      vertexPointer[count*(2+numVertexCoords)+1] = vertexPointer[(count-4)*(2+numVertexCoords)+1];
+      vertexPointer[count*vertexStride  ] = vertexPointer[(count-4)*vertexStride];
+      vertexPointer[count*vertexStride+1] = vertexPointer[(count-4)*vertexStride+1];
       count++;
-      vertexPointer[count*(2+numVertexCoords)  ] = vertexPointer[(count-3)*(2+numVertexCoords)];
-      vertexPointer[count*(2+numVertexCoords)+1] = vertexPointer[(count-3)*(2+numVertexCoords)+1];
+      vertexPointer[count*vertexStride  ] = vertexPointer[(count-3)*vertexStride];
+      vertexPointer[count*vertexStride+1] = vertexPointer[(count-3)*vertexStride+1];
       count++;
    }
 }
@@ -703,23 +726,25 @@ public void glesTexCoord2fv(float * a)         { glesTexCoord2f(a[0], a[1]); }
 public void glesVertex2f(float x, float y)
 {
    numVertexCoords = 2;
+   vertexStride = vertexOffset + numVertexCoords;
+
    if(vertexCount + 4 > beginBufferSize)
    {
       beginBufferSize = beginBufferSize + beginBufferSize/2;
-      vertexPointer = renew vertexPointer float[beginBufferSize * 5];
+      vertexPointer = renew vertexPointer float[beginBufferSize * vertexStride];
    }
 
-   vertexPointer[vertexCount*4+2] = x;
-   vertexPointer[vertexCount*4+3] = y;
+   vertexPointer[vertexCount*vertexStride+vertexOffset] = x;
+   vertexPointer[vertexCount*vertexStride+vertexOffset + 1] = y;
    vertexCount++;
 
    if(beginMode == GL_QUADS && ((beginCount % 4) == 3))
    {
-      vertexPointer[vertexCount*4+2] = vertexPointer[(vertexCount-4)*4+2];
-      vertexPointer[vertexCount*4+3] = vertexPointer[(vertexCount-4)*4+3];
+      vertexPointer[vertexCount*vertexStride+vertexOffset] = vertexPointer[(vertexCount-4)*vertexStride+vertexOffset];
+      vertexPointer[vertexCount*vertexStride+vertexOffset + 1] = vertexPointer[(vertexCount-4)*vertexStride+vertexOffset + 1];
       vertexCount++;
-      vertexPointer[vertexCount*4+2] = vertexPointer[(vertexCount-3)*4+2];
-      vertexPointer[vertexCount*4+3] = vertexPointer[(vertexCount-3)*4+3];
+      vertexPointer[vertexCount*vertexStride+vertexOffset] = vertexPointer[(vertexCount-3)*vertexStride+vertexOffset];
+      vertexPointer[vertexCount*vertexStride+vertexOffset + 1] = vertexPointer[(vertexCount-3)*vertexStride+vertexOffset + 1];
       vertexCount++;
    }
    beginCount++;
@@ -732,10 +757,16 @@ public void glesEnd(void)
    int mode = beginMode;
    if(mode == GL_QUADS)        mode = GL_TRIANGLES;
    else if(mode == GL_POLYGON) mode = GL_TRIANGLE_FAN;
+
    GLSelectVBO(0);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-   glTexCoordPointer(numVertexCoords, GL_FLOAT, (numVertexCoords+2)*sizeof(float),vertexPointer);
-   glVertexPointer  (numVertexCoords, GL_FLOAT, (numVertexCoords+2)*sizeof(float),vertexPointer+2);
+   glTexCoordPointer(2, GL_FLOAT,  vertexStride * sizeof(float), vertexPointer);
+   if(vertexColorValues)
+   {
+      glEnableClientState(GL_COLOR_ARRAY);
+      glColorPointer(4, GL_FLOAT, vertexStride * sizeof(float), vertexPointer + 2);
+   }
+   glVertexPointer  (numVertexCoords, GL_FLOAT, (vertexStride)*sizeof(float),vertexPointer+vertexOffset);
    if(normalCount && normalCount == vertexCount)
    {
       glEnableClientState(GL_NORMAL_ARRAY);
@@ -745,8 +776,13 @@ public void glesEnd(void)
    glDrawArrays(mode, 0, vertexCount);
    if(normalCount)
       glDisableClientState(GL_NORMAL_ARRAY);
+   if(vertexColorValues)
+      glDisableClientState(GL_COLOR_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    normalCount = 0;
+   vertexColorValues = false;
+   numVertexCoords = 2;
+   beginMode = -1;
 }
 
 // Vertex Pointer
@@ -805,19 +841,59 @@ public void glesTexReuseDoubleVP(int numCoords)
    glTexCoordPointer(numCoords, GL_FLOAT, 0, floatVPBuffer);
 }
 
+public void glesColor4f(float r, float g, float b, float a)
+{
+   if(beginMode != (GLenum)-1)
+   {
+      int count = vertexCount;
+
+      vertexColorValues = true;
+      vertexOffset = 6;
+      vertexStride = vertexOffset + numVertexCoords;
+
+      if(vertexCount + vertexStride > beginBufferSize)
+      {
+         beginBufferSize = beginBufferSize + beginBufferSize/2;
+         vertexPointer = renew vertexPointer float[beginBufferSize * vertexStride];
+      }
+
+      vertexPointer[count*vertexStride + 2] = r;
+      vertexPointer[count*vertexStride + 3] = g;
+      vertexPointer[count*vertexStride + 4] = b;
+      vertexPointer[count*vertexStride + 5] = a;
+      count++;
+
+      if(beginMode == GL_QUADS && ((beginCount % 4) == 3))
+      {
+         vertexPointer[count*vertexStride + 2] = vertexPointer[(count-4) * vertexStride + 2];
+         vertexPointer[count*vertexStride + 3] = vertexPointer[(count-4) * vertexStride + 3];
+         vertexPointer[count*vertexStride + 4] = vertexPointer[(count-4) * vertexStride + 4];
+         vertexPointer[count*vertexStride + 5] = vertexPointer[(count-4) * vertexStride + 5];
+         count++;
+         vertexPointer[count*vertexStride + 2] = vertexPointer[(count-3) * vertexStride + 2];
+         vertexPointer[count*vertexStride + 3] = vertexPointer[(count-3) * vertexStride + 3];
+         vertexPointer[count*vertexStride + 4] = vertexPointer[(count-3) * vertexStride + 4];
+         vertexPointer[count*vertexStride + 5] = vertexPointer[(count-3) * vertexStride + 5];
+         count++;
+      }
+   }
+   else
+      glColor4f(r, g, b, a);
+}
+
 public void glesColor3f( float r, float g, float b )
 {
-   glColor4f(r, g, b, 1.0f);
+   glesColor4f(r, g, b, 1.0f);
 }
 
 public void glesColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
 {
-   glColor4f(r/255.0f, g/255.0f, b/255.0f, a/255.0f);
+   glesColor4f(r/255.0f, g/255.0f, b/255.0f, a/255.0f);
 }
 
 public void glesColor4fv(float * a)
 {
-   glColor4f(a[0], a[1], a[2], a[3]);
+   glesColor4f(a[0], a[1], a[2], a[3]);
 }
 
 public void glesBufferDatad(int target, int size, void * data, int usage)
@@ -1060,26 +1136,28 @@ void glesMultMatrixd( double * i )
 public void glesVertex3f( float x, float y, float z )
 {
    numVertexCoords = 3;
-   if(vertexCount + 4 > beginBufferSize)
+   vertexStride = vertexOffset + numVertexCoords;
+
+   if(vertexCount + vertexStride > beginBufferSize)
    {
       beginBufferSize = beginBufferSize + beginBufferSize/2;
-      vertexPointer = renew vertexPointer float[beginBufferSize * 5];
+      vertexPointer = renew vertexPointer float[beginBufferSize * vertexStride];
    }
 
-   vertexPointer[vertexCount*5+2] = x;
-   vertexPointer[vertexCount*5+3] = y;
-   vertexPointer[vertexCount*5+4] = z;
+   vertexPointer[vertexCount*vertexStride+vertexOffset] = x;
+   vertexPointer[vertexCount*vertexStride+vertexOffset+1] = y;
+   vertexPointer[vertexCount*vertexStride+vertexOffset+2] = z;
    vertexCount++;
 
    if(beginMode == GL_QUADS && ((beginCount % 4) == 3))
    {
-      vertexPointer[vertexCount*5+2] = vertexPointer[(vertexCount-4)*5+2];
-      vertexPointer[vertexCount*5+3] = vertexPointer[(vertexCount-4)*5+3];
-      vertexPointer[vertexCount*5+4] = vertexPointer[(vertexCount-4)*5+4];
+      vertexPointer[vertexCount*vertexStride+vertexOffset] = vertexPointer[(vertexCount-4)*vertexStride+vertexOffset];
+      vertexPointer[vertexCount*vertexStride+vertexOffset+1] = vertexPointer[(vertexCount-4)*vertexStride+vertexOffset+1];
+      vertexPointer[vertexCount*vertexStride+vertexOffset+2] = vertexPointer[(vertexCount-4)*vertexStride+vertexOffset+2];
       vertexCount++;
-      vertexPointer[vertexCount*5+2] = vertexPointer[(vertexCount-3)*5+2];
-      vertexPointer[vertexCount*5+3] = vertexPointer[(vertexCount-3)*5+3];
-      vertexPointer[vertexCount*5+4] = vertexPointer[(vertexCount-3)*5+4];
+      vertexPointer[vertexCount*vertexStride+vertexOffset] = vertexPointer[(vertexCount-3)*vertexStride+vertexOffset];
+      vertexPointer[vertexCount*vertexStride+vertexOffset+1] = vertexPointer[(vertexCount-3)*vertexStride+vertexOffset+1];
+      vertexPointer[vertexCount*vertexStride+vertexOffset+2] = vertexPointer[(vertexCount-3)*vertexStride+vertexOffset+2];
       vertexCount++;
    }
    beginCount++;
@@ -1140,7 +1218,7 @@ public void glesTerminate()
 }
 
 static GLuint stippleTexture;
-#if defined(_GLES)
+#if defined(_GLES) || defined(EM_MODE)
 static bool stippleEnabled;
 #endif
 
@@ -1172,8 +1250,10 @@ public void glesLineStipple( int i, unsigned short j )
 
 public void glesLightModeli( unsigned int pname, int param )
 {
+#if !defined(EM_MODE)
    if(pname == GL_LIGHT_MODEL_TWO_SIDE)
       glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, param);
+#endif
 }
 
 #ifdef __ANDROID__
@@ -1222,7 +1302,7 @@ bool GLSelectVBO(uint vbo)
 
 void GLGenBuffers(int count, uint * buffer)
 {
-#ifdef __ANDROID__
+#if defined(__ANDROID__) || defined(__EMSCRIPTEN__)
    glGenBuffers(count, buffer);
 #else
 #if defined(__WIN32__)
@@ -1234,7 +1314,7 @@ void GLGenBuffers(int count, uint * buffer)
 
 void GLDeleteBuffers(int count, GLuint * buffer)
 {
-#ifdef __ANDROID__
+#if defined(__ANDROID__) || defined(__EMSCRIPTEN__)
    glDeleteBuffers(count, buffer);
 #else
 #if defined(__WIN32__)
@@ -1246,7 +1326,7 @@ void GLDeleteBuffers(int count, GLuint * buffer)
 
 void GLBindBuffer(int target, uint buffer)
 {
-#ifdef __ANDROID__
+#if defined(__ANDROID__) || defined(__EMSCRIPTEN__)
    glBindBuffer(target, buffer);
 #else
 #if defined(__WIN32__)
@@ -1254,6 +1334,7 @@ void GLBindBuffer(int target, uint buffer)
 #endif
       glBindBufferARB(target, buffer);
 #endif
+   currentVertexBuffer = buffer;
 }
 
 public void GLVertexPointer(int numCoords, int glType, int stride, void *ptr, int numVertices)
@@ -1278,7 +1359,7 @@ public void GLBufferData(int type, GLenum target, int size, const GLvoid *data,
    else
 #endif
 
-#ifdef __ANDROID__
+#if defined(__ANDROID__) || defined(__EMSCRIPTEN__)
       glBufferData(target, size, data, usage);
 #else
 
@@ -1870,7 +1951,9 @@ class OpenGLDisplayDriver : DisplayDriver
          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);
@@ -2782,7 +2865,7 @@ class OpenGLDisplayDriver : DisplayDriver
 
       glColor4fv(oglSurface.foreground);
       glBegin(GL_LINES);
-#ifdef _GLES
+#if defined(_GLES) || defined(EM_MODE)
       if(stippleEnabled)
       {
          glTexCoord2f(0.5f, 0);
@@ -2815,7 +2898,7 @@ class OpenGLDisplayDriver : DisplayDriver
       //Logf("Rectangle\n");
 
       glColor4fv(oglSurface.foreground);
-#ifdef _GLES
+#if defined(_GLES) || defined(EM_MODE)
       if(stippleEnabled)
       {
          glBegin(GL_LINES);
@@ -2865,7 +2948,7 @@ class OpenGLDisplayDriver : DisplayDriver
 
       glColor4fv(oglSurface.background);
 
-#ifdef __EMSCRIPTEN__
+#ifdef EM_MODE
       glBegin(GL_QUADS);
       glVertex2f(x1+surface.offset.x, y1+surface.offset.y);
       glVertex2f(x1+surface.offset.x, y2+surface.offset.y+1);
@@ -3047,6 +3130,7 @@ class OpenGLDisplayDriver : DisplayDriver
 
    void StretchDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
    {
+#if !defined(EM_MODE)
       float s2dw,s2dh,d2sw,d2sh;
       //bool flipX = false, flipY = false;
 
@@ -3143,10 +3227,12 @@ class OpenGLDisplayDriver : DisplayDriver
          glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
          glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
       }
+#endif
    }
 
    void BlitDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
    {
+#if !defined(EM_MODE)
       //Logf("BlitDI\n");
 
       //Clip against the edges of the source
@@ -3207,6 +3293,7 @@ class OpenGLDisplayDriver : DisplayDriver
          glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
          glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
       }
+#endif
    }
 
    void FilterDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
@@ -3307,7 +3394,7 @@ class OpenGLDisplayDriver : DisplayDriver
 
       if(stipple)
       {
-#if defined(_GLES)
+#if defined(_GLES) || defined(EM_MODE)
          stippleEnabled = true;
          glesLineStipple(1, (uint16)stipple);
 #else
@@ -3317,7 +3404,7 @@ class OpenGLDisplayDriver : DisplayDriver
       }
       else
       {
-#if defined(_GLES)
+#if defined(_GLES) || defined(EM_MODE)
          stippleEnabled = false;
          glMatrixMode(GL_TEXTURE);
          glLoadIdentity();
@@ -3368,8 +3455,10 @@ class OpenGLDisplayDriver : DisplayDriver
             break;
          case ambient:
          {
+#if !defined(EM_MODE)
             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
             break;
          }
          case alphaWrite:
@@ -3389,6 +3478,7 @@ class OpenGLDisplayDriver : DisplayDriver
 
    void SetLight(Display display, int id, Light light)
    {
+#if !defined(EM_MODE)
       //Logf("SetLight\n");
 
       if(light != null)
@@ -3535,11 +3625,13 @@ class OpenGLDisplayDriver : DisplayDriver
             position[1] = direction.y;
             position[2] = direction.z;
 
+            PrintLn("position");
             glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
          }
       }
       else
          glDisable(GL_LIGHT0 + id);
+#endif
    }
 
    void SetCamera(Display display, Surface surface, Camera camera)
@@ -3565,7 +3657,10 @@ class OpenGLDisplayDriver : DisplayDriver
 
          // *** Projection Matrix ***
          if(!display.display3D.camera)
+         {
+            glMatrixMode(GL_PROJECTION);
             glPushMatrix();
+         }
          else
             glMatrixMode(GL_PROJECTION);
          if(display.display3D.collectingHits)
@@ -3611,8 +3706,10 @@ class OpenGLDisplayDriver : DisplayDriver
          // ...
 
          glEnable(GL_DEPTH_TEST);
+#if !defined(EM_MODE)
          glEnable(GL_LIGHTING);
          glShadeModel(GL_SMOOTH);
+#endif
          glDepthMask((byte)bool::true);
          oglDisplay.depthWrite = true;
 
@@ -3628,7 +3725,9 @@ class OpenGLDisplayDriver : DisplayDriver
          glDisable(GL_LIGHTING);
          glDisable(GL_FOG);
          glDisable(GL_TEXTURE_2D);
+#if !defined(EM_MODE)
          glShadeModel(GL_FLAT);
+#endif
          glEnable(GL_BLEND);
          glDisable(GL_MULTISAMPLE_ARB);
 
@@ -3650,12 +3749,16 @@ class OpenGLDisplayDriver : DisplayDriver
       // Basic Properties
       if(material.flags.doubleSided)
       {
+#if !defined(EM_MODE)
          glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, !material.flags.singleSideLight);
+#endif
          glDisable(GL_CULL_FACE);
       }
       else
       {
+#if !defined(EM_MODE)
          glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, bool::false);
+#endif
          glEnable(GL_CULL_FACE);
       }
 
@@ -3692,6 +3795,9 @@ class OpenGLDisplayDriver : DisplayDriver
       else
          glDisable(GL_TEXTURE_2D);
 
+#ifdef EM_MODE
+      glColor4f(material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity);
+#else
       if(mesh.flags.colors)
       {
          glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
@@ -3719,6 +3825,7 @@ class OpenGLDisplayDriver : DisplayDriver
       }
 
       glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &material.power);
+#endif
    }
 
    void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
@@ -3960,7 +4067,7 @@ class OpenGLDisplayDriver : DisplayDriver
    {
       //Logf("SelectMesh\n");
 
-#if !defined( __ANDROID__) && !defined(__APPLE__)
+#if !defined( __ANDROID__) && !defined(__APPLE__) && !defined(__EMSCRIPTEN__)
 
 #if defined(__WIN32__)
       if(glUnlockArraysEXT)
@@ -4044,7 +4151,7 @@ class OpenGLDisplayDriver : DisplayDriver
                glDisableClientState(GL_COLOR_ARRAY);
          }
 
-#if !defined(__ANDROID__) && !defined(__APPLE__)
+#if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__EMSCRIPTEN__)
 
 #if defined(__WIN32__)
          if(glLockArraysEXT)