2009-05-08 13:28:41 +00:00
/*
* OpenClonk , http : //www.openclonk.org
*
2013-12-17 20:01:09 +00:00
* Copyright ( c ) 2001 - 2009 , RedWolf Design GmbH , http : //www.clonk.de/
* Copyright ( c ) 2009 - 2013 , The OpenClonk Team and contributors
2009-05-08 13:28:41 +00:00
*
2013-12-17 20:01:09 +00:00
* Distributed under the terms of the ISC license ; see accompanying file
* " COPYING " for details .
2009-05-08 13:28:41 +00:00
*
2013-12-17 20:01:09 +00:00
* " Clonk " is a registered trademark of Matthes Bender , used with permission .
* See accompanying file " TRADEMARK " for details .
2009-05-08 13:28:41 +00:00
*
2013-12-17 20:01:09 +00:00
* To redistribute this file separately , substitute the full license texts
* for the above references .
2009-05-08 13:28:41 +00:00
*/
/* OpenGL implementation of NewGfx */
2009-10-20 03:39:24 +00:00
# include "C4Include.h"
2012-04-27 17:04:43 +00:00
# include <C4DrawGL.h>
2011-11-01 22:17:41 +00:00
2011-10-03 14:06:41 +00:00
# include <C4Surface.h>
2011-10-03 15:19:24 +00:00
# include <C4Window.h>
2014-11-06 16:19:41 +00:00
# include <C4FoWRegion.h>
2009-08-12 20:03:50 +00:00
# include "C4Rect.h"
2010-09-05 13:07:45 +00:00
# include "C4Config.h"
# include "C4Application.h"
2009-05-08 13:28:41 +00:00
2013-10-29 13:27:18 +00:00
# ifndef USE_CONSOLE
2009-05-08 13:28:41 +00:00
2010-01-26 18:35:15 +00:00
// MSVC doesn't define M_PI in math.h unless requested
# ifdef _MSC_VER
# define _USE_MATH_DEFINES
# endif /* _MSC_VER */
2009-05-08 13:28:41 +00:00
# include <stdio.h>
# include <math.h>
# include <limits.h>
2014-10-07 19:57:02 +00:00
C4DrawGLShader : : C4DrawGLShader ( Type shader_type )
{
GLint gl_type ;
switch ( shader_type )
{
case FRAGMENT : gl_type = GL_FRAGMENT_SHADER_ARB ; break ;
case VERTEX : gl_type = GL_VERTEX_SHADER_ARB ; break ;
case GEOMETRY : gl_type = GL_GEOMETRY_SHADER_ARB ; break ;
default : assert ( false ) ; break ;
}
Shader = glCreateShaderObjectARB ( gl_type ) ;
if ( ! Shader ) throw C4DrawGLError ( FormatString ( " Failed to create shader " ) ) ; // TODO: custom error class?
}
C4DrawGLShader : : ~ C4DrawGLShader ( )
{
glDeleteObjectARB ( Shader ) ;
}
void C4DrawGLShader : : Load ( const char * code )
{
glShaderSourceARB ( Shader , 1 , & code , NULL ) ;
glCompileShaderARB ( Shader ) ;
GLint compile_status ;
glGetObjectParameterivARB ( Shader , GL_OBJECT_COMPILE_STATUS_ARB , & compile_status ) ;
if ( compile_status ! = GL_TRUE )
{
const char * shader_type_str ;
switch ( GetType ( ) )
{
case VERTEX : shader_type_str = " vertex " ; break ;
case FRAGMENT : shader_type_str = " fragment " ; break ;
case GEOMETRY : shader_type_str = " geometry " ; break ;
default : assert ( false ) ; break ;
}
GLint length ;
glGetObjectParameterivARB ( Shader , GL_OBJECT_INFO_LOG_LENGTH_ARB , & length ) ;
if ( length > 0 )
{
std : : vector < char > error_message ( length ) ;
glGetInfoLogARB ( Shader , length , NULL , & error_message [ 0 ] ) ;
throw C4DrawGLError ( FormatString ( " Failed to compile %s shader: %s " , shader_type_str , & error_message [ 0 ] ) ) ;
}
else
{
throw C4DrawGLError ( FormatString ( " Failed to compile %s shader " , shader_type_str ) ) ;
}
}
}
StdMeshMaterialShader : : Type C4DrawGLShader : : GetType ( ) const
{
GLint shader_type ;
glGetObjectParameterivARB ( Shader , GL_OBJECT_SUBTYPE_ARB , & shader_type ) ;
switch ( shader_type )
{
case GL_FRAGMENT_SHADER_ARB : return FRAGMENT ;
case GL_VERTEX_SHADER_ARB : return VERTEX ;
case GL_GEOMETRY_SHADER_ARB : return GEOMETRY ;
default : assert ( false ) ; return static_cast < StdMeshMaterialShader : : Type > ( - 1 ) ;
}
}
C4DrawGLProgram : : C4DrawGLProgram ( const C4DrawGLShader * fragment_shader , const C4DrawGLShader * vertex_shader , const C4DrawGLShader * geometry_shader )
{
Program = glCreateProgramObjectARB ( ) ;
if ( fragment_shader ! = NULL )
glAttachObjectARB ( Program , fragment_shader - > Shader ) ;
if ( vertex_shader ! = NULL )
glAttachObjectARB ( Program , vertex_shader - > Shader ) ;
if ( geometry_shader ! = NULL )
glAttachObjectARB ( Program , geometry_shader - > Shader ) ;
glLinkProgramARB ( Program ) ;
GLint link_status ;
glGetObjectParameterivARB ( Program , GL_OBJECT_LINK_STATUS_ARB , & link_status ) ;
if ( link_status ! = GL_TRUE )
{
GLint length ;
glGetObjectParameterivARB ( Program , GL_OBJECT_INFO_LOG_LENGTH_ARB , & length ) ;
if ( length > 0 )
{
std : : vector < char > error_message ( length ) ;
glGetInfoLogARB ( Program , length , NULL , & error_message [ 0 ] ) ;
glDeleteObjectARB ( Program ) ;
throw C4DrawGLError ( FormatString ( " Failed to link program: %s " , & error_message [ 0 ] ) ) ;
}
else
{
glDeleteObjectARB ( Program ) ;
throw C4DrawGLError ( StdStrBuf ( " Failed to link program " ) ) ;
}
}
}
C4DrawGLProgram : : ~ C4DrawGLProgram ( )
{
glDeleteObjectARB ( Program ) ;
}
2010-03-06 14:07:30 +00:00
CStdGL : : CStdGL ( ) :
2010-03-28 18:58:01 +00:00
pMainCtx ( 0 )
{
2009-05-08 13:28:41 +00:00
Default ( ) ;
2010-03-06 14:07:30 +00:00
byByteCnt = 4 ;
2009-05-08 13:28:41 +00:00
// global ptr
pGL = this ;
2010-03-18 12:52:09 +00:00
lines_tex = 0 ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
CStdGL : : ~ CStdGL ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
Clear ( ) ;
pGL = NULL ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void CStdGL : : Clear ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
NoPrimaryClipper ( ) ;
2010-12-29 14:19:46 +00:00
//if (pTexMgr) pTexMgr->IntUnlock(); // cannot do this here or we can't preserve textures across GL reinitialization as required when changing multisampling
2009-05-31 00:09:15 +00:00
InvalidateDeviceObjects ( ) ;
NoPrimaryClipper ( ) ;
RenderTarget = NULL ;
// clear context
if ( pCurrCtx ) pCurrCtx - > Deselect ( ) ;
2010-03-06 14:07:30 +00:00
pMainCtx = 0 ;
2011-10-03 14:34:08 +00:00
C4Draw : : Clear ( ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void CStdGL : : FillBG ( DWORD dwClr )
2010-03-28 18:58:01 +00:00
{
2010-03-06 14:07:30 +00:00
if ( ! pCurrCtx ) return ;
2011-03-11 02:37:27 +00:00
glClearColor ( ( float ) GetRedValue ( dwClr ) / 255.0f , ( float ) GetGreenValue ( dwClr ) / 255.0f , ( float ) GetBlueValue ( dwClr ) / 255.0f , 0.0f ) ;
2009-05-08 13:28:41 +00:00
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool CStdGL : : UpdateClipper ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// no render target? do nothing
if ( ! RenderTarget | | ! Active ) return true ;
// negative/zero?
2014-11-23 21:26:09 +00:00
C4Rect clipRect = GetClipRect ( ) ;
if ( clipRect . Wdt < = 0 | | clipRect . Hgt < = 0 )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
ClipAll = true ;
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
ClipAll = false ;
// set it
2014-11-23 21:26:09 +00:00
glViewport ( clipRect . x , RenderTarget - > Hgt - clipRect . y - clipRect . Hgt , clipRect . Wdt , clipRect . Hgt ) ;
2009-05-08 13:28:41 +00:00
glMatrixMode ( GL_PROJECTION ) ;
glLoadIdentity ( ) ;
2009-09-10 02:54:12 +00:00
// Set clipping plane to -1000 and 1000 so that large meshes are not
// clipped away.
2010-02-06 17:33:30 +00:00
//glOrtho((GLdouble) iX, (GLdouble) (iX+iWdt), (GLdouble) (iY+iHgt), (GLdouble) iY, -1000.0f, 1000.0f);
2014-11-23 21:26:09 +00:00
gluOrtho2D ( ( GLdouble ) clipRect . x , ( GLdouble ) ( clipRect . x + clipRect . Wdt ) , ( GLdouble ) ( clipRect . y + clipRect . Hgt ) , ( GLdouble ) clipRect . y ) ;
2009-05-08 13:28:41 +00:00
//gluOrtho2D((GLdouble) 0, (GLdouble) xRes, (GLdouble) yRes, (GLdouble) yRes-iHgt);
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-10-03 14:07:07 +00:00
bool CStdGL : : PrepareRendering ( C4Surface * sfcToSurface )
2009-05-08 13:28:41 +00:00
{
// call from gfx thread only!
if ( ! pApp | | ! pApp - > AssertMainThread ( ) ) return false ;
// not ready?
if ( ! Active )
//if (!RestoreDeviceObjects())
2010-03-28 18:58:01 +00:00
return false ;
2009-05-08 13:28:41 +00:00
// target?
if ( ! sfcToSurface ) return false ;
// target locked?
if ( sfcToSurface - > Locked ) return false ;
// target is already set as render target?
if ( sfcToSurface ! = RenderTarget )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// target is a render-target?
if ( ! sfcToSurface - > IsRenderTarget ( ) ) return false ;
2010-03-06 14:07:30 +00:00
// context
if ( sfcToSurface - > pCtx & & sfcToSurface - > pCtx ! = pCurrCtx )
if ( ! sfcToSurface - > pCtx - > Select ( ) ) return false ;
2009-05-08 13:28:41 +00:00
// set target
RenderTarget = sfcToSurface ;
// new target has different size; needs other clipping rect
UpdateClipper ( ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// done
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-08-27 21:12:01 +00:00
CStdGLCtx * CStdGL : : CreateContext ( C4Window * pWindow , C4AbstractApp * pApp )
2010-03-28 18:58:01 +00:00
{
2009-06-02 23:59:04 +00:00
DebugLog ( " gl: Create Context... " ) ;
2009-05-08 13:28:41 +00:00
// safety
if ( ! pWindow ) return NULL ;
// create it
CStdGLCtx * pCtx = new CStdGLCtx ( ) ;
2010-03-06 14:07:30 +00:00
if ( ! pMainCtx ) pMainCtx = pCtx ;
2009-05-08 13:28:41 +00:00
if ( ! pCtx - > Init ( pWindow , pApp ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
delete pCtx ; Error ( " gl: Error creating secondary context! " ) ; return NULL ;
2010-03-28 18:58:01 +00:00
}
2010-12-03 19:18:36 +00:00
// creation selected the new context - switch back to previous context
RenderTarget = NULL ;
pCurrCtx = NULL ;
2009-05-08 13:28:41 +00:00
// done
return pCtx ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2012-03-23 21:53:56 +00:00
# ifdef USE_WIN32_WINDOWS
2011-08-27 14:20:39 +00:00
CStdGLCtx * CStdGL : : CreateContext ( HWND hWindow , C4AbstractApp * pApp )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// safety
if ( ! hWindow ) return NULL ;
// create it
CStdGLCtx * pCtx = new CStdGLCtx ( ) ;
if ( ! pCtx - > Init ( NULL , pApp , hWindow ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
delete pCtx ; Error ( " gl: Error creating secondary context! " ) ; return NULL ;
2010-03-28 18:58:01 +00:00
}
2010-12-03 19:18:36 +00:00
if ( ! pMainCtx )
{
pMainCtx = pCtx ;
}
else
{
// creation selected the new context - switch back to previous context
RenderTarget = NULL ;
pCurrCtx = NULL ;
}
2009-05-08 13:28:41 +00:00
// done
return pCtx ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
# endif
2014-11-04 16:24:55 +00:00
bool CStdGL : : CreatePrimarySurfaces ( unsigned int , unsigned int , int iColorDepth , unsigned int )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// store options
2009-05-31 00:09:15 +00:00
return RestoreDeviceObjects ( ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2014-11-07 20:28:52 +00:00
void CStdGL : : SetupMultiBlt ( const C4BltTransform * pTransform , GLuint baseTex , GLuint overlayTex , GLuint normalTex , DWORD dwOverlayModClr )
2014-10-08 01:48:11 +00:00
{
2014-11-04 16:24:55 +00:00
// Initialize multi blit shader.
2014-10-08 01:48:11 +00:00
int iAdditive = dwBlitMode & C4GFXBLIT_ADDITIVE ;
glBlendFunc ( GL_SRC_ALPHA , iAdditive ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA ) ;
2014-10-08 04:21:05 +00:00
// TODO: The locations could be cached
2014-10-08 01:48:11 +00:00
GLint fMod2Location = glGetUniformLocationARB ( multi_blt_program - > Program , " fMod2 " ) ;
2014-11-06 16:19:41 +00:00
GLint fUseLightLocation = glGetUniformLocationARB ( multi_blt_program - > Program , " fUseLight " ) ;
2014-10-08 01:48:11 +00:00
GLint fUseTextureLocation = glGetUniformLocationARB ( multi_blt_program - > Program , " fUseTexture " ) ;
2014-11-02 01:46:30 +00:00
GLint fUseOverlayLocation = glGetUniformLocationARB ( multi_blt_program - > Program , " fUseOverlay " ) ;
2014-11-07 20:28:52 +00:00
GLint fUseNormalLocation = glGetUniformLocationARB ( multi_blt_program - > Program , " fUseNormal " ) ;
2014-10-08 01:48:11 +00:00
GLint clrModLocation = glGetUniformLocationARB ( multi_blt_program - > Program , " clrMod " ) ;
2014-11-02 01:46:30 +00:00
GLint overlayClrModLocation = glGetUniformLocationARB ( multi_blt_program - > Program , " overlayClrMod " ) ;
2014-11-19 16:18:07 +00:00
GLint ambientBrightnessLocation = glGetUniformLocationARB ( multi_blt_program - > Program , " ambientBrightness " ) ;
2014-11-06 16:19:41 +00:00
GLint lightLocation = glGetUniformLocationARB ( multi_blt_program - > Program , " Light " ) ;
2014-11-17 14:35:50 +00:00
GLint ambientLocation = glGetUniformLocationARB ( multi_blt_program - > Program , " Ambient " ) ;
2014-11-02 01:46:30 +00:00
GLint textureLocation = glGetUniformLocationARB ( multi_blt_program - > Program , " Texture " ) ;
GLint overlayLocation = glGetUniformLocationARB ( multi_blt_program - > Program , " Overlay " ) ;
2014-11-07 20:28:52 +00:00
GLint normalLocation = glGetUniformLocationARB ( multi_blt_program - > Program , " Normal " ) ;
2014-10-08 01:48:11 +00:00
const int fMod2 = ( dwBlitMode & C4GFXBLIT_MOD2 ) ! = 0 ;
2014-11-06 16:19:41 +00:00
const int fUseLight = ( pFoW ! = NULL ) ;
2014-11-02 01:46:30 +00:00
const int fUseTexture = ( baseTex ! = 0 ) ;
const int fUseOverlay = ( overlayTex ! = 0 ) ;
2014-11-07 20:28:52 +00:00
const int fUseNormal = ( normalTex ! = 0 ) ;
2014-10-08 01:48:11 +00:00
const DWORD dwModClr = BlitModulated ? BlitModulateClr : 0xffffffff ;
const float dwMod [ 4 ] = {
( ( dwModClr > > 16 ) & 0xff ) / 255.0f ,
( ( dwModClr > > 8 ) & 0xff ) / 255.0f ,
( ( dwModClr ) & 0xff ) / 255.0f ,
( ( dwModClr > > 24 ) & 0xff ) / 255.0f
} ;
2014-11-02 01:46:30 +00:00
const float dwOverlayMod [ 4 ] = {
( ( dwOverlayModClr > > 16 ) & 0xff ) / 255.0f ,
( ( dwOverlayModClr > > 8 ) & 0xff ) / 255.0f ,
( ( dwOverlayModClr ) & 0xff ) / 255.0f ,
( ( dwOverlayModClr > > 24 ) & 0xff ) / 255.0f
} ;
2014-10-08 01:48:11 +00:00
glUseProgramObjectARB ( multi_blt_program - > Program ) ;
glUniform1iARB ( fMod2Location , fMod2 ) ;
2014-11-06 16:19:41 +00:00
glUniform1iARB ( fUseLightLocation , fUseLight ) ;
2014-10-08 04:21:05 +00:00
glUniform1iARB ( fUseTextureLocation , fUseTexture ) ;
2014-11-02 01:46:30 +00:00
glUniform1iARB ( fUseOverlayLocation , fUseOverlay ) ;
2014-11-07 20:28:52 +00:00
glUniform1iARB ( fUseNormalLocation , fUseNormal ) ;
2014-10-08 01:48:11 +00:00
glUniform4fvARB ( clrModLocation , 1 , dwMod ) ;
2014-11-07 20:28:52 +00:00
if ( fUseNormal )
{
2014-11-17 14:35:50 +00:00
glActiveTexture ( GL_TEXTURE4 ) ;
2014-11-07 20:28:52 +00:00
glEnable ( GL_TEXTURE_2D ) ;
glBindTexture ( GL_TEXTURE_2D , normalTex ) ;
2014-11-17 14:35:50 +00:00
glUniform1iARB ( normalLocation , 4 ) ;
2014-11-07 20:28:52 +00:00
}
2014-11-06 16:19:41 +00:00
if ( fUseLight )
2014-10-08 01:48:11 +00:00
{
2014-11-17 14:35:50 +00:00
const C4Rect LightRect = pFoW - > getRegion ( ) ;
const int32_t iLightWdt = pFoW - > getSurface ( ) - > Wdt ;
const int32_t iLightHgt = pFoW - > getSurface ( ) - > Hgt ;
2014-11-18 21:44:06 +00:00
int iVpWdt = Min ( iClipX2 , RenderTarget - > Wdt - 1 ) - iClipX1 + 1 ;
int iVpHgt = Min ( iClipY2 , RenderTarget - > Hgt - 1 ) - iClipY1 + 1 ;
int iX = iClipX1 ; if ( iX < 0 ) { iVpWdt + = iX ; iX = 0 ; }
int iY = iClipY1 ; if ( iY < 0 ) { iVpHgt + = iY ; iY = 0 ; }
2014-11-17 14:35:50 +00:00
glMatrixMode ( GL_TEXTURE ) ;
// Ambient texture
glActiveTexture ( GL_TEXTURE3 ) ;
glEnable ( GL_TEXTURE_2D ) ;
glBindTexture ( GL_TEXTURE_2D , pFoW - > getFoW ( ) - > Ambient . Tex ) ;
glUniform1iARB ( ambientLocation , 3 ) ;
// Setup the texture matrix
glLoadIdentity ( ) ;
glScalef ( 1.0f / pFoW - > getFoW ( ) - > Ambient . GetLandscapeWidth ( ) , 1.0f / pFoW - > getFoW ( ) - > Ambient . GetLandscapeHeight ( ) , 1.0f ) ;
glTranslatef ( LightRect . x , LightRect . y , 0.0f ) ; // TODO: LightRect should have floating point accuracy for this to work best
glScalef ( ( float ) LightRect . Wdt / ( float ) iVpWdt , ( float ) LightRect . Hgt / ( float ) iVpHgt , 1.0f ) ;
2014-11-18 21:44:06 +00:00
glTranslatef ( - iX , iVpHgt + iY , 0.0f ) ;
2014-11-17 14:35:50 +00:00
glScalef ( 1.0f , - 1.0f , 1.0f ) ;
// Light texture
2014-11-02 01:46:30 +00:00
glActiveTexture ( GL_TEXTURE2 ) ;
2014-10-08 01:48:11 +00:00
glEnable ( GL_TEXTURE_2D ) ;
2014-11-06 16:19:41 +00:00
glBindTexture ( GL_TEXTURE_2D , pFoW - > getSurface ( ) - > ppTex [ 0 ] - > texName ) ;
glUniform1iARB ( lightLocation , 2 ) ;
2014-10-08 04:21:05 +00:00
2014-11-17 14:35:50 +00:00
// Setup the texture matrix
2014-10-08 04:21:05 +00:00
glLoadIdentity ( ) ;
2014-11-06 16:19:41 +00:00
glTranslatef ( 0.0f , 1.0f - ( float ) LightRect . Hgt / ( float ) iLightHgt , 0.0f ) ;
glScalef ( 1.0f / iLightWdt , 1.0f / iLightHgt , 1.0f ) ;
2014-11-17 14:35:50 +00:00
glScalef ( ( float ) LightRect . Wdt / ( float ) iVpWdt , ( float ) LightRect . Hgt / ( float ) iVpHgt , 1.0f ) ;
2014-11-19 16:10:22 +00:00
glTranslatef ( - iX , - iY , 0.0f ) ;
2014-11-06 16:19:41 +00:00
2014-10-08 04:21:05 +00:00
glMatrixMode ( GL_MODELVIEW ) ;
2014-11-19 16:18:07 +00:00
glUniform1fARB ( ambientBrightnessLocation , pFoW - > getFoW ( ) - > Ambient . GetBrightness ( ) ) ;
2014-10-08 01:48:11 +00:00
}
2014-11-02 01:46:30 +00:00
if ( overlayTex ! = 0 )
{
glActiveTexture ( GL_TEXTURE1 ) ;
glBindTexture ( GL_TEXTURE_2D , overlayTex ) ;
glUniform1iARB ( overlayLocation , 1 ) ;
glUniform4fvARB ( overlayClrModLocation , 1 , dwOverlayMod ) ;
}
2014-10-08 04:21:05 +00:00
glActiveTexture ( GL_TEXTURE0 ) ;
2014-11-02 01:46:30 +00:00
if ( baseTex ! = 0 )
2014-10-08 04:21:05 +00:00
{
glEnable ( GL_TEXTURE_2D ) ;
2014-11-02 01:46:30 +00:00
glBindTexture ( GL_TEXTURE_2D , baseTex ) ;
2014-10-08 04:21:05 +00:00
glUniform1iARB ( textureLocation , 0 ) ;
}
2014-10-08 01:48:11 +00:00
2014-11-02 01:46:30 +00:00
// Apply zoom and transform
2014-10-08 04:21:05 +00:00
glPushMatrix ( ) ;
2014-10-08 01:48:11 +00:00
glTranslatef ( ZoomX , ZoomY , 0.0f ) ;
glScalef ( Zoom , Zoom , 1.0f ) ;
glTranslatef ( - ZoomX , - ZoomY , 0.0f ) ;
2014-11-02 01:46:30 +00:00
if ( pTransform )
{
const GLfloat transform [ 16 ] = { pTransform - > mat [ 0 ] , pTransform - > mat [ 3 ] , 0 , pTransform - > mat [ 6 ] , pTransform - > mat [ 1 ] , pTransform - > mat [ 4 ] , 0 , pTransform - > mat [ 7 ] , 0 , 0 , 1 , 0 , pTransform - > mat [ 2 ] , pTransform - > mat [ 5 ] , 0 , pTransform - > mat [ 8 ] } ;
glMultMatrixf ( transform ) ;
}
2014-10-08 04:21:05 +00:00
}
2014-11-07 20:28:52 +00:00
void CStdGL : : ResetMultiBlt ( GLuint baseTex , GLuint overlayTex , GLuint normalTex )
2014-10-08 04:21:05 +00:00
{
glPopMatrix ( ) ;
2014-11-17 14:35:50 +00:00
if ( normalTex ! = 0 ) { glActiveTexture ( GL_TEXTURE4 ) ; glDisable ( GL_TEXTURE_2D ) ; }
if ( pFoW ! = NULL ) { glActiveTexture ( GL_TEXTURE3 ) ; glDisable ( GL_TEXTURE_2D ) ; glActiveTexture ( GL_TEXTURE2 ) ; glDisable ( GL_TEXTURE_2D ) ; }
2014-11-02 01:46:30 +00:00
if ( overlayTex ! = 0 ) { glActiveTexture ( GL_TEXTURE1 ) ; glDisable ( GL_TEXTURE_2D ) ; }
2014-10-08 04:21:05 +00:00
glActiveTexture ( GL_TEXTURE0 ) ;
2014-11-02 01:46:30 +00:00
if ( baseTex ! = 0 ) glDisable ( GL_TEXTURE_2D ) ;
2014-10-08 04:21:05 +00:00
glUseProgramObjectARB ( 0 ) ;
}
void CStdGL : : PerformMultiPix ( C4Surface * sfcTarget , const C4BltVertex * vertices , unsigned int n_vertices )
{
// Only direct rendering
assert ( sfcTarget - > IsRenderTarget ( ) ) ;
if ( ! PrepareRendering ( sfcTarget ) ) return ;
// Draw on pixel center:
glPushMatrix ( ) ;
glTranslatef ( 0.5f , 0.5f , 0.0f ) ;
// Feed the vertices to the GL
2014-11-07 20:28:52 +00:00
SetupMultiBlt ( NULL , 0 , 0 , 0 , 0 ) ;
2014-10-08 01:48:11 +00:00
glEnableClientState ( GL_VERTEX_ARRAY ) ;
glEnableClientState ( GL_COLOR_ARRAY ) ;
2014-10-08 02:51:34 +00:00
// This is a workaround. Instead of submitting the whole vertex array to the GL, we do it
// in batches of 256 vertices. The intel graphics driver on Linux crashes with
// significantly larger arrays, such as 400. It's not clear to me why, maybe POINT drawing
// is just not very well tested.
const unsigned int BATCH_SIZE = 256 ;
for ( unsigned int i = 0 ; i < n_vertices ; i + = BATCH_SIZE )
{
glVertexPointer ( 2 , GL_FLOAT , sizeof ( C4BltVertex ) , & vertices [ i ] . ftx ) ;
glColorPointer ( 4 , GL_UNSIGNED_BYTE , sizeof ( C4BltVertex ) , & vertices [ i ] . color [ 0 ] ) ;
glDrawArrays ( GL_POINTS , 0 , std : : min ( n_vertices - i , BATCH_SIZE ) ) ;
}
2014-10-08 01:48:11 +00:00
glDisableClientState ( GL_VERTEX_ARRAY ) ;
glDisableClientState ( GL_COLOR_ARRAY ) ;
glPopMatrix ( ) ;
2014-10-08 04:21:05 +00:00
2014-11-07 20:28:52 +00:00
ResetMultiBlt ( 0 , 0 , 0 ) ;
2014-10-08 04:21:05 +00:00
}
void CStdGL : : PerformMultiLines ( C4Surface * sfcTarget , const C4BltVertex * vertices , unsigned int n_vertices , float width )
{
// Only direct rendering
assert ( sfcTarget - > IsRenderTarget ( ) ) ;
if ( ! PrepareRendering ( sfcTarget ) ) return ;
// In a first step, we transform the lines array to a triangle array, so that we can draw
// the lines with some thickness.
// In principle, this step could be easily (and probably much more efficiently) performed
// by a geometry shader as well, however that would require OpenGL 3.2.
C4BltVertex * tri_vertices = new C4BltVertex [ n_vertices * 3 ] ;
for ( unsigned int i = 0 ; i < n_vertices ; i + = 2 )
{
const float x1 = vertices [ i ] . ftx ;
const float y1 = vertices [ i ] . fty ;
const float x2 = vertices [ i + 1 ] . ftx ;
const float y2 = vertices [ i + 1 ] . fty ;
float offx = y1 - y2 ;
float offy = x2 - x1 ;
float l = sqrtf ( offx * offx + offy * offy ) ;
// avoid division by zero
l + = 0.000000005f ;
offx * = width / l ;
offy * = width / l ;
tri_vertices [ 3 * i + 0 ] . ftx = x1 + offx ; tri_vertices [ 3 * i + 0 ] . fty = y1 + offy ;
tri_vertices [ 3 * i + 1 ] . ftx = x1 - offx ; tri_vertices [ 3 * i + 1 ] . fty = y1 - offy ;
tri_vertices [ 3 * i + 2 ] . ftx = x2 - offx ; tri_vertices [ 3 * i + 2 ] . fty = y2 - offy ;
tri_vertices [ 3 * i + 3 ] . ftx = x2 + offx ; tri_vertices [ 3 * i + 3 ] . fty = y2 + offy ;
for ( int j = 0 ; j < 4 ; + + j )
{
tri_vertices [ 3 * i + 0 ] . color [ j ] = vertices [ i ] . color [ j ] ;
tri_vertices [ 3 * i + 1 ] . color [ j ] = vertices [ i ] . color [ j ] ;
tri_vertices [ 3 * i + 2 ] . color [ j ] = vertices [ i + 1 ] . color [ j ] ;
tri_vertices [ 3 * i + 3 ] . color [ j ] = vertices [ i + 1 ] . color [ j ] ;
}
tri_vertices [ 3 * i + 0 ] . tx = 0.f ; tri_vertices [ 3 * i + 0 ] . ty = 0.f ;
tri_vertices [ 3 * i + 1 ] . tx = 0.f ; tri_vertices [ 3 * i + 1 ] . ty = 2.f ;
tri_vertices [ 3 * i + 2 ] . tx = 1.f ; tri_vertices [ 3 * i + 2 ] . ty = 2.f ;
tri_vertices [ 3 * i + 3 ] . tx = 1.f ; tri_vertices [ 3 * i + 3 ] . ty = 0.f ;
tri_vertices [ 3 * i + 4 ] = tri_vertices [ 3 * i + 2 ] ; // duplicate vertex
tri_vertices [ 3 * i + 5 ] = tri_vertices [ 3 * i + 0 ] ; // duplicate vertex
}
// Then, feed the vertices to the GL
2014-11-07 20:28:52 +00:00
SetupMultiBlt ( NULL , lines_tex , 0 , 0 , 0 ) ;
2014-10-08 04:21:05 +00:00
glEnableClientState ( GL_VERTEX_ARRAY ) ;
glEnableClientState ( GL_COLOR_ARRAY ) ;
glClientActiveTexture ( GL_TEXTURE0 ) ; // lines_tex was loaded in tex0 by SetupMultiBlt
glEnableClientState ( GL_TEXTURE_COORD_ARRAY ) ;
glTexCoordPointer ( 2 , GL_FLOAT , sizeof ( C4BltVertex ) , & tri_vertices [ 0 ] . tx ) ;
glVertexPointer ( 2 , GL_FLOAT , sizeof ( C4BltVertex ) , & tri_vertices [ 0 ] . ftx ) ;
glColorPointer ( 4 , GL_UNSIGNED_BYTE , sizeof ( C4BltVertex ) , & tri_vertices [ 0 ] . color [ 0 ] ) ;
glDrawArrays ( GL_TRIANGLES , 0 , n_vertices * 3 ) ;
delete [ ] tri_vertices ;
glDisableClientState ( GL_TEXTURE_COORD_ARRAY ) ;
glDisableClientState ( GL_VERTEX_ARRAY ) ;
glDisableClientState ( GL_COLOR_ARRAY ) ;
2014-11-07 20:28:52 +00:00
ResetMultiBlt ( lines_tex , 0 , 0 ) ;
2014-10-08 01:48:11 +00:00
}
2014-11-07 20:28:52 +00:00
void CStdGL : : PerformMultiTris ( C4Surface * sfcTarget , const C4BltVertex * vertices , unsigned int n_vertices , const C4BltTransform * pTransform , C4TexRef * pTex , C4TexRef * pOverlay , C4TexRef * pNormal , DWORD dwOverlayModClr )
2014-10-08 17:35:55 +00:00
{
// Only direct rendering
assert ( sfcTarget - > IsRenderTarget ( ) ) ;
if ( ! PrepareRendering ( sfcTarget ) ) return ;
// Feed the vertices to the GL
2014-11-07 20:28:52 +00:00
SetupMultiBlt ( pTransform , pTex ? pTex - > texName : 0 , pOverlay ? pOverlay - > texName : 0 , pNormal ? pNormal - > texName : 0 , dwOverlayModClr ) ;
2014-10-08 17:35:55 +00:00
glEnableClientState ( GL_VERTEX_ARRAY ) ;
glEnableClientState ( GL_COLOR_ARRAY ) ;
if ( pTex )
{
2014-11-02 01:46:30 +00:00
// We use the texture coordinate array in texture0 for
// both the base and the overlay texture
2014-10-08 17:35:55 +00:00
glClientActiveTexture ( GL_TEXTURE0 ) ; // pTex was loaded in tex0 by SetupMultiBlt
glEnableClientState ( GL_TEXTURE_COORD_ARRAY ) ;
glTexCoordPointer ( 2 , GL_FLOAT , sizeof ( C4BltVertex ) , & vertices [ 0 ] . tx ) ;
}
glVertexPointer ( 2 , GL_FLOAT , sizeof ( C4BltVertex ) , & vertices [ 0 ] . ftx ) ;
glColorPointer ( 4 , GL_UNSIGNED_BYTE , sizeof ( C4BltVertex ) , & vertices [ 0 ] . color [ 0 ] ) ;
glDrawArrays ( GL_TRIANGLES , 0 , n_vertices ) ;
if ( pTex ) glDisableClientState ( GL_TEXTURE_COORD_ARRAY ) ;
glDisableClientState ( GL_VERTEX_ARRAY ) ;
glDisableClientState ( GL_COLOR_ARRAY ) ;
2014-11-07 20:28:52 +00:00
ResetMultiBlt ( pTex ? pTex - > texName : 0 , pOverlay ? pOverlay - > texName : 0 , pNormal ? pNormal - > texName : 0 ) ;
2014-10-08 17:35:55 +00:00
}
2009-05-08 13:28:41 +00:00
bool CStdGL : : RestoreDeviceObjects ( )
2010-03-28 18:58:01 +00:00
{
2010-03-06 14:07:30 +00:00
assert ( pMainCtx ) ;
2009-05-08 13:28:41 +00:00
// delete any previous objects
InvalidateDeviceObjects ( ) ;
2010-02-18 20:19:04 +00:00
2010-03-06 14:07:30 +00:00
// set states
Active = pMainCtx - > Select ( ) ;
RenderTarget = pApp - > pWindow - > pSurface ;
2014-11-02 21:57:28 +00:00
// TODO: I think this should be updated. We need at least GLSL shaders now, which I think is OpenGL 2.0(?)
2010-03-06 14:07:30 +00:00
// BGRA Pixel Formats, Multitexturing, Texture Combine Environment Modes
2012-03-03 22:25:50 +00:00
// Check for GL 1.2 and two functions from 1.3 we need.
if ( ! GLEW_VERSION_1_2 | |
glActiveTexture = = NULL | |
glClientActiveTexture = = NULL
) {
2010-08-03 17:02:00 +00:00
return Error ( " gl: OpenGL Version 1.3 or higher required. A better graphics driver will probably help. " ) ;
2010-03-28 18:58:01 +00:00
}
2010-03-06 14:07:30 +00:00
2010-02-18 20:19:04 +00:00
// lines texture
glPixelStorei ( GL_UNPACK_ALIGNMENT , 1 ) ;
glGenTextures ( 1 , & lines_tex ) ;
glBindTexture ( GL_TEXTURE_2D , lines_tex ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_S , GL_MIRRORED_REPEAT ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , GL_MIRRORED_REPEAT ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR ) ;
const char * linedata = byByteCnt = = 2 ? " \xff \xf0 \xff \xff " : " \xff \xff \xff \x00 \xff \xff \xff \xff " ;
glTexImage2D ( GL_TEXTURE_2D , 0 , 4 , 1 , 2 , 0 , GL_BGRA , byByteCnt = = 2 ? GL_UNSIGNED_SHORT_4_4_4_4_REV : GL_UNSIGNED_INT_8_8_8_8_REV , linedata ) ;
MaxTexSize = 64 ;
GLint s = 0 ;
glGetIntegerv ( GL_MAX_TEXTURE_SIZE , & s ) ;
if ( s > 0 ) MaxTexSize = s ;
2009-05-08 13:28:41 +00:00
// restore gamma if active
if ( Active )
EnableGamma ( ) ;
// reset blit states
dwBlitMode = 0 ;
2014-10-08 01:48:11 +00:00
// The following shaders are used for drawing primitives such as points, lines and sprites.
2014-11-02 21:57:28 +00:00
// They are used in PerformMultiPix, PerformMultiLines and PerformMultiTris.
2014-10-08 01:48:11 +00:00
// The fragment shader applies the color modulation, mod2 drawing and the color modulation map
// on top of the original fragment color.
// The vertex shader does not do anything special, but it delegates input values to the
// fragment shader.
2014-11-02 01:46:30 +00:00
// TODO: It might be more efficient to use separate shaders for pixels, lines and tris.
2014-10-08 01:48:11 +00:00
const char * vertex_shader_text =
" varying vec2 texcoord; "
" void main() "
" { "
" texcoord = gl_MultiTexCoord0.xy; "
" gl_FrontColor = gl_Color; "
" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; "
" } " ;
const char * fragment_shader_text =
" uniform int fMod2; "
2014-11-06 16:19:41 +00:00
" uniform int fUseLight; "
2014-10-08 01:48:11 +00:00
" uniform int fUseTexture; "
2014-11-02 01:46:30 +00:00
" uniform int fUseOverlay; "
2014-11-07 20:28:52 +00:00
" uniform int fUseNormal; "
2014-10-08 01:48:11 +00:00
" uniform vec4 clrMod; "
2014-11-02 01:46:30 +00:00
" uniform vec4 overlayClrMod; "
2014-11-19 16:18:07 +00:00
" uniform float ambientBrightness; "
2014-10-08 01:48:11 +00:00
" uniform sampler2D Texture; "
2014-11-02 01:46:30 +00:00
" uniform sampler2D Overlay; "
2014-11-06 16:19:41 +00:00
" uniform sampler2D Light; "
2014-11-17 14:35:50 +00:00
" uniform sampler2D Ambient; "
2014-11-07 20:28:52 +00:00
" uniform sampler2D Normal; "
2014-10-08 01:48:11 +00:00
" varying vec2 texcoord; "
" void main() "
" { "
2014-11-07 16:53:10 +00:00
// Start with the base color
" vec4 primaryColor = gl_Color; "
// Get texture
2014-10-08 01:48:11 +00:00
" if(fUseTexture != 0) "
2014-10-08 04:21:05 +00:00
" primaryColor = primaryColor * texture2D(Texture, texcoord); "
2014-11-07 16:53:10 +00:00
// Get overlay, if any
" vec4 overlayColor = vec4(1.0, 1.0, 1.0, 0.0); "
" if(fUseOverlay != 0) "
" overlayColor = gl_Color * texture2D(Overlay, texcoord); "
// Mix base with overlay, and apply clrmod (separately for base and overlay)
" primaryColor.rgb = overlayColor.a * overlayClrMod.rgb * overlayColor.rgb + (1.0 - overlayColor.a) * clrMod.rgb * primaryColor.rgb; "
2014-11-02 02:45:14 +00:00
// Add alpha for base and overlay, and use weighted mean of clrmod alpha
2014-11-07 16:53:10 +00:00
" primaryColor.a = clamp(primaryColor.a + overlayColor.a, 0.0, 1.0) * (primaryColor.a * clrMod.a + overlayColor.a * overlayClrMod.a) / (primaryColor.a + overlayColor.a); "
// Add fog of war (light)
2014-11-17 14:35:50 +00:00
" vec3 lightClr = vec3(1.0, 1.0, 1.0); "
2014-11-07 16:53:10 +00:00
" if(fUseLight != 0) "
" { "
" vec4 lightPx = texture2D(Light, (gl_TextureMatrix[2] * gl_FragCoord).xy); "
2014-11-17 14:35:50 +00:00
" vec3 lightDir = normalize(vec3(vec2(1.0, 1.0) - lightPx.gb * 3.0, 0.3)); "
" float lightIntensity = 2.0 * lightPx.r; "
" vec3 normalDir; "
2014-11-07 20:28:52 +00:00
" if(fUseNormal != 0) "
" { "
" vec4 normalPx = texture2D(Normal, texcoord); "
" normalDir = normalize(vec3( (normalPx.xy - vec2(0.5, 0.5))*2.0, 0.3)); "
" } "
" else "
" { "
" normalDir = vec3(0.0, 0.0, 1.0); "
" } "
2014-11-19 16:18:07 +00:00
" float ambient = texture2D(Ambient, (gl_TextureMatrix[3] * gl_FragCoord).xy).r * ambientBrightness; "
" lightClr = ambient * lightClr + (1.0 - min(ambient, 1.0)) * vec3(1.0, 1.0, 1.0) * lightIntensity * (0.25 + 0.75 * dot(normalDir, lightDir)); "
2014-11-07 16:53:10 +00:00
" } "
// Final output, depending on blit mode
2014-10-08 01:48:11 +00:00
" if(fMod2 != 0) "
2014-11-17 14:35:50 +00:00
" gl_FragColor = clamp(2.0 * primaryColor * vec4(lightClr, 1.0) - 0.5, 0.0, 1.0); "
2014-10-08 01:48:11 +00:00
" else "
2014-11-17 14:35:50 +00:00
" gl_FragColor = clamp(primaryColor * vec4(lightClr, 1.0), 0.0, 1.0); "
2014-10-08 01:48:11 +00:00
" } " ;
C4DrawGLShader vertex_shader ( StdMeshMaterialShader : : VERTEX ) ;
vertex_shader . Load ( vertex_shader_text ) ;
C4DrawGLShader fragment_shader ( StdMeshMaterialShader : : FRAGMENT ) ;
fragment_shader . Load ( fragment_shader_text ) ;
multi_blt_program . reset ( new C4DrawGLProgram ( & fragment_shader , & vertex_shader , NULL ) ) ;
2009-05-08 13:28:41 +00:00
// done
return Active ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool CStdGL : : InvalidateDeviceObjects ( )
{
bool fSuccess = true ;
// clear gamma
2010-03-28 18:58:01 +00:00
# ifndef USE_SDL_MAINLOOP
2009-05-08 13:28:41 +00:00
DisableGamma ( ) ;
2010-03-28 18:58:01 +00:00
# endif
2009-05-08 13:28:41 +00:00
// deactivate
Active = false ;
2014-10-08 01:48:11 +00:00
multi_blt_program . reset ( NULL ) ;
2009-05-08 13:28:41 +00:00
// invalidate font objects
// invalidate primary surfaces
2010-02-18 20:19:04 +00:00
if ( lines_tex )
2010-03-28 18:58:01 +00:00
{
2010-02-18 20:19:04 +00:00
glDeleteTextures ( 1 , & lines_tex ) ;
lines_tex = 0 ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
return fSuccess ;
}
2014-01-03 14:13:09 +00:00
bool CStdGL : : EnsureAnyContext ( )
{
// Make sure some context is selected
if ( pCurrCtx ) return true ;
if ( ! pMainCtx ) return false ;
return pMainCtx - > Select ( ) ;
}
2010-08-03 17:02:00 +00:00
bool CStdGL : : Error ( const char * szMsg )
{
2012-06-06 15:13:51 +00:00
# ifdef USE_WIN32_WINDOWS
DWORD err = GetLastError ( ) ;
# endif
2012-06-06 14:49:40 +00:00
bool r = C4Draw : : Error ( szMsg ) ;
# ifdef USE_WIN32_WINDOWS
wchar_t * lpMsgBuf ;
FormatMessage (
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS ,
NULL ,
err ,
MAKELANGID ( LANG_NEUTRAL , SUBLANG_DEFAULT ) ,
( LPTSTR ) & lpMsgBuf ,
0 , NULL ) ;
LogF ( " gl: GetLastError() = %d - %s " , err , StdStrBuf ( lpMsgBuf ) . getData ( ) ) ;
LocalFree ( lpMsgBuf ) ;
# endif
2010-08-03 17:02:00 +00:00
LogF ( " gl: %s " , glGetString ( GL_VENDOR ) ) ;
LogF ( " gl: %s " , glGetString ( GL_RENDERER ) ) ;
LogF ( " gl: %s " , glGetString ( GL_VERSION ) ) ;
LogF ( " gl: %s " , glGetString ( GL_EXTENSIONS ) ) ;
2012-06-06 14:49:40 +00:00
return r ;
2010-08-03 17:02:00 +00:00
}
2009-05-08 13:28:41 +00:00
bool CStdGL : : CheckGLError ( const char * szAtOp )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
GLenum err = glGetError ( ) ;
if ( ! err ) return true ;
2014-11-24 18:42:15 +00:00
LogF ( " GL error with %s: %d - %s " , szAtOp , err , gluErrorString ( err ) ) ;
2010-03-28 18:58:01 +00:00
return false ;
}
2009-05-08 13:28:41 +00:00
CStdGL * pGL = NULL ;
2012-04-07 19:33:39 +00:00
# ifdef USE_WIN32_WINDOWS
2009-05-08 13:28:41 +00:00
void CStdGL : : TaskOut ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
if ( pCurrCtx ) pCurrCtx - > Deselect ( ) ;
2010-03-28 18:58:01 +00:00
}
2010-09-05 13:07:45 +00:00
# endif
2009-05-08 13:28:41 +00:00
bool CStdGL : : OnResolutionChanged ( unsigned int iXRes , unsigned int iYRes )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Re-create primary clipper to adapt to new size.
CreatePrimaryClipper ( iXRes , iYRes ) ;
2010-02-18 20:19:04 +00:00
RestoreDeviceObjects ( ) ;
2009-05-08 13:28:41 +00:00
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void CStdGL : : Default ( )
2010-03-28 18:58:01 +00:00
{
2011-10-03 14:34:08 +00:00
C4Draw : : Default ( ) ;
2010-03-06 14:07:30 +00:00
pCurrCtx = NULL ;
2009-05-08 13:28:41 +00:00
iPixelFormat = 0 ;
sfcFmt = 0 ;
iClrDpt = 0 ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2013-10-29 13:27:18 +00:00
# endif // USE_CONSOLE