DEADSOFTWARE

glIsEnabled uses interanl structures, added glPushAttrib/glPopAttrib (not fully imple...
[nanogl.git] / nanoWrap.cpp
index a2189f3164bffae87fe64c65efb5f2022da995fe..62e37ad3382b9be144ba24a03a1b5324629a60c9 100644 (file)
@@ -30,155 +30,166 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include "glesinterface.h"
 #include "nanogl.h"
 
-#define GL_TEXTURE0_ARB                     0x84C0
-#define GL_TEXTURE1_ARB                     0x84C1
-
-struct nanoState                 
-    {                                  
-    GLboolean alpha_test;              
-    GLboolean blend;                   
-    GLboolean clip_planei;             
-    GLboolean color_logic_op;          
-    GLboolean color_material;          
-    GLboolean cull_face;               
-    GLboolean depth_test;              
-    GLboolean dither;                  
-    GLboolean fog;                     
-    GLboolean lighti;                  
-    GLboolean lighting;                
-    GLboolean line_smooth;             
-    GLboolean matrix_palette_oes;      
-    GLboolean multisample;             
-    GLboolean normalize;               
-    GLboolean point_smooth;            
-    GLboolean point_sprite_oes;        
-    GLboolean polygon_offset_fill;     
-    GLboolean rescale_normal;          
-    GLboolean sample_alpha_to_coverage;
-    GLboolean sample_alpha_to_one;     
-    GLboolean sample_coverage;         
-    GLboolean scissor_test;            
-    GLboolean stencil_test;            
-    GLboolean depthmask;               
-    GLclampf depth_range_near;         
-    GLclampf depth_range_far;          
-    GLenum depth_func;                 
-    GLenum cullface;                   
-    GLenum shademodel;                 
-    GLenum sfactor;                    
-    GLenum dfactor;                    
-    GLenum matrixmode;                 
-    };                                 
+#define GL_TEXTURE0_ARB 0x84C0
+#define GL_TEXTURE1_ARB 0x84C1
+
+struct nanoState
+{
+       GLboolean alpha_test;
+       GLboolean blend;
+       GLboolean clip_planei;
+       GLboolean color_logic_op;
+       GLboolean color_material;
+       GLboolean cull_face;
+       GLboolean depth_test;
+       GLboolean dither;
+       GLboolean fog;
+       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;
+       GLboolean multisample;
+       GLboolean normalize;
+       GLboolean point_smooth;
+       GLboolean point_sprite_oes;
+       GLboolean polygon_offset_fill;
+       GLboolean rescale_normal;
+       GLboolean sample_alpha_to_coverage;
+       GLboolean sample_alpha_to_one;
+       GLboolean sample_coverage;
+       GLboolean scissor_test;
+       GLboolean stencil_test;
+       GLboolean depthmask;
+       GLclampd depth_range_near;
+       GLclampd depth_range_far;
+       GLenum depth_func;
+       GLenum cullface;
+       GLenum shademodel;
+       GLenum sfactor;
+       GLenum dfactor;
+       GLenum matrixmode;
+};
 
 static struct nanoState nanoglState;
 
-static struct nanoState nanoglInitState = 
-    {                                
-    GL_FALSE,                        
-    GL_FALSE,                        
-    GL_FALSE,                        
-    GL_FALSE,                        
-    GL_FALSE,                        
-    GL_FALSE,                        
-    GL_FALSE,                        
-    GL_TRUE,                         
-    GL_FALSE,                        
-    GL_FALSE,                        
-    GL_FALSE,                        
-    GL_FALSE,                        
-    GL_FALSE,                        
-    GL_TRUE,                         
-    GL_FALSE,                        
-    GL_FALSE,                        
-    GL_FALSE,                        
-    GL_FALSE,                        
-    GL_FALSE,                        
-    GL_FALSE,                        
-    GL_FALSE,                        
-    GL_FALSE,                        
-    GL_FALSE,                        
-    GL_FALSE,                        
-    GL_TRUE,                         
-    0.0f,                            
-    1.0f,                            
-    GL_LESS,                         
-    GL_BACK,                         
-    GL_SMOOTH,                       
-    GL_ONE,                          
-    GL_ZERO,                         
-    GL_MODELVIEW,                                        
-    };                               
+static struct nanoState nanoglInitState =
+{
+        GL_FALSE,
+        GL_FALSE,
+        GL_FALSE,
+        GL_FALSE,
+        GL_FALSE,
+        GL_FALSE,
+        GL_FALSE,
+        GL_TRUE,
+        GL_FALSE,
+        GL_FALSE,
+        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,
+        GL_FALSE,
+        GL_FALSE,
+        GL_FALSE,
+        GL_FALSE,
+        GL_FALSE,
+        GL_FALSE,
+        GL_FALSE,
+        GL_FALSE,
+        GL_TRUE,
+        0.0f,
+        1.0f,
+        GL_LESS,
+        GL_BACK,
+        GL_SMOOTH,
+        GL_ONE,
+        GL_ZERO,
+        GL_MODELVIEW,
+};
 
 struct booleanstate
-    {
-    GLboolean value;
-    GLboolean changed;
-    };
+{
+       GLboolean value;
+       GLboolean changed;
+};
 
 struct floatstate
-    {
-    GLfloat value;
-    GLboolean changed;
-    };
-    
+{
+       GLfloat value;
+       GLboolean changed;
+};
+
 struct uintstate
-    {
-    GLuint value;
-    GLboolean changed;
-    };
-    
-struct ptrstate
-    {
-    GLint size;
-    GLenum type;
-    GLsizei stride;
-    GLvoid* ptr;
-    GLboolean changed;
-    GLboolean enabled;
-    };
+{
+       GLuint value;
+       GLboolean changed;
+};
 
+struct ptrstate
+{
+       GLint size;
+       GLenum type;
+       GLsizei stride;
+       GLvoid *ptr;
+       GLboolean changed;
+       GLboolean enabled;
+};
 
 struct nanotmuState
-    {
-    struct booleanstate texture_2d;
-    struct floatstate texture_env_mode;                                         
-    struct uintstate boundtexture;      
-    struct ptrstate vertex_array;                                       
-    struct ptrstate color_array;
-    struct ptrstate texture_coord_array;
-    struct ptrstate normal_array;
-
-    };
+{
+       struct booleanstate texture_2d;
+       struct floatstate texture_env_mode;
+       struct uintstate boundtexture;
+       struct ptrstate vertex_array;
+       struct ptrstate color_array;
+       struct ptrstate texture_coord_array;
+       struct ptrstate normal_array;
+};
 
 static struct nanotmuState tmuState0;
 static struct nanotmuState tmuState1;
-        
-static struct nanotmuState tmuInitState = 
+
+static struct nanotmuState tmuInitState =
     {
-    {GL_FALSE, GL_FALSE},           
-    {GL_MODULATE,GL_FALSE},        
-    {0x7fffffff,GL_FALSE},
-    {4,GL_FLOAT,0, NULL, GL_FALSE, GL_FALSE},
-    {4,GL_FLOAT,0, NULL, GL_FALSE, GL_FALSE},
-    {4,GL_FLOAT,0, NULL, GL_FALSE, GL_FALSE},
-    {3,GL_FLOAT,0, NULL, GL_FALSE, GL_FALSE},
-    };   
+        {GL_FALSE, GL_FALSE},
+        {GL_MODULATE, GL_FALSE},
+        {0x7fffffff, GL_FALSE},
+        {4, GL_FLOAT, 0, NULL, GL_FALSE, GL_FALSE},
+        {4, GL_FLOAT, 0, NULL, GL_FALSE, GL_FALSE},
+        {4, GL_FLOAT, 0, NULL, GL_FALSE, GL_FALSE},
+        {3, GL_FLOAT, 0, NULL, GL_FALSE, GL_FALSE},
+};
 
-static struct nanotmuStateactivetmuState = &tmuState0;
+static struct nanotmuState *activetmuState = &tmuState0;
 
-extern "C++" GlESInterface* glEsImpl;
+extern GlESInterface *glEsImpl;
 
 static GLenum wrapperPrimitiveMode = GL_QUADS;
-GLboolean useTexCoordArray = GL_FALSE;
-static GLenum activetmu = GL_TEXTURE0;
-static GLenum clientactivetmu = GL_TEXTURE0;
+GLboolean useTexCoordArray         = GL_FALSE;
+static GLenum activetmu            = GL_TEXTURE0;
+static GLenum clientactivetmu      = GL_TEXTURE0;
 
-#if defined(__MULTITEXTURE_SUPPORT__)
+#if defined( __MULTITEXTURE_SUPPORT__ )
 GLboolean useMultiTexCoordArray = GL_FALSE;
 #endif
 
-
-#if !defined (__WINS__)
+#if !defined( __WINS__ )
 //#define __FORCEINLINE __forceinline
 #define __FORCEINLINE inline
 #else
@@ -186,431 +197,571 @@ GLboolean useMultiTexCoordArray = GL_FALSE;
 #endif
 
 static GLboolean delayedttmuchange = GL_FALSE;
-static GLenum delayedtmutarget = GL_TEXTURE0;
+static GLenum delayedtmutarget     = GL_TEXTURE0;
 
 struct VertexAttrib
-    {
-    float x;
-    float y;
-    float z;
-#if !defined(__MULTITEXTURE_SUPPORT__)
-    float padding;
+{
+       float x;
+       float y;
+       float z;
+#if !defined( __MULTITEXTURE_SUPPORT__ )
+       float padding;
 #endif
-    unsigned char red;
-    unsigned char green;
-    unsigned char blue;
-    unsigned char alpha;
-    
-    float s;
-    float t;
-#if defined(__MULTITEXTURE_SUPPORT__)
-    float s_multi;
-    float t_multi;
+       unsigned char red;
+       unsigned char green;
+       unsigned char blue;
+       unsigned char alpha;
+
+       float s;
+       float t;
+#if defined( __MULTITEXTURE_SUPPORT__ )
+       float s_multi;
+       float t_multi;
 #endif
-    };
+};
 
-static VertexAttrib vertexattribs[40000];
+static VertexAttrib vertexattribs[60000];
 
-static GLushort indexArray[30000];
+static GLushort indexArray[50000];
 
 static GLuint vertexCount = 0;
-static GLuint indexCount = 0;
-static GLuint vertexMark = 0;
-static int indexbase = 0;
+static GLuint indexCount  = 0;
+static GLuint vertexMark  = 0;
+static int indexbase      = 0;
 
-static VertexAttrib* ptrVertexAttribArray = NULL;
-static VertexAttribptrVertexAttribArrayMark = NULL;
+static VertexAttrib *ptrVertexAttribArray     = NULL;
+static VertexAttrib *ptrVertexAttribArrayMark = NULL;
 
 static VertexAttrib currentVertexAttrib;
-#if defined(__MULTITEXTURE_SUPPORT__)
-static VertexAttrib currentVertexAttribInit = {0.0f,0.0f,0.0f,
-                                    255,255,255,255,
-                                    0.0f,0.0f,
-                                    0.0f,0.0f
-                                    };
+#if defined( __MULTITEXTURE_SUPPORT__ )
+static VertexAttrib currentVertexAttribInit = {0.0f, 0.0f, 0.0f, 255, 255, 255, 255, 0.0f, 0.0f, 0.0f, 0.0f};
 #else
-static VertexAttrib currentVertexAttribInit = {0.0f,0.0f,0.0f,0.0f,
-                                    255,255,255,255,
-                                    0.0f,0.0f,
-                                    };
+static VertexAttrib currentVertexAttribInit = {
+    0.0f, 0.0f, 0.0f, 0.0f, 255, 255, 255, 255, 0.0f, 0.0f,
+};
 #endif
-static GLushortptrIndexArray = NULL;
+static GLushort *ptrIndexArray = NULL;
 
 static GLboolean arraysValid = GL_FALSE;
 
-void InitGLStructs()
-    {
-    ptrVertexAttribArray = vertexattribs;
-    ptrVertexAttribArrayMark = ptrVertexAttribArray;
-    ptrIndexArray = indexArray;
-    
-    memcpy(&nanoglState, &nanoglInitState, sizeof(struct nanoState));
-    memcpy(&tmuState0,&tmuInitState,sizeof(struct nanotmuState));
-    memcpy(&tmuState1,&tmuInitState,sizeof(struct nanotmuState));    
-    memcpy(&currentVertexAttrib,&currentVertexAttribInit,sizeof(struct VertexAttrib));
-    
-    activetmuState = &tmuState0;
-    wrapperPrimitiveMode = GL_QUADS;
-    useTexCoordArray = GL_FALSE;
-    activetmu = GL_TEXTURE0;
-    clientactivetmu = GL_TEXTURE0;
-    delayedttmuchange = GL_FALSE;
-    delayedtmutarget = GL_TEXTURE0;
-    vertexCount = 0;
-    indexCount = 0;
-    vertexMark = 0;
-    indexbase = 0;
-    arraysValid = GL_FALSE;
-    }
-
-void ResetNanoState()
-{
-
-       if (tmuState0.color_array.enabled)
-       {
-               glEsImpl->glEnableClientState(GL_COLOR_ARRAY);
+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;
+       ptrVertexAttribArrayMark = ptrVertexAttribArray;
+       ptrIndexArray            = indexArray;
+
+       memcpy( &nanoglState, &nanoglInitState, sizeof( struct nanoState ) );
+       memcpy( &tmuState0, &tmuInitState, sizeof( struct nanotmuState ) );
+       memcpy( &tmuState1, &tmuInitState, sizeof( struct nanotmuState ) );
+       memcpy( &currentVertexAttrib, &currentVertexAttribInit, sizeof( struct VertexAttrib ) );
+
+       activetmuState       = &tmuState0;
+       wrapperPrimitiveMode = GL_QUADS;
+       useTexCoordArray     = GL_FALSE;
+       activetmu            = GL_TEXTURE0;
+       clientactivetmu      = GL_TEXTURE0;
+       delayedttmuchange    = GL_FALSE;
+       delayedtmutarget     = GL_TEXTURE0;
+       vertexCount          = 0;
+       indexCount           = 0;
+       vertexMark           = 0;
+       indexbase            = 0;
+       arraysValid          = GL_FALSE;
+
+       memset(attribStack, 0, sizeof( struct attribStore ));
+       attribStackCount = 0;
+}
+
+void ResetNanoState( )
+{
+
+       if ( tmuState0.color_array.enabled )
+       {
+               glEsImpl->glEnableClientState( GL_COLOR_ARRAY );
        }
        else
        {
-               glEsImpl->glDisableClientState(GL_COLOR_ARRAY);
+               glEsImpl->glDisableClientState( GL_COLOR_ARRAY );
        }
 
-       if (tmuState0.vertex_array.enabled)
+       if ( tmuState0.vertex_array.enabled )
        {
-               glEsImpl->glEnableClientState(GL_VERTEX_ARRAY);
+               glEsImpl->glEnableClientState( GL_VERTEX_ARRAY );
        }
        else
        {
-               glEsImpl->glDisableClientState(GL_VERTEX_ARRAY);
+               glEsImpl->glDisableClientState( GL_VERTEX_ARRAY );
        }
 
-       if (tmuState0.texture_coord_array.enabled)
+       if ( tmuState0.texture_coord_array.enabled )
        {
-               glEsImpl->glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+               glEsImpl->glEnableClientState( GL_TEXTURE_COORD_ARRAY );
        }
        else
        {
-               glEsImpl->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+               glEsImpl->glDisableClientState( GL_TEXTURE_COORD_ARRAY );
        }
 
-    if (tmuState0.normal_array.enabled)
-    {
-        glEsImpl->glEnableClientState(GL_NORMAL_ARRAY);
-    }
-    else
-    {
-        glEsImpl->glDisableClientState(GL_NORMAL_ARRAY);
-    }
-       glEsImpl->glVertexPointer(tmuState0.vertex_array.size,
-                       tmuState0.vertex_array.type,
-                       tmuState0.vertex_array.stride,
-                       tmuState0.vertex_array.ptr);
-
-       glEsImpl->glTexCoordPointer(tmuState0.texture_coord_array.size,
-                       tmuState0.texture_coord_array.type,
-                       tmuState0.texture_coord_array.stride,
-                       tmuState0.texture_coord_array.ptr);
-
-       glEsImpl->glColorPointer(tmuState0.color_array.size,
-                       tmuState0.color_array.type,
-                       tmuState0.color_array.stride,
-                       tmuState0.color_array.ptr);
+       if ( tmuState0.normal_array.enabled )
+       {
+               glEsImpl->glEnableClientState( GL_NORMAL_ARRAY );
+       }
+       else
+       {
+               glEsImpl->glDisableClientState( GL_NORMAL_ARRAY );
+       }
+       glEsImpl->glVertexPointer( tmuState0.vertex_array.size,
+                                  tmuState0.vertex_array.type,
+                                  tmuState0.vertex_array.stride,
+                                  tmuState0.vertex_array.ptr );
 
-    glEsImpl->glNormalPointer(
-            tmuState0.normal_array.type,
-            tmuState0.normal_array.stride,
-            tmuState0.normal_array.ptr);
+       glEsImpl->glTexCoordPointer( tmuState0.texture_coord_array.size,
+                                    tmuState0.texture_coord_array.type,
+                                    tmuState0.texture_coord_array.stride,
+                                    tmuState0.texture_coord_array.ptr );
 
-       glEsImpl->glMatrixMode(nanoglState.matrixmode);
+       glEsImpl->glColorPointer( tmuState0.color_array.size,
+                                 tmuState0.color_array.type,
+                                 tmuState0.color_array.stride,
+                                 tmuState0.color_array.ptr );
 
+       glEsImpl->glNormalPointer(
+           tmuState0.normal_array.type,
+           tmuState0.normal_array.stride,
+           tmuState0.normal_array.ptr );
 
+       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);
+       glEsImpl->glBlendFunc( nanoglState.sfactor, nanoglState.dfactor );
 
        //glEsImpl->glBindTexture(GL_TEXTURE_2D, stackTextureState);
 
-       glEsImpl->glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, activetmuState->texture_env_mode.value);
+       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 (delayedttmuchange)
-        {
-        delayedttmuchange = GL_FALSE;
+void FlushOnStateChange( )
+{
+       if( skipnanogl )
+               return;
+       if ( delayedttmuchange )
+       {
+               delayedttmuchange = GL_FALSE;
 #ifndef USE_CORE_PROFILE
-        glEsImpl->glActiveTexture(delayedtmutarget);
+               glEsImpl->glActiveTexture( delayedtmutarget );
 #endif
-        }
-
-    if (!vertexCount)
-        return;
-
-    if (!arraysValid)
-        {
-        glEsImpl->glClientActiveTexture(GL_TEXTURE0);
-        glEsImpl->glVertexPointer(3, GL_FLOAT, sizeof(VertexAttrib), &vertexattribs[0].x);
-        glEsImpl->glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(VertexAttrib), &vertexattribs[0].red);
-        glEsImpl->glTexCoordPointer(2, GL_FLOAT, sizeof(VertexAttrib), &vertexattribs[0].s);    
-        glEsImpl->glEnableClientState(GL_VERTEX_ARRAY);
-        glEsImpl->glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-        glEsImpl->glEnableClientState(GL_COLOR_ARRAY);
-#if defined(__MULTITEXTURE_SUPPORT__)        
-        glEsImpl->glClientActiveTexture(GL_TEXTURE1);
-        glEsImpl->glTexCoordPointer(2, GL_FLOAT, sizeof(VertexAttrib), &vertexattribs[0].s_multi); 
-        glEsImpl->glEnableClientState(GL_TEXTURE_COORD_ARRAY);  
-        glEsImpl->glClientActiveTexture(GL_TEXTURE0);   
-#endif
-        arraysValid = GL_TRUE;
-        }
-
-    glEsImpl->glDrawElements( GL_TRIANGLES,vertexCount,GL_UNSIGNED_SHORT, indexArray );
+       }
 
+       if ( !vertexCount )
+               return;
 
-#if defined(__MULTITEXTURE_SUPPORT__)            
-    useMultiTexCoordArray = GL_FALSE;
-#endif
-    vertexCount = 0;
-    indexCount = 0;
-    ptrVertexAttribArray = vertexattribs;
-    ptrVertexAttribArrayMark = ptrVertexAttribArray;
-    ptrIndexArray = indexArray;
-    useTexCoordArray = GL_FALSE;
-    }
-void nanoGL_Flush()
+       if ( !arraysValid )
        {
-       FlushOnStateChange();
+               glEsImpl->glClientActiveTexture( GL_TEXTURE0 );
+               glEsImpl->glVertexPointer( 3, GL_FLOAT, sizeof( VertexAttrib ), &vertexattribs[0].x );
+               glEsImpl->glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( VertexAttrib ), &vertexattribs[0].red );
+               glEsImpl->glTexCoordPointer( 2, GL_FLOAT, sizeof( VertexAttrib ), &vertexattribs[0].s );
+               glEsImpl->glEnableClientState( GL_VERTEX_ARRAY );
+               glEsImpl->glEnableClientState( GL_TEXTURE_COORD_ARRAY );
+               glEsImpl->glEnableClientState( GL_COLOR_ARRAY );
+#if defined( __MULTITEXTURE_SUPPORT__ )
+               glEsImpl->glClientActiveTexture( GL_TEXTURE1 );
+               glEsImpl->glTexCoordPointer( 2, GL_FLOAT, sizeof( VertexAttrib ), &vertexattribs[0].s_multi );
+               glEsImpl->glEnableClientState( GL_TEXTURE_COORD_ARRAY );
+               glEsImpl->glClientActiveTexture( GL_TEXTURE0 );
+#endif
+               arraysValid = GL_TRUE;
        }
-void nanoGL_Reset()
+
+       glEsImpl->glDrawElements( GL_TRIANGLES, vertexCount, GL_UNSIGNED_SHORT, indexArray );
+
+#if defined( __MULTITEXTURE_SUPPORT__ )
+       useMultiTexCoordArray = GL_FALSE;
+#endif
+       vertexCount              = 0;
+       indexCount               = 0;
+       ptrVertexAttribArray     = vertexattribs;
+       ptrVertexAttribArrayMark = ptrVertexAttribArray;
+       ptrIndexArray            = indexArray;
+       useTexCoordArray         = GL_FALSE;
+}
+void nanoGL_Flush( )
 {
-       ResetNanoState();
+       FlushOnStateChange( );
+}
+void nanoGL_Reset( )
+{
+       ResetNanoState( );
+}
+void glBegin( GLenum mode )
+{
+       wrapperPrimitiveMode     = mode;
+       vertexMark               = vertexCount;
+       ptrVertexAttribArrayMark = ptrVertexAttribArray;
+       indexbase                = indexCount;
 }
-void glBegin(GLenum mode)
-    {
-    wrapperPrimitiveMode = mode;
-    vertexMark = vertexCount;    
-    ptrVertexAttribArrayMark = ptrVertexAttribArray;
-    indexbase = indexCount;
-    }
-    
-void glEnd(void)
-    {
-    vertexCount+=((unsigned char*)ptrVertexAttribArray-(unsigned char*)ptrVertexAttribArrayMark)/sizeof(VertexAttrib);
-    if (vertexCount < 3)
-        {
-        return;
-        }
-    switch (wrapperPrimitiveMode)
-        {
-        case GL_QUADS:
-            {
-            *ptrIndexArray++ = indexCount;
-            *ptrIndexArray++ = indexCount+1;
-            *ptrIndexArray++ = indexCount+2;
-            *ptrIndexArray++ = indexCount;
-            *ptrIndexArray++ = indexCount+2;
-            *ptrIndexArray++ = indexCount+3;
-            indexCount+=4;
-            vertexCount+=2;
-            }
-            break;
-        case GL_TRIANGLES:
-            {
-            int  vcount = (vertexCount-vertexMark)/3;
-            for (int count = 0; count < vcount; count++)
-                {
-                *ptrIndexArray++ = indexCount;
-                *ptrIndexArray++ = indexCount+1;
-                *ptrIndexArray++ = indexCount+2;            
-                indexCount+=3;    
-                }
-            }
-            break;
-        case GL_TRIANGLE_STRIP:
-            {
-            *ptrIndexArray++ = indexCount;
-            *ptrIndexArray++ = indexCount+1;
-            *ptrIndexArray++ = indexCount+2;
-            indexCount+=3;
-            int vcount = ((vertexCount-vertexMark)-3);
-            if (vcount && ((long)ptrIndexArray & 0x02))
-                {
-                *ptrIndexArray++ = indexCount-1; // 2 
-                *ptrIndexArray++ = indexCount-2; // 1
-                *ptrIndexArray++ = indexCount;   // 3
-                indexCount++;
-                vcount-=1;    
-                int odd = vcount&1;
-                vcount/=2;
-                unsigned int* longptr = (unsigned int*) ptrIndexArray;
-
-                for (int count = 0; count < vcount; count++)
-                    {
-                    *(longptr++) = (indexCount-2) | ((indexCount-1)<<16);                    
-                    *(longptr++) = (indexCount) | ((indexCount)<<16);                    
-                    *(longptr++) = (indexCount-1) | ((indexCount+1)<<16);
-                    indexCount+=2;
-                    }
-                ptrIndexArray = (unsigned short*)(longptr);
-                if (odd)
-                    {
-                    *ptrIndexArray++ = indexCount-2; // 2 
-                    *ptrIndexArray++ = indexCount-1; // 1
-                    *ptrIndexArray++ = indexCount;   // 3
-                    indexCount++;    
-                    }
-                }
-           else
-                {
-                //already aligned
-                int odd = vcount&1;
-                vcount/=2;
-                unsigned int* longptr = (unsigned int*) ptrIndexArray;
-
-                for (int count = 0; count < vcount; count++)
-                    {                    
-                    *(longptr++) = (indexCount-1) | ((indexCount-2)<<16);                    
-                    *(longptr++) = (indexCount) | ((indexCount-1)<<16);                    
-                    *(longptr++) = (indexCount) | ((indexCount+1)<<16);
-                    indexCount+=2;
-
-                    }
-                ptrIndexArray = (unsigned short*)(longptr);
-                if (odd)
-                    {
-                    
-                    *ptrIndexArray++ = indexCount-1; // 2 
-                    *ptrIndexArray++ = indexCount-2; // 1
-                    *ptrIndexArray++ = indexCount;   // 3
-                    indexCount++;    
-                    }
-                }            
-            vertexCount+=(vertexCount-vertexMark-3)*2;
-            }
-            break;
-        case GL_POLYGON:
-        case GL_TRIANGLE_FAN:
-            {
-            *ptrIndexArray++ = indexCount++;
-            *ptrIndexArray++ = indexCount++;
-            *ptrIndexArray++ = indexCount++;
-            int vcount = ((vertexCount-vertexMark)-3);
-            for (int count = 0; count < vcount; count++)
-                {
-                *ptrIndexArray++ = indexbase;
-                *ptrIndexArray++ = indexCount-1;
-                *ptrIndexArray++ = indexCount++;                
-                vertexCount+=2;
-                }
-             }   
-            break;
 
-        default:
-            break;
-        }
-    }
+void glEnd( void )
+{
+       vertexCount += ( (unsigned char *)ptrVertexAttribArray - (unsigned char *)ptrVertexAttribArrayMark ) / sizeof( VertexAttrib );
+       if ( vertexCount < 3 )
+       {
+               return;
+       }
+       switch ( wrapperPrimitiveMode )
+       {
+       case GL_QUADS:
+       {
+               *ptrIndexArray++ = indexCount;
+               *ptrIndexArray++ = indexCount + 1;
+               *ptrIndexArray++ = indexCount + 2;
+               *ptrIndexArray++ = indexCount;
+               *ptrIndexArray++ = indexCount + 2;
+               *ptrIndexArray++ = indexCount + 3;
+               indexCount += 4;
+               vertexCount += 2;
+       }
+       break;
+       case GL_TRIANGLES:
+       {
+               int vcount = ( vertexCount - vertexMark ) / 3;
+               for ( int count = 0; count < vcount; count++ )
+               {
+                       *ptrIndexArray++ = indexCount;
+                       *ptrIndexArray++ = indexCount + 1;
+                       *ptrIndexArray++ = indexCount + 2;
+                       indexCount += 3;
+               }
+       }
+       break;
+       case GL_TRIANGLE_STRIP:
+       {
+               *ptrIndexArray++ = indexCount;
+               *ptrIndexArray++ = indexCount + 1;
+               *ptrIndexArray++ = indexCount + 2;
+               indexCount += 3;
+               int vcount = ( ( vertexCount - vertexMark ) - 3 );
+               if ( vcount && ( (long)ptrIndexArray & 0x02 ) )
+               {
+                       *ptrIndexArray++ = indexCount - 1; // 2
+                       *ptrIndexArray++ = indexCount - 2; // 1
+                       *ptrIndexArray++ = indexCount;     // 3
+                       indexCount++;
+                       vcount -= 1;
+                       int odd = vcount & 1;
+                       vcount /= 2;
+                       unsigned int *longptr = (unsigned int *)ptrIndexArray;
+
+                       for ( int count = 0; count < vcount; count++ )
+                       {
+                               *( longptr++ ) = ( indexCount - 2 ) | ( ( indexCount - 1 ) << 16 );
+                               *( longptr++ ) = ( indexCount ) | ( ( indexCount ) << 16 );
+                               *( longptr++ ) = ( indexCount - 1 ) | ( ( indexCount + 1 ) << 16 );
+                               indexCount += 2;
+                       }
+                       ptrIndexArray = (unsigned short *)( longptr );
+                       if ( odd )
+                       {
+                               *ptrIndexArray++ = indexCount - 2; // 2
+                               *ptrIndexArray++ = indexCount - 1; // 1
+                               *ptrIndexArray++ = indexCount;     // 3
+                               indexCount++;
+                       }
+               }
+               else
+               {
+                       //already aligned
+                       int odd = vcount & 1;
+                       vcount /= 2;
+                       unsigned int *longptr = (unsigned int *)ptrIndexArray;
 
-void glEnable (GLenum cap)
-    {
-    GLboolean statechanged = GL_FALSE;
-    switch(cap)
-        {
-        case GL_ALPHA_TEST:
-            {
-            if (!nanoglState.alpha_test)
-                {
-                nanoglState.alpha_test = GL_TRUE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-        case GL_BLEND:
-            {
-            if (!nanoglState.blend)
-                {
-                nanoglState.blend = GL_TRUE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-        //case GL_CLIP_PLANEi
-        case GL_COLOR_LOGIC_OP:
-            {
-            if (!nanoglState.color_logic_op)
-                {
-                nanoglState.color_logic_op = GL_TRUE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-        case GL_COLOR_MATERIAL:
-            {
-            if (!nanoglState.color_material)
-                {
-                nanoglState.color_material = GL_TRUE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-        case GL_CULL_FACE:
-            {
-            if (!nanoglState.cull_face)
-                {
-                nanoglState.cull_face = GL_TRUE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-        case GL_DEPTH_TEST:
-            {
-            if (!nanoglState.depth_test)
-                {
-                nanoglState.depth_test = GL_TRUE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-        case GL_DITHER:
-            {
-            if (!nanoglState.dither)
-                {
-                nanoglState.dither = GL_TRUE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-        case GL_FOG:
-        //case GL_LIGHTi
-            {
-            if (!nanoglState.fog)
-                {
-                nanoglState.fog = GL_TRUE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-        case GL_LIGHTING:
-            {
-            if (!nanoglState.lighting)
-                {
-                nanoglState.lighting = GL_TRUE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-        case GL_LINE_SMOOTH:
-            {
-            if (!nanoglState.line_smooth)
-                {
-                nanoglState.line_smooth = GL_TRUE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-/*        case GL_MATRIX_PALETTE_OES:
+                       for ( int count = 0; count < vcount; count++ )
+                       {
+                               *( longptr++ ) = ( indexCount - 1 ) | ( ( indexCount - 2 ) << 16 );
+                               *( longptr++ ) = ( indexCount ) | ( ( indexCount - 1 ) << 16 );
+                               *( longptr++ ) = ( indexCount ) | ( ( indexCount + 1 ) << 16 );
+                               indexCount += 2;
+                       }
+                       ptrIndexArray = (unsigned short *)( longptr );
+                       if ( odd )
+                       {
+
+                               *ptrIndexArray++ = indexCount - 1; // 2
+                               *ptrIndexArray++ = indexCount - 2; // 1
+                               *ptrIndexArray++ = indexCount;     // 3
+                               indexCount++;
+                       }
+               }
+               vertexCount += ( vertexCount - vertexMark - 3 ) * 2;
+       }
+       break;
+       case GL_POLYGON:
+       case GL_TRIANGLE_FAN:
+       {
+               *ptrIndexArray++ = indexCount++;
+               *ptrIndexArray++ = indexCount++;
+               *ptrIndexArray++ = indexCount++;
+               int vcount       = ( ( vertexCount - vertexMark ) - 3 );
+               for ( int count = 0; count < vcount; count++ )
+               {
+                       *ptrIndexArray++ = indexbase;
+                       *ptrIndexArray++ = indexCount - 1;
+                       *ptrIndexArray++ = indexCount++;
+                       vertexCount += 2;
+               }
+       }
+       break;
+
+       default:
+               break;
+       }
+       if ( ptrVertexAttribArray - vertexattribs > 20000 * sizeof( VertexAttrib ) ||
+            ptrIndexArray - indexArray > 15000 * sizeof( GLushort ) )
+               FlushOnStateChange( );
+}
+
+void glEnable( GLenum cap )
+{
+       if( skipnanogl )
+       {
+               glEsImpl->glEnable( cap );
+               return;
+       }
+       GLboolean statechanged = GL_FALSE;
+       switch ( cap )
+       {
+       case GL_ALPHA_TEST:
+       {
+               if ( !nanoglState.alpha_test )
+               {
+                       nanoglState.alpha_test = GL_TRUE;
+                       statechanged           = GL_TRUE;
+               }
+               break;
+       }
+       case GL_BLEND:
+       {
+               if ( !nanoglState.blend )
+               {
+                       nanoglState.blend = GL_TRUE;
+                       statechanged      = GL_TRUE;
+               }
+               break;
+       }
+       //case GL_CLIP_PLANEi
+       case GL_COLOR_LOGIC_OP:
+       {
+               if ( !nanoglState.color_logic_op )
+               {
+                       nanoglState.color_logic_op = GL_TRUE;
+                       statechanged               = GL_TRUE;
+               }
+               break;
+       }
+       case GL_COLOR_MATERIAL:
+       {
+               if ( !nanoglState.color_material )
+               {
+                       nanoglState.color_material = GL_TRUE;
+                       statechanged               = GL_TRUE;
+               }
+               break;
+       }
+       case GL_CULL_FACE:
+       {
+               if ( !nanoglState.cull_face )
+               {
+                       nanoglState.cull_face = GL_TRUE;
+                       statechanged          = GL_TRUE;
+               }
+               break;
+       }
+       case GL_DEPTH_TEST:
+       {
+               if ( !nanoglState.depth_test )
+               {
+                       nanoglState.depth_test = GL_TRUE;
+                       statechanged           = GL_TRUE;
+               }
+               break;
+       }
+       case GL_DITHER:
+       {
+               if ( !nanoglState.dither )
+               {
+                       nanoglState.dither = GL_TRUE;
+                       statechanged       = GL_TRUE;
+               }
+               break;
+       }
+       case GL_FOG:
+       {
+               if ( !nanoglState.fog )
+               {
+                       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 )
+               {
+                       nanoglState.lighting = GL_TRUE;
+                       statechanged         = GL_TRUE;
+               }
+               break;
+       }
+       case GL_LINE_SMOOTH:
+       {
+               if ( !nanoglState.line_smooth )
+               {
+                       nanoglState.line_smooth = GL_TRUE;
+                       statechanged            = GL_TRUE;
+               }
+               break;
+       }
+       /*        case GL_MATRIX_PALETTE_OES:
             {
             if (!nanoglState.matrix_palette_oes)
                 {
@@ -619,217 +770,303 @@ void glEnable (GLenum cap)
                 }
             break;
             }*/
-        case GL_MULTISAMPLE:
-            {
-            if (!nanoglState.multisample)
-                {
-                nanoglState.multisample = GL_TRUE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-        case GL_NORMALIZE:
+       case GL_MULTISAMPLE:
+       {
+               if ( !nanoglState.multisample )
+               {
+                       nanoglState.multisample = GL_TRUE;
+                       statechanged            = GL_TRUE;
+               }
+               break;
+       }
+       case GL_NORMALIZE:
+       {
+               if ( !nanoglState.normalize )
+               {
+                       nanoglState.normalize = GL_TRUE;
+                       statechanged          = GL_TRUE;
+               }
+               break;
+       }
+       /*        case GL_POINT_SPRITE_OES:
             {
-            if (!nanoglState.normalize)
+            if (!nanoglState.point_sprite_oes)
                 {
-                nanoglState.normalize = GL_TRUE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-/*        case GL_POINT_SPRITE_OES:
-            {
-            if (!nanoglState.point_sprite_oes)
-                {
-                nanoglState.point_sprite_oes = GL_TRUE;
+                nanoglState.point_sprite_oes = GL_TRUE;
                 statechanged = GL_TRUE;
                 }
             break;
             }*/
-        case GL_POLYGON_OFFSET_FILL:
-            {
-            if (!nanoglState.polygon_offset_fill)
-                {
-                nanoglState.polygon_offset_fill = GL_TRUE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-        case GL_RESCALE_NORMAL:
-            {
-            if (!nanoglState.rescale_normal)
-                {
-                nanoglState.rescale_normal = GL_TRUE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-        case GL_SAMPLE_ALPHA_TO_COVERAGE:
-            {
-            if (!nanoglState.sample_alpha_to_coverage)
-                {
-                nanoglState.sample_alpha_to_coverage = GL_TRUE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-        case GL_SAMPLE_ALPHA_TO_ONE:
-            {
-            if (!nanoglState.sample_alpha_to_one)
-                {
-                nanoglState.sample_alpha_to_one = GL_TRUE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-        case GL_SAMPLE_COVERAGE:
-            {
-            if (!nanoglState.sample_coverage)
-                {
-                nanoglState.sample_coverage = GL_TRUE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-        case GL_SCISSOR_TEST:
-            {
-            if (!nanoglState.scissor_test)
-                {
-                nanoglState.scissor_test = GL_TRUE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-        case GL_STENCIL_TEST:
-            {
-            return;
-/*            if (!nanoglState.stencil_test)
-                {
-                nanoglState.stencil_test = GL_TRUE;
-                statechanged = GL_TRUE;
-                }*/
-            break;
-            }
-        case GL_TEXTURE_2D:   
-            {
-            if (!activetmuState->texture_2d.value)
-                {
-                FlushOnStateChange();
-                glEsImpl->glEnable(cap);
-                activetmuState->texture_2d.value = GL_TRUE;
-                return;              
-                }
-            break;
-            }
-        default:
-            break;
-        }
-        
-    if (statechanged)
-        {
-        FlushOnStateChange();
-        glEsImpl->glEnable(cap);
-        }    
-    }
-
-void glDisable (GLenum cap)
-    {
-    GLboolean statechanged = GL_FALSE;
-    switch(cap)
-        {
-        case GL_ALPHA_TEST:
-            {
-            if (nanoglState.alpha_test)
-                {
-                nanoglState.alpha_test = GL_FALSE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-        case GL_BLEND:
-            {
-            if (nanoglState.blend)
-                {
-                nanoglState.blend = GL_FALSE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-        //case GL_CLIP_PLANEi
-        case GL_COLOR_LOGIC_OP:
-            {
-            if (nanoglState.color_logic_op)
-                {
-                nanoglState.color_logic_op = GL_FALSE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-        case GL_COLOR_MATERIAL:
-            {
-            if (nanoglState.color_material)
-                {
-                nanoglState.color_material = GL_FALSE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-        case GL_CULL_FACE:
-            {
-            if (nanoglState.cull_face)
-                {
-                nanoglState.cull_face = GL_FALSE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-        case GL_DEPTH_TEST:
-            {
-            if (nanoglState.depth_test)
-                {
-                nanoglState.depth_test = GL_FALSE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-        case GL_DITHER:
-            {
-            if (nanoglState.dither)
-                {
-                nanoglState.dither = GL_FALSE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-        case GL_FOG:
-        //case GL_LIGHTi
-            {
-            if (nanoglState.fog)
-                {
-                nanoglState.fog = GL_FALSE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-        case GL_LIGHTING:
-            {
-            if (nanoglState.lighting)
-                {
-                nanoglState.lighting = GL_FALSE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-        case GL_LINE_SMOOTH:
-            {
-            if (nanoglState.line_smooth)
-                {
-                nanoglState.line_smooth = GL_FALSE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-/*        case GL_MATRIX_PALETTE_OES:
+       case GL_POLYGON_OFFSET_FILL:
+       {
+               if ( !nanoglState.polygon_offset_fill )
+               {
+                       nanoglState.polygon_offset_fill = GL_TRUE;
+                       statechanged                    = GL_TRUE;
+               }
+               break;
+       }
+       case GL_RESCALE_NORMAL:
+       {
+               if ( !nanoglState.rescale_normal )
+               {
+                       nanoglState.rescale_normal = GL_TRUE;
+                       statechanged               = GL_TRUE;
+               }
+               break;
+       }
+       case GL_SAMPLE_ALPHA_TO_COVERAGE:
+       {
+               if ( !nanoglState.sample_alpha_to_coverage )
+               {
+                       nanoglState.sample_alpha_to_coverage = GL_TRUE;
+                       statechanged                         = GL_TRUE;
+               }
+               break;
+       }
+       case GL_SAMPLE_ALPHA_TO_ONE:
+       {
+               if ( !nanoglState.sample_alpha_to_one )
+               {
+                       nanoglState.sample_alpha_to_one = GL_TRUE;
+                       statechanged                    = GL_TRUE;
+               }
+               break;
+       }
+       case GL_SAMPLE_COVERAGE:
+       {
+               if ( !nanoglState.sample_coverage )
+               {
+                       nanoglState.sample_coverage = GL_TRUE;
+                       statechanged                = GL_TRUE;
+               }
+               break;
+       }
+       case GL_SCISSOR_TEST:
+       {
+               if ( !nanoglState.scissor_test )
+               {
+                       nanoglState.scissor_test = GL_TRUE;
+                       statechanged             = GL_TRUE;
+               }
+               break;
+       }
+       case GL_STENCIL_TEST:
+       {
+               if (!nanoglState.stencil_test)
+               {
+                       nanoglState.stencil_test = GL_TRUE;
+                       statechanged = GL_TRUE;
+               }
+               break;
+       }
+       case GL_TEXTURE_2D:
+       {
+               if ( !activetmuState->texture_2d.value )
+               {
+                       FlushOnStateChange( );
+                       glEsImpl->glEnable( cap );
+                       activetmuState->texture_2d.value = GL_TRUE;
+                       return;
+               }
+               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;
+       }
+
+       if ( statechanged )
+       {
+               FlushOnStateChange( );
+               glEsImpl->glEnable( cap );
+       }
+}
+
+void glDisable( GLenum cap )
+{
+       if( skipnanogl )
+       {
+               glEsImpl->glDisable( cap );
+               return;
+       }
+       GLboolean statechanged = GL_FALSE;
+       switch ( cap )
+       {
+       case GL_ALPHA_TEST:
+       {
+               if ( nanoglState.alpha_test )
+               {
+                       nanoglState.alpha_test = GL_FALSE;
+                       statechanged           = GL_TRUE;
+               }
+               break;
+       }
+       case GL_BLEND:
+       {
+               if ( nanoglState.blend )
+               {
+                       nanoglState.blend = GL_FALSE;
+                       statechanged      = GL_TRUE;
+               }
+               break;
+       }
+       //case GL_CLIP_PLANEi
+       case GL_COLOR_LOGIC_OP:
+       {
+               if ( nanoglState.color_logic_op )
+               {
+                       nanoglState.color_logic_op = GL_FALSE;
+                       statechanged               = GL_TRUE;
+               }
+               break;
+       }
+       case GL_COLOR_MATERIAL:
+       {
+               if ( nanoglState.color_material )
+               {
+                       nanoglState.color_material = GL_FALSE;
+                       statechanged               = GL_TRUE;
+               }
+               break;
+       }
+       case GL_CULL_FACE:
+       {
+               if ( nanoglState.cull_face )
+               {
+                       nanoglState.cull_face = GL_FALSE;
+                       statechanged          = GL_TRUE;
+               }
+               break;
+       }
+       case GL_DEPTH_TEST:
+       {
+               if ( nanoglState.depth_test )
+               {
+                       nanoglState.depth_test = GL_FALSE;
+                       statechanged           = GL_TRUE;
+               }
+               break;
+       }
+       case GL_DITHER:
+       {
+               if ( nanoglState.dither )
+               {
+                       nanoglState.dither = GL_FALSE;
+                       statechanged       = GL_TRUE;
+               }
+               break;
+       }
+       case GL_FOG:
+       {
+               if ( nanoglState.fog )
+               {
+                       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 )
+               {
+                       nanoglState.lighting = GL_FALSE;
+                       statechanged         = GL_TRUE;
+               }
+               break;
+       }
+       case GL_LINE_SMOOTH:
+       {
+               if ( nanoglState.line_smooth )
+               {
+                       nanoglState.line_smooth = GL_FALSE;
+                       statechanged            = GL_TRUE;
+               }
+               break;
+       }
+       /*        case GL_MATRIX_PALETTE_OES:
             {
             if (nanoglState.matrix_palette_oes)
                 {
@@ -838,25 +1075,25 @@ void glDisable (GLenum cap)
                 }
             break;
             }*/
-        case GL_MULTISAMPLE:
-            {
-            if (nanoglState.multisample)
-                {
-                nanoglState.multisample = GL_FALSE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-        case GL_NORMALIZE:
-            {
-            if (nanoglState.normalize)
-                {
-                nanoglState.normalize = GL_FALSE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-/*        case GL_POINT_SPRITE_OES:
+       case GL_MULTISAMPLE:
+       {
+               if ( nanoglState.multisample )
+               {
+                       nanoglState.multisample = GL_FALSE;
+                       statechanged            = GL_TRUE;
+               }
+               break;
+       }
+       case GL_NORMALIZE:
+       {
+               if ( nanoglState.normalize )
+               {
+                       nanoglState.normalize = GL_FALSE;
+                       statechanged          = GL_TRUE;
+               }
+               break;
+       }
+       /*        case GL_POINT_SPRITE_OES:
             {
             if (nanoglState.point_sprite_oes)
                 {
@@ -865,977 +1102,1189 @@ void glDisable (GLenum cap)
                 }
             break;
             }*/
-        case GL_POLYGON_OFFSET_FILL:
-            {
-            if (nanoglState.polygon_offset_fill)
-                {
-                nanoglState.polygon_offset_fill = GL_FALSE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-        case GL_RESCALE_NORMAL:
-            {
-            if (nanoglState.rescale_normal)
-                {
-                nanoglState.rescale_normal = GL_FALSE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-        case GL_SAMPLE_ALPHA_TO_COVERAGE:
-            {
-            if (nanoglState.sample_alpha_to_coverage)
-                {
-                nanoglState.sample_alpha_to_coverage = GL_FALSE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-        case GL_SAMPLE_ALPHA_TO_ONE:
-            {
-            if (nanoglState.sample_alpha_to_one)
-                {
-                nanoglState.sample_alpha_to_one = GL_FALSE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-        case GL_SAMPLE_COVERAGE:
-            {
-            if (nanoglState.sample_coverage)
-                {
-                nanoglState.sample_coverage = GL_FALSE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-        case GL_SCISSOR_TEST:
-            {
-            if (nanoglState.scissor_test)
-                {
-                nanoglState.scissor_test = GL_FALSE;
-                statechanged = GL_TRUE;
-                }
-            break;
-            }
-        case GL_STENCIL_TEST:
-            {
-            return;
-/*            if (nanoglState.stencil_test)
-                {
-                nanoglState.stencil_test = GL_FALSE;
-                statechanged = GL_TRUE;
-                }*/
-            break;
-            }
-        case GL_TEXTURE_2D:   
-            {
-            if (activetmuState->texture_2d.value)
-                {
-                FlushOnStateChange();
-                glEsImpl->glDisable(cap);
-                activetmuState->texture_2d.value = GL_FALSE;
-                return;
+       case GL_POLYGON_OFFSET_FILL:
+       {
+               if ( nanoglState.polygon_offset_fill )
+               {
+                       nanoglState.polygon_offset_fill = GL_FALSE;
+                       statechanged                    = GL_TRUE;
+               }
+               break;
+       }
+       case GL_RESCALE_NORMAL:
+       {
+               if ( nanoglState.rescale_normal )
+               {
+                       nanoglState.rescale_normal = GL_FALSE;
+                       statechanged               = GL_TRUE;
+               }
+               break;
+       }
+       case GL_SAMPLE_ALPHA_TO_COVERAGE:
+       {
+               if ( nanoglState.sample_alpha_to_coverage )
+               {
+                       nanoglState.sample_alpha_to_coverage = GL_FALSE;
+                       statechanged                         = GL_TRUE;
+               }
+               break;
+       }
+       case GL_SAMPLE_ALPHA_TO_ONE:
+       {
+               if ( nanoglState.sample_alpha_to_one )
+               {
+                       nanoglState.sample_alpha_to_one = GL_FALSE;
+                       statechanged                    = GL_TRUE;
+               }
+               break;
+       }
+       case GL_SAMPLE_COVERAGE:
+       {
+               if ( nanoglState.sample_coverage )
+               {
+                       nanoglState.sample_coverage = GL_FALSE;
+                       statechanged                = GL_TRUE;
+               }
+               break;
+       }
+       case GL_SCISSOR_TEST:
+       {
+               if ( nanoglState.scissor_test )
+               {
+                       nanoglState.scissor_test = GL_FALSE;
+                       statechanged             = GL_TRUE;
+               }
+               break;
+       }
+       case GL_STENCIL_TEST:
+       {
+               if (nanoglState.stencil_test)
+               {
+                       nanoglState.stencil_test = GL_FALSE;
+                       statechanged = GL_TRUE;
+               }
+               break;
+       }
+       case GL_TEXTURE_2D:
+       {
+               if ( activetmuState->texture_2d.value )
+               {
+                       FlushOnStateChange( );
+                       glEsImpl->glDisable( cap );
+                       activetmuState->texture_2d.value = GL_FALSE;
+                       return;
+               }
+               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;
+       }
+
+       if ( statechanged )
+       {
+               FlushOnStateChange( );
+               glEsImpl->glDisable( cap );
+       }
+}
 
+void glVertex2f( GLfloat x, GLfloat y )
+{
+       glVertex3f( x, y, 0.0f );
+}
 
-                }
-            break;
-            }
-        default:
-            break;
-        }
-        
-    if (statechanged)
-        {
-        FlushOnStateChange();
-        glEsImpl->glDisable(cap);
-        }    
-    }
-    
-void glVertex2f(GLfloat x, GLfloat y)
-    {
-    glVertex3f(x,y,0.0f);
-    }
+__FORCEINLINE unsigned int ClampTo255( float value )
+{
+       unsigned int retval = (unsigned int)( value );
+       if ( retval > 255 )
+       {
+               retval = 255;
+       }
+       return retval;
+}
 
+void glColor3f( GLfloat red, GLfloat green, GLfloat blue )
+{
+       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 = 255;
+}
 
-__FORCEINLINE unsigned int ClampTo255(float value)
-    {
-    unsigned int retval = (unsigned int)(value);
-    if (retval > 255)
-        {
-        retval = 255;
-        }
-    return retval;
-    }
-
-void glColor3f(        GLfloat red, GLfloat green, GLfloat blue)
-    {
-    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 = 255;
-    }
+void glTexCoord2fv( const GLfloat *v )
+{
+       memcpy( &currentVertexAttrib.s, v, 2 * sizeof( float ) );
+}
 
+void glTexCoord2f( GLfloat s, GLfloat t )
+{
+       currentVertexAttrib.s = s;
+       currentVertexAttrib.t = t;
+}
 
-void glTexCoord2fv( const GLfloat *v ) 
-    {
-    memcpy(&currentVertexAttrib.s, v, 2*sizeof(float));
-    }
+void glViewport( GLint x, GLint y, GLsizei width, GLsizei height )
+{
+       FlushOnStateChange( );
+       glEsImpl->glViewport( x, y, width, height );
+}
 
+void glLoadIdentity( void )
+{
+       FlushOnStateChange( );
+       glEsImpl->glLoadIdentity( );
+}
 
-void glTexCoord2f(GLfloat s, GLfloat t)
-    {
-    currentVertexAttrib.s = s;
-    currentVertexAttrib.t = t;
-    }
-    
-void glViewport (GLint x, GLint y, GLsizei width, GLsizei height)
-    {
-    FlushOnStateChange();
-    glEsImpl->glViewport(x,y,width,height);
-    }
-    
-void glLoadIdentity (void)
-    {
-    FlushOnStateChange();
-    glEsImpl->glLoadIdentity();
-    }
-    
-void glColor4f (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
-    {
-    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 glColor4f( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha )
+{
+       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)
-    {
-    FlushOnStateChange();
+void glOrtho( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar )
+{
+       FlushOnStateChange( );
 #ifdef USE_CORE_PROFILE
-       glEsImpl->glOrtho(left,right,bottom,top, zNear,zFar);
+       glEsImpl->glOrtho( left, right, bottom, top, zNear, zFar );
 #else
-    glEsImpl->glOrthof(left,right,bottom,top, zNear,zFar);
+       glEsImpl->glOrthof( left, right, bottom, top, zNear, zFar );
 #endif
-    }
+}
 
-void glMatrixMode (GLenum mode)
-    {
-    if (nanoglState.matrixmode == mode)
-        {
-        return;
-        }
-    nanoglState.matrixmode = mode;
-    FlushOnStateChange();
-    glEsImpl->glMatrixMode(mode);
-    }
+// Rikku2000: Light
+void glLightf( GLenum light, GLenum pname, GLfloat param )
+{
+       FlushOnStateChange( );
 
-void glTexParameterf (GLenum target, GLenum pname, GLfloat param)
-    {
-    if (pname == GL_TEXTURE_BORDER_COLOR)
-        {
-        return; // not supported by opengl es
-        }
-    if (    (pname == GL_TEXTURE_WRAP_S ||
-             pname == GL_TEXTURE_WRAP_T) &&
-             param == GL_CLAMP)
-             {
-             param = 0x812F;
-             }
+       glEsImpl->glLightf( light, pname, param );
+}
+void glLightfv( GLenum light, GLenum pname, const GLfloat *params )
+{
+       FlushOnStateChange( );
 
-    FlushOnStateChange();
-    glEsImpl->glTexParameterf(target, pname,param);
-    }
-    
-void glTexParameterfv( GLenum target, GLenum pname, const GLfloat *params) 
-    {
-    glTexParameterf(target, pname, params[0]);
-    }
+       glEsImpl->glLightfv( light, pname, params );
+}
+void glLightModelf( GLenum pname, GLfloat param )
+{
+       FlushOnStateChange( );
 
-void glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
-    {
-    FlushOnStateChange();
-    internalformat = format;
-    glEsImpl->glTexImage2D(target, level, internalformat, width, height,border,format,type,pixels);
-    }
+       glEsImpl->glLightModelf( pname, param );
+}
+void glLightModelfv( GLenum pname, const GLfloat *params )
+{
+       FlushOnStateChange( );
 
-void glDrawBuffer(GLenum /*mode*/)
-    {
-    }
+       glEsImpl->glLightModelfv( pname, params );
+}
+void glMaterialf( GLenum face, GLenum pname, GLfloat param )
+{
+       FlushOnStateChange( );
 
-void glTranslatef (GLfloat x, GLfloat y, GLfloat z)
-    {
-    FlushOnStateChange();
-    glEsImpl->glTranslatef(x,y,z);
-    }
-    
-void glRotatef (GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
-    {
-    FlushOnStateChange();
-    glEsImpl->glRotatef(angle, x, y, z);
-    }
+       glEsImpl->glMaterialf( face, pname, param );
+}
+void glMaterialfv( GLenum face, GLenum pname, const GLfloat *params )
+{
+       FlushOnStateChange( );
 
-void glScalef (GLfloat x, GLfloat y, GLfloat z)
-    {
-    FlushOnStateChange();
-    glEsImpl->glScalef(x,y,z);
-    }
-    
-void glDepthRange(GLclampf zNear, GLclampf zFar)
-    {
-    if ((nanoglState.depth_range_near == zNear) &&(nanoglState.depth_range_far == zFar))
-        {
-        return;
-        }
-    else
-        {
-        nanoglState.depth_range_near = zNear;
-        nanoglState.depth_range_far = zFar;
-        }
-    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 )
+       {
+               return;
+       }
+       nanoglState.matrixmode = mode;
+       FlushOnStateChange( );
+       glEsImpl->glMatrixMode( mode );
+}
+
+void glTexParameterf( GLenum target, GLenum pname, GLfloat param )
+{
+       if ( pname == GL_TEXTURE_BORDER_COLOR )
+       {
+               return; // not supported by opengl es
+       }
+       if ( ( pname == GL_TEXTURE_WRAP_S ||
+              pname == GL_TEXTURE_WRAP_T ) &&
+            param == GL_CLAMP )
+       {
+               param = 0x812F;
+       }
+
+       FlushOnStateChange( );
+       glEsImpl->glTexParameterf( target, pname, param );
+}
+
+void glTexParameterfv( GLenum target, GLenum pname, const GLfloat *params )
+{
+       glTexParameterf( target, pname, params[0] );
+}
+
+void glTexImage2D( GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels )
+{
+       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, data );
+
+       if( data != pixels )
+               free(data);
+}
+
+void glDrawBuffer( GLenum /*mode*/ )
+{
+}
+
+void glTranslatef( GLfloat x, GLfloat y, GLfloat z )
+{
+       FlushOnStateChange( );
+       glEsImpl->glTranslatef( x, y, z );
+}
+
+void glRotatef( GLfloat angle, GLfloat x, GLfloat y, GLfloat z )
+{
+       FlushOnStateChange( );
+       glEsImpl->glRotatef( angle, x, y, z );
+}
+
+void glScalef( GLfloat x, GLfloat y, GLfloat z )
+{
+       FlushOnStateChange( );
+       glEsImpl->glScalef( x, y, z );
+}
+
+void glDepthRange( GLclampd zNear, GLclampd zFar )
+{
+       if ( ( nanoglState.depth_range_near == zNear ) && ( nanoglState.depth_range_far == zFar ) )
+       {
+               return;
+       }
+       else
+       {
+               nanoglState.depth_range_near = zNear;
+               nanoglState.depth_range_far  = zFar;
+       }
+       FlushOnStateChange( );
 #ifdef USE_CORE_PROFILE
-       glEsImpl->glDepthRange(zNear, zFar);
+       glEsImpl->glDepthRange( zNear, zFar );
 #else
-    glEsImpl->glDepthRangef(zNear, zFar);
+       glEsImpl->glDepthRangef( zNear, zFar );
 #endif
-    }
-
-void glDepthFunc (GLenum func)
-    {
-    if (nanoglState.depth_func == func)
-        {
-        return;
-        }
-    else
-        {
-        nanoglState.depth_func = func;
-        }
-    FlushOnStateChange();
-    glEsImpl->glDepthFunc(func);
-    }
+}
 
-void glFinish (void)
-    {
-    FlushOnStateChange();
-    glEsImpl->glFinish();
-    }
+void glDepthFunc( GLenum func )
+{
+       if ( nanoglState.depth_func == func )
+       {
+               return;
+       }
+       else
+       {
+               nanoglState.depth_func = func;
+       }
+       FlushOnStateChange( );
+       glEsImpl->glDepthFunc( func );
+}
 
-void glGetFloatv (GLenum pname, GLfloat *params)
-    {
-    FlushOnStateChange();
-    glEsImpl->glGetFloatv(pname, params);
-    }
+void glFinish( void )
+{
+       FlushOnStateChange( );
+       glEsImpl->glFinish( );
+}
 
-void glCullFace (GLenum mode)
-    {
-    if (nanoglState.cullface == mode)
-        {
-        return;
-        }
-    else
-        {
-        nanoglState.cullface = mode;
-        }
-    FlushOnStateChange();
-    glEsImpl->glCullFace(mode);
-    }
+void glGetFloatv( GLenum pname, GLfloat *params )
+{
+       FlushOnStateChange( );
+       glEsImpl->glGetFloatv( pname, params );
+}
 
-void glFrustum (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
-    {
-    FlushOnStateChange();
-    glEsImpl->glFrustumf(left,right,bottom,top,zNear,zFar);
-    }
+void glCullFace( GLenum mode )
+{
+       if ( nanoglState.cullface == mode )
+       {
+               return;
+       }
+       else
+       {
+               nanoglState.cullface = mode;
+       }
+       FlushOnStateChange( );
+       glEsImpl->glCullFace( mode );
+}
 
-void glClear (GLbitfield mask)
-    {
-    FlushOnStateChange();
-    glEsImpl->glClear(mask);
-    }
+void glFrustum( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar )
+{
+       FlushOnStateChange( );
+       glEsImpl->glFrustumf( left, right, bottom, top, zNear, zFar );
+}
 
+void glClear( GLbitfield mask )
+{
+       FlushOnStateChange( );
+       glEsImpl->glClear( mask );
+}
 
 void glVertex3f( GLfloat x, GLfloat y, GLfloat z )
-    {
-    GLfloat* vert = (GLfloat*)ptrVertexAttribArray++;
-    *vert++ = x;
-    *vert++ = y;
-    *vert++ = z;
-#if defined(__MULTITEXTURE_SUPPORT__)
-    memcpy(vert, &currentVertexAttrib.red, 5*sizeof(GLfloat));
+{
+       GLfloat *vert = (GLfloat *)ptrVertexAttribArray++;
+       *vert++       = x;
+       *vert++       = y;
+       *vert++       = z;
+#if defined( __MULTITEXTURE_SUPPORT__ )
+       memcpy( vert, &currentVertexAttrib.red, 5 * sizeof( GLfloat ) );
 #else
-    memcpy(vert+1, &currentVertexAttrib.red, 3*sizeof(GLfloat));
+       memcpy( vert + 1, &currentVertexAttrib.red, 3 * sizeof( GLfloat ) );
 #endif
-
-    }
+}
 
 void glColor4fv( const GLfloat *v )
-    {
-    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);
-    }
-    
-void glColor3ubv( const GLubyte* v)
-    {
-    currentVertexAttrib.red = v[0];
-    currentVertexAttrib.green = v[1];
-    currentVertexAttrib.blue = v[2];
-    currentVertexAttrib.alpha = 255;
-    }
-    
-void glColor4ubv( const GLubyte *v ) 
-    {  
-    //*((unsigned int*)(&currentVertexAttrib.red)) = *((unsigned int*)(v));
-    currentVertexAttrib.red = v[0];
-    currentVertexAttrib.green = v[1];
-    currentVertexAttrib.blue = v[2];
-    currentVertexAttrib.alpha = v[3];
-    }
-    
-void glColor3fv( const GLfloat *v ) 
-    {
-    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 = 255;
-    }
+{
+       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 )
+{
+       currentVertexAttrib.red   = v[0];
+       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));
+       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 )
+{
+       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 = 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)
-    {
-    currentVertexAttrib.red = red;
-    currentVertexAttrib.green = green;
-    currentVertexAttrib.blue = blue;
-    currentVertexAttrib.alpha = alpha;
-    }
+void glColor4ub( GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha )
+{
+       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)
-    {
-    currentVertexAttrib.red = red;
-    currentVertexAttrib.green = green;
-    currentVertexAttrib.blue = blue;
-    currentVertexAttrib.alpha = 255;
-    }
+void glColor3ub( GLubyte red, GLubyte green, GLubyte blue )
+{
+       currentVertexAttrib.red   = red;
+       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 ) 
-    {
-    FlushOnStateChange();
-    glEsImpl->glNormal3f(v[0],v[1],v[2]);
-    }
+void glNormal3fv( const GLfloat *v )
+{
+       FlushOnStateChange( );
+       glEsImpl->glNormal3f( v[0], v[1], v[2] );
+}
 
 void glCopyTexImage2D( GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border )
-    {
-    FlushOnStateChange();
-    glEsImpl->glCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
-    }
+{
+       FlushOnStateChange( );
+       glEsImpl->glCopyTexImage2D( target, level, internalformat, x, y, width, height, border );
+}
 
-void glTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
-    {
-    glTexImage2D(GL_TEXTURE_2D, level, internalformat,  width, 1, border, format, type, pixels);
-    }
+void glTexImage1D( GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels )
+{
+       glTexImage2D( GL_TEXTURE_2D, level, internalformat, width, 1, border, format, type, pixels );
+}
 
-void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
-    {
-    glTexImage2D(GL_TEXTURE_2D, level, internalformat,  width, height, border, format, type, pixels);
-    }
+void glTexImage3D( GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels )
+{
+       glTexImage2D( GL_TEXTURE_2D, level, internalformat, width, height, border, format, type, pixels );
+}
 
 void glTexSubImage1D( GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels )
-    {
-    glTexSubImage2D(target,level,xoffset,0,width,1,format,type,pixels);
-    }
+{
+       glTexSubImage2D( target, level, xoffset, 0, width, 1, format, type, pixels );
+}
 
 void glTexSubImage3D( GLenum target, GLint level,
-                                         GLint xoffset, GLint yoffset,
-                                         GLint zoffset, GLsizei width,
-                                         GLsizei height, GLsizei depth,
-                                         GLenum format,
-                                         GLenum type, const GLvoid *pixels)
-    {
-    glTexSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixels);
-    }
+                      GLint xoffset, GLint yoffset,
+                      GLint zoffset, GLsizei width,
+                      GLsizei height, GLsizei depth,
+                      GLenum format,
+                      GLenum type, const GLvoid *pixels )
+{
+       glTexSubImage2D( target, level, xoffset, yoffset, width, height, format, type, pixels );
+}
 
+GLboolean glIsTexture( GLuint texture )
+{
+       FlushOnStateChange( );
+       return glEsImpl->glIsTexture( texture );
+}
 
+// TODO: add native normal/reflection map texgen support
 
-GLboolean glIsTexture(GLuint texture)
-    {
-    FlushOnStateChange();
-    return glEsImpl->glIsTexture(texture);
-    }
+void glTexGeni( GLenum coord, GLenum pname, GLint param )
+{
+       FlushOnStateChange();
+       //glEsImpl->glTexGeniOES( coord, pname, param );
+}
+
+void glTexGenfv( GLenum coord, GLenum pname, const GLfloat *params )
+{
+       FlushOnStateChange();
+       //glEsImpl->glTexGenfvOES( coord, pname, params );
+}
+
+//-- --//
+
+void glHint( GLenum target, GLenum mode )
+{
+       FlushOnStateChange( );
+       glEsImpl->glHint( target, mode );
+}
+
+void glBlendFunc( GLenum sfactor, GLenum dfactor )
+{
+       if( skipnanogl )
+       {
+               glEsImpl->glBlendFunc( sfactor, dfactor );
+               return;
+       }
+       if ( ( nanoglState.sfactor == sfactor ) && ( nanoglState.dfactor == dfactor ) )
+       {
+               return;
+       }
+
+       nanoglState.sfactor = sfactor;
+       nanoglState.dfactor = dfactor;
+       FlushOnStateChange( );
+       glEsImpl->glBlendFunc( sfactor, dfactor );
+}
+
+void glPopMatrix( void )
+{
+       FlushOnStateChange( );
+       glEsImpl->glPopMatrix( );
+}
 
+void glShadeModel( GLenum mode )
+{
+       if ( nanoglState.shademodel == mode )
+       {
+               return;
+       }
+       nanoglState.shademodel = mode;
+       FlushOnStateChange( );
+       glEsImpl->glShadeModel( mode );
+}
+
+void glPushMatrix( void )
+{
+       FlushOnStateChange( );
+       glEsImpl->glPushMatrix( );
+}
+
+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 )
+               {
+                       if ( param == activetmuState->texture_env_mode.value )
+                       {
+                               return;
+                       }
+                       else
+                       {
+                               FlushOnStateChange( );
+                               glEsImpl->glTexEnvf( target, pname, param );
+                               activetmuState->texture_env_mode.value = param;
+                               return;
+                       }
+               }
+       }
+       FlushOnStateChange( );
+       glEsImpl->glTexEnvf( target, pname, param );
+}
+
+void glVertex3fv( const GLfloat *v )
+{
+       GLfloat *vert = (GLfloat *)ptrVertexAttribArray++;
+       memcpy( vert, v, 3 * sizeof( GLfloat ) );
+#if defined( __MULTITEXTURE_SUPPORT__ )
+       memcpy( vert + 3, &currentVertexAttrib.red, 5 * sizeof( GLfloat ) );
+#else
+       memcpy( vert + 4, &currentVertexAttrib.red, 3 * sizeof( GLfloat ) );
+#endif
+}
+
+void glDepthMask( GLboolean flag )
+{
+       if( !skipnanogl )
+       {
+       if ( nanoglState.depthmask == flag )
+       {
+               return;
+       }
+       nanoglState.depthmask = flag;
+       FlushOnStateChange( );
+       }
+       glEsImpl->glDepthMask( flag );
+}
 
-void glTexGeni( GLenum coord, GLenum pname, GLint param )
+void glBindTexture( GLenum target, GLuint texture )
 {
-//for mirrors? not needed for original hl?
+       if( skipnanogl )
+       {
+               glEsImpl->glBindTexture( target,texture );
+               return;
+       }
+       if ( activetmuState->boundtexture.value == texture )
+       {
+               return;
+       }
+       FlushOnStateChange( );
+       activetmuState->boundtexture.value = texture;
+       glEsImpl->glBindTexture( target, texture );
 }
 
-void glTexGenfv( GLenum coord, GLenum pname, const GLfloat *params )
+void glGetIntegerv( GLenum pname, GLint *params )
 {
-//for mirrors? not needed for original hl?
+       FlushOnStateChange( );
+       glEsImpl->glGetIntegerv( pname, params );
 }
 
-//-- --//
+GLubyte nano_extensions_string[4096];
+const GLubyte *glGetString( GLenum name )
+{
 
-void glHint (GLenum target, GLenum mode)
-    {
-    FlushOnStateChange();
-    glEsImpl->glHint(target, mode);
-    }
+       if ( name == GL_EXTENSIONS )
+       {
+#if defined( __MULTITEXTURE_SUPPORT__ )
+               sprintf( (char *)nano_extensions_string, "%s %s", glEsImpl->glGetString( name ), "GL_ARB_multitexture EXT_texture_env_add" );
+#else
+               sprintf( (char *)nano_extensions_string, "%s %s", glEsImpl->glGetString( name ), "EXT_texture_env_add" );
+#endif
+               return nano_extensions_string;
+       }
+       return glEsImpl->glGetString( name );
+}
 
-void glBlendFunc (GLenum sfactor, GLenum dfactor)
-    {
-    if ((nanoglState.sfactor == sfactor) && (nanoglState.dfactor == dfactor))
-        {
-        return;
-        }
-    nanoglState.sfactor = sfactor;
-    nanoglState.dfactor = dfactor;
-    FlushOnStateChange();
-    glEsImpl->glBlendFunc(sfactor, dfactor);
-    }
+void glAlphaFunc( GLenum func, GLclampf ref )
+{
+       FlushOnStateChange( );
+       glEsImpl->glAlphaFunc( func, ref );
+}
 
-void glPopMatrix (void)
-    {
-    FlushOnStateChange();
-    glEsImpl->glPopMatrix();
-    }
+void glFlush( void )
+{
+       FlushOnStateChange( );
+       glEsImpl->glFlush( );
+}
 
-void glShadeModel (GLenum mode)
-    {
-    if (nanoglState.shademodel == mode)
-        {
-        return;
-        }
-    nanoglState.shademodel = mode;
-    FlushOnStateChange();
-    glEsImpl->glShadeModel(mode);
-    }
+void glReadPixels( GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels )
+{
+       if ( format == GL_DEPTH_COMPONENT )
+       {
+               // OpenglEs 1.1 does not support reading depth buffer without an extension
+               memset( pixels, 0xff, 4 );
+               return;
+       }
+       FlushOnStateChange( );
+       glEsImpl->glReadPixels( x, y, width, height, format, type, pixels );
+}
 
-void glPushMatrix (void)
-    {
-    FlushOnStateChange();
-    glEsImpl->glPushMatrix();
-    }
+void glReadBuffer( GLenum /*mode*/ )
+{
+}
 
-void glTexEnvf (GLenum target, GLenum pname, GLfloat param)
-    {
-    if (target == GL_TEXTURE_ENV)
-        {
-        if (pname == GL_TEXTURE_ENV_MODE)
-            {
-            if (param == activetmuState->texture_env_mode.value)
-                {
-                return;
-                } 
-            else
-                {
-                FlushOnStateChange();
-                glEsImpl->glTexEnvf(target, pname, param);
-                activetmuState->texture_env_mode.value = param;
-                return;
-                }
-            }
-        }
-    FlushOnStateChange();
-    glEsImpl->glTexEnvf(target, pname, param);
-    }
+void glLoadMatrixf( const GLfloat *m )
+{
+       FlushOnStateChange( );
+       glEsImpl->glLoadMatrixf( m );
+}
 
-void glVertex3fv( const GLfloat *v )
-    {
-    GLfloat* vert = (GLfloat*)ptrVertexAttribArray++;
-    memcpy(vert, v, 3*sizeof(GLfloat));
-#if defined(__MULTITEXTURE_SUPPORT__)
-    memcpy(vert+3, &currentVertexAttrib.red, 5*sizeof(GLfloat));
-#else
-    memcpy(vert+4, &currentVertexAttrib.red, 3*sizeof(GLfloat));
-#endif
-    }
-    
+void glTexSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels )
+{
+       FlushOnStateChange( );
+       glEsImpl->glTexSubImage2D( target, level, xoffset, yoffset, width, height, format, type, pixels );
+}
 
-void glDepthMask (GLboolean flag)
-    {
-    if (nanoglState.depthmask == flag)
-        {
-        return;
-        }
-    nanoglState.depthmask = flag;
-    FlushOnStateChange();
-    glEsImpl->glDepthMask(flag);
-    }
+void glClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha )
+{
+       FlushOnStateChange( );
+       glEsImpl->glClearColor( red, green, blue, alpha );
+}
 
-void glBindTexture (GLenum target, GLuint texture)
-    {
-    if (activetmuState->boundtexture.value == texture)
-        {
-        return;
-        }
-    FlushOnStateChange();
-    activetmuState->boundtexture.value = texture;
-    glEsImpl->glBindTexture(target, texture);
-    }
+GLenum glGetError( void )
+{
+       //FlushOnStateChange();
+       return GL_NO_ERROR; //glEsImpl->glGetError();
+}
 
+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 glGetIntegerv (GLenum pname, GLint *params)
-    {
-    FlushOnStateChange();
-    glEsImpl->glGetIntegerv(pname, params);
-    }
+void glActiveTextureARB( 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;
+}
 
-GLubyte nano_extensions_string[4096];
-const GLubyte* glGetString (GLenum name)
-    {
+void glClientActiveTexture( GLenum texture )
+{
+       if( skipnanogl )
+       {
+               glEsImpl->glClientActiveTexture( texture );
+               return;
+       }
+       clientactivetmu = texture;
+}
+void glClientActiveTextureARB( GLenum texture )
+{
+       if( skipnanogl )
+       {
+               glEsImpl->glClientActiveTexture( texture );
+               return;
+       }
+       clientactivetmu = texture;
+}
 
-    if (name == GL_EXTENSIONS)
-        {
-#if defined(__MULTITEXTURE_SUPPORT__)
-        sprintf((char*)nano_extensions_string,"%s %s",glEsImpl->glGetString(name),"GL_ARB_multitexture EXT_texture_env_add");
-#else
-        sprintf((char*)nano_extensions_string,"%s %s",glEsImpl->glGetString(name),"EXT_texture_env_add");
-#endif
-        return nano_extensions_string;
-        }
-    return glEsImpl->glGetString(name);
-    }
 
-void glAlphaFunc (GLenum func, GLclampf ref)
-    {
-    FlushOnStateChange();
-    glEsImpl->glAlphaFunc(func,ref);
-    }
+void glPolygonMode( GLenum face, GLenum mode )
+{
+}
 
-void glFlush (void)
-    {
-    FlushOnStateChange();
-    glEsImpl->glFlush();
-    }
+void glDeleteTextures( GLsizei n, const GLuint *textures )
+{
+       FlushOnStateChange( );
+       glEsImpl->glDeleteTextures( n, textures );
+}
 
-void glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels)
-    {
-    if (format == GL_DEPTH_COMPONENT)
-        {
-        // OpenglEs 1.1 does not support reading depth buffer without an extension
-        memset(pixels, 0xff,4);
-        return;   
-        }
-    FlushOnStateChange();
-    glEsImpl->glReadPixels(x,y,width,height,format,type,pixels);
-    }
+void glClearDepth( GLclampd depth )
+{
+       FlushOnStateChange( );
+       glEsImpl->glClearDepthf( depth );
+}
 
-void glReadBuffer( GLenum /*mode*/ )
-    {
-    
-    }
+void glClipPlane( GLenum plane, const GLdouble *equation )
+{
+       FlushOnStateChange( );
+       float array[4];
+       array[0] = ( GLfloat )( equation[0] );
+       array[1] = ( GLfloat )( equation[1] );
+       array[2] = ( GLfloat )( equation[2] );
+       array[3] = ( GLfloat )( equation[3] );
+       glEsImpl->glClipPlanef( plane, array );
+}
 
-void glLoadMatrixf (const GLfloat *m)
-    {
-    FlushOnStateChange();
-    glEsImpl->glLoadMatrixf(m);
-    }
+void glScissor( GLint x, GLint y, GLsizei width, GLsizei height )
+{
+       FlushOnStateChange( );
+       glEsImpl->glScissor( x, y, width, height );
+}
 
-void glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
-    {
-    FlushOnStateChange();
-    glEsImpl->glTexSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixels);
-    }
+void glPointSize( GLfloat size )
+{
+       FlushOnStateChange( );
+       glEsImpl->glPointSize( size );
+}
 
-void glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
-    {
-    FlushOnStateChange();
-    glEsImpl->glClearColor(red,green,blue,alpha);
-    }
+void glArrayElement( GLint i )
+{
+}
+void glLineWidth( GLfloat width )
+{
+}
+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 );
+}
 
-GLenum glGetError (void)
-    {
-    //FlushOnStateChange();
-    return GL_NO_ERROR;//glEsImpl->glGetError();
-    }
+struct ptrstate vertex_array;
+struct ptrstate color_array;
+struct ptrstate texture_coord_array;
 
-void glActiveTexture (GLenum texture)
-    {
-    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 glClientActiveTexture (GLenum texture)
-    {
-    clientactivetmu = texture;
-    }
-    
-void glPolygonMode( GLenum face, GLenum mode )
-    {
-    }
+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( );
+       // setup correct vertex/color/texcoord pointers
+       if ( arraysValid ||
+            tmuState0.vertex_array.changed ||
+            tmuState0.color_array.changed ||
+            tmuState0.texture_coord_array.changed || tmuState0.normal_array.changed )
+       {
+               glEsImpl->glClientActiveTexture( GL_TEXTURE0 );
+       }
+       if ( arraysValid || tmuState0.vertex_array.changed )
+       {
+               if ( tmuState0.vertex_array.enabled )
+               {
+                       glEsImpl->glEnableClientState( GL_VERTEX_ARRAY );
+               }
+               else
+               {
+                       glEsImpl->glDisableClientState( GL_VERTEX_ARRAY );
+               }
+               glEsImpl->glVertexPointer( tmuState0.vertex_array.size,
+                                          tmuState0.vertex_array.type,
+                                          tmuState0.vertex_array.stride,
+                                          tmuState0.vertex_array.ptr );
+               tmuState0.vertex_array.changed = GL_FALSE;
+       }
+       if ( arraysValid || tmuState0.color_array.changed )
+       {
+               if ( tmuState0.color_array.enabled )
+               {
+                       glEsImpl->glEnableClientState( GL_COLOR_ARRAY );
+               }
+               else
+               {
+                       glEsImpl->glDisableClientState( GL_COLOR_ARRAY );
+                       glEsImpl->glColor4f( currentVertexAttrib.red/255.0f, currentVertexAttrib.green/255.0f,
+                                       currentVertexAttrib.blue/255.0f, currentVertexAttrib.alpha/255.0f );
 
-void glDeleteTextures( GLsizei n, const GLuint *textures ) 
-    {
-    FlushOnStateChange();
-    glEsImpl->glDeleteTextures(n,textures);
-    }
+               }
+               glEsImpl->glColorPointer( tmuState0.color_array.size,
+                                         tmuState0.color_array.type,
+                                         tmuState0.color_array.stride,
+                                         tmuState0.color_array.ptr );
+               tmuState0.color_array.changed = GL_FALSE;
+       }
+       if ( arraysValid || tmuState0.normal_array.changed )
+       {
+               if ( tmuState0.normal_array.enabled )
+               {
+                       glEsImpl->glEnableClientState( GL_NORMAL_ARRAY );
+               }
+               else
+               {
+                       glEsImpl->glDisableClientState( GL_NORMAL_ARRAY );
+               }
+               glEsImpl->glNormalPointer( tmuState0.normal_array.type,
+                                          tmuState0.normal_array.stride,
+                                          tmuState0.normal_array.ptr );
+               tmuState0.normal_array.changed = GL_FALSE;
+       }
+       if ( arraysValid || tmuState0.texture_coord_array.changed )
+       {
+               tmuState0.texture_coord_array.changed = GL_FALSE;
+               if ( tmuState0.texture_coord_array.enabled )
+               {
+                       glEsImpl->glEnableClientState( GL_TEXTURE_COORD_ARRAY );
+               }
+               else
+               {
+                       glEsImpl->glDisableClientState( GL_TEXTURE_COORD_ARRAY );
+               }
+               glEsImpl->glTexCoordPointer( tmuState0.texture_coord_array.size,
+                                            tmuState0.texture_coord_array.type,
+                                            tmuState0.texture_coord_array.stride,
+                                            tmuState0.texture_coord_array.ptr );
+       }
 
-void glClearDepth( GLclampf depth ) 
-    {
-    FlushOnStateChange();
-    glEsImpl->glClearDepthf( depth ); 
-    }
+       if ( arraysValid || tmuState1.texture_coord_array.changed )
+       {
+               tmuState1.texture_coord_array.changed = GL_FALSE;
+               glEsImpl->glClientActiveTexture( GL_TEXTURE1 );
+               if ( tmuState1.texture_coord_array.enabled )
+               {
+                       glEsImpl->glEnableClientState( GL_TEXTURE_COORD_ARRAY );
+               }
+               else
+               {
+                       glEsImpl->glDisableClientState( GL_TEXTURE_COORD_ARRAY );
+               }
+               glEsImpl->glTexCoordPointer( tmuState1.texture_coord_array.size,
+                                            tmuState1.texture_coord_array.type,
+                                            tmuState1.texture_coord_array.stride,
+                                            tmuState1.texture_coord_array.ptr );
+       }
 
-void glClipPlane( GLenum plane, const GLdouble *equation ) 
-    {
-    FlushOnStateChange();
-    float array[4];
-    array[0] = (GLfloat)(equation[0]);
-    array[1] = (GLfloat)(equation[1]);
-    array[2] = (GLfloat)(equation[2]);
-    array[3] = (GLfloat)(equation[3]);
-    glEsImpl->glClipPlanef( plane, array );
-    }
-
-void glScissor( GLint x, GLint y, GLsizei width, GLsizei height ) 
-    {
-    FlushOnStateChange();
-    glEsImpl->glScissor( x, y, width,height);
-    }
+       arraysValid = GL_FALSE;
+       glEsImpl->glDrawElements( mode, count, type, indices );
+}
 
-void glPointSize( GLfloat size ) 
-    {
-    FlushOnStateChange();
-    glEsImpl->glPointSize( size );
-    }
+bool vboarray;
 
-void glArrayElement(GLint i) {}
-void glLineWidth(GLfloat width) {}
-void glCallList( GLuint list ) {}
-void glColorMask( GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha ) {}
-void glStencilFunc( GLenum func, GLint ref, GLuint mask ) {}
-void glStencilOp( GLenum fail, GLenum zfail, GLenum zpass ) {}
+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 )
+       {
+               clientstate = &tmuState0;
+       }
+       else if ( clientactivetmu == GL_TEXTURE1 )
+       {
+               clientstate = &tmuState1;
+       }
+       else
+       {
+               return;
+       }
+       switch ( array )
+       {
+       case GL_VERTEX_ARRAY:
+               if ( clientstate->vertex_array.enabled )
+               {
+                       return;
+               }
+               clientstate->vertex_array.enabled = GL_TRUE;
+               clientstate->vertex_array.changed = GL_TRUE;
+               break;
+       case GL_COLOR_ARRAY:
+               if ( clientstate->color_array.enabled )
+               {
+                       return;
+               }
+               clientstate->color_array.enabled = GL_TRUE;
+               clientstate->color_array.changed = GL_TRUE;
 
-struct ptrstate vertex_array;                                       
-struct ptrstate color_array;
-struct ptrstate texture_coord_array;
+               break;
+       case GL_NORMAL_ARRAY:
+               if ( clientstate->normal_array.enabled )
+               {
+                       return;
+               }
+               clientstate->normal_array.enabled = GL_TRUE;
+               clientstate->normal_array.changed = GL_TRUE;
 
-void glDrawElements( GLenum mode, GLsizei count, GLenum type, const GLvoid *indices ) 
-    {
-    // ensure that all primitives specified between glBegin/glEnd pairs
-    // are rendered first, and that we have correct tmu in use..
-    FlushOnStateChange();
-    // setup correct vertex/color/texcoord pointers
-    if (arraysValid || 
-        tmuState0.vertex_array.changed ||
-        tmuState0.color_array.changed ||
-        tmuState0.texture_coord_array.changed || tmuState0.normal_array.changed)
-        {
-        glEsImpl->glClientActiveTexture(GL_TEXTURE0);
-        }
-    if (arraysValid || tmuState0.vertex_array.changed)
-        {
-        if (tmuState0.vertex_array.enabled)
-            {
-            glEsImpl->glEnableClientState(GL_VERTEX_ARRAY);
-            }
-        else
-            {
-            glEsImpl->glDisableClientState(GL_VERTEX_ARRAY);
-            }
-        glEsImpl->glVertexPointer(tmuState0.vertex_array.size, 
-                                  tmuState0.vertex_array.type, 
-                                  tmuState0.vertex_array.stride, 
-                                  tmuState0.vertex_array.ptr);
-        tmuState0.vertex_array.changed = GL_FALSE;
-        }
-    if (arraysValid || tmuState0.color_array.changed)
-        {
-        if (tmuState0.color_array.enabled)
-            {
-            glEsImpl->glEnableClientState(GL_COLOR_ARRAY);
-            }
-        else
-            {
-            glEsImpl->glDisableClientState(GL_COLOR_ARRAY);
-            }
-        glEsImpl->glColorPointer(tmuState0.color_array.size, 
-                                 tmuState0.color_array.type, 
-                                 tmuState0.color_array.stride, 
-                                 tmuState0.color_array.ptr);
-        tmuState0.color_array.changed = GL_FALSE;
-        }
-    if (arraysValid || tmuState0.normal_array.changed)
-        {
-        if (tmuState0.normal_array.enabled)
-            {
-            glEsImpl->glEnableClientState(GL_NORMAL_ARRAY);
-            }
-        else
-            {
-            glEsImpl->glDisableClientState(GL_NORMAL_ARRAY);
-            }
-        glEsImpl->glNormalPointer(tmuState0.normal_array.type,
-                                 tmuState0.normal_array.stride,
-                                 tmuState0.normal_array.ptr);
-        tmuState0.normal_array.changed = GL_FALSE;
-        }
-    if (arraysValid || tmuState0.texture_coord_array.changed)
-        {
-        tmuState0.texture_coord_array.changed = GL_FALSE;
-        if (tmuState0.texture_coord_array.enabled)
-            {
-            glEsImpl->glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-            }
-        else
-            {
-            glEsImpl->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-            }
-        glEsImpl->glTexCoordPointer(tmuState0.texture_coord_array.size, 
-                                        tmuState0.texture_coord_array.type, 
-                                        tmuState0.texture_coord_array.stride, 
-                                        tmuState0.texture_coord_array.ptr);
-        }
-    if (arraysValid || tmuState1.texture_coord_array.changed)
-        {
-        tmuState1.texture_coord_array.changed = GL_FALSE;
-        glEsImpl->glClientActiveTexture(GL_TEXTURE1);
-        if (tmuState1.texture_coord_array.enabled)
-            {
-            glEsImpl->glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-            }
-        else
-            {
-            glEsImpl->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-            }
-        glEsImpl->glTexCoordPointer(tmuState1.texture_coord_array.size, 
-                                        tmuState1.texture_coord_array.type, 
-                                        tmuState1.texture_coord_array.stride, 
-                                        tmuState1.texture_coord_array.ptr);
-        }
-
-    arraysValid = GL_FALSE;
-    glEsImpl->glDrawElements(mode, count, type, indices);
-    }
-
-void glEnableClientState(GLenum  array) 
-    {
-    struct nanotmuState* clientstate = NULL;
-    if (clientactivetmu == GL_TEXTURE0)
-        {
-        clientstate = &tmuState0;
-        }
-    else if (clientactivetmu == GL_TEXTURE1)
-        {
-        clientstate = &tmuState1;
-        }
-    else
-        {
-        return;
-        }
-    switch (array)
-        {
-        case GL_VERTEX_ARRAY:
-            if (clientstate->vertex_array.enabled)
-                {
-                return;
-                }
-            clientstate->vertex_array.enabled = GL_TRUE;
-            clientstate->vertex_array.changed = GL_TRUE;
-            break;
-        case GL_COLOR_ARRAY:
-            if (clientstate->color_array.enabled)
-                {
-                return;
-                }
-            clientstate->color_array.enabled = GL_TRUE;
-            clientstate->color_array.changed = GL_TRUE;
+               break;
+       case GL_TEXTURE_COORD_ARRAY:
+               if ( clientstate->texture_coord_array.enabled )
+               {
+                       return;
+               }
+               clientstate->texture_coord_array.enabled = GL_TRUE;
+               clientstate->texture_coord_array.changed = GL_TRUE;
+               break;
+       default:
+               break;
+       }
+}
+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 )
+       {
+               clientstate = &tmuState0;
+       }
+       else if ( clientactivetmu == GL_TEXTURE1 )
+       {
+               clientstate = &tmuState1;
+       }
+       else
+       {
+               return;
+       }
+       switch ( array )
+       {
+       case GL_VERTEX_ARRAY:
+               if ( !clientstate->vertex_array.enabled )
+               {
+                       return;
+               }
+               clientstate->vertex_array.enabled = GL_FALSE;
+               clientstate->vertex_array.changed = GL_TRUE;
+               break;
+       case GL_COLOR_ARRAY:
+               if ( !clientstate->color_array.enabled )
+               {
+                       return;
+               }
+               clientstate->color_array.enabled = GL_FALSE;
+               clientstate->color_array.changed = GL_TRUE;
 
-            break;
-        case GL_NORMAL_ARRAY:
-            if (clientstate->normal_array.enabled)
-                {
-                return;
-                }
-            clientstate->normal_array.enabled = GL_TRUE;
-            clientstate->normal_array.changed = GL_TRUE;
+               break;
+       case GL_NORMAL_ARRAY:
+               if ( !clientstate->normal_array.enabled )
+               {
+                       return;
+               }
+               clientstate->normal_array.enabled = GL_FALSE;
+               clientstate->normal_array.changed = GL_TRUE;
 
-            break;
-        case GL_TEXTURE_COORD_ARRAY:
-            if (clientstate->texture_coord_array.enabled)
-                {
-                return;
-                }
-            clientstate->texture_coord_array.enabled = GL_TRUE;
-            clientstate->texture_coord_array.changed = GL_TRUE;
-            break;
-        default:
-            break;
-        }
-    }
-void glDisableClientState(GLenum  array) 
-    {
-    struct nanotmuState* clientstate = NULL;
-    if (clientactivetmu == GL_TEXTURE0)
-        {
-        clientstate = &tmuState0;
-        }
-    else if (clientactivetmu == GL_TEXTURE1)
-        {
-        clientstate = &tmuState1;
-        }
-    else
-        {
-        return;
-        }
-    switch (array)
-        {
-        case GL_VERTEX_ARRAY:
-            if (!clientstate->vertex_array.enabled)
-                {
-                return;
-                }
-            clientstate->vertex_array.enabled = GL_FALSE;
-            clientstate->vertex_array.changed = GL_TRUE;
-            break;
-        case GL_COLOR_ARRAY:
-            if (!clientstate->color_array.enabled)
-                {
-                return;
-                }
-            clientstate->color_array.enabled = GL_FALSE;
-            clientstate->color_array.changed = GL_TRUE;
+               break;
+       case GL_TEXTURE_COORD_ARRAY:
+               if ( !clientstate->texture_coord_array.enabled )
+               {
+                       return;
+               }
+               clientstate->texture_coord_array.enabled = GL_FALSE;
+               clientstate->texture_coord_array.changed = GL_TRUE;
+               break;
+       default:
+               break;
+       }
+}
+void glVertexPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer )
+{
 
-            break;
-        case GL_NORMAL_ARRAY:
-            if (!clientstate->normal_array.enabled)
-                {
-                return;
-                }
-            clientstate->normal_array.enabled = GL_FALSE;
-            clientstate->normal_array.changed = GL_TRUE;
+       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 &&
+            tmuState0.vertex_array.ptr == pointer )
+       {
+               return;
+       }
+       tmuState0.vertex_array.size    = size;
+       tmuState0.vertex_array.stride  = stride;
+       tmuState0.vertex_array.type    = type;
+       tmuState0.vertex_array.ptr     = (GLvoid *)pointer;
+       tmuState0.vertex_array.changed = GL_TRUE;
+}
+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 )
+       {
+               clientstate = &tmuState0;
+       }
+       else if ( clientactivetmu == GL_TEXTURE1 )
+       {
+               clientstate = &tmuState1;
+       }
+       if ( clientstate->texture_coord_array.size == size &&
+            clientstate->texture_coord_array.stride == stride &&
+            clientstate->texture_coord_array.type == type &&
+            clientstate->texture_coord_array.ptr == pointer )
+       {
+               return;
+       }
+       clientstate->texture_coord_array.size    = size;
+       clientstate->texture_coord_array.stride  = stride;
+       clientstate->texture_coord_array.type    = type;
+       clientstate->texture_coord_array.ptr     = (GLvoid *)pointer;
+       clientstate->texture_coord_array.changed = GL_TRUE;
+}
+void glColorPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer )
+{
+       if ( tmuState0.color_array.size == size &&
+            tmuState0.color_array.stride == stride &&
+            tmuState0.color_array.type == type &&
+            tmuState0.color_array.ptr == pointer )
+       {
+               return;
+       }
+       tmuState0.color_array.size    = size;
+       tmuState0.color_array.stride  = stride;
+       tmuState0.color_array.type    = type;
+       tmuState0.color_array.ptr     = (GLvoid *)pointer;
+       tmuState0.color_array.changed = GL_TRUE;
+}
 
-            break;
-        case GL_TEXTURE_COORD_ARRAY:
-            if (!clientstate->texture_coord_array.enabled)
-                {
-                return;
-                }
-            clientstate->texture_coord_array.enabled = GL_FALSE;
-            clientstate->texture_coord_array.changed = GL_TRUE;
-            break;
-        default:
-            break;
-        }
-    }
-void glVertexPointer(  GLint size,     GLenum type,GLsizei     stride, const GLvoid *pointer ) 
-    {
-    if (tmuState0.vertex_array.size == size &&
-        tmuState0.vertex_array.stride == stride &&
-        tmuState0.vertex_array.type == type &&
-        tmuState0.vertex_array.ptr == pointer)
-        {
-        return;
-        }
-    tmuState0.vertex_array.size = size;
-    tmuState0.vertex_array.stride = stride;
-    tmuState0.vertex_array.type = type;
-    tmuState0.vertex_array.ptr  = (GLvoid*)pointer;
-    tmuState0.vertex_array.changed = GL_TRUE;
-    }
-void glTexCoordPointer( GLint  size,  GLenum type,  GLsizei stride,  const     GLvoid *pointer ) 
-    {
-    struct nanotmuState* clientstate = NULL;
-    if (clientactivetmu == GL_TEXTURE0)
-        {
-        clientstate = &tmuState0;
-        }
-    else if (clientactivetmu == GL_TEXTURE1)
-        {
-        clientstate = &tmuState1;
-        }
-    if (clientstate->texture_coord_array.size == size &&
-        clientstate->texture_coord_array.stride == stride &&
-        clientstate->texture_coord_array.type == type &&
-        clientstate->texture_coord_array.ptr == pointer)
-        {
-        return;
-        }
-    clientstate->texture_coord_array.size = size;
-    clientstate->texture_coord_array.stride = stride;
-    clientstate->texture_coord_array.type = type;
-    clientstate->texture_coord_array.ptr  = (GLvoid*)pointer;
-    clientstate->texture_coord_array.changed = GL_TRUE;
-    }
-void glColorPointer( GLint size,  GLenum type,  GLsizei stride,  const GLvoid *pointer ) 
-    {
-    if (tmuState0.color_array.size == size &&
-        tmuState0.color_array.stride == stride &&
-        tmuState0.color_array.type == type &&
-        tmuState0.color_array.ptr == pointer)
-        {
-        return;
-        }
-    tmuState0.color_array.size = size;
-    tmuState0.color_array.stride = stride;
-    tmuState0.color_array.type = type;
-    tmuState0.color_array.ptr  = (GLvoid*)pointer;
-    tmuState0.color_array.changed = GL_TRUE;
-    }
-
-void glNormalPointer( GLenum type,  GLsizei stride,  const GLvoid *pointer )
-    {
-    int size = 0;
-    if (tmuState0.normal_array.size == size &&
-        tmuState0.normal_array.stride == stride &&
-        tmuState0.normal_array.type == type &&
-        tmuState0.normal_array.ptr == pointer)
-        {
-        return;
-        }
-    tmuState0.normal_array.size = size;
-    tmuState0.normal_array.stride = stride;
-    tmuState0.normal_array.type = type;
-    tmuState0.normal_array.ptr  = (GLvoid*)pointer;
-    tmuState0.normal_array.changed = GL_TRUE;
-    }
-void glPolygonOffset( GLfloat factor, GLfloat units ) 
-    {
-    FlushOnStateChange();
-    glEsImpl->glPolygonOffset(factor, units);
-    }
-void glStencilMask( GLuint mask ) {}
-void glClearStencil( GLint s ) {}
+void glNormalPointer( GLenum type, GLsizei stride, const GLvoid *pointer )
+{
+       int size = 0;
+       if ( tmuState0.normal_array.size == size &&
+            tmuState0.normal_array.stride == stride &&
+            tmuState0.normal_array.type == type &&
+            tmuState0.normal_array.ptr == pointer )
+       {
+               return;
+       }
+       tmuState0.normal_array.size    = size;
+       tmuState0.normal_array.stride  = stride;
+       tmuState0.normal_array.type    = type;
+       tmuState0.normal_array.ptr     = (GLvoid *)pointer;
+       tmuState0.normal_array.changed = GL_TRUE;
+}
+void glPolygonOffset( GLfloat factor, GLfloat units )
+{
+       FlushOnStateChange( );
+       glEsImpl->glPolygonOffset( factor, units );
+}
+void glStencilMask( GLuint mask )
+{
+       FlushOnStateChange( );
+       glEsImpl->glStencilMask( mask );
+}
+void glClearStencil( GLint s )
+{
+       FlushOnStateChange( );
+       glEsImpl->glClearStencil( s );
+}
 
-#if defined(__MULTITEXTURE_SUPPORT__)
+#if defined( __MULTITEXTURE_SUPPORT__ )
 
 extern "C" void glMultiTexCoord2fARB( GLenum target, GLfloat s, GLfloat t );
 
 void glMultiTexCoord2fARB( GLenum target, GLfloat s, GLfloat t )
-    {
-    if (target == GL_TEXTURE0)
-        {
-        glTexCoord2f(s,t);
-        }
-    else
-        {
-        currentVertexAttrib.s_multi = s;
-        currentVertexAttrib.t_multi = t;
-        }
-    }
+{
+       if ( target == GL_TEXTURE0 )
+       {
+               glTexCoord2f( s, t );
+       }
+       else
+       {
+               currentVertexAttrib.s_multi = s;
+               currentVertexAttrib.t_multi = t;
+       }
+}
 #endif
 
 /* Vladimir  */
@@ -1844,274 +2293,478 @@ void glMultiTexCoord2fARB( GLenum target, GLfloat s, GLfloat t )
     FlushOnStateChange();
     glEsImpl->glDrawArrays(mode, first , count);
 }*/
-void glMultMatrixf (const GLfloat *m)
+void glMultMatrixf( const GLfloat *m )
 {
-    FlushOnStateChange();
-    glEsImpl->glMultMatrixf(m);
+       FlushOnStateChange( );
+       glEsImpl->glMultMatrixf( m );
 }
 
-void glPixelStorei (GLenum pname, GLint param)
+void glPixelStorei( GLenum pname, GLint param )
 {
-    FlushOnStateChange();
-    glEsImpl->glPixelStorei(pname, param);
+       FlushOnStateChange( );
+       glEsImpl->glPixelStorei( pname, param );
 }
 
-
-void glFogf (GLenum pname, GLfloat param)
+void glFogi( GLenum pname, GLint param )
 {
-       FlushOnStateChange();
-       glEsImpl->glFogf(pname, param);
+       FlushOnStateChange( );
+       glEsImpl->glFogf( pname, param );
 }
 
-void glFogfv (GLenum pname, const GLfloat *params)
+void glFogf( GLenum pname, GLfloat param )
 {
-       FlushOnStateChange();
-       glEsImpl->glFogfv(pname, params);
+       FlushOnStateChange( );
+       glEsImpl->glFogf( pname, param );
 }
 
-void glGetTexParameteriv (GLenum target, GLenum pname, GLint *params)
+void glFogfv( GLenum pname, const GLfloat *params )
 {
-       FlushOnStateChange();
-       glEsImpl->glGetTexParameteriv(target, pname, params);
+       FlushOnStateChange( );
+       glEsImpl->glFogfv( pname, params );
 }
 
+void glGetTexParameteriv( GLenum target, GLenum pname, GLint *params )
+{
+       FlushOnStateChange( );
+       glEsImpl->glGetTexParameteriv( target, pname, params );
+}
 
 // This gives: called unimplemented OpenGL ES API (Android)
-void glTexParameteri (GLenum target, GLenum pname, GLint param)
+void glTexParameteri( GLenum target, GLenum pname, GLint param )
 {
-    if (pname == GL_TEXTURE_BORDER_COLOR) {
+       if ( pname == GL_TEXTURE_BORDER_COLOR )
+       {
                return; // not supported by opengl es
        }
-    if (    (pname == GL_TEXTURE_WRAP_S ||
-             pname == GL_TEXTURE_WRAP_T) &&
-             param == GL_CLAMP)   {
+       if ( ( pname == GL_TEXTURE_WRAP_S ||
+              pname == GL_TEXTURE_WRAP_T ) &&
+            param == GL_CLAMP )
+       {
                param = 0x812F;
        }
 
-       FlushOnStateChange();
-       glEsImpl->glTexParameteri(target, pname, param);
+       FlushOnStateChange( );
+       glEsImpl->glTexParameteri( target, pname, param );
 }
 
-void glTexParameterx (GLenum target, GLenum pname, GLfixed param)
+void glTexParameterx( GLenum target, GLenum pname, GLfixed param )
 {
-    if (pname == GL_TEXTURE_BORDER_COLOR) {
+       if ( pname == GL_TEXTURE_BORDER_COLOR )
+       {
                return; // not supported by opengl es
        }
-    if (    (pname == GL_TEXTURE_WRAP_S ||
-             pname == GL_TEXTURE_WRAP_T) &&
-             param == GL_CLAMP)   {
+       if ( ( pname == GL_TEXTURE_WRAP_S ||
+              pname == GL_TEXTURE_WRAP_T ) &&
+            param == GL_CLAMP )
+       {
                param = 0x812F;
        }
-       FlushOnStateChange();
-       glEsImpl->glTexParameterx(target, pname, param);
+       FlushOnStateChange( );
+       glEsImpl->glTexParameterx( target, pname, param );
 }
 
-void glGenTextures (GLsizei n, GLuint *textures)
+void glGenTextures( GLsizei n, GLuint *textures )
 {
-       FlushOnStateChange();
-       glEsImpl->glGenTextures(n, textures);
+       FlushOnStateChange( );
+       glEsImpl->glGenTextures( n, textures );
 }
 
-void glFrontFace (GLenum mode)
+void glFrontFace( GLenum mode )
 {
-       FlushOnStateChange();
-       glEsImpl->glFrontFace(mode);
+       FlushOnStateChange( );
+       glEsImpl->glFrontFace( mode );
 }
 // End Vladimir
 
-void glTexEnvi (GLenum target, GLenum pname, GLint param)
-    {
-    if (target == GL_TEXTURE_ENV)
-        {
-        if (pname == GL_TEXTURE_ENV_MODE)
-            {
-            if (param == activetmuState->texture_env_mode.value)
-                {
-                return;
-                }
-            else
-                {
-                FlushOnStateChange();
-                glEsImpl->glTexEnvi(target, pname, param);
-                activetmuState->texture_env_mode.value = param;
-                return;
-                }
-            }
-        }
-    FlushOnStateChange();
-    glEsImpl->glTexEnvi(target, pname, param);
-    }
-
-void glMultiTexCoord3fARB(GLenum, GLfloat, GLfloat, GLfloat)
+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 )
+               {
+                       if ( param == activetmuState->texture_env_mode.value )
+                       {
+                               return;
+                       }
+                       else
+                       {
+                               FlushOnStateChange( );
+                               glEsImpl->glTexEnvi( target, pname, param );
+                               activetmuState->texture_env_mode.value = param;
+                               return;
+                       }
+               }
+       }
+       FlushOnStateChange( );
+       glEsImpl->glTexEnvi( target, pname, param );
 }
 
-void glMultiTexCoord2f(GLenum, GLfloat, GLfloat)
+#ifdef __MULTITEXTURE_SUPPORT__
+void glMultiTexCoord3fARB( GLenum a, GLfloat b, GLfloat c, GLfloat )
 {
+       return glMultiTexCoord2fARB( a, b, c );
+}
 
+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 ) mode = GL_TRIANGLE_FAN;
-       FlushOnStateChange();
+       if ( mode == GL_QUADS )
+               mode = GL_TRIANGLE_FAN;
+       FlushOnStateChange( );
        // setup correct vertex/color/texcoord pointers
-       if (arraysValid ||
-               tmuState0.vertex_array.changed ||
-               tmuState0.color_array.changed ||
-               tmuState0.texture_coord_array.changed || tmuState0.normal_array.changed)
+       if ( arraysValid ||
+            tmuState0.vertex_array.changed ||
+            tmuState0.color_array.changed ||
+            tmuState0.texture_coord_array.changed || tmuState0.normal_array.changed )
+       {
+               glEsImpl->glClientActiveTexture( GL_TEXTURE0 );
+       }
+       if ( arraysValid || tmuState0.vertex_array.changed )
+       {
+               if ( tmuState0.vertex_array.enabled )
                {
-               glEsImpl->glClientActiveTexture(GL_TEXTURE0);
+                       glEsImpl->glEnableClientState( GL_VERTEX_ARRAY );
                }
-       if (arraysValid || tmuState0.vertex_array.changed)
-               {
-               if (tmuState0.vertex_array.enabled)
-                       {
-                       glEsImpl->glEnableClientState(GL_VERTEX_ARRAY);
-                       }
                else
-                       {
-                       glEsImpl->glDisableClientState(GL_VERTEX_ARRAY);
-                       }
-               glEsImpl->glVertexPointer(tmuState0.vertex_array.size,
-                                                                 tmuState0.vertex_array.type,
-                                                                 tmuState0.vertex_array.stride,
-                                                                 tmuState0.vertex_array.ptr);
-               tmuState0.vertex_array.changed = GL_FALSE;
+               {
+                       glEsImpl->glDisableClientState( GL_VERTEX_ARRAY );
                }
-       if (arraysValid || tmuState0.color_array.changed)
+               glEsImpl->glVertexPointer( tmuState0.vertex_array.size,
+                                          tmuState0.vertex_array.type,
+                                          tmuState0.vertex_array.stride,
+                                          tmuState0.vertex_array.ptr );
+               tmuState0.vertex_array.changed = GL_FALSE;
+       }
+       if ( arraysValid || tmuState0.color_array.changed )
+       {
+               if ( tmuState0.color_array.enabled )
                {
-               if (tmuState0.color_array.enabled)
-                       {
-                       glEsImpl->glEnableClientState(GL_COLOR_ARRAY);
-                       }
+                       glEsImpl->glEnableClientState( GL_COLOR_ARRAY );
+               }
                else
-                       {
-                       glEsImpl->glDisableClientState(GL_COLOR_ARRAY);
-                       }
-               glEsImpl->glColorPointer(tmuState0.color_array.size,
-                                                                tmuState0.color_array.type,
-                                                                tmuState0.color_array.stride,
-                                                                tmuState0.color_array.ptr);
-               tmuState0.color_array.changed = GL_FALSE;
+               {
+                       glEsImpl->glDisableClientState( GL_COLOR_ARRAY );
+                       glEsImpl->glColor4f( currentVertexAttrib.red/255.0f, currentVertexAttrib.green/255.0f,
+                                       currentVertexAttrib.blue/255.0f, currentVertexAttrib.alpha/255.0f );
+
                }
-       if (arraysValid || tmuState0.normal_array.changed)
+               glEsImpl->glColorPointer( tmuState0.color_array.size,
+                                         tmuState0.color_array.type,
+                                         tmuState0.color_array.stride,
+                                         tmuState0.color_array.ptr );
+               tmuState0.color_array.changed = GL_FALSE;
+       }
+       if ( arraysValid || tmuState0.normal_array.changed )
+       {
+               if ( tmuState0.normal_array.enabled )
                {
-               if (tmuState0.normal_array.enabled)
-                       {
-                       glEsImpl->glEnableClientState(GL_NORMAL_ARRAY);
-                       }
-               else
-                       {
-                       glEsImpl->glDisableClientState(GL_NORMAL_ARRAY);
-                       }
-               glEsImpl->glNormalPointer(tmuState0.normal_array.type,
-                                                                tmuState0.normal_array.stride,
-                                                                tmuState0.normal_array.ptr);
-               tmuState0.normal_array.changed = GL_FALSE;
+                       glEsImpl->glEnableClientState( GL_NORMAL_ARRAY );
                }
-       if (arraysValid || tmuState0.texture_coord_array.changed)
+               else
                {
+                       glEsImpl->glDisableClientState( GL_NORMAL_ARRAY );
+               }
+               glEsImpl->glNormalPointer( tmuState0.normal_array.type,
+                                          tmuState0.normal_array.stride,
+                                          tmuState0.normal_array.ptr );
+               tmuState0.normal_array.changed = GL_FALSE;
+       }
+       if ( arraysValid || tmuState0.texture_coord_array.changed )
+       {
                tmuState0.texture_coord_array.changed = GL_FALSE;
-               if (tmuState0.texture_coord_array.enabled)
-                       {
-                       glEsImpl->glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-                       }
+               if ( tmuState0.texture_coord_array.enabled )
+               {
+                       glEsImpl->glEnableClientState( GL_TEXTURE_COORD_ARRAY );
+               }
                else
-                       {
-                       glEsImpl->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-                       }
-               glEsImpl->glTexCoordPointer(tmuState0.texture_coord_array.size,
-                                                                               tmuState0.texture_coord_array.type,
-                                                                               tmuState0.texture_coord_array.stride,
-                                                                               tmuState0.texture_coord_array.ptr);
+               {
+                       glEsImpl->glDisableClientState( GL_TEXTURE_COORD_ARRAY );
                }
+               glEsImpl->glTexCoordPointer( tmuState0.texture_coord_array.size,
+                                            tmuState0.texture_coord_array.type,
+                                            tmuState0.texture_coord_array.stride,
+                                            tmuState0.texture_coord_array.ptr );
+       }
 
-       if (arraysValid || tmuState1.texture_coord_array.changed)
-               {
+       if ( arraysValid || tmuState1.texture_coord_array.changed )
+       {
                tmuState1.texture_coord_array.changed = GL_FALSE;
-               glEsImpl->glClientActiveTexture(GL_TEXTURE1);
-               if (tmuState1.texture_coord_array.enabled)
-                       {
-                       glEsImpl->glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-                       }
+               glEsImpl->glClientActiveTexture( GL_TEXTURE1 );
+               if ( tmuState1.texture_coord_array.enabled )
+               {
+                       glEsImpl->glEnableClientState( GL_TEXTURE_COORD_ARRAY );
+               }
                else
-                       {
-                       glEsImpl->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-                       }
-               glEsImpl->glTexCoordPointer(tmuState1.texture_coord_array.size,
-                                                                               tmuState1.texture_coord_array.type,
-                                                                               tmuState1.texture_coord_array.stride,
-                                                                               tmuState1.texture_coord_array.ptr);
+               {
+                       glEsImpl->glDisableClientState( GL_TEXTURE_COORD_ARRAY );
                }
+               glEsImpl->glTexCoordPointer( tmuState1.texture_coord_array.size,
+                                            tmuState1.texture_coord_array.type,
+                                            tmuState1.texture_coord_array.stride,
+                                            tmuState1.texture_coord_array.ptr );
+       }
 
        arraysValid = GL_FALSE;
-       glEsImpl->glDrawArrays(mode, first, count);
-       }
+       glEsImpl->glDrawArrays( mode, first, count );
+}
 /*void glNormalPointer(GLenum type, GLsizei stride, const void *ptr)
 {
     glEsImpl->glNormalPointer( type, stride, ptr );
 }*/
 
-void glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+void glCopyTexSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height )
 {
-    FlushOnStateChange();
-    glEsImpl->glCopyTexSubImage2D( target, level, xoffset, yoffset, x, y, width, height );
+       FlushOnStateChange( );
+       glEsImpl->glCopyTexSubImage2D( target, level, xoffset, yoffset, x, y, width, height );
 }
 
-void glGenFramebuffers (GLsizei n, GLuint* framebuffers)
+void glGenFramebuffers( GLsizei n, GLuint *framebuffers )
 {
-    FlushOnStateChange();
-    glEsImpl->glGenFramebuffers( n, framebuffers );
+       FlushOnStateChange( );
+       glEsImpl->glGenFramebuffers( n, framebuffers );
 }
 
-
-void glGenRenderbuffers( GLsizei n, GLuint* renderbuffers )
+void glGenRenderbuffers( GLsizei n, GLuint *renderbuffers )
 {
-    FlushOnStateChange();
+       FlushOnStateChange( );
        glEsImpl->glGenRenderbuffers( n, renderbuffers );
 }
 
-void glBindRenderbuffer(GLenum target, GLuint renderbuffer)
+void glBindRenderbuffer( GLenum target, GLuint renderbuffer )
 {
-    FlushOnStateChange();
-    glEsImpl->glBindRenderbuffer( target, renderbuffer );
+       FlushOnStateChange( );
+       glEsImpl->glBindRenderbuffer( target, renderbuffer );
 }
 
-void glBindFramebuffer(GLenum target, GLuint framebuffer)\
+void glBindFramebuffer( GLenum target, GLuint framebuffer )
 {
-    FlushOnStateChange();
-    glEsImpl->glBindFramebuffer( target, framebuffer );
+       FlushOnStateChange( );
+       glEsImpl->glBindFramebuffer( target, framebuffer );
 }
 
-void glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+void glFramebufferRenderbuffer( GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer )
 {
-    FlushOnStateChange();
-    glEsImpl->glFramebufferRenderbuffer( target, attachment, renderbuffertarget, renderbuffer );
+       FlushOnStateChange( );
+       glEsImpl->glFramebufferRenderbuffer( target, attachment, renderbuffertarget, renderbuffer );
 }
 
-void glDeleteFramebuffers(GLsizei n, const GLuint *framebuffers)
+void glDeleteFramebuffers( GLsizei n, const GLuint *framebuffers )
 {
-    FlushOnStateChange();
-    glEsImpl->glDeleteFramebuffers(n, framebuffers);
+       FlushOnStateChange( );
+       glEsImpl->glDeleteFramebuffers( n, framebuffers );
 }
 
-void glDeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
+void glDeleteRenderbuffers( GLsizei n, const GLuint *renderbuffers )
 {
-    FlushOnStateChange();
-    glEsImpl->glDeleteRenderbuffers( n, renderbuffers );
+       FlushOnStateChange( );
+       glEsImpl->glDeleteRenderbuffers( n, renderbuffers );
 }
-void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+void glFramebufferTexture2D( GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level )
 {
-    FlushOnStateChange();
-    glEsImpl->glFramebufferTexture2D(target, attachment,textarget,texture,level);
+       FlushOnStateChange( );
+       glEsImpl->glFramebufferTexture2D( target, attachment, textarget, texture, level );
 }
 
-void glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+void glRenderbufferStorage( GLenum target, GLenum internalformat, GLsizei width, GLsizei height )
 {
-    FlushOnStateChange();
-    glEsImpl->glRenderbufferStorage(target, internalformat, width, height );
+       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
+       }
+}