ecere/gfx/drivers/OpenGL: Fixed VBO/IBOs mixup
[sdk] / ecere / src / gfx / drivers / OpenGLDisplayDriver.ec
index b0a7c1b..31bb57e 100644 (file)
@@ -101,6 +101,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
@@ -374,7 +384,7 @@ static int curStack = 0;
 #if defined(_GLES)
 
    // OpenGL ES Porting Kit
-
+#if defined(__ANDROID__)
    #define glBindFramebuffer        glBindFramebufferOES
    #define glBindRenderbuffer       glBindRenderbufferOES
    #define GL_FRAMEBUFFER           GL_FRAMEBUFFER_OES
@@ -386,7 +396,6 @@ static int curStack = 0;
    #define glDeleteFramebuffers     glDeleteFramebuffersOES
    #define glDeleteRenderbuffers    glDeleteRenderbuffersOES
 
-#if defined(__ANDROID__)
    #define GL_POLYGON_STIPPLE 0xFFFF
    #define GL_LINE_STIPPLE 0xFFFF
    #define GL_LINE 0xFFFF
@@ -422,6 +431,7 @@ static int curStack = 0;
    #define glColor4fv            glesColor4fv
    #define glLineStipple         glesLineStipple
    #define glNormal3fv           glesNormal3fv
+   #define glNormal3f            glesNormal3f
    #define glTexCoord2fv         glesTexCoord2fv
    #define glColorMaterial       glesColorMaterial
 
@@ -576,9 +586,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)
 {
@@ -595,10 +608,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];
    }
 }
@@ -610,20 +628,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++;
    }
 }
@@ -634,23 +652,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++;
@@ -663,10 +683,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);
@@ -676,8 +702,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
@@ -736,19 +767,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)
@@ -989,26 +1060,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++;
@@ -1138,6 +1211,18 @@ void (APIENTRY * glBufferDataARB) (GLenum target, int size, const GLvoid *data,
 
 static int currentVertexBuffer;
 
+public void GLLoadMatrix(Matrix matrix)
+{
+   float m[16] =
+   {
+      (float)matrix.m[0][0], (float)matrix.m[0][1], (float)matrix.m[0][2], (float)matrix.m[0][3],
+      (float)matrix.m[1][0], (float)matrix.m[1][1], (float)matrix.m[1][2], (float)matrix.m[1][3],
+      (float)matrix.m[2][0], (float)matrix.m[2][1], (float)matrix.m[2][2], (float)matrix.m[2][3],
+      (float)matrix.m[3][0], (float)matrix.m[3][1], (float)matrix.m[3][2], (float)matrix.m[3][3]
+   };
+   glLoadMatrixf(m);
+}
+
 bool GLSelectVBO(uint vbo)
 {
    if(currentVertexBuffer != vbo)
@@ -1183,6 +1268,8 @@ void GLBindBuffer(int target, uint buffer)
 #endif
       glBindBufferARB(target, buffer);
 #endif
+   if(target == GL_ARRAY_BUFFER_ARB)
+      currentVertexBuffer = buffer;
 }
 
 public void GLVertexPointer(int numCoords, int glType, int stride, void *ptr, int numVertices)
@@ -3675,7 +3762,6 @@ class OpenGLDisplayDriver : DisplayDriver
          mesh.data = OGLMesh { };
       if(mesh.data)
       {
-         OGLMesh oglMesh = mesh.data;
          if(mesh.nVertices == nVertices)
          {
             // Same number of vertices, adding features (Leaves the other features pointers alone)
@@ -3689,8 +3775,6 @@ class OpenGLDisplayDriver : DisplayDriver
                   }
                   else
                      mesh.vertices = new Vector3Df[nVertices];
-                  if(!oglMesh.vertices)
-                     GLGenBuffers(1, &oglMesh.vertices);
                }
                if(!mesh.flags.normals && flags.normals)
                {
@@ -3700,20 +3784,14 @@ class OpenGLDisplayDriver : DisplayDriver
                   }
                   else
                      mesh.normals = new Vector3Df[nVertices];
-                  if(!oglMesh.normals)
-                     GLGenBuffers( 1, &oglMesh.normals);
                }
                if(!mesh.flags.texCoords1 && flags.texCoords1)
                {
                   mesh.texCoords = new Pointf[nVertices];
-                  if(!oglMesh.texCoords)
-                     GLGenBuffers( 1, &oglMesh.texCoords);
                }
                if(!mesh.flags.colors && flags.colors)
                {
                   mesh.colors = new ColorRGBAf[nVertices];
-                  if(!oglMesh.colors)
-                     GLGenBuffers( 1, &oglMesh.colors);
                }
             }
          }
@@ -3729,8 +3807,6 @@ class OpenGLDisplayDriver : DisplayDriver
                }
                else
                   mesh.vertices = renew mesh.vertices Vector3Df[nVertices];
-               if(!oglMesh.vertices)
-                  GLGenBuffers(1, &oglMesh.vertices);
             }
             if(flags.normals)
             {
@@ -3740,20 +3816,14 @@ class OpenGLDisplayDriver : DisplayDriver
                }
                else
                   mesh.normals = renew mesh.normals Vector3Df[nVertices];
-               if(!oglMesh.normals)
-                  GLGenBuffers( 1, &oglMesh.normals);
             }
             if(flags.texCoords1)
             {
                mesh.texCoords = renew mesh.texCoords Pointf[nVertices];
-               if(!oglMesh.texCoords)
-                  GLGenBuffers( 1, &oglMesh.texCoords);
             }
             if(flags.colors)
             {
                mesh.colors = renew mesh.colors ColorRGBAf[nVertices];
-               if(!oglMesh.colors)
-                  GLGenBuffers( 1, &oglMesh.colors);
             }
          }
          result = true;
@@ -3768,26 +3838,34 @@ class OpenGLDisplayDriver : DisplayDriver
 
       if(vboAvailable)
       {
-         if(flags.vertices && oglMesh.vertices)
+         if(flags.vertices)
          {
+            if(!oglMesh.vertices)
+               GLGenBuffers(1, &oglMesh.vertices);
             GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.vertices);
             GLBufferData( mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT, GL_ARRAY_BUFFER_ARB, mesh.nVertices * (mesh.flags.doubleVertices ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.vertices, GL_STATIC_DRAW_ARB );
          }
 
-         if(flags.normals && oglMesh.normals)
+         if(flags.normals)
          {
+            if(!oglMesh.normals)
+               GLGenBuffers(1, &oglMesh.normals);
             GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.normals);
             GLBufferData( mesh.flags.doubleNormals ? GL_DOUBLE : GL_FLOAT, GL_ARRAY_BUFFER_ARB, mesh.nVertices * (mesh.flags.doubleNormals ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.normals, GL_STATIC_DRAW_ARB );
          }
 
-         if(flags.texCoords1 && oglMesh.texCoords)
+         if(flags.texCoords1)
          {
+            if(!oglMesh.texCoords)
+               GLGenBuffers(1, &oglMesh.texCoords);
             GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.texCoords);
             GLBufferData( GL_FLOAT, GL_ARRAY_BUFFER_ARB, mesh.nVertices * sizeof(Pointf), mesh.texCoords, GL_STATIC_DRAW_ARB );
          }
 
-         if(flags.colors && oglMesh.colors)
+         if(flags.colors)
          {
+            if(!oglMesh.colors)
+               GLGenBuffers( 1, &oglMesh.colors);
             GLBindBuffer( GL_ARRAY_BUFFER_ARB, oglMesh.colors);
             GLBufferData( GL_FLOAT, GL_ARRAY_BUFFER_ARB, mesh.nVertices * sizeof(ColorRGBAf), mesh.colors, GL_STATIC_DRAW_ARB );
          }
@@ -3866,16 +3944,16 @@ class OpenGLDisplayDriver : DisplayDriver
          {
             GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.vertices );
             if(mesh.flags.doubleVertices)
-               glVertexPointerd(3, 0, (double *)(vboAvailable ? null : mesh.vertices), mesh.nVertices);
+               glVertexPointerd(3, 0, oglMesh.vertices ? null : (double *)mesh.vertices, mesh.nVertices);
             else
-               glVertexPointer(3, GL_FLOAT, 0, vboAvailable ? null : mesh.vertices);
+               glVertexPointer(3, GL_FLOAT, 0, oglMesh.vertices ? null : mesh.vertices);
 
             // *** Normals Stream ***
             if(mesh.normals || mesh.flags.normals)
             {
                glEnableClientState(GL_NORMAL_ARRAY);
                GLBindBuffer(GL_ARRAY_BUFFER_ARB, oglMesh.normals);
-               glNormalPointer(/*mesh.flags.doubleNormals ? GL_DOUBLE : */GL_FLOAT, 0, vboAvailable ? null : mesh.normals);
+               glNormalPointer(/*mesh.flags.doubleNormals ? GL_DOUBLE : */GL_FLOAT, 0, oglMesh.normals ? null : mesh.normals);
             }
             else
                glDisableClientState(GL_NORMAL_ARRAY);
@@ -3885,7 +3963,7 @@ class OpenGLDisplayDriver : DisplayDriver
             {
                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
                GLBindBuffer( GL_ARRAY_BUFFER_ARB, oglMesh.texCoords);
-               glTexCoordPointer(2, GL_FLOAT, 0, vboAvailable ? null : mesh.texCoords);
+               glTexCoordPointer(2, GL_FLOAT, 0, oglMesh.texCoords ? null : mesh.texCoords);
             }
             else
                glDisableClientState(GL_TEXTURE_COORD_ARRAY);
@@ -3895,11 +3973,10 @@ class OpenGLDisplayDriver : DisplayDriver
             {
                glEnableClientState(GL_COLOR_ARRAY);
                GLBindBuffer( GL_ARRAY_BUFFER_ARB, oglMesh.colors);
-               glColorPointer(4, GL_FLOAT, 0, vboAvailable ? null : mesh.colors);
+               glColorPointer(4, GL_FLOAT, 0, oglMesh.colors ? null : mesh.colors);
             }
             else
                glDisableClientState(GL_COLOR_ARRAY);
-
          }
          else
          {