diff options
author | Andrey Nazarov <skuller@skuller.net> | 2007-08-14 20:18:08 +0000 |
---|---|---|
committer | Andrey Nazarov <skuller@skuller.net> | 2007-08-14 20:18:08 +0000 |
commit | f294db4ccf45f6274e65260dd6f9a2c5faa94313 (patch) | |
tree | e8cf1ba2bfe9c8417eec17faf912442f52fc4ef2 /source/gl_state.c |
Initial import of the new Q2PRO tree.
Diffstat (limited to 'source/gl_state.c')
-rw-r--r-- | source/gl_state.c | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/source/gl_state.c b/source/gl_state.c new file mode 100644 index 0000000..6dbfbae --- /dev/null +++ b/source/gl_state.c @@ -0,0 +1,216 @@ +/* +Copyright (C) 2003-2006 Andrey Nazarov + +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 "gl_local.h" + +glState_t gls; + +void GL_BindTexture( int texnum ) { + if( gls.texnum[gls.tmu] == texnum ) { + return; + } + + qglBindTexture( GL_TEXTURE_2D, texnum ); + c.texSwitches++; + gls.texnum[gls.tmu] = texnum; +} + +void GL_SelectTMU( int tmu ) { + if( gls.tmu == tmu ) { + return; + } + + if( tmu < 0 || tmu >= gl_static.numTextureUnits ) { + Com_Error( ERR_FATAL, "GL_SelectTMU: bad tmu %d", tmu ); + } + + qglActiveTextureARB( GL_TEXTURE0_ARB + tmu ); + qglClientActiveTextureARB( GL_TEXTURE0_ARB + tmu ); + + gls.tmu = tmu; +} + +void GL_TexEnv( GLenum texenv ) { + if( gls.texenv[gls.tmu] == texenv ) { + return; + } + + switch( texenv ) { + case GL_REPLACE: + qglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); + break; + case GL_MODULATE: + qglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + break; + case GL_BLEND: + qglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND ); + break; + case GL_ADD: + qglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD ); + break; + default: + Com_Error( ERR_FATAL, "GL_TexEnv: bad texenv" ); + break; + } + + gls.texenv[gls.tmu] = texenv; +} + +void GL_CullFace( glCullFace_t cull ) { + if( gls.cull == cull ) { + return; + } + switch( cull ) { + case GLS_CULL_DISABLE: + qglDisable( GL_CULL_FACE ); + break; + case GLS_CULL_FRONT: + qglEnable( GL_CULL_FACE ); + qglCullFace( GL_FRONT ); + break; + case GLS_CULL_BACK: + qglEnable( GL_CULL_FACE ); + qglCullFace( GL_BACK ); + break; + default: + Com_Error( ERR_FATAL, "GL_CullFace: bad cull" ); + break; + } + + gls.cull = cull; +} + +void GL_Bits( glStateBits_t bits ) { + glStateBits_t diff = bits ^ gls.bits; + + if( !diff ) { + return; + } + + if( diff & GLS_BLEND_MASK ) { + if( bits & GLS_BLEND_MASK ) { + qglEnable( GL_BLEND ); + if( bits & GLS_BLEND_BLEND ) { + qglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + } else if( bits & GLS_BLEND_ADD ) { + qglBlendFunc( GL_SRC_ALPHA, GL_ONE ); + } else if( bits & GLS_BLEND_MODULATE ) { + qglBlendFunc( GL_DST_COLOR, GL_ONE ); + } + } else { + qglDisable( GL_BLEND ); + } + } + + if( diff & GLS_DEPTHMASK_FALSE ) { + if( bits & GLS_DEPTHMASK_FALSE ) { + qglDepthMask( GL_FALSE ); + } else { + qglDepthMask( GL_TRUE ); + } + } + + if( diff & GLS_DEPTHTEST_DISABLE ) { + if( bits & GLS_DEPTHTEST_DISABLE ) { + qglDisable( GL_DEPTH_TEST ); + } else { + qglEnable( GL_DEPTH_TEST ); + } + } + + if( diff & GLS_ALPHATEST_ENABLE ) { + if( bits & GLS_ALPHATEST_ENABLE ) { + qglEnable( GL_ALPHA_TEST ); + } else { + qglDisable( GL_ALPHA_TEST ); + } + } + + gls.bits = bits; +} + +void GL_Setup2D( void ) { + qglViewport( 0, 0, gl_config.vidWidth, gl_config.vidHeight ); + + qglMatrixMode( GL_PROJECTION ); + qglLoadIdentity(); + + qglOrtho( 0, gl_config.vidWidth, gl_config.vidHeight, 0, -1, 1 ); + draw.scale = 1; + + *( uint32 * )draw.color = *( uint32 * )colorWhite; + + if( draw.flags & DRAW_CLIP_MASK ) { + qglDisable( GL_SCISSOR_TEST ); + } + + draw.flags = 0; + + qglMatrixMode( GL_MODELVIEW ); + qglLoadIdentity(); + + GL_Bits( GLS_DEPTHTEST_DISABLE ); + GL_CullFace( GLS_CULL_DISABLE ); +} + +static inline void MYgluPerspective( GLdouble fovy, GLdouble aspect, + GLdouble zNear, GLdouble zFar ) +{ + GLdouble xmin, xmax, ymin, ymax; + + ymax = zNear * tan( fovy * M_PI / 360.0 ); + ymin = -ymax; + + xmin = ymin * aspect; + xmax = ymax * aspect; + + qglFrustum( xmin, xmax, ymin, ymax, zNear, zFar ); +} + +void GL_Setup3D( void ) { + float screenAspect; + int yb; + + yb = glr.fd.y + glr.fd.height; + qglViewport( glr.fd.x, gl_config.vidHeight - yb, + glr.fd.width, glr.fd.height ); + + screenAspect = ( float )glr.fd.width / glr.fd.height; + qglMatrixMode( GL_PROJECTION ); + qglLoadIdentity(); + MYgluPerspective( glr.fd.fov_y, screenAspect, + gl_znear->value, gl_zfar->value ); + + qglMatrixMode( GL_MODELVIEW ); + qglLoadIdentity(); + + qglRotatef( -90, 1, 0, 0 ); /* put z axis up */ + qglRotatef( 90, 0, 0, 1 ); /* put y axis west, x axis north */ + qglRotatef( -glr.fd.viewangles[ROLL], 1, 0, 0 ); + qglRotatef( -glr.fd.viewangles[PITCH], 0, 1, 0 ); + qglRotatef( -glr.fd.viewangles[YAW], 0, 0, 1 ); + qglTranslatef( -glr.fd.vieworg[0], -glr.fd.vieworg[1], -glr.fd.vieworg[2] ); + + GL_Bits( GLS_DEFAULT ); + GL_CullFace( GLS_CULL_FRONT ); + + qglClear( GL_DEPTH_BUFFER_BIT ); +} + |