Rice Video Plugin for GLES1.1
[mupen64plus-pandora.git] / source / rice_gles / src / OGLRender.cpp
diff --git a/source/rice_gles/src/OGLRender.cpp b/source/rice_gles/src/OGLRender.cpp
new file mode 100755 (executable)
index 0000000..e723de9
--- /dev/null
@@ -0,0 +1,1590 @@
+/*
+Copyright (C) 2003 Rice1964
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+*/
+
+#include "osal_opengl.h"
+
+#if SDL_VIDEO_OPENGL
+#include "OGLExtensions.h"
+#elif SDL_VIDEO_OPENGL_ES2
+#include "OGLES2FragmentShaders.h"
+#endif
+#include "OGLDebug.h"
+#include "OGLRender.h"
+#include "OGLGraphicsContext.h"
+#include "OGLTexture.h"
+#include "TextureManager.h"
+
+#ifdef PAULSCODE
+//include "ae_bridge.h"
+//static int hardwareType = HARDWARE_TYPE_UNKNOWN;
+#endif
+
+// FIXME: Use OGL internal L/T and matrix stack
+// FIXME: Use OGL lookupAt function
+// FIXME: Use OGL DisplayList
+
+UVFlagMap OGLXUVFlagMaps[] =
+{
+    {TEXTURE_UV_FLAG_WRAP, GL_REPEAT},
+    {TEXTURE_UV_FLAG_MIRROR, GL_MIRRORED_REPEAT_ARB},
+    {TEXTURE_UV_FLAG_CLAMP, GL_CLAMP},
+};
+
+#if SDL_VIDEO_OPENGL_ES2
+  static GLuint disabledTextureID;
+#endif
+
+//===================================================================
+OGLRender::OGLRender()
+{
+    COGLGraphicsContext *pcontext = (COGLGraphicsContext *)(CGraphicsContext::g_pGraphicsContext);
+    m_bSupportFogCoordExt = pcontext->m_bSupportFogCoord;
+    m_bMultiTexture = pcontext->m_bSupportMultiTexture;
+#ifdef HAVE_GLES
+    m_bSupportClampToEdge = true;
+#else
+    m_bSupportClampToEdge = false;
+#endif
+    for( int i=0; i<8; i++ )
+    {
+        m_curBoundTex[i]=0;
+        m_texUnitEnabled[i]=FALSE;
+    }
+
+#if SDL_VIDEO_OPENGL
+/*#ifdef HAVE_GLES
+    m_bEnableMultiTexture = true;
+#else*/
+    m_bEnableMultiTexture = false;
+//#endif
+
+#elif SDL_VIDEO_OPENGL_ES2
+    m_bEnableMultiTexture = true;
+
+    //Create a texture as replacement for glEnable/Disable(GL_TEXTURE_2D)
+    unsigned int white[8*8];
+       for (int i=0; i<8*8; i++) {
+               //white[i].r = white[i].g = white[i].b = 0;
+               //white[i].a = 0;
+               white[i] = 0;
+       }
+    glGenTextures(1,&disabledTextureID);
+    OPENGL_CHECK_ERRORS;
+    glBindTexture(GL_TEXTURE_2D, disabledTextureID);
+    OPENGL_CHECK_ERRORS;
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    OPENGL_CHECK_ERRORS;
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, white);
+    OPENGL_CHECK_ERRORS;
+#endif
+}
+
+OGLRender::~OGLRender()
+{
+    ClearDeviceObjects();
+}
+
+bool OGLRender::InitDeviceObjects()
+{
+    // enable Z-buffer by default
+    ZBufferEnable(true);
+    return true;
+}
+
+bool OGLRender::ClearDeviceObjects()
+{
+    return true;
+}
+
+void OGLRender::Initialize(void)
+{
+    glMatrixMode(GL_MODELVIEW);
+    OPENGL_CHECK_ERRORS;
+    glLoadIdentity();
+    OPENGL_CHECK_ERRORS;
+
+    glViewportWrapper(0, windowSetting.statusBarHeightToUse, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight);
+    OPENGL_CHECK_ERRORS;
+
+#if SDL_VIDEO_OPENGL
+    COGLGraphicsContext *pcontext = (COGLGraphicsContext *)(CGraphicsContext::g_pGraphicsContext);
+#ifndef HAVE_GLES
+    if( pcontext->IsExtensionSupported("GL_IBM_texture_mirrored_repeat") )
+    {
+        OGLXUVFlagMaps[TEXTURE_UV_FLAG_MIRROR].realFlag = GL_MIRRORED_REPEAT_IBM;
+    }
+    else if( pcontext->IsExtensionSupported("ARB_texture_mirrored_repeat") )
+#endif
+    {
+        OGLXUVFlagMaps[TEXTURE_UV_FLAG_MIRROR].realFlag = GL_MIRRORED_REPEAT_ARB;
+    }
+#ifndef HAVE_GLES
+    else
+    {
+        OGLXUVFlagMaps[TEXTURE_UV_FLAG_MIRROR].realFlag = GL_REPEAT;
+    }
+    if( pcontext->IsExtensionSupported("GL_ARB_texture_border_clamp") || pcontext->IsExtensionSupported("GL_EXT_texture_edge_clamp") )
+#endif
+    {
+        m_bSupportClampToEdge = true;
+        OGLXUVFlagMaps[TEXTURE_UV_FLAG_CLAMP].realFlag = GL_CLAMP_TO_EDGE;
+    }
+#ifndef HAVE_GLES
+    else
+    {
+        m_bSupportClampToEdge = false;
+        OGLXUVFlagMaps[TEXTURE_UV_FLAG_CLAMP].realFlag = GL_CLAMP;
+    }
+#endif
+    glVertexPointer( 4, GL_FLOAT, sizeof(float)*5, &(g_vtxProjected5[0][0]) );
+    OPENGL_CHECK_ERRORS;
+    glEnableClientState( GL_VERTEX_ARRAY );
+    OPENGL_CHECK_ERRORS;
+
+    if( m_bMultiTexture )
+    {
+        pglClientActiveTextureARB( GL_TEXTURE0_ARB );
+        OPENGL_CHECK_ERRORS;
+        glTexCoordPointer( 2, GL_FLOAT, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[0].u) );
+        OPENGL_CHECK_ERRORS;
+        glEnableClientState( GL_TEXTURE_COORD_ARRAY );
+        OPENGL_CHECK_ERRORS;
+
+        pglClientActiveTextureARB( GL_TEXTURE1_ARB );
+        OPENGL_CHECK_ERRORS;
+        glTexCoordPointer( 2, GL_FLOAT, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[1].u) );
+        OPENGL_CHECK_ERRORS;
+        glEnableClientState( GL_TEXTURE_COORD_ARRAY );
+        OPENGL_CHECK_ERRORS;
+       }
+    else
+    {
+        glTexCoordPointer( 2, GL_FLOAT, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[0].u) );
+        OPENGL_CHECK_ERRORS;
+        glEnableClientState( GL_TEXTURE_COORD_ARRAY );
+        OPENGL_CHECK_ERRORS;
+    }
+#ifndef HAVE_GLES
+    if (m_bSupportFogCoordExt)
+    {
+        pglFogCoordPointerEXT( GL_FLOAT, sizeof(float)*5, &(g_vtxProjected5[0][4]) );
+        OPENGL_CHECK_ERRORS;
+        glEnableClientState( GL_FOG_COORDINATE_ARRAY_EXT );
+        OPENGL_CHECK_ERRORS;
+        glFogi( GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT );
+        OPENGL_CHECK_ERRORS;
+        glFogi(GL_FOG_MODE, GL_LINEAR); // Fog Mode
+        OPENGL_CHECK_ERRORS;
+        glFogf(GL_FOG_DENSITY, 1.0f); // How Dense Will The Fog Be
+        OPENGL_CHECK_ERRORS;
+        glHint(GL_FOG_HINT, GL_FASTEST); // Fog Hint Value
+        OPENGL_CHECK_ERRORS;
+        glFogi( GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT );
+        OPENGL_CHECK_ERRORS;
+        glFogf( GL_FOG_START, 0.0f );
+        OPENGL_CHECK_ERRORS;
+        glFogf( GL_FOG_END, 1.0f );
+        OPENGL_CHECK_ERRORS;
+    }
+#endif
+    //glColorPointer( 1, GL_UNSIGNED_BYTE, sizeof(TLITVERTEX), &g_vtxBuffer[0].r);
+    glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(uint8)*4, &(g_oglVtxColors[0][0]) );
+    OPENGL_CHECK_ERRORS;
+    glEnableClientState( GL_COLOR_ARRAY );
+    OPENGL_CHECK_ERRORS;
+#ifndef HAVE_GLES
+    if( pcontext->IsExtensionSupported("GL_NV_depth_clamp") )
+    {
+        glEnable(GL_DEPTH_CLAMP_NV);
+        OPENGL_CHECK_ERRORS;
+    }
+#endif
+#elif SDL_VIDEO_OPENGL_ES2
+    OGLXUVFlagMaps[TEXTURE_UV_FLAG_MIRROR].realFlag = GL_MIRRORED_REPEAT;
+    m_bSupportClampToEdge = true;
+    OGLXUVFlagMaps[TEXTURE_UV_FLAG_CLAMP].realFlag = GL_CLAMP_TO_EDGE;
+#endif
+
+#ifdef PAULSCODE
+//    hardwareType = Android_JNI_GetHardwareType();
+#endif
+}
+//===================================================================
+TextureFilterMap OglTexFilterMap[2]=
+{
+    {FILTER_POINT, GL_NEAREST},
+    {FILTER_LINEAR, GL_LINEAR},
+};
+
+void OGLRender::ApplyTextureFilter()
+{
+    static uint32 minflag=0xFFFF, magflag=0xFFFF;
+    static uint32 mtex;
+
+    if( m_texUnitEnabled[0] )
+    {
+        if( mtex != m_curBoundTex[0] )
+        {
+            mtex = m_curBoundTex[0];
+            minflag = m_dwMinFilter;
+            magflag = m_dwMagFilter;
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, OglTexFilterMap[m_dwMinFilter].realFilter);
+            OPENGL_CHECK_ERRORS;
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, OglTexFilterMap[m_dwMagFilter].realFilter);
+            OPENGL_CHECK_ERRORS;
+        }
+        else
+        {
+            if( minflag != (unsigned int)m_dwMinFilter )
+            {
+                minflag = m_dwMinFilter;
+                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, OglTexFilterMap[m_dwMinFilter].realFilter);
+                OPENGL_CHECK_ERRORS;
+            }
+            if( magflag != (unsigned int)m_dwMagFilter )
+            {
+                magflag = m_dwMagFilter;
+                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, OglTexFilterMap[m_dwMagFilter].realFilter);
+                OPENGL_CHECK_ERRORS;
+            }   
+        }
+    }
+}
+
+void OGLRender::SetShadeMode(RenderShadeMode mode)
+{
+#if SDL_VIDEO_OPENGL
+    if( mode == SHADE_SMOOTH )
+        glShadeModel(GL_SMOOTH);
+    else
+        glShadeModel(GL_FLAT);
+    OPENGL_CHECK_ERRORS;
+#endif
+}
+
+void OGLRender::ZBufferEnable(BOOL bZBuffer)
+{
+    gRSP.bZBufferEnabled = bZBuffer;
+    if( g_curRomInfo.bForceDepthBuffer )
+        bZBuffer = TRUE;
+    if( bZBuffer )
+    {
+        glDepthMask(GL_TRUE);
+        OPENGL_CHECK_ERRORS;
+        //glEnable(GL_DEPTH_TEST);
+        glDepthFunc( GL_LEQUAL );
+        OPENGL_CHECK_ERRORS;
+    }
+    else
+    {
+        glDepthMask(GL_FALSE);
+        OPENGL_CHECK_ERRORS;
+        //glDisable(GL_DEPTH_TEST);
+        glDepthFunc( GL_ALWAYS );
+        OPENGL_CHECK_ERRORS;
+    }
+}
+
+void OGLRender::ClearBuffer(bool cbuffer, bool zbuffer)
+{
+    uint32 flag=0;
+    if( cbuffer )   flag |= GL_COLOR_BUFFER_BIT;
+    if( zbuffer )   flag |= GL_DEPTH_BUFFER_BIT;
+    float depth = ((gRDP.originalFillColor&0xFFFF)>>2)/(float)0x3FFF;
+    glClearDepth(depth);
+    OPENGL_CHECK_ERRORS;
+    glClear(flag);
+    OPENGL_CHECK_ERRORS;
+}
+
+void OGLRender::ClearZBuffer(float depth)
+{
+    uint32 flag=GL_DEPTH_BUFFER_BIT;
+    glClearDepth(depth);
+    OPENGL_CHECK_ERRORS;
+    glClear(flag);
+    OPENGL_CHECK_ERRORS;
+}
+
+void OGLRender::SetZCompare(BOOL bZCompare)
+{
+    if( g_curRomInfo.bForceDepthBuffer )
+        bZCompare = TRUE;
+
+    gRSP.bZBufferEnabled = bZCompare;
+    if( bZCompare == TRUE )
+    {
+        //glEnable(GL_DEPTH_TEST);
+        glDepthFunc( GL_LEQUAL );
+        OPENGL_CHECK_ERRORS;
+    }
+    else
+    {
+        //glDisable(GL_DEPTH_TEST);
+        glDepthFunc( GL_ALWAYS );
+        OPENGL_CHECK_ERRORS;
+    }
+}
+
+void OGLRender::SetZUpdate(BOOL bZUpdate)
+{
+    if( g_curRomInfo.bForceDepthBuffer )
+        bZUpdate = TRUE;
+
+    if( bZUpdate )
+    {
+        //glEnable(GL_DEPTH_TEST);
+        glDepthMask(GL_TRUE);
+        OPENGL_CHECK_ERRORS;
+    }
+    else
+    {
+        glDepthMask(GL_FALSE);
+        OPENGL_CHECK_ERRORS;
+    }
+}
+
+void OGLRender::ApplyZBias(int bias)
+{
+    float f1 = bias > 0 ? -3.0f : 0.0f;  // z offset = -3.0 * max(abs(dz/dx),abs(dz/dy)) per pixel delta z slope
+    float f2 = bias > 0 ? -3.0f : 0.0f;  // z offset += -3.0 * 1 bit
+
+#ifdef PAULSCODE
+//    Android_JNI_GetPolygonOffset(hardwareType, bias, &f1, &f2);
+//     glPolygonOffset(0.2f, 0.2f);
+#endif
+
+    if (bias > 0)
+    {
+        glEnable(GL_POLYGON_OFFSET_FILL);  // enable z offsets
+        OPENGL_CHECK_ERRORS;
+    }
+    else
+    {
+        glDisable(GL_POLYGON_OFFSET_FILL);  // disable z offsets
+        OPENGL_CHECK_ERRORS;
+    }
+    glPolygonOffset(f1, f2);  // set bias functions
+    OPENGL_CHECK_ERRORS;
+}
+
+void OGLRender::SetZBias(int bias)
+{
+#if defined(DEBUGGER)
+    if( pauseAtNext == true )
+      DebuggerAppendMsg("Set zbias = %d", bias);
+#endif
+    // set member variable and apply the setting in opengl
+    m_dwZBias = bias;
+    ApplyZBias(bias);
+}
+
+void OGLRender::SetAlphaRef(uint32 dwAlpha)
+{
+    if (m_dwAlpha != dwAlpha)
+    {
+        m_dwAlpha = dwAlpha;
+#if SDL_VIDEO_OPENGL
+        glAlphaFunc(GL_GEQUAL, (float)dwAlpha);
+        OPENGL_CHECK_ERRORS;
+#endif
+    }
+}
+
+void OGLRender::ForceAlphaRef(uint32 dwAlpha)
+{
+#if SDL_VIDEO_OPENGL
+    float ref = dwAlpha/255.0f;
+    glAlphaFunc(GL_GEQUAL, ref);
+    OPENGL_CHECK_ERRORS;
+#elif SDL_VIDEO_OPENGL_ES2
+    m_dwAlpha = dwAlpha;
+#endif
+}
+
+void OGLRender::SetFillMode(FillMode mode)
+{
+#if SDL_VIDEO_OPENGL
+#ifndef HAVE_GLES
+    if( mode == RICE_FILLMODE_WINFRAME )
+    {
+        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+        OPENGL_CHECK_ERRORS;
+    }
+    else
+    {
+        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+        OPENGL_CHECK_ERRORS;
+    }
+#endif
+#endif
+}
+
+void OGLRender::SetCullMode(bool bCullFront, bool bCullBack)
+{
+    CRender::SetCullMode(bCullFront, bCullBack);
+    if( bCullFront && bCullBack )
+    {
+        glCullFace(GL_FRONT_AND_BACK);
+        OPENGL_CHECK_ERRORS;
+        glEnable(GL_CULL_FACE);
+        OPENGL_CHECK_ERRORS;
+    }
+    else if( bCullFront )
+    {
+        glCullFace(GL_FRONT);
+        OPENGL_CHECK_ERRORS;
+        glEnable(GL_CULL_FACE);
+        OPENGL_CHECK_ERRORS;
+    }
+    else if( bCullBack )
+    {
+        glCullFace(GL_BACK);
+        OPENGL_CHECK_ERRORS;
+        glEnable(GL_CULL_FACE);
+        OPENGL_CHECK_ERRORS;
+    }
+    else
+    {
+        glDisable(GL_CULL_FACE);
+        OPENGL_CHECK_ERRORS;
+    }
+}
+
+bool OGLRender::SetCurrentTexture(int tile, CTexture *handler,uint32 dwTileWidth, uint32 dwTileHeight, TxtrCacheEntry *pTextureEntry)
+{
+    RenderTexture &texture = g_textures[tile];
+    texture.pTextureEntry = pTextureEntry;
+
+    if( handler!= NULL  && texture.m_lpsTexturePtr != handler->GetTexture() )
+    {
+        texture.m_pCTexture = handler;
+        texture.m_lpsTexturePtr = handler->GetTexture();
+
+        texture.m_dwTileWidth = dwTileWidth;
+        texture.m_dwTileHeight = dwTileHeight;
+
+        if( handler->m_bIsEnhancedTexture )
+        {
+            texture.m_fTexWidth = (float)pTextureEntry->pTexture->m_dwCreatedTextureWidth;
+            texture.m_fTexHeight = (float)pTextureEntry->pTexture->m_dwCreatedTextureHeight;
+        }
+        else
+        {
+            texture.m_fTexWidth = (float)handler->m_dwCreatedTextureWidth;
+            texture.m_fTexHeight = (float)handler->m_dwCreatedTextureHeight;
+        }
+    }
+    
+    return true;
+}
+
+bool OGLRender::SetCurrentTexture(int tile, TxtrCacheEntry *pEntry)
+{
+    if (pEntry != NULL && pEntry->pTexture != NULL)
+    {   
+        SetCurrentTexture( tile, pEntry->pTexture,  pEntry->ti.WidthToCreate, pEntry->ti.HeightToCreate, pEntry);
+        return true;
+    }
+    else
+    {
+        SetCurrentTexture( tile, NULL, 64, 64, NULL );
+        return false;
+    }
+    return true;
+}
+
+void OGLRender::SetAddressUAllStages(uint32 dwTile, TextureUVFlag dwFlag)
+{
+    SetTextureUFlag(dwFlag, dwTile);
+}
+
+void OGLRender::SetAddressVAllStages(uint32 dwTile, TextureUVFlag dwFlag)
+{
+    SetTextureVFlag(dwFlag, dwTile);
+}
+
+void OGLRender::SetTexWrapS(int unitno,GLuint flag)
+{
+    static GLuint mflag;
+    static GLuint mtex;
+#ifdef DEBUGGER
+    if( unitno != 0 )
+    {
+        DebuggerAppendMsg("Check me, unitno != 0 in base ogl");
+    }
+#endif
+    if( m_curBoundTex[0] != mtex || mflag != flag )
+    {
+        mtex = m_curBoundTex[0];
+        mflag = flag;
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, flag);
+        OPENGL_CHECK_ERRORS;
+    }
+}
+void OGLRender::SetTexWrapT(int unitno,GLuint flag)
+{
+    static GLuint mflag;
+    static GLuint mtex;
+    if( m_curBoundTex[0] != mtex || mflag != flag )
+    {
+        mtex = m_curBoundTex[0];
+        mflag = flag;
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, flag);
+        OPENGL_CHECK_ERRORS;
+    }
+}
+
+void OGLRender::SetTextureUFlag(TextureUVFlag dwFlag, uint32 dwTile)
+{
+    TileUFlags[dwTile] = dwFlag;
+    if( dwTile == gRSP.curTile )    // For basic OGL, only support the 1st texel
+    {
+        COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;
+        if( pTexture )
+        {
+            EnableTexUnit(0,TRUE);
+            BindTexture(pTexture->m_dwTextureName, 0);
+        }
+        SetTexWrapS(0, OGLXUVFlagMaps[dwFlag].realFlag);
+    }
+}
+void OGLRender::SetTextureVFlag(TextureUVFlag dwFlag, uint32 dwTile)
+{
+    TileVFlags[dwTile] = dwFlag;
+    if( dwTile == gRSP.curTile )    // For basic OGL, only support the 1st texel
+    {
+        COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;
+        if( pTexture ) 
+        {
+            EnableTexUnit(0,TRUE);
+            BindTexture(pTexture->m_dwTextureName, 0);
+        }
+        SetTexWrapT(0, OGLXUVFlagMaps[dwFlag].realFlag);
+    }
+}
+
+// Basic render drawing functions
+
+bool OGLRender::RenderTexRect()
+{
+    glViewportWrapper(0, windowSetting.statusBarHeightToUse, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight);
+    OPENGL_CHECK_ERRORS;
+
+    GLboolean cullface = glIsEnabled(GL_CULL_FACE);
+    glDisable(GL_CULL_FACE);
+    OPENGL_CHECK_ERRORS;
+
+    float depth = -(g_texRectTVtx[3].z*2-1);
+
+#if SDL_VIDEO_OPENGL
+#ifdef HAVE_GLES
+    GLfloat colour[] = {
+            g_texRectTVtx[3].r, g_texRectTVtx[3].g, g_texRectTVtx[3].b, g_texRectTVtx[3].a,
+            g_texRectTVtx[2].r, g_texRectTVtx[2].g, g_texRectTVtx[2].b, g_texRectTVtx[2].a,
+            g_texRectTVtx[1].r, g_texRectTVtx[1].g, g_texRectTVtx[1].b, g_texRectTVtx[1].a,
+            g_texRectTVtx[0].r, g_texRectTVtx[0].g, g_texRectTVtx[0].b, g_texRectTVtx[0].a
+    };
+
+    GLfloat tex[] = {
+            g_texRectTVtx[3].tcord[0].u,g_texRectTVtx[3].tcord[0].v,
+            g_texRectTVtx[2].tcord[0].u,g_texRectTVtx[2].tcord[0].v,
+            g_texRectTVtx[1].tcord[0].u,g_texRectTVtx[1].tcord[0].v,
+            g_texRectTVtx[0].tcord[0].u,g_texRectTVtx[0].tcord[0].v
+    };
+    GLfloat tex2[] = {
+            g_texRectTVtx[3].tcord[1].u,g_texRectTVtx[3].tcord[1].v,
+            g_texRectTVtx[2].tcord[1].u,g_texRectTVtx[2].tcord[1].v,
+            g_texRectTVtx[1].tcord[1].u,g_texRectTVtx[1].tcord[1].v,
+            g_texRectTVtx[0].tcord[1].u,g_texRectTVtx[0].tcord[1].v
+    };
+
+    GLfloat vertices[] = {
+            g_texRectTVtx[3].x, g_texRectTVtx[3].y, depth, 1,
+            g_texRectTVtx[2].x, g_texRectTVtx[2].y, depth, 1,
+            g_texRectTVtx[1].x, g_texRectTVtx[1].y, depth, 1,
+            g_texRectTVtx[0].x, g_texRectTVtx[0].y, depth, 1
+    };
+
+    if( m_bMultiTexture )
+    {
+               glClientActiveTexture( GL_TEXTURE1 );
+               //if (m_texUnitEnabled[1])
+                       glTexCoordPointer(2, GL_FLOAT, 0, &tex2);
+               /*else
+                       glDisableClientState(GL_TEXTURE_COORD_ARRAY);*/
+               glClientActiveTexture( GL_TEXTURE0 );
+    }
+       //if (m_texUnitEnabled[0])
+               glTexCoordPointer(2, GL_FLOAT, 0, &tex);
+       /*else
+               glDisableClientState(GL_TEXTURE_COORD_ARRAY);*/
+
+    glColorPointer(4, GL_FLOAT,0, &colour );
+    glVertexPointer(4,GL_FLOAT, 0, &vertices);
+    glTexCoordPointer(2, GL_FLOAT, 0, &tex);
+    OPENGL_CHECK_ERRORS;
+    glDrawArrays(GL_TRIANGLE_FAN,0,4);
+    OPENGL_CHECK_ERRORS;
+
+    //Restore old pointers
+    glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(uint8)*4, &(g_oglVtxColors[0][0]) );
+
+    glVertexPointer( 4, GL_FLOAT, sizeof(float)*5, &(g_vtxProjected5[0][0]) );
+//     if (m_texUnitEnabled[0])
+               glTexCoordPointer( 2, GL_FLOAT, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[0].u) );
+/*     else
+               glEnableClientState(GL_TEXTURE_COORD_ARRAY);*/
+    if( m_bMultiTexture )
+    {
+               glClientActiveTexture( GL_TEXTURE1 );
+//             if (m_texUnitEnabled[1])
+                       glTexCoordPointer( 2, GL_FLOAT, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[1].u) );
+/*             else
+                       glEnableClientState( GL_TEXTURE_COORD_ARRAY );*/
+    }
+#else
+
+    glBegin(GL_TRIANGLE_FAN);
+
+    glColor4f(g_texRectTVtx[3].r, g_texRectTVtx[3].g, g_texRectTVtx[3].b, g_texRectTVtx[3].a);
+    TexCoord(g_texRectTVtx[3]);
+    glVertex3f(g_texRectTVtx[3].x, g_texRectTVtx[3].y, depth);
+    
+    glColor4f(g_texRectTVtx[2].r, g_texRectTVtx[2].g, g_texRectTVtx[2].b, g_texRectTVtx[2].a);
+    TexCoord(g_texRectTVtx[2]);
+    glVertex3f(g_texRectTVtx[2].x, g_texRectTVtx[2].y, depth);
+
+    glColor4f(g_texRectTVtx[1].r, g_texRectTVtx[1].g, g_texRectTVtx[1].b, g_texRectTVtx[1].a);
+    TexCoord(g_texRectTVtx[1]);
+    glVertex3f(g_texRectTVtx[1].x, g_texRectTVtx[1].y, depth);
+
+    glColor4f(g_texRectTVtx[0].r, g_texRectTVtx[0].g, g_texRectTVtx[0].b, g_texRectTVtx[0].a);
+    TexCoord(g_texRectTVtx[0]);
+    glVertex3f(g_texRectTVtx[0].x, g_texRectTVtx[0].y, depth);
+
+    glEnd();
+#endif
+    OPENGL_CHECK_ERRORS;
+
+#elif SDL_VIDEO_OPENGL_ES2
+    GLfloat colour[] = {
+            g_texRectTVtx[3].r, g_texRectTVtx[3].g, g_texRectTVtx[3].b, g_texRectTVtx[3].a,
+            g_texRectTVtx[2].r, g_texRectTVtx[2].g, g_texRectTVtx[2].b, g_texRectTVtx[2].a,
+            g_texRectTVtx[1].r, g_texRectTVtx[1].g, g_texRectTVtx[1].b, g_texRectTVtx[1].a,
+            g_texRectTVtx[0].r, g_texRectTVtx[0].g, g_texRectTVtx[0].b, g_texRectTVtx[0].a
+    };
+
+    GLfloat tex[] = {
+            g_texRectTVtx[3].tcord[0].u,g_texRectTVtx[3].tcord[0].v,
+            g_texRectTVtx[2].tcord[0].u,g_texRectTVtx[2].tcord[0].v,
+            g_texRectTVtx[1].tcord[0].u,g_texRectTVtx[1].tcord[0].v,
+            g_texRectTVtx[0].tcord[0].u,g_texRectTVtx[0].tcord[0].v
+    };
+
+    float w = windowSetting.uDisplayWidth / 2.0f, h = windowSetting.uDisplayHeight / 2.0f, inv = 1.0f;
+
+    GLfloat vertices[] = {
+            -inv + g_texRectTVtx[3].x / w, inv - g_texRectTVtx[3].y / h, depth, 1,
+            -inv + g_texRectTVtx[2].x / w, inv - g_texRectTVtx[2].y / h, depth, 1,
+            -inv + g_texRectTVtx[1].x / w, inv - g_texRectTVtx[1].y / h, depth, 1,
+            -inv + g_texRectTVtx[0].x / w, inv - g_texRectTVtx[0].y / h, depth, 1
+    };
+
+    glVertexAttribPointer(VS_COLOR, 4, GL_FLOAT,GL_TRUE, 0, &colour );
+    glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,0,&vertices);
+    glVertexAttribPointer(VS_TEXCOORD0,2,GL_FLOAT,GL_FALSE, 0, &tex);
+    OPENGL_CHECK_ERRORS;
+    glDrawArrays(GL_TRIANGLE_FAN,0,4);
+    OPENGL_CHECK_ERRORS;
+
+    //Restore old pointers
+    glVertexAttribPointer(VS_COLOR, 4, GL_UNSIGNED_BYTE,GL_TRUE, sizeof(uint8)*4, &(g_oglVtxColors[0][0]) );
+    glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][0]));
+    glVertexAttribPointer(VS_TEXCOORD0,2,GL_FLOAT,GL_FALSE, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[0].u));
+#endif
+
+    if( cullface ) glEnable(GL_CULL_FACE);
+    OPENGL_CHECK_ERRORS;
+
+    return true;
+}
+
+bool OGLRender::RenderFillRect(uint32 dwColor, float depth)
+{
+    float a = (dwColor>>24)/255.0f;
+    float r = ((dwColor>>16)&0xFF)/255.0f;
+    float g = ((dwColor>>8)&0xFF)/255.0f;
+    float b = (dwColor&0xFF)/255.0f;
+    glViewportWrapper(0, windowSetting.statusBarHeightToUse, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight);
+    OPENGL_CHECK_ERRORS;
+
+    GLboolean cullface = glIsEnabled(GL_CULL_FACE);
+    glDisable(GL_CULL_FACE);
+    OPENGL_CHECK_ERRORS;
+
+#if SDL_VIDEO_OPENGL
+#ifdef HAVE_GLES
+    GLfloat colour[] = {
+            r,g,b,a,
+            r,g,b,a,
+            r,g,b,a,
+            r,g,b,a};
+
+    GLfloat vertices[] = {
+            m_fillRectVtx[0].x, m_fillRectVtx[1].y, depth, 1,
+            m_fillRectVtx[1].x, m_fillRectVtx[1].y, depth, 1,
+            m_fillRectVtx[1].x, m_fillRectVtx[0].y, depth, 1,
+            m_fillRectVtx[0].x, m_fillRectVtx[0].y, depth, 1
+    };
+
+    glColorPointer(4, GL_FLOAT, 0, &colour );
+    glVertexPointer(4,GL_FLOAT, 0,&vertices);
+    if( m_bMultiTexture ) {
+               if (m_texUnitEnabled[1])
+               {
+                       glClientActiveTexture( GL_TEXTURE1 );
+                       glActiveTexture( GL_TEXTURE1 );
+                       glDisableClientState( GL_TEXTURE_COORD_ARRAY );
+                       glDisable(GL_TEXTURE_2D);
+               }
+    }
+       if (m_texUnitEnabled[0]) {
+        glClientActiveTexture( GL_TEXTURE0 );
+               glActiveTexture( GL_TEXTURE0 );
+               glDisableClientState( GL_TEXTURE_COORD_ARRAY );
+               glDisable(GL_TEXTURE_2D);
+       }
+    OPENGL_CHECK_ERRORS;
+    glColor4f(r,g,b,a);
+    glDrawArrays(GL_TRIANGLE_FAN,0,4);
+    OPENGL_CHECK_ERRORS;
+    //Restore old pointers
+    glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(uint8)*4, &(g_oglVtxColors[0][0]) );
+    glVertexPointer( 4, GL_FLOAT, sizeof(float)*5, &(g_vtxProjected5[0][0]) );
+       if (m_texUnitEnabled[0]) {
+               glEnableClientState( GL_TEXTURE_COORD_ARRAY );
+               glEnable(GL_TEXTURE_2D);
+       }
+    if( m_bMultiTexture ) {
+               glClientActiveTexture( GL_TEXTURE1 );
+               glActiveTexture( GL_TEXTURE1 );
+               if (m_texUnitEnabled[1])
+               {
+                       glEnable(GL_TEXTURE_2D);
+                       glEnableClientState( GL_TEXTURE_COORD_ARRAY );
+               }
+               glActiveTexture( GL_TEXTURE0 );
+    }
+#else
+
+    glBegin(GL_TRIANGLE_FAN);
+    glColor4f(r,g,b,a);
+    glVertex4f(m_fillRectVtx[0].x, m_fillRectVtx[1].y, depth, 1);
+    glVertex4f(m_fillRectVtx[1].x, m_fillRectVtx[1].y, depth, 1);
+    glVertex4f(m_fillRectVtx[1].x, m_fillRectVtx[0].y, depth, 1);
+    glVertex4f(m_fillRectVtx[0].x, m_fillRectVtx[0].y, depth, 1);
+    glEnd();
+    OPENGL_CHECK_ERRORS;
+#endif
+#elif SDL_VIDEO_OPENGL_ES2
+
+    GLfloat colour[] = {
+            r,g,b,a,
+            r,g,b,a,
+            r,g,b,a,
+            r,g,b,a};
+
+    float w = windowSetting.uDisplayWidth / 2.0f, h = windowSetting.uDisplayHeight / 2.0f, inv = 1.0f;
+
+    GLfloat vertices[] = {
+            -inv + m_fillRectVtx[0].x / w, inv - m_fillRectVtx[1].y / h, depth, 1,
+            -inv + m_fillRectVtx[1].x / w, inv - m_fillRectVtx[1].y / h, depth, 1,
+            -inv + m_fillRectVtx[1].x / w, inv - m_fillRectVtx[0].y / h, depth, 1,
+            -inv + m_fillRectVtx[0].x / w, inv - m_fillRectVtx[0].y / h, depth, 1
+    };
+
+    glVertexAttribPointer(VS_COLOR, 4, GL_FLOAT,GL_FALSE, 0, &colour );
+    glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,0,&vertices);
+    glDisableVertexAttribArray(VS_TEXCOORD0);
+    OPENGL_CHECK_ERRORS;
+    glDrawArrays(GL_TRIANGLE_FAN,0,4);
+    OPENGL_CHECK_ERRORS;
+
+    //Restore old pointers
+    glVertexAttribPointer(VS_COLOR, 4, GL_UNSIGNED_BYTE,GL_TRUE, sizeof(uint8)*4, &(g_oglVtxColors[0][0]) );
+    glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][0]));
+    glEnableVertexAttribArray(VS_TEXCOORD0);
+
+#endif
+
+    if( cullface ) glEnable(GL_CULL_FACE);
+    OPENGL_CHECK_ERRORS;
+
+    return true;
+}
+
+bool OGLRender::RenderLine3D()
+{
+#if SDL_VIDEO_OPENGL
+    ApplyZBias(0);  // disable z offsets
+
+#ifdef HAVE_GLES
+    GLfloat colour[] = {
+            m_line3DVtx[1].r,m_line3DVtx[1].g,m_line3DVtx[1].b,m_line3DVtx[1].a,
+            m_line3DVtx[1].r,m_line3DVtx[1].g,m_line3DVtx[1].b,m_line3DVtx[1].a,
+            m_line3DVtx[0].r,m_line3DVtx[0].g,m_line3DVtx[0].b,m_line3DVtx[0].a,
+            m_line3DVtx[0].r,m_line3DVtx[0].g,m_line3DVtx[0].b,m_line3DVtx[0].a};
+
+    GLfloat vertices[] = {
+            m_line3DVector[3].x, m_line3DVector[3].y, -m_line3DVtx[1].z, 1,
+            m_line3DVector[2].x, m_line3DVector[2].y, -m_line3DVtx[0].z, 1,
+            m_line3DVector[1].x, m_line3DVector[1].y, -m_line3DVtx[1].z, 1,
+            m_line3DVector[0].x, m_line3DVector[0].y, -m_line3DVtx[0].z, 1
+    };
+
+    glColorPointer(4, GL_FLOAT, 0, &colour );
+    glVertexPointer(4,GL_FLOAT, 0,&vertices);
+    if( m_bMultiTexture )
+    {
+               glClientActiveTexture( GL_TEXTURE1 );
+               glDisableClientState( GL_TEXTURE_COORD_ARRAY );
+        glClientActiveTexture( GL_TEXTURE0 );
+    }
+    glDisableClientState( GL_TEXTURE_COORD_ARRAY );
+    OPENGL_CHECK_ERRORS;
+    glDrawArrays(GL_TRIANGLE_FAN,0,4);
+    OPENGL_CHECK_ERRORS;
+    //Restore old pointers
+    glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(uint8)*4, &(g_oglVtxColors[0][0]) );
+    glEnableClientState( GL_TEXTURE_COORD_ARRAY );
+    glVertexPointer( 4, GL_FLOAT, sizeof(float)*5, &(g_vtxProjected5[0][0]) );
+    if( m_bMultiTexture )
+    {
+               glClientActiveTexture( GL_TEXTURE1 );
+               glEnableClientState( GL_TEXTURE_COORD_ARRAY );
+    }
+#else
+    glBegin(GL_TRIANGLE_FAN);
+
+    glColor4f(m_line3DVtx[1].r, m_line3DVtx[1].g, m_line3DVtx[1].b, m_line3DVtx[1].a);
+    glVertex3f(m_line3DVector[3].x, m_line3DVector[3].y, -m_line3DVtx[1].z);
+    glVertex3f(m_line3DVector[2].x, m_line3DVector[2].y, -m_line3DVtx[0].z);
+    
+    glColor4ub(m_line3DVtx[0].r, m_line3DVtx[0].g, m_line3DVtx[0].b, m_line3DVtx[0].a);
+    glVertex3f(m_line3DVector[1].x, m_line3DVector[1].y, -m_line3DVtx[1].z);
+    glVertex3f(m_line3DVector[0].x, m_line3DVector[0].y, -m_line3DVtx[0].z);
+
+    glEnd();
+#endif
+    OPENGL_CHECK_ERRORS;
+
+    ApplyZBias(m_dwZBias);  // set Z offset back to previous value
+#endif
+
+    return true;
+}
+
+extern FiddledVtx * g_pVtxBase;
+
+// This is so weired that I can not do vertex transform by myself. I have to use
+// OpenGL internal transform
+bool OGLRender::RenderFlushTris()
+{
+    if( !m_bSupportFogCoordExt )    
+        SetFogFlagForNegativeW();
+    else
+    {
+        if( !gRDP.bFogEnableInBlender && gRSP.bFogEnabled )
+        {
+            TurnFogOnOff(false);
+        }
+    }
+
+    ApplyZBias(m_dwZBias);  // set the bias factors
+
+    glViewportWrapper(windowSetting.vpLeftW, windowSetting.uDisplayHeight-windowSetting.vpTopW-windowSetting.vpHeightW+windowSetting.statusBarHeightToUse, windowSetting.vpWidthW, windowSetting.vpHeightW, false);
+    OPENGL_CHECK_ERRORS;
+
+//    if (options.bOGLVertexClipper == FALSE )
+    {
+        glDrawElements( GL_TRIANGLES, gRSP.numVertices, GL_UNSIGNED_SHORT, g_vtxIndex );
+        OPENGL_CHECK_ERRORS;
+    }
+/*    else
+    {
+        //ClipVertexesOpenGL();
+        // Redo the index
+        // Set the array
+        glVertexPointer( 4, GL_FLOAT, sizeof(float)*5, &(g_vtxProjected5Clipped[0][0]) );
+        glEnableClientState( GL_VERTEX_ARRAY );
+
+        pglClientActiveTextureARB( GL_TEXTURE0_ARB );
+        glTexCoordPointer( 2, GL_FLOAT, sizeof( TLITVERTEX ), &(g_clippedVtxBuffer[0].tcord[0].u) );
+        glEnableClientState( GL_TEXTURE_COORD_ARRAY );
+
+        pglClientActiveTextureARB( GL_TEXTURE1_ARB );
+        glTexCoordPointer( 2, GL_FLOAT, sizeof( TLITVERTEX ), &(g_clippedVtxBuffer[0].tcord[1].u) );
+        glEnableClientState( GL_TEXTURE_COORD_ARRAY );
+
+        glDrawElements( GL_TRIANGLES, gRSP.numVertices, GL_UNSIGNED_SHORT, g_vtxIndex );
+
+        // Reset the array
+        pglClientActiveTextureARB( GL_TEXTURE0_ARB );
+        glTexCoordPointer( 2, GL_FLOAT, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[0].u) );
+        glEnableClientState( GL_TEXTURE_COORD_ARRAY );
+
+        pglClientActiveTextureARB( GL_TEXTURE1_ARB );
+        glTexCoordPointer( 2, GL_FLOAT, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[1].u) );
+        glEnableClientState( GL_TEXTURE_COORD_ARRAY );
+
+        glVertexPointer( 4, GL_FLOAT, sizeof(float)*5, &(g_vtxProjected5[0][0]) );
+        glEnableClientState( GL_VERTEX_ARRAY );
+    }
+*/
+
+    if( !m_bSupportFogCoordExt )    
+        RestoreFogFlag();
+    else
+    {
+        if( !gRDP.bFogEnableInBlender && gRSP.bFogEnabled )
+        {
+            TurnFogOnOff(true);
+        }
+    }
+    return true;
+}
+
+void OGLRender::DrawSimple2DTexture(float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, COLOR dif, COLOR spe, float z, float rhw)
+{
+    if( status.bVIOriginIsUpdated == true && currentRomOptions.screenUpdateSetting==SCREEN_UPDATE_AT_1ST_PRIMITIVE )
+    {
+        status.bVIOriginIsUpdated=false;
+        CGraphicsContext::Get()->UpdateFrame();
+        DEBUGGER_PAUSE_AND_DUMP_NO_UPDATE(NEXT_SET_CIMG,{DebuggerAppendMsg("Screen Update at 1st Simple2DTexture");});
+    }
+
+    StartDrawSimple2DTexture(x0, y0, x1, y1, u0, v0, u1, v1, dif, spe, z, rhw);
+
+    GLboolean cullface = glIsEnabled(GL_CULL_FACE);
+    glDisable(GL_CULL_FACE);
+    OPENGL_CHECK_ERRORS;
+
+    glViewportWrapper(0, windowSetting.statusBarHeightToUse, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight);
+    OPENGL_CHECK_ERRORS;
+
+    float a = (g_texRectTVtx[0].dcDiffuse >>24)/255.0f;
+    float r = ((g_texRectTVtx[0].dcDiffuse>>16)&0xFF)/255.0f;
+    float g = ((g_texRectTVtx[0].dcDiffuse>>8)&0xFF)/255.0f;
+    float b = (g_texRectTVtx[0].dcDiffuse&0xFF)/255.0f;
+
+#if SDL_VIDEO_OPENGL
+
+#ifdef HAVE_GLES
+    GLfloat colour[] = {
+            r,g,b,a,
+            r,g,b,a,
+            r,g,b,a,
+            r,g,b,a,
+            r,g,b,a,
+            r,g,b,a};
+
+    GLfloat tex[] = {
+            g_texRectTVtx[0].tcord[0].u,g_texRectTVtx[0].tcord[0].v,
+            g_texRectTVtx[1].tcord[0].u,g_texRectTVtx[1].tcord[0].v,
+            g_texRectTVtx[2].tcord[0].u,g_texRectTVtx[2].tcord[0].v,
+            g_texRectTVtx[0].tcord[0].u,g_texRectTVtx[0].tcord[0].v,
+            g_texRectTVtx[2].tcord[0].u,g_texRectTVtx[2].tcord[0].v,
+            g_texRectTVtx[3].tcord[0].u,g_texRectTVtx[3].tcord[0].v
+    };
+
+    GLfloat vertices[] = {
+            g_texRectTVtx[0].x, g_texRectTVtx[0].y, -g_texRectTVtx[0].z, 1,
+            g_texRectTVtx[1].x, g_texRectTVtx[1].y, -g_texRectTVtx[1].z, 1,
+            g_texRectTVtx[2].x, g_texRectTVtx[2].y, -g_texRectTVtx[2].z, 1,
+            g_texRectTVtx[0].x, g_texRectTVtx[0].y, -g_texRectTVtx[0].z, 1,
+            g_texRectTVtx[2].x, g_texRectTVtx[2].y, -g_texRectTVtx[2].z, 1,
+            g_texRectTVtx[3].x, g_texRectTVtx[3].y, -g_texRectTVtx[3].z, 1
+    };
+
+    glColorPointer(4, GL_FLOAT, 0, &colour );
+    glVertexPointer(4,GL_FLOAT, 0,&vertices);
+    if( m_bMultiTexture )
+    {
+               glClientActiveTexture( GL_TEXTURE1 );
+//             if (m_texUnitEnabled[1])
+                       glTexCoordPointer(2, GL_FLOAT, 0, &tex);
+/*             else
+                       glDisableClientState( GL_TEXTURE_COORD_ARRAY );*/
+        glClientActiveTexture( GL_TEXTURE0 );
+    }
+//     if (m_texUnitEnabled[0])
+                       glTexCoordPointer(2, GL_FLOAT, 0, &tex);
+/*             else
+                       glDisableClientState( GL_TEXTURE_COORD_ARRAY );*/
+    glDrawArrays(GL_TRIANGLES,0,6);
+    //Restore old pointers
+    glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(uint8)*4, &(g_oglVtxColors[0][0]) );
+    glTexCoordPointer( 2, GL_FLOAT, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[0].u) );
+//     if (m_texUnitEnabled[1])
+               glVertexPointer( 4, GL_FLOAT, sizeof(float)*5, &(g_vtxProjected5[0][0]) );
+/*     else
+                       glEnableClientState( GL_TEXTURE_COORD_ARRAY );*/
+    if( m_bMultiTexture )
+    {
+               glClientActiveTexture( GL_TEXTURE1 );
+//             if (m_texUnitEnabled[1])
+                       glTexCoordPointer( 2, GL_FLOAT, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[1].u) );
+/*             else
+                       glEnableClientState( GL_TEXTURE_COORD_ARRAY );*/
+    }
+#else
+    glBegin(GL_TRIANGLES);
+
+    glColor4f(r,g,b,a);
+
+    OGLRender::TexCoord(g_texRectTVtx[0]);
+    glVertex3f(g_texRectTVtx[0].x, g_texRectTVtx[0].y, -g_texRectTVtx[0].z);
+
+    OGLRender::TexCoord(g_texRectTVtx[1]);
+    glVertex3f(g_texRectTVtx[1].x, g_texRectTVtx[1].y, -g_texRectTVtx[1].z);
+
+    OGLRender::TexCoord(g_texRectTVtx[2]);
+    glVertex3f(g_texRectTVtx[2].x, g_texRectTVtx[2].y, -g_texRectTVtx[2].z);
+
+    OGLRender::TexCoord(g_texRectTVtx[0]);
+    glVertex3f(g_texRectTVtx[0].x, g_texRectTVtx[0].y, -g_texRectTVtx[0].z);
+
+    OGLRender::TexCoord(g_texRectTVtx[2]);
+    glVertex3f(g_texRectTVtx[2].x, g_texRectTVtx[2].y, -g_texRectTVtx[2].z);
+
+    OGLRender::TexCoord(g_texRectTVtx[3]);
+    glVertex3f(g_texRectTVtx[3].x, g_texRectTVtx[3].y, -g_texRectTVtx[3].z);
+    glEnd();
+#endif    
+    OPENGL_CHECK_ERRORS;
+
+#elif SDL_VIDEO_OPENGL_ES2
+
+    GLfloat colour[] = {
+            r,g,b,a,
+            r,g,b,a,
+            r,g,b,a,
+            r,g,b,a,
+            r,g,b,a,
+            r,g,b,a
+    };
+
+    GLfloat tex[] = {
+            g_texRectTVtx[0].tcord[0].u,g_texRectTVtx[0].tcord[0].v,
+            g_texRectTVtx[1].tcord[0].u,g_texRectTVtx[1].tcord[0].v,
+            g_texRectTVtx[2].tcord[0].u,g_texRectTVtx[2].tcord[0].v,
+
+            g_texRectTVtx[0].tcord[0].u,g_texRectTVtx[0].tcord[0].v,
+            g_texRectTVtx[2].tcord[0].u,g_texRectTVtx[2].tcord[0].v,
+            g_texRectTVtx[3].tcord[0].u,g_texRectTVtx[3].tcord[0].v,
+    };
+
+     float w = windowSetting.uDisplayWidth / 2.0f, h = windowSetting.uDisplayHeight / 2.0f, inv = 1.0f;
+
+    GLfloat vertices[] = {
+            -inv + g_texRectTVtx[0].x/ w, inv - g_texRectTVtx[0].y/ h, -g_texRectTVtx[0].z,1,
+            -inv + g_texRectTVtx[1].x/ w, inv - g_texRectTVtx[1].y/ h, -g_texRectTVtx[1].z,1,
+            -inv + g_texRectTVtx[2].x/ w, inv - g_texRectTVtx[2].y/ h, -g_texRectTVtx[2].z,1,
+
+            -inv + g_texRectTVtx[0].x/ w, inv - g_texRectTVtx[0].y/ h, -g_texRectTVtx[0].z,1,
+            -inv + g_texRectTVtx[2].x/ w, inv - g_texRectTVtx[2].y/ h, -g_texRectTVtx[2].z,1,
+            -inv + g_texRectTVtx[3].x/ w, inv - g_texRectTVtx[3].y/ h, -g_texRectTVtx[3].z,1
+    };
+
+    glVertexAttribPointer(VS_COLOR, 4, GL_FLOAT,GL_FALSE, 0, &colour );
+    glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,0,&vertices);
+    glVertexAttribPointer(VS_TEXCOORD0,2,GL_FLOAT,GL_FALSE, 0, &tex);
+    OPENGL_CHECK_ERRORS;
+    glDrawArrays(GL_TRIANGLES,0,6);
+    OPENGL_CHECK_ERRORS;
+
+    //Restore old pointers
+    glVertexAttribPointer(VS_COLOR, 4, GL_UNSIGNED_BYTE,GL_TRUE, sizeof(uint8)*4, &(g_oglVtxColors[0][0]) );
+    glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][0]));
+    glVertexAttribPointer(VS_TEXCOORD0,2,GL_FLOAT,GL_FALSE, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[0].u));
+
+#endif
+
+    if( cullface ) glEnable(GL_CULL_FACE);
+    OPENGL_CHECK_ERRORS;
+}
+
+void OGLRender::DrawSimpleRect(int nX0, int nY0, int nX1, int nY1, uint32 dwColor, float depth, float rhw)
+{
+    StartDrawSimpleRect(nX0, nY0, nX1, nY1, dwColor, depth, rhw);
+
+    GLboolean cullface = glIsEnabled(GL_CULL_FACE);
+    glDisable(GL_CULL_FACE);
+    OPENGL_CHECK_ERRORS;
+
+    float a = (dwColor>>24)/255.0f;
+    float r = ((dwColor>>16)&0xFF)/255.0f;
+    float g = ((dwColor>>8)&0xFF)/255.0f;
+    float b = (dwColor&0xFF)/255.0f;
+
+#if SDL_VIDEO_OPENGL
+
+#ifdef HAVE_GLES
+    GLfloat colour[] = {
+            r,g,b,a,
+            r,g,b,a,
+            r,g,b,a,
+            r,g,b,a};
+
+    GLfloat vertices[] = {
+            m_simpleRectVtx[1].x, m_simpleRectVtx[0].y, -depth, 1,
+            m_simpleRectVtx[1].x, m_simpleRectVtx[1].y, -depth, 1,
+            m_simpleRectVtx[0].x, m_simpleRectVtx[1].y, -depth, 1,
+            m_simpleRectVtx[0].x, m_simpleRectVtx[0].y, -depth, 1
+    };
+
+    glColorPointer(4, GL_FLOAT, 0, &colour );
+    glVertexPointer(4,GL_FLOAT, 0,&vertices);
+    if( m_bMultiTexture )
+    {
+               glClientActiveTexture( GL_TEXTURE1 );
+               if (m_texUnitEnabled[1]) {
+                       glActiveTexture( GL_TEXTURE1 );
+                       glDisable(GL_TEXTURE_2D);
+               }
+               glDisableClientState( GL_TEXTURE_COORD_ARRAY );
+        glClientActiveTexture( GL_TEXTURE0 );
+    }
+       if (m_texUnitEnabled[0]) {
+               glActiveTexture( GL_TEXTURE0 );
+               glDisable(GL_TEXTURE_2D);
+       }
+    glDisableClientState( GL_TEXTURE_COORD_ARRAY );
+    OPENGL_CHECK_ERRORS;
+    glColor4f(r,g,b,a);
+    glDrawArrays(GL_TRIANGLE_FAN,0,4);
+    OPENGL_CHECK_ERRORS;
+    //Restore old pointers
+    glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(uint8)*4, &(g_oglVtxColors[0][0]) );
+    glEnableClientState( GL_TEXTURE_COORD_ARRAY );
+    glVertexPointer( 4, GL_FLOAT, sizeof(float)*5, &(g_vtxProjected5[0][0]) );
+       if (m_texUnitEnabled[0]) {
+               glEnable(GL_TEXTURE_2D);
+       }
+    if( m_bMultiTexture )
+    {
+               if (m_texUnitEnabled[1]) {
+                       glActiveTexture( GL_TEXTURE1 );
+                       glEnable(GL_TEXTURE_2D);
+               }
+               glClientActiveTexture( GL_TEXTURE1 );
+               glEnableClientState( GL_TEXTURE_COORD_ARRAY );
+    }
+#else
+    glBegin(GL_TRIANGLE_FAN);
+
+    glColor4f(r,g,b,a);
+    glVertex3f(m_simpleRectVtx[1].x, m_simpleRectVtx[0].y, -depth);
+    glVertex3f(m_simpleRectVtx[1].x, m_simpleRectVtx[1].y, -depth);
+    glVertex3f(m_simpleRectVtx[0].x, m_simpleRectVtx[1].y, -depth);
+    glVertex3f(m_simpleRectVtx[0].x, m_simpleRectVtx[0].y, -depth);
+    
+    glEnd();
+#endif
+    OPENGL_CHECK_ERRORS;
+
+#elif SDL_VIDEO_OPENGL_ES2
+
+    GLfloat colour[] = {
+            r,g,b,a,
+            r,g,b,a,
+            r,g,b,a,
+            r,g,b,a};
+    float w = windowSetting.uDisplayWidth / 2.0f, h = windowSetting.uDisplayHeight / 2.0f, inv = 1.0f;
+
+    GLfloat vertices[] = {
+            -inv + m_simpleRectVtx[1].x / w, inv - m_simpleRectVtx[0].y / h, -depth, 1,
+            -inv + m_simpleRectVtx[1].x / w, inv - m_simpleRectVtx[1].y / h, -depth, 1,
+            -inv + m_simpleRectVtx[0].x / w, inv - m_simpleRectVtx[1].y / h, -depth, 1,
+            -inv + m_simpleRectVtx[0].x / w, inv - m_simpleRectVtx[0].y / h, -depth, 1
+    };
+
+    glVertexAttribPointer(VS_COLOR, 4, GL_FLOAT,GL_FALSE, 0, &colour );
+    glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,0,&vertices);
+    glDisableVertexAttribArray(VS_TEXCOORD0);
+    OPENGL_CHECK_ERRORS;
+    glDrawArrays(GL_TRIANGLE_FAN,0,4);
+    OPENGL_CHECK_ERRORS;
+
+    //Restore old pointers
+    glVertexAttribPointer(VS_COLOR, 4, GL_UNSIGNED_BYTE,GL_TRUE, sizeof(uint8)*4, &(g_oglVtxColors[0][0]) );
+    glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][0]));
+    glEnableVertexAttribArray(VS_TEXCOORD0);
+
+#endif
+
+    if( cullface ) glEnable(GL_CULL_FACE);
+    OPENGL_CHECK_ERRORS;
+}
+
+void OGLRender::InitCombinerBlenderForSimpleRectDraw(uint32 tile)
+{
+    //glEnable(GL_CULL_FACE);
+    EnableTexUnit(0,FALSE);
+    OPENGL_CHECK_ERRORS;
+    glEnable(GL_BLEND);
+    OPENGL_CHECK_ERRORS;
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    OPENGL_CHECK_ERRORS;
+    //glEnable(GL_ALPHA_TEST);
+}
+
+COLOR OGLRender::PostProcessDiffuseColor(COLOR curDiffuseColor)
+{
+    uint32 color = curDiffuseColor;
+    uint32 colorflag = m_pColorCombiner->m_pDecodedMux->m_dwShadeColorChannelFlag;
+    uint32 alphaflag = m_pColorCombiner->m_pDecodedMux->m_dwShadeAlphaChannelFlag;
+    if( colorflag+alphaflag != MUX_0 )
+    {
+        if( (colorflag & 0xFFFFFF00) == 0 && (alphaflag & 0xFFFFFF00) == 0 )
+        {
+            color = (m_pColorCombiner->GetConstFactor(colorflag, alphaflag, curDiffuseColor));
+        }
+        else
+            color = (CalculateConstFactor(colorflag, alphaflag, curDiffuseColor));
+    }
+
+    //return (color<<8)|(color>>24);
+    return color;
+}
+
+COLOR OGLRender::PostProcessSpecularColor()
+{
+    return 0;
+}
+
+void OGLRender::SetViewportRender()
+{
+    glViewportWrapper(windowSetting.vpLeftW, windowSetting.uDisplayHeight-windowSetting.vpTopW-windowSetting.vpHeightW+windowSetting.statusBarHeightToUse, windowSetting.vpWidthW, windowSetting.vpHeightW);
+    OPENGL_CHECK_ERRORS;
+}
+
+void OGLRender::RenderReset()
+{
+    CRender::RenderReset();
+
+    glMatrixMode(GL_PROJECTION);
+    OPENGL_CHECK_ERRORS;
+    glLoadIdentity();
+    OPENGL_CHECK_ERRORS;
+    glOrtho(0, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight, 0, -1, 1);
+    OPENGL_CHECK_ERRORS;
+
+    // position viewer 
+    glMatrixMode(GL_MODELVIEW);
+    OPENGL_CHECK_ERRORS;
+    glLoadIdentity();
+    OPENGL_CHECK_ERRORS;
+}
+
+void OGLRender::SetAlphaTestEnable(BOOL bAlphaTestEnable)
+{
+#ifdef DEBUGGER
+    if( bAlphaTestEnable && debuggerEnableAlphaTest )
+#else
+    if( bAlphaTestEnable )
+#endif
+#if SDL_VIDEO_OPENGL
+        glEnable(GL_ALPHA_TEST);
+    else
+        glDisable(GL_ALPHA_TEST);
+#elif SDL_VIDEO_OPENGL_ES2
+    {
+        COGL_FragmentProgramCombiner* frag = (COGL_FragmentProgramCombiner*)m_pColorCombiner;
+        frag->m_AlphaRef = m_dwAlpha / 255.0f;
+    }
+    else
+    {
+        COGL_FragmentProgramCombiner* frag = (COGL_FragmentProgramCombiner*)m_pColorCombiner;
+        frag->m_AlphaRef = 0.0f;
+    }
+#endif
+    OPENGL_CHECK_ERRORS;
+}
+
+void OGLRender::BindTexture(GLuint texture, int unitno)
+{
+#ifdef DEBUGGER
+    if( unitno != 0 )
+    {
+        DebuggerAppendMsg("Check me, base ogl bind texture, unit no != 0");
+    }
+#endif
+    if( m_curBoundTex[0] != texture )
+    {
+        glBindTexture(GL_TEXTURE_2D,texture);
+        OPENGL_CHECK_ERRORS;
+        m_curBoundTex[0] = texture;
+    }
+}
+
+void OGLRender::DisBindTexture(GLuint texture, int unitno)
+{
+    //EnableTexUnit(0,FALSE);
+    //glBindTexture(GL_TEXTURE_2D, 0);  //Not to bind any texture
+}
+
+void OGLRender::EnableTexUnit(int unitno, BOOL flag)
+{
+#ifdef DEBUGGER
+    if( unitno != 0 )
+    {
+        DebuggerAppendMsg("Check me, in the base ogl render, unitno!=0");
+    }
+#endif
+    if( m_texUnitEnabled[0] != flag )          //strange, why 0 and not unitno?
+    {
+        m_texUnitEnabled[0] = flag;
+#if SDL_VIDEO_OPENGL
+        if( flag == TRUE ) {
+//                     pglActiveTexture(GL_TEXTURE0_ARB + unitno);
+            glEnable(GL_TEXTURE_2D);
+        } else {
+//                     pglActiveTexture(GL_TEXTURE0_ARB + unitno);
+            glDisable(GL_TEXTURE_2D);
+               }
+/*             if (m_bMultiTexture)
+                       pglActiveTexture(GL_TEXTURE1_ARB);*/
+#elif SDL_VIDEO_OPENGL_ES2
+        if(flag)
+        {
+            pglActiveTexture(GL_TEXTURE0_ARB + unitno);
+            OPENGL_CHECK_ERRORS;
+            glBindTexture(GL_TEXTURE_2D,m_curBoundTex[unitno]);
+        }
+        else
+        {
+            pglActiveTexture(GL_TEXTURE0_ARB + unitno);
+            OPENGL_CHECK_ERRORS;
+            glEnable(GL_BLEND); //Need blend for transparent disabled texture
+            glBindTexture(GL_TEXTURE_2D,disabledTextureID);
+        }
+#endif
+        OPENGL_CHECK_ERRORS;
+    }
+}
+
+void OGLRender::TexCoord2f(float u, float v)
+{
+#ifdef HAVE_GLES
+       printf("*SEB* TexCoord2f(%f, %f)\n", u, v);
+#else
+    glTexCoord2f(u, v);
+#endif
+}
+
+void OGLRender::TexCoord(TLITVERTEX &vtxInfo)
+{
+#ifdef HAVE_GLES
+       printf("*SEB* TexCoord(%f, %f)\n", vtxInfo.tcord[0].u, vtxInfo.tcord[0].v);
+#else
+    glTexCoord2f(vtxInfo.tcord[0].u, vtxInfo.tcord[0].v);
+#endif
+}
+
+void OGLRender::UpdateScissor()
+{
+    if( options.bEnableHacks && g_CI.dwWidth == 0x200 && gRDP.scissor.right == 0x200 && g_CI.dwWidth>(*g_GraphicsInfo.VI_WIDTH_REG & 0xFFF) )
+    {
+        // Hack for RE2
+        uint32 width = *g_GraphicsInfo.VI_WIDTH_REG & 0xFFF;
+        uint32 height = (gRDP.scissor.right*gRDP.scissor.bottom)/width;
+        glEnable(GL_SCISSOR_TEST);
+        OPENGL_CHECK_ERRORS;
+        glScissor(0, int(height*windowSetting.fMultY+windowSetting.statusBarHeightToUse),
+            int(width*windowSetting.fMultX), int(height*windowSetting.fMultY) );
+        OPENGL_CHECK_ERRORS;
+    }
+    else
+    {
+        UpdateScissorWithClipRatio();
+    }
+}
+
+void OGLRender::ApplyRDPScissor(bool force)
+{
+    if( !force && status.curScissor == RDP_SCISSOR )    return;
+
+    if( options.bEnableHacks && g_CI.dwWidth == 0x200 && gRDP.scissor.right == 0x200 && g_CI.dwWidth>(*g_GraphicsInfo.VI_WIDTH_REG & 0xFFF) )
+    {
+        // Hack for RE2
+        uint32 width = *g_GraphicsInfo.VI_WIDTH_REG & 0xFFF;
+        uint32 height = (gRDP.scissor.right*gRDP.scissor.bottom)/width;
+        glEnable(GL_SCISSOR_TEST);
+        OPENGL_CHECK_ERRORS;
+        glScissor(0, int(height*windowSetting.fMultY+windowSetting.statusBarHeightToUse),
+            int(width*windowSetting.fMultX), int(height*windowSetting.fMultY) );
+        OPENGL_CHECK_ERRORS;
+    }
+    else
+    {
+        glScissor(int(gRDP.scissor.left*windowSetting.fMultX), int((windowSetting.uViHeight-gRDP.scissor.bottom)*windowSetting.fMultY+windowSetting.statusBarHeightToUse),
+            int((gRDP.scissor.right-gRDP.scissor.left)*windowSetting.fMultX), int((gRDP.scissor.bottom-gRDP.scissor.top)*windowSetting.fMultY ));
+        OPENGL_CHECK_ERRORS;
+    }
+
+    status.curScissor = RDP_SCISSOR;
+}
+
+void OGLRender::ApplyScissorWithClipRatio(bool force)
+{
+    if( !force && status.curScissor == RSP_SCISSOR )    return;
+
+    glEnable(GL_SCISSOR_TEST);
+    OPENGL_CHECK_ERRORS;
+    glScissor(windowSetting.clipping.left, int((windowSetting.uViHeight-gRSP.real_clip_scissor_bottom)*windowSetting.fMultY)+windowSetting.statusBarHeightToUse,
+        windowSetting.clipping.width, windowSetting.clipping.height);
+    OPENGL_CHECK_ERRORS;
+
+    status.curScissor = RSP_SCISSOR;
+}
+
+void OGLRender::SetFogMinMax(float fMin, float fMax)
+{
+#if SDL_VIDEO_OPENGL
+    glFogf(GL_FOG_START, gRSPfFogMin); // Fog Start Depth
+    OPENGL_CHECK_ERRORS;
+    glFogf(GL_FOG_END, gRSPfFogMax); // Fog End Depth
+    OPENGL_CHECK_ERRORS;
+#elif SDL_VIDEO_OPENGL_ES2
+    ((COGL_FragmentProgramCombiner*)m_pColorCombiner)->UpdateFog(gRSP.bFogEnabled);
+    OPENGL_CHECK_ERRORS;
+#endif
+}
+
+void OGLRender::TurnFogOnOff(bool flag)
+{
+#if SDL_VIDEO_OPENGL
+    if( flag )
+        glEnable(GL_FOG);
+    else
+        glDisable(GL_FOG);
+    OPENGL_CHECK_ERRORS;
+#elif SDL_VIDEO_OPENGL_ES2
+    ((COGL_FragmentProgramCombiner*)m_pColorCombiner)->UpdateFog(flag);
+    OPENGL_CHECK_ERRORS;
+#endif
+}
+
+void OGLRender::SetFogEnable(bool bEnable)
+{
+    DEBUGGER_IF_DUMP( (gRSP.bFogEnabled != (bEnable==TRUE) && logFog ), TRACE1("Set Fog %s", bEnable? "enable":"disable"));
+
+    gRSP.bFogEnabled = bEnable&&(options.fogMethod == 1);
+    
+    // If force fog
+    if(options.fogMethod == 2)
+    {
+        gRSP.bFogEnabled = true;
+    }
+
+#if SDL_VIDEO_OPENGL
+    if( gRSP.bFogEnabled )
+    {
+        //TRACE2("Enable fog, min=%f, max=%f",gRSPfFogMin,gRSPfFogMax );
+        glFogfv(GL_FOG_COLOR, gRDP.fvFogColor); // Set Fog Color
+        OPENGL_CHECK_ERRORS;
+        glFogf(GL_FOG_START, gRSPfFogMin); // Fog Start Depth
+        OPENGL_CHECK_ERRORS;
+        glFogf(GL_FOG_END, gRSPfFogMax); // Fog End Depth
+        OPENGL_CHECK_ERRORS;
+        glEnable(GL_FOG);
+        OPENGL_CHECK_ERRORS;
+    }
+    else
+    {
+        glDisable(GL_FOG);
+        OPENGL_CHECK_ERRORS;
+    }
+#elif SDL_VIDEO_OPENGL_ES2
+    ((COGL_FragmentProgramCombiner*)m_pColorCombiner)->UpdateFog(gRSP.bFogEnabled);
+    OPENGL_CHECK_ERRORS;
+#endif
+}
+
+void OGLRender::SetFogColor(uint32 r, uint32 g, uint32 b, uint32 a)
+{
+    gRDP.fogColor = COLOR_RGBA(r, g, b, a); 
+    gRDP.fvFogColor[0] = r/255.0f;      //r
+    gRDP.fvFogColor[1] = g/255.0f;      //g
+    gRDP.fvFogColor[2] = b/255.0f;      //b
+    gRDP.fvFogColor[3] = a/255.0f;      //a
+#if SDL_VIDEO_OPENGL
+    glFogfv(GL_FOG_COLOR, gRDP.fvFogColor); // Set Fog Color
+#endif
+    OPENGL_CHECK_ERRORS;
+}
+
+void OGLRender::DisableMultiTexture()
+{
+    pglActiveTexture(GL_TEXTURE1_ARB);
+    OPENGL_CHECK_ERRORS;
+    EnableTexUnit(1,FALSE);
+    pglActiveTexture(GL_TEXTURE0_ARB);
+    OPENGL_CHECK_ERRORS;
+    EnableTexUnit(0,FALSE);
+    pglActiveTexture(GL_TEXTURE0_ARB);
+    OPENGL_CHECK_ERRORS;
+    EnableTexUnit(0,TRUE);
+}
+
+void OGLRender::EndRendering(void)
+{
+#if SDL_VIDEO_OPENGL
+    glFlush();
+    OPENGL_CHECK_ERRORS;
+#endif
+    if( CRender::gRenderReferenceCount > 0 ) 
+        CRender::gRenderReferenceCount--;
+}
+
+void OGLRender::glViewportWrapper(GLint x, GLint y, GLsizei width, GLsizei height, bool flag)
+{
+    static GLint mx=0,my=0;
+    static GLsizei m_width=0, m_height=0;
+    static bool mflag=true;
+
+    if( x!=mx || y!=my || width!=m_width || height!=m_height || mflag!=flag)
+    {
+        mx=x;
+        my=y;
+        m_width=width;
+        m_height=height;
+        mflag=flag;
+        glMatrixMode(GL_PROJECTION);
+        OPENGL_CHECK_ERRORS;
+        glLoadIdentity();
+        OPENGL_CHECK_ERRORS;
+        if( flag )  glOrtho(0, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight, 0, -1, 1);
+        OPENGL_CHECK_ERRORS;
+        glViewport(x,y,width,height);
+//printf("glViewport(%i, %i, %i, %i)\n", x, y, width, height);
+        OPENGL_CHECK_ERRORS;
+    }
+}