DEADSOFTWARE

glIsEnabled uses interanl structures, added glPushAttrib/glPopAttrib (not fully imple...
[nanogl.git] / nanoWrap.cpp
index b46b4c796cf1dff53a3d1beea2b600141a8f48b4..62e37ad3382b9be144ba24a03a1b5324629a60c9 100644 (file)
@@ -44,7 +44,14 @@ struct nanoState
        GLboolean depth_test;
        GLboolean dither;
        GLboolean fog;
-       GLboolean lighti;
+       GLboolean light0;
+       GLboolean light1;
+       GLboolean light2;
+       GLboolean light3;
+       GLboolean light4;
+       GLboolean light5;
+       GLboolean light6;
+       GLboolean light7;
        GLboolean lighting;
        GLboolean line_smooth;
        GLboolean matrix_palette_oes;
@@ -60,9 +67,8 @@ struct nanoState
        GLboolean scissor_test;
        GLboolean stencil_test;
        GLboolean depthmask;
-       GLboolean stupidglesbug;
-       GLclampf depth_range_near;
-       GLclampf depth_range_far;
+       GLclampd depth_range_near;
+       GLclampd depth_range_far;
        GLenum depth_func;
        GLenum cullface;
        GLenum shademodel;
@@ -88,6 +94,13 @@ static struct nanoState nanoglInitState =
         GL_FALSE,
         GL_FALSE,
         GL_FALSE,
+        GL_FALSE,
+        GL_FALSE,
+        GL_FALSE,
+        GL_FALSE,
+        GL_FALSE,
+        GL_FALSE,
+        GL_FALSE,
         GL_TRUE,
         GL_FALSE,
         GL_FALSE,
@@ -100,7 +113,6 @@ static struct nanoState nanoglInitState =
         GL_FALSE,
         GL_FALSE,
         GL_TRUE,
-               GL_FALSE,
         0.0f,
         1.0f,
         GL_LESS,
@@ -166,7 +178,7 @@ static struct nanotmuState tmuInitState =
 
 static struct nanotmuState *activetmuState = &tmuState0;
 
-extern "C++" GlESInterface *glEsImpl;
+extern GlESInterface *glEsImpl;
 
 static GLenum wrapperPrimitiveMode = GL_QUADS;
 GLboolean useTexCoordArray         = GL_FALSE;
@@ -232,6 +244,66 @@ static GLushort *ptrIndexArray = NULL;
 
 static GLboolean arraysValid = GL_FALSE;
 
+static GLboolean skipnanogl;
+
+#define STACK_ATTRIB_ENABLE_BIT_LEN (sizeof(stackAttribEnableBit) / sizeof(stackAttribEnableBit[0]))
+static const GLenum stackAttribEnableBit[] =
+{
+       GL_ALPHA_TEST,
+       GL_BLEND,
+       GL_CLIP_PLANE0,
+       GL_CLIP_PLANE1,
+       GL_CLIP_PLANE2,
+       GL_CLIP_PLANE3,
+       GL_CLIP_PLANE4,
+       GL_CLIP_PLANE5,
+       GL_COLOR_MATERIAL,
+       GL_CULL_FACE,
+       GL_DEPTH_TEST,
+       GL_DITHER,
+       GL_FOG,
+       GL_LIGHT0,
+       GL_LIGHT1,
+       GL_LIGHT2,
+       GL_LIGHT3,
+       GL_LIGHT4,
+       GL_LIGHT5,
+       GL_LIGHT6,
+       GL_LIGHT7,
+       GL_LIGHTING,
+       GL_LINE_SMOOTH,
+       GL_COLOR_LOGIC_OP,
+       GL_MULTISAMPLE,
+       GL_NORMALIZE,
+       GL_POINT_SMOOTH,
+       GL_POLYGON_OFFSET_LINE,
+       GL_POLYGON_OFFSET_FILL,
+       GL_POLYGON_OFFSET_POINT,
+       GL_POLYGON_SMOOTH,
+       GL_POLYGON_STIPPLE,
+       GL_SAMPLE_ALPHA_TO_COVERAGE,
+       GL_SAMPLE_ALPHA_TO_ONE,
+       GL_SAMPLE_COVERAGE,
+       GL_SCISSOR_TEST,
+       GL_STENCIL_TEST,
+       GL_TEXTURE_1D,
+       GL_TEXTURE_2D,
+       GL_TEXTURE_GEN_S,
+       GL_TEXTURE_GEN_T,
+       GL_TEXTURE_GEN_R,
+       GL_TEXTURE_GEN_Q,
+};
+
+#define MAX_ATTRIB_STACK 16
+struct attribStore
+{
+       GLbitfield mask;
+       GLboolean enable[STACK_ATTRIB_ENABLE_BIT_LEN];
+};
+
+static struct attribStore attribStack[MAX_ATTRIB_STACK];
+static int attribStackCount = 0;
+
 void InitGLStructs( )
 {
        ptrVertexAttribArray     = vertexattribs;
@@ -255,6 +327,9 @@ void InitGLStructs( )
        vertexMark           = 0;
        indexbase            = 0;
        arraysValid          = GL_FALSE;
+
+       memset(attribStack, 0, sizeof( struct attribStore ));
+       attribStackCount = 0;
 }
 
 void ResetNanoState( )
@@ -317,7 +392,8 @@ void ResetNanoState( )
 
        glEsImpl->glMatrixMode( nanoglState.matrixmode );
 
-       glEsImpl->glColor4f( currentVertexAttrib.red, currentVertexAttrib.green, currentVertexAttrib.blue, currentVertexAttrib.alpha );
+       glEsImpl->glColor4f( currentVertexAttrib.red/255.0f, currentVertexAttrib.green/255.0f,
+                currentVertexAttrib.blue/255.0f, currentVertexAttrib.alpha/255.0f );
 
        glEsImpl->glBlendFunc( nanoglState.sfactor, nanoglState.dfactor );
 
@@ -326,10 +402,16 @@ void ResetNanoState( )
        glEsImpl->glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, activetmuState->texture_env_mode.value );
 
        arraysValid = GL_FALSE;
+       skipnanogl = GL_FALSE;
+
+       memset(attribStack, 0, sizeof( struct attribStore ));
+       attribStackCount = 0;
 }
 
 void FlushOnStateChange( )
 {
+       if( skipnanogl )
+               return;
        if ( delayedttmuchange )
        {
                delayedttmuchange = GL_FALSE;
@@ -487,7 +569,7 @@ void glEnd( void )
                *ptrIndexArray++ = indexCount++;
                *ptrIndexArray++ = indexCount++;
                *ptrIndexArray++ = indexCount++;
-               int vcount = ( ( vertexCount - vertexMark ) - 3 );
+               int vcount       = ( ( vertexCount - vertexMark ) - 3 );
                for ( int count = 0; count < vcount; count++ )
                {
                        *ptrIndexArray++ = indexbase;
@@ -508,6 +590,11 @@ void glEnd( void )
 
 void glEnable( GLenum cap )
 {
+       if( skipnanogl )
+       {
+               glEsImpl->glEnable( cap );
+               return;
+       }
        GLboolean statechanged = GL_FALSE;
        switch ( cap )
        {
@@ -576,15 +663,86 @@ void glEnable( GLenum cap )
                break;
        }
        case GL_FOG:
-               //case GL_LIGHTi
+       {
+               if ( !nanoglState.fog )
                {
-                       if ( !nanoglState.fog )
-                       {
-                               nanoglState.fog = GL_TRUE;
-                               statechanged    = GL_TRUE;
-                       }
-                       break;
+                       nanoglState.fog = GL_TRUE;
+                       statechanged    = GL_TRUE;
+               }
+               break;
+       }
+       case GL_LIGHT0:
+       {
+               if ( !nanoglState.light0 )
+               {
+                       nanoglState.light0 = GL_TRUE;
+                       statechanged       = GL_TRUE;
+               }
+               break;
+       }
+       case GL_LIGHT1:
+       {
+               if ( !nanoglState.light1 )
+               {
+                       nanoglState.light1 = GL_TRUE;
+                       statechanged       = GL_TRUE;
+               }
+               break;
+       }
+       case GL_LIGHT2:
+       {
+               if ( !nanoglState.light2 )
+               {
+                       nanoglState.light2 = GL_TRUE;
+                       statechanged       = GL_TRUE;
                }
+               break;
+       }
+       case GL_LIGHT3:
+       {
+               if ( !nanoglState.light3 )
+               {
+                       nanoglState.light3 = GL_TRUE;
+                       statechanged       = GL_TRUE;
+               }
+               break;
+       }
+       case GL_LIGHT4:
+       {
+               if ( !nanoglState.light4 )
+               {
+                       nanoglState.light4 = GL_TRUE;
+                       statechanged       = GL_TRUE;
+               }
+               break;
+       }
+       case GL_LIGHT5:
+       {
+               if ( !nanoglState.light5 )
+               {
+                       nanoglState.light5 = GL_TRUE;
+                       statechanged       = GL_TRUE;
+               }
+               break;
+       }
+       case GL_LIGHT6:
+       {
+               if ( !nanoglState.light6 )
+               {
+                       nanoglState.light6 = GL_TRUE;
+                       statechanged       = GL_TRUE;
+               }
+               break;
+       }
+       case GL_LIGHT7:
+       {
+               if ( !nanoglState.light7 )
+               {
+                       nanoglState.light7 = GL_TRUE;
+                       statechanged       = GL_TRUE;
+               }
+               break;
+       }
        case GL_LIGHTING:
        {
                if ( !nanoglState.lighting )
@@ -695,12 +853,11 @@ void glEnable( GLenum cap )
        }
        case GL_STENCIL_TEST:
        {
-               return;
-               /*            if (!nanoglState.stencil_test)
-                {
-                nanoglState.stencil_test = GL_TRUE;
-                statechanged = GL_TRUE;
-                }*/
+               if (!nanoglState.stencil_test)
+               {
+                       nanoglState.stencil_test = GL_TRUE;
+                       statechanged = GL_TRUE;
+               }
                break;
        }
        case GL_TEXTURE_2D:
@@ -714,6 +871,17 @@ void glEnable( GLenum cap )
                }
                break;
        }
+#if 0 // todo: implement cubemap texgen
+       case GL_TEXTURE_GEN_S:
+       case GL_TEXTURE_GEN_T:
+       case GL_TEXTURE_GEN_R:
+       case GL_TEXTURE_GEN_Q:
+       {
+               FlushOnStateChange( );
+               nanoglState.texgen = true;
+               return;
+       }
+#endif
        default:
                break;
        }
@@ -727,6 +895,11 @@ void glEnable( GLenum cap )
 
 void glDisable( GLenum cap )
 {
+       if( skipnanogl )
+       {
+               glEsImpl->glDisable( cap );
+               return;
+       }
        GLboolean statechanged = GL_FALSE;
        switch ( cap )
        {
@@ -795,15 +968,86 @@ void glDisable( GLenum cap )
                break;
        }
        case GL_FOG:
-               //case GL_LIGHTi
+       {
+               if ( nanoglState.fog )
                {
-                       if ( nanoglState.fog )
-                       {
-                               nanoglState.fog = GL_FALSE;
-                               statechanged    = GL_TRUE;
-                       }
-                       break;
+                       nanoglState.fog = GL_FALSE;
+                       statechanged    = GL_TRUE;
+               }
+               break;
+       }
+       case GL_LIGHT0:
+       {
+               if ( !nanoglState.light0 )
+               {
+                       nanoglState.light0 = GL_FALSE;
+                       statechanged       = GL_TRUE;
+               }
+               break;
+       }
+       case GL_LIGHT1:
+       {
+               if ( !nanoglState.light1 )
+               {
+                       nanoglState.light1 = GL_FALSE;
+                       statechanged       = GL_TRUE;
                }
+               break;
+       }
+       case GL_LIGHT2:
+       {
+               if ( !nanoglState.light2 )
+               {
+                       nanoglState.light2 = GL_FALSE;
+                       statechanged       = GL_TRUE;
+               }
+               break;
+       }
+       case GL_LIGHT3:
+       {
+               if ( !nanoglState.light3 )
+               {
+                       nanoglState.light3 = GL_FALSE;
+                       statechanged       = GL_TRUE;
+               }
+               break;
+       }
+       case GL_LIGHT4:
+       {
+               if ( !nanoglState.light4 )
+               {
+                       nanoglState.light4 = GL_FALSE;
+                       statechanged       = GL_TRUE;
+               }
+               break;
+       }
+       case GL_LIGHT5:
+       {
+               if ( !nanoglState.light5 )
+               {
+                       nanoglState.light5 = GL_FALSE;
+                       statechanged       = GL_TRUE;
+               }
+               break;
+       }
+       case GL_LIGHT6:
+       {
+               if ( !nanoglState.light6 )
+               {
+                       nanoglState.light6 = GL_FALSE;
+                       statechanged       = GL_TRUE;
+               }
+               break;
+       }
+       case GL_LIGHT7:
+       {
+               if ( !nanoglState.light7 )
+               {
+                       nanoglState.light7 = GL_FALSE;
+                       statechanged       = GL_TRUE;
+               }
+               break;
+       }
        case GL_LIGHTING:
        {
                if ( nanoglState.lighting )
@@ -914,12 +1158,11 @@ void glDisable( GLenum cap )
        }
        case GL_STENCIL_TEST:
        {
-               return;
-               /*            if (nanoglState.stencil_test)
-                {
-                nanoglState.stencil_test = GL_FALSE;
-                statechanged = GL_TRUE;
-                }*/
+               if (nanoglState.stencil_test)
+               {
+                       nanoglState.stencil_test = GL_FALSE;
+                       statechanged = GL_TRUE;
+               }
                break;
        }
        case GL_TEXTURE_2D:
@@ -933,6 +1176,17 @@ void glDisable( GLenum cap )
                }
                break;
        }
+#if 0
+       case GL_TEXTURE_GEN_S:
+       case GL_TEXTURE_GEN_T:
+       case GL_TEXTURE_GEN_R:
+       case GL_TEXTURE_GEN_Q:
+       {
+               FlushOnStateChange( );
+               nanoglState.texgen = false;
+               return;
+       }
+#endif
        default:
                break;
        }
@@ -991,23 +1245,14 @@ void glLoadIdentity( void )
 }
 
 void glColor4f( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha )
-{      
-       if( nanoglState.stupidglesbug )
-       {
-               currentVertexAttrib.red = (unsigned char)ClampTo255( ( red * alpha ) * 255.0f );
-               currentVertexAttrib.green = (unsigned char)ClampTo255( ( green * alpha ) * 255.0f );
-               currentVertexAttrib.blue = (unsigned char)ClampTo255( ( blue * alpha ) * 255.0f );
-       }
-       else
-       {
-               currentVertexAttrib.red   = (unsigned char)ClampTo255( red * 255.0f );
-               currentVertexAttrib.green = (unsigned char)ClampTo255( green * 255.0f );
-               currentVertexAttrib.blue  = (unsigned char)ClampTo255( blue * 255.0f );
-       }
+{
+       currentVertexAttrib.red   = (unsigned char)ClampTo255( red * 255.0f );
+       currentVertexAttrib.green = (unsigned char)ClampTo255( green * 255.0f );
+       currentVertexAttrib.blue  = (unsigned char)ClampTo255( blue * 255.0f );
        currentVertexAttrib.alpha = (unsigned char)ClampTo255( alpha * 255.0f );
 }
 
-void glOrtho( GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar )
+void glOrtho( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar )
 {
        FlushOnStateChange( );
 #ifdef USE_CORE_PROFILE
@@ -1017,6 +1262,50 @@ void glOrtho( GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat
 #endif
 }
 
+// Rikku2000: Light
+void glLightf( GLenum light, GLenum pname, GLfloat param )
+{
+       FlushOnStateChange( );
+
+       glEsImpl->glLightf( light, pname, param );
+}
+void glLightfv( GLenum light, GLenum pname, const GLfloat *params )
+{
+       FlushOnStateChange( );
+
+       glEsImpl->glLightfv( light, pname, params );
+}
+void glLightModelf( GLenum pname, GLfloat param )
+{
+       FlushOnStateChange( );
+
+       glEsImpl->glLightModelf( pname, param );
+}
+void glLightModelfv( GLenum pname, const GLfloat *params )
+{
+       FlushOnStateChange( );
+
+       glEsImpl->glLightModelfv( pname, params );
+}
+void glMaterialf( GLenum face, GLenum pname, GLfloat param )
+{
+       FlushOnStateChange( );
+
+       glEsImpl->glMaterialf( face, pname, param );
+}
+void glMaterialfv( GLenum face, GLenum pname, const GLfloat *params )
+{
+       FlushOnStateChange( );
+
+       glEsImpl->glMaterialfv( face, pname, params );
+}
+void glColorMaterial( GLenum face, GLenum mode )
+{
+       FlushOnStateChange( );
+
+       glEsImpl->glColorMaterial( face, mode );
+}
+
 void glMatrixMode( GLenum mode )
 {
        if ( nanoglState.matrixmode == mode )
@@ -1052,9 +1341,27 @@ void glTexParameterfv( GLenum target, GLenum pname, const GLfloat *params )
 
 void glTexImage2D( GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels )
 {
-       FlushOnStateChange( );
+       unsigned char *data = (unsigned char*)pixels;
+
+       if( pixels && internalformat == GL_RGB && format == GL_RGBA ) // strip alpha from texture
+       {
+               unsigned char *in = data, *out;
+               int i = 0, size = width * height * 4;
+
+               data = out = (unsigned char*)malloc( size );
+       
+               for( i = 0; i < size; i += 4, in += 4, out += 4 )
+               {
+                       memcpy( out, in, 3 );
+                       out[3] = 255;
+               }
+       }
+               
        internalformat = format;
-       glEsImpl->glTexImage2D( target, level, internalformat, width, height, border, format, type, pixels );
+       glEsImpl->glTexImage2D( target, level, internalformat, width, height, border, format, type, data );
+
+       if( data != pixels )
+               free(data);
 }
 
 void glDrawBuffer( GLenum /*mode*/ )
@@ -1079,7 +1386,7 @@ void glScalef( GLfloat x, GLfloat y, GLfloat z )
        glEsImpl->glScalef( x, y, z );
 }
 
-void glDepthRange( GLclampf zNear, GLclampf zFar )
+void glDepthRange( GLclampd zNear, GLclampd zFar )
 {
        if ( ( nanoglState.depth_range_near == zNear ) && ( nanoglState.depth_range_far == zFar ) )
        {
@@ -1138,7 +1445,7 @@ void glCullFace( GLenum mode )
        glEsImpl->glCullFace( mode );
 }
 
-void glFrustum( GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar )
+void glFrustum( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar )
 {
        FlushOnStateChange( );
        glEsImpl->glFrustumf( left, right, bottom, top, zNear, zFar );
@@ -1155,7 +1462,7 @@ void glVertex3f( GLfloat x, GLfloat y, GLfloat z )
        GLfloat *vert = (GLfloat *)ptrVertexAttribArray++;
        *vert++       = x;
        *vert++       = y;
-       *vert++ = z;
+       *vert++       = z;
 #if defined( __MULTITEXTURE_SUPPORT__ )
        memcpy( vert, &currentVertexAttrib.red, 5 * sizeof( GLfloat ) );
 #else
@@ -1164,20 +1471,14 @@ void glVertex3f( GLfloat x, GLfloat y, GLfloat z )
 }
 
 void glColor4fv( const GLfloat *v )
-{      
-       if( nanoglState.stupidglesbug )
-       {
-               currentVertexAttrib.red = (unsigned char)ClampTo255( ( v[0] * v[3] ) * 255.0f );
-               currentVertexAttrib.green = (unsigned char)ClampTo255( ( v[1] * v[3] ) * 255.0f );
-               currentVertexAttrib.blue = (unsigned char)ClampTo255( ( v[2] * v[3] ) * 255.0f );
-       }
-       else
-       {
-               currentVertexAttrib.red   = (unsigned char)ClampTo255( v[0] * 255.0f );
-               currentVertexAttrib.green = (unsigned char)ClampTo255( v[1] * 255.0f );
-               currentVertexAttrib.blue  = (unsigned char)ClampTo255( v[2] * 255.0f );
-       }
+{
+       currentVertexAttrib.red   = (unsigned char)ClampTo255( v[0] * 255.0f );
+       currentVertexAttrib.green = (unsigned char)ClampTo255( v[1] * 255.0f );
+       currentVertexAttrib.blue  = (unsigned char)ClampTo255( v[2] * 255.0f );
        currentVertexAttrib.alpha = (unsigned char)ClampTo255( v[3] * 255.0f );
+       if( skipnanogl )
+               glEsImpl->glColor4f( currentVertexAttrib.red/255.0f, currentVertexAttrib.green/255.0f,
+                        currentVertexAttrib.blue/255.0f, currentVertexAttrib.alpha/255.0f );
 }
 
 void glColor3ubv( const GLubyte *v )
@@ -1186,24 +1487,21 @@ void glColor3ubv( const GLubyte *v )
        currentVertexAttrib.green = v[1];
        currentVertexAttrib.blue  = v[2];
        currentVertexAttrib.alpha = 255;
+       if( skipnanogl )
+               glEsImpl->glColor4f( currentVertexAttrib.red/255.0f, currentVertexAttrib.green/255.0f,
+                        currentVertexAttrib.blue/255.0f, currentVertexAttrib.alpha/255.0f );
 }
 
 void glColor4ubv( const GLubyte *v )
 {
        //*((unsigned int*)(&currentVertexAttrib.red)) = *((unsigned int*)(v));
-       if( nanoglState.stupidglesbug )
-       {
-               currentVertexAttrib.red   = (unsigned char)ClampTo255( v[0] * v[3] / 255.0f );
-               currentVertexAttrib.green = (unsigned char)ClampTo255( v[1] * v[3] / 255.0f );
-               currentVertexAttrib.blue  = (unsigned char)ClampTo255( v[2] * v[3] / 255.0f );
-       }
-       else
-       {
-               currentVertexAttrib.red   = v[0];
-               currentVertexAttrib.green = v[1];
-               currentVertexAttrib.blue  = v[2];
-       }
+       currentVertexAttrib.red   = v[0];
+       currentVertexAttrib.green = v[1];
+       currentVertexAttrib.blue  = v[2];
        currentVertexAttrib.alpha = v[3];
+       if( skipnanogl )
+               glEsImpl->glColor4f( currentVertexAttrib.red/255.0f, currentVertexAttrib.green/255.0f,
+                        currentVertexAttrib.blue/255.0f, currentVertexAttrib.alpha/255.0f );
 }
 
 void glColor3fv( const GLfloat *v )
@@ -1212,25 +1510,22 @@ void glColor3fv( const GLfloat *v )
        currentVertexAttrib.green = (unsigned char)ClampTo255( v[1] * 255.0f );
        currentVertexAttrib.blue  = (unsigned char)ClampTo255( v[2] * 255.0f );
        currentVertexAttrib.alpha = 255;
+       if( skipnanogl )
+               glEsImpl->glColor4f( currentVertexAttrib.red/255.0f, currentVertexAttrib.green/255.0f,
+                        currentVertexAttrib.blue/255.0f, currentVertexAttrib.alpha/255.0f );
 }
 
 //-- nicknekit: xash3d funcs --
 
 void glColor4ub( GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha )
 {
-       if( nanoglState.stupidglesbug )
-       {
-               currentVertexAttrib.red   = (unsigned char)ClampTo255( red   * alpha / 255.0f );
-               currentVertexAttrib.green = (unsigned char)ClampTo255( green * alpha / 255.0f );
-               currentVertexAttrib.blue  = (unsigned char)ClampTo255( blue  * alpha / 255.0f );
-       }
-       else
-       {
-               currentVertexAttrib.red   = red;
-               currentVertexAttrib.green = green;
-               currentVertexAttrib.blue  = blue;
-       }
+       currentVertexAttrib.red   = red;
+       currentVertexAttrib.green = green;
+       currentVertexAttrib.blue  = blue;
        currentVertexAttrib.alpha = alpha;
+       if( skipnanogl )
+               glEsImpl->glColor4f( currentVertexAttrib.red/255.0f, currentVertexAttrib.green/255.0f,
+                        currentVertexAttrib.blue/255.0f, currentVertexAttrib.alpha/255.0f );
 }
 
 void glColor3ub( GLubyte red, GLubyte green, GLubyte blue )
@@ -1239,6 +1534,9 @@ void glColor3ub( GLubyte red, GLubyte green, GLubyte blue )
        currentVertexAttrib.green = green;
        currentVertexAttrib.blue  = blue;
        currentVertexAttrib.alpha = 255;
+       if( skipnanogl )
+               glEsImpl->glColor4f( currentVertexAttrib.red/255.0f, currentVertexAttrib.green/255.0f,
+                        currentVertexAttrib.blue/255.0f, currentVertexAttrib.alpha/255.0f );
 }
 
 void glNormal3fv( const GLfloat *v )
@@ -1284,14 +1582,18 @@ GLboolean glIsTexture( GLuint texture )
        return glEsImpl->glIsTexture( texture );
 }
 
+// TODO: add native normal/reflection map texgen support
+
 void glTexGeni( GLenum coord, GLenum pname, GLint param )
 {
-       //for mirrors? not needed for original hl?
+       FlushOnStateChange();
+       //glEsImpl->glTexGeniOES( coord, pname, param );
 }
 
 void glTexGenfv( GLenum coord, GLenum pname, const GLfloat *params )
 {
-       //for mirrors? not needed for original hl?
+       FlushOnStateChange();
+       //glEsImpl->glTexGenfvOES( coord, pname, params );
 }
 
 //-- --//
@@ -1304,19 +1606,16 @@ void glHint( GLenum target, GLenum mode )
 
 void glBlendFunc( GLenum sfactor, GLenum dfactor )
 {
-       if ( ( nanoglState.sfactor == sfactor ) && ( nanoglState.dfactor == dfactor ) )
+       if( skipnanogl )
        {
+               glEsImpl->glBlendFunc( sfactor, dfactor );
                return;
        }
-       
-       if( sfactor == GL_SRC_ALPHA && dfactor == GL_ONE ) 
+       if ( ( nanoglState.sfactor == sfactor ) && ( nanoglState.dfactor == dfactor ) )
        {
-               sfactor = GL_ONE; // workaround gles bug
-               nanoglState.stupidglesbug = GL_TRUE;
+               return;
        }
-       else
-               nanoglState.stupidglesbug = GL_FALSE;
-       
+
        nanoglState.sfactor = sfactor;
        nanoglState.dfactor = dfactor;
        FlushOnStateChange( );
@@ -1348,6 +1647,11 @@ void glPushMatrix( void )
 
 void glTexEnvf( GLenum target, GLenum pname, GLfloat param )
 {
+       if( skipnanogl )
+       {
+               glEsImpl->glTexEnvf( target, pname, param );
+               return;
+       }
        if ( target == GL_TEXTURE_ENV )
        {
                if ( pname == GL_TEXTURE_ENV_MODE )
@@ -1382,17 +1686,25 @@ void glVertex3fv( const GLfloat *v )
 
 void glDepthMask( GLboolean flag )
 {
+       if( !skipnanogl )
+       {
        if ( nanoglState.depthmask == flag )
        {
                return;
        }
        nanoglState.depthmask = flag;
        FlushOnStateChange( );
+       }
        glEsImpl->glDepthMask( flag );
 }
 
 void glBindTexture( GLenum target, GLuint texture )
 {
+       if( skipnanogl )
+       {
+               glEsImpl->glBindTexture( target,texture );
+               return;
+       }
        if ( activetmuState->boundtexture.value == texture )
        {
                return;
@@ -1478,6 +1790,42 @@ GLenum glGetError( void )
 
 void glActiveTexture( GLenum texture )
 {
+       if( skipnanogl )
+       {
+               glEsImpl->glActiveTexture( texture );
+               return;
+       }
+       if ( activetmu == texture )
+       {
+               return;
+       }
+       if ( delayedttmuchange )
+       {
+               delayedttmuchange = GL_FALSE;
+       }
+       else
+       {
+               delayedttmuchange = GL_TRUE;
+               delayedtmutarget  = texture;
+       }
+       if ( texture == GL_TEXTURE0 )
+       {
+               activetmuState = &tmuState0;
+       }
+       else
+       {
+               activetmuState = &tmuState1;
+       }
+       activetmu = texture;
+}
+
+void glActiveTextureARB( GLenum texture )
+{
+       if( skipnanogl )
+       {
+               glEsImpl->glActiveTexture( texture );
+               return;
+       }
        if ( activetmu == texture )
        {
                return;
@@ -1504,9 +1852,24 @@ void glActiveTexture( GLenum texture )
 
 void glClientActiveTexture( GLenum texture )
 {
+       if( skipnanogl )
+       {
+               glEsImpl->glClientActiveTexture( texture );
+               return;
+       }
+       clientactivetmu = texture;
+}
+void glClientActiveTextureARB( GLenum texture )
+{
+       if( skipnanogl )
+       {
+               glEsImpl->glClientActiveTexture( texture );
+               return;
+       }
        clientactivetmu = texture;
 }
 
+
 void glPolygonMode( GLenum face, GLenum mode )
 {
 }
@@ -1517,7 +1880,7 @@ void glDeleteTextures( GLsizei n, const GLuint *textures )
        glEsImpl->glDeleteTextures( n, textures );
 }
 
-void glClearDepth( GLclampf depth )
+void glClearDepth( GLclampd depth )
 {
        FlushOnStateChange( );
        glEsImpl->glClearDepthf( depth );
@@ -1557,12 +1920,18 @@ void glCallList( GLuint list )
 }
 void glColorMask( GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha )
 {
+       FlushOnStateChange( );
+       glEsImpl->glColorMask( red, green, blue, alpha );       
 }
 void glStencilFunc( GLenum func, GLint ref, GLuint mask )
 {
+       FlushOnStateChange( );
+       glEsImpl->glStencilFunc( func, ref, mask );     
 }
 void glStencilOp( GLenum fail, GLenum zfail, GLenum zpass )
 {
+       FlushOnStateChange( );
+       glEsImpl->glStencilOp( fail, zfail, zpass );
 }
 
 struct ptrstate vertex_array;
@@ -1571,6 +1940,11 @@ struct ptrstate texture_coord_array;
 
 void glDrawElements( GLenum mode, GLsizei count, GLenum type, const GLvoid *indices )
 {
+       if( skipnanogl )
+       {
+               glEsImpl->glDrawElements( mode, count, type, indices );
+               return;
+       }
        // ensure that all primitives specified between glBegin/glEnd pairs
        // are rendered first, and that we have correct tmu in use..
        FlushOnStateChange( );
@@ -1607,6 +1981,9 @@ void glDrawElements( GLenum mode, GLsizei count, GLenum type, const GLvoid *indi
                else
                {
                        glEsImpl->glDisableClientState( GL_COLOR_ARRAY );
+                       glEsImpl->glColor4f( currentVertexAttrib.red/255.0f, currentVertexAttrib.green/255.0f,
+                                       currentVertexAttrib.blue/255.0f, currentVertexAttrib.alpha/255.0f );
+
                }
                glEsImpl->glColorPointer( tmuState0.color_array.size,
                                          tmuState0.color_array.type,
@@ -1668,8 +2045,17 @@ void glDrawElements( GLenum mode, GLsizei count, GLenum type, const GLvoid *indi
        glEsImpl->glDrawElements( mode, count, type, indices );
 }
 
+bool vboarray;
+
 void glEnableClientState( GLenum array )
 {
+       if( skipnanogl )
+       {
+               glEsImpl->glEnableClientState( array );
+               if( array == GL_VERTEX_ARRAY )
+                       vboarray = true;
+               return;
+       }
        struct nanotmuState *clientstate = NULL;
        if ( clientactivetmu == GL_TEXTURE0 )
        {
@@ -1725,6 +2111,13 @@ void glEnableClientState( GLenum array )
 }
 void glDisableClientState( GLenum array )
 {
+       if( skipnanogl )
+       {
+               glEsImpl->glDisableClientState( array );
+               if( array == GL_VERTEX_ARRAY )
+                       vboarray = false;
+               return;
+       }
        struct nanotmuState *clientstate = NULL;
        if ( clientactivetmu == GL_TEXTURE0 )
        {
@@ -1780,6 +2173,12 @@ void glDisableClientState( GLenum array )
 }
 void glVertexPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer )
 {
+
+       if( skipnanogl )
+       {
+               glEsImpl->glVertexPointer( size, type, stride, pointer );
+               return;
+       }
        if ( tmuState0.vertex_array.size == size &&
             tmuState0.vertex_array.stride == stride &&
             tmuState0.vertex_array.type == type &&
@@ -1795,6 +2194,11 @@ void glVertexPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *poi
 }
 void glTexCoordPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer )
 {
+       if( skipnanogl )
+       {
+               glEsImpl->glTexCoordPointer( size, type, stride, pointer );
+               return;
+       }
        struct nanotmuState *clientstate = NULL;
        if ( clientactivetmu == GL_TEXTURE0 )
        {
@@ -1856,9 +2260,13 @@ void glPolygonOffset( GLfloat factor, GLfloat units )
 }
 void glStencilMask( GLuint mask )
 {
+       FlushOnStateChange( );
+       glEsImpl->glStencilMask( mask );
 }
 void glClearStencil( GLint s )
 {
+       FlushOnStateChange( );
+       glEsImpl->glClearStencil( s );
 }
 
 #if defined( __MULTITEXTURE_SUPPORT__ )
@@ -1897,6 +2305,12 @@ void glPixelStorei( GLenum pname, GLint param )
        glEsImpl->glPixelStorei( pname, param );
 }
 
+void glFogi( GLenum pname, GLint param )
+{
+       FlushOnStateChange( );
+       glEsImpl->glFogf( pname, param );
+}
+
 void glFogf( GLenum pname, GLfloat param )
 {
        FlushOnStateChange( );
@@ -1964,6 +2378,11 @@ void glFrontFace( GLenum mode )
 
 void glTexEnvi( GLenum target, GLenum pname, GLint param )
 {
+       if( skipnanogl )
+       {
+               glEsImpl->glTexEnvi( target, pname, param );
+               return;
+       }
        if ( target == GL_TEXTURE_ENV )
        {
                if ( pname == GL_TEXTURE_ENV_MODE )
@@ -1991,12 +2410,18 @@ void glMultiTexCoord3fARB( GLenum a, GLfloat b, GLfloat c, GLfloat )
        return glMultiTexCoord2fARB( a, b, c );
 }
 
-void glMultiTexCoord2f( GLenum, GLfloat, GLfloat )
+void glMultiTexCoord2f( GLenum a, GLfloat b, GLfloat c )
 {
+       glMultiTexCoord2fARB(a,b,c);
 }
 #endif
 void glDrawArrays( GLenum mode, GLint first, GLsizei count )
 {
+       if( skipnanogl )
+       {
+               glEsImpl->glDrawArrays( mode, first, count );
+               return;
+       }
        // ensure that all primitives specified between glBegin/glEnd pairs
        // are rendered first, and that we have correct tmu in use..
        if ( mode == GL_QUADS )
@@ -2035,6 +2460,9 @@ void glDrawArrays( GLenum mode, GLint first, GLsizei count )
                else
                {
                        glEsImpl->glDisableClientState( GL_COLOR_ARRAY );
+                       glEsImpl->glColor4f( currentVertexAttrib.red/255.0f, currentVertexAttrib.green/255.0f,
+                                       currentVertexAttrib.blue/255.0f, currentVertexAttrib.alpha/255.0f );
+
                }
                glEsImpl->glColorPointer( tmuState0.color_array.size,
                                          tmuState0.color_array.type,
@@ -2158,3 +2586,185 @@ void glRenderbufferStorage( GLenum target, GLenum internalformat, GLsizei width,
        FlushOnStateChange( );
        glEsImpl->glRenderbufferStorage( target, internalformat, width, height );
 }
+
+void glBindBufferARB( GLuint target, GLuint index )
+{
+       static int sindex;
+
+       if( index && !sindex && !skipnanogl )
+               FlushOnStateChange();
+       glEsImpl->glDisableClientState( GL_COLOR_ARRAY );
+       glEsImpl->glColor4f( currentVertexAttrib.red/255.0f, currentVertexAttrib.green/255.0f,
+                currentVertexAttrib.blue/255.0f, currentVertexAttrib.alpha/255.0f );
+
+       skipnanogl = (!!index) || vboarray;
+       glEsImpl->glBindBuffer( target, index );
+       if( sindex && !index )
+       {
+               arraysValid = GL_FALSE;
+       }
+       sindex = index;
+}
+
+void glGenBuffersARB( GLuint count, GLuint *indexes )
+{
+       glEsImpl->glGenBuffers( count, indexes );
+}
+
+void glDeleteBuffersARB( GLuint count, GLuint *indexes )
+{
+       glEsImpl->glDeleteBuffers( count, indexes );
+}
+
+void glBufferDataARB( GLuint target, GLuint size, void *buffer, GLuint type )
+{
+       glEsImpl->glBufferData( target, size, buffer, type );
+}
+
+void glBufferSubDataARB( GLuint target, GLsizei offset, GLsizei size, void *buffer )
+{
+       glEsImpl->glBufferSubData( target, offset, size, buffer );
+}
+
+GLboolean glIsEnabled(GLenum cap)
+{
+       FlushOnStateChange( );
+
+       if( skipnanogl )
+       {
+               return glEsImpl->glIsEnabled(cap);
+       }
+
+       switch ( cap )
+       {
+       case GL_ALPHA_TEST:
+               return nanoglState.alpha_test;
+       case GL_BLEND:
+               return nanoglState.blend;
+       case GL_COLOR_LOGIC_OP:
+               return nanoglState.color_logic_op;
+       case GL_COLOR_MATERIAL:
+               return nanoglState.color_material;
+       case GL_CULL_FACE:
+               return nanoglState.cull_face;
+       case GL_DEPTH_TEST:
+               return nanoglState.depth_test;
+       case GL_DITHER:
+               return nanoglState.dither;
+       case GL_FOG:
+               return nanoglState.fog;
+       case GL_LIGHT0:
+               return nanoglState.light0;
+       case GL_LIGHT1:
+               return nanoglState.light1;
+       case GL_LIGHT2:
+               return nanoglState.light2;
+       case GL_LIGHT3:
+               return nanoglState.light3;
+       case GL_LIGHT4:
+               return nanoglState.light4;
+       case GL_LIGHT5:
+               return nanoglState.light5;
+       case GL_LIGHT6:
+               return nanoglState.light6;
+       case GL_LIGHT7:
+               return nanoglState.light7;
+       case GL_LIGHTING:
+               return nanoglState.lighting;
+       case GL_LINE_SMOOTH:
+               return nanoglState.line_smooth;
+       case GL_MULTISAMPLE:
+               return nanoglState.multisample;
+       case GL_NORMALIZE:
+               return nanoglState.normalize;
+       case GL_POLYGON_OFFSET_FILL:
+               return nanoglState.polygon_offset_fill;
+       case GL_RESCALE_NORMAL:
+               return nanoglState.rescale_normal;
+       case GL_SAMPLE_ALPHA_TO_COVERAGE:
+               return nanoglState.sample_alpha_to_coverage;
+       case GL_SAMPLE_ALPHA_TO_ONE:
+               return nanoglState.sample_alpha_to_one;
+       case GL_SAMPLE_COVERAGE:
+               return nanoglState.sample_coverage;
+       case GL_SCISSOR_TEST:
+               return nanoglState.scissor_test;
+       case GL_STENCIL_TEST:
+               return nanoglState.stencil_test;
+       case GL_TEXTURE_2D:
+               return activetmuState->texture_2d.value;
+       default:
+               return glIsEnabled(cap);
+       }
+}
+
+void glPushAttrib(GLbitfield mask)
+{
+       FlushOnStateChange( );
+
+       if( (attribStackCount < 0) || (attribStackCount > MAX_ATTRIB_STACK) )
+       {
+               return;
+       }
+
+       attribStack[attribStackCount].mask = mask;
+
+       if( mask & GL_ENABLE_BIT )
+       {
+               for(int i = 0; i < STACK_ATTRIB_ENABLE_BIT_LEN; i++)
+               {
+                       attribStack[attribStackCount].enable[i] = glIsEnabled(stackAttribEnableBit[i]);
+               }
+       }
+
+       if( mask & GL_COLOR_BUFFER_BIT )
+       {
+               // TODO
+       }
+
+       if( mask & GL_CURRENT_BIT )
+       {
+               // TODO
+       }
+
+       attribStackCount += 1;
+}
+
+void glPopAttrib()
+{
+       FlushOnStateChange( );
+
+       attribStackCount -= 1;
+       if((attribStackCount < 0) || (attribStackCount > MAX_ATTRIB_STACK))
+       {
+               attribStackCount += 1;
+               return;
+       }
+       
+       GLbitfield mask = attribStack[attribStackCount].mask;
+
+       if( mask & GL_ENABLE_BIT )
+       {
+               for(int i = 0; i < STACK_ATTRIB_ENABLE_BIT_LEN; i++)
+               {
+                       if( attribStack[attribStackCount].enable[i] )
+                       {
+                               glEnable(stackAttribEnableBit[i]);
+                       }
+                       else
+                       {
+                               glDisable(stackAttribEnableBit[i]);
+                       }
+               }
+       }
+
+       if( mask & GL_COLOR_BUFFER_BIT )
+       {
+               // TODO
+       }
+
+       if( mask & GL_CURRENT_BIT )
+       {
+               // TODO
+       }
+}