tenebrae2/gl_bumpradeon.c
2004-03-24 00:20:38 +00:00

1495 lines
56 KiB
C

/*
Copyright (C) 2001-2002 Charles Hollemeersch
Radeon Version (C) 2002-2003 Jarno Paananen
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.
PENTA: the whole file is freakin penta...
Same as gl_bumpmap.c but Radeon 8500+ optimized
These routines require 6 texture units, vertex shader and pixel shader
This could be further optimized for Radeon 9700 (specular exponent for
example), but would need better documentation and extension.
All lights not require only 1 pass:
1 diffuse + specular with optional light filter
*/
#include "quakedef.h"
#include "glATI.h"
PFNGLGENFRAGMENTSHADERSATIPROC qglGenFragmentShadersATI = NULL;
PFNGLBINDFRAGMENTSHADERATIPROC qglBindFragmentShaderATI = NULL;
PFNGLDELETEFRAGMENTSHADERATIPROC qglDeleteFragmentShaderATI = NULL;
PFNGLBEGINFRAGMENTSHADERATIPROC qglBeginFragmentShaderATI = NULL;
PFNGLENDFRAGMENTSHADERATIPROC qglEndFragmentShaderATI = NULL;
PFNGLPASSTEXCOORDATIPROC qglPassTexCoordATI = NULL;
PFNGLSAMPLEMAPATIPROC qglSampleMapATI = NULL;
PFNGLCOLORFRAGMENTOP1ATIPROC qglColorFragmentOp1ATI = NULL;
PFNGLCOLORFRAGMENTOP2ATIPROC qglColorFragmentOp2ATI = NULL;
PFNGLCOLORFRAGMENTOP3ATIPROC qglColorFragmentOp3ATI = NULL;
PFNGLALPHAFRAGMENTOP1ATIPROC qglAlphaFragmentOp1ATI = NULL;
PFNGLALPHAFRAGMENTOP2ATIPROC qglAlphaFragmentOp2ATI = NULL;
PFNGLALPHAFRAGMENTOP3ATIPROC qglAlphaFragmentOp3ATI = NULL;
PFNGLSETFRAGMENTSHADERCONSTANTATIPROC qglSetFragmentShaderConstantATI = NULL;
PFNGLBEGINVERTEXSHADEREXTPROC qglBeginVertexShaderEXT = NULL;
PFNGLENDVERTEXSHADEREXTPROC qglEndVertexShaderEXT = NULL;
PFNGLBINDVERTEXSHADEREXTPROC qglBindVertexShaderEXT = NULL;
PFNGLGENVERTEXSHADERSEXTPROC qglGenVertexShadersEXT = NULL;
PFNGLDELETEVERTEXSHADEREXTPROC qglDeleteVertexShaderEXT = NULL;
PFNGLSHADEROP1EXTPROC qglShaderOp1EXT = NULL;
PFNGLSHADEROP2EXTPROC qglShaderOp2EXT = NULL;
PFNGLSHADEROP3EXTPROC qglShaderOp3EXT = NULL;
PFNGLSWIZZLEEXTPROC qglSwizzleEXT = NULL;
PFNGLWRITEMASKEXTPROC qglWriteMaskEXT = NULL;
PFNGLINSERTCOMPONENTEXTPROC qglInsertComponentEXT = NULL;
PFNGLEXTRACTCOMPONENTEXTPROC qglExtractComponentEXT = NULL;
PFNGLGENSYMBOLSEXTPROC qglGenSymbolsEXT = NULL;
PFNGLSETINVARIANTEXTPROC qglSetInvariantEXT = NULL;
PFNGLSETLOCALCONSTANTEXTPROC qglSetLocalConstantEXT = NULL;
PFNGLVARIANTBVEXTPROC qglVariantbvEXT = NULL;
PFNGLVARIANTSVEXTPROC qglVariantsvEXT = NULL;
PFNGLVARIANTIVEXTPROC qglVariantivEXT = NULL;
PFNGLVARIANTFVEXTPROC qglVariantfvEXT = NULL;
PFNGLVARIANTDVEXTPROC qglVariantdvEXT = NULL;
PFNGLVARIANTUBVEXTPROC qglVariantubvEXT = NULL;
PFNGLVARIANTUSVEXTPROC qglVariantusvEXT = NULL;
PFNGLVARIANTUIVEXTPROC qglVariantuivEXT = NULL;
PFNGLVARIANTPOINTEREXTPROC qglVariantPointerEXT = NULL;
PFNGLENABLEVARIANTCLIENTSTATEEXTPROC qglEnableVariantClientStateEXT = NULL;
PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC qglDisableVariantClientStateEXT = NULL;
PFNGLBINDLIGHTPARAMETEREXTPROC qglBindLightParameterEXT = NULL;
PFNGLBINDMATERIALPARAMETEREXTPROC qglBindMaterialParameterEXT = NULL;
PFNGLBINDTEXGENPARAMETEREXTPROC qglBindTexGenParameterEXT = NULL;
PFNGLBINDTEXTUREUNITPARAMETEREXTPROC qglBindTextureUnitParameterEXT = NULL;
PFNGLBINDPARAMETEREXTPROC qglBindParameterEXT = NULL;
PFNGLISVARIANTENABLEDEXTPROC qglIsVariantEnabledEXT = NULL;
PFNGLGETVARIANTBOOLEANVEXTPROC qglGetVariantBooleanvEXT = NULL;
PFNGLGETVARIANTINTEGERVEXTPROC qglGetVariantIntegervEXT = NULL;
PFNGLGETVARIANTFLOATVEXTPROC qglGetVariantFloatvEXT = NULL;
PFNGLGETVARIANTPOINTERVEXTPROC qglGetVariantPointervEXT = NULL;
PFNGLGETINVARIANTBOOLEANVEXTPROC qglGetInvariantBooleanvEXT = NULL;
PFNGLGETINVARIANTINTEGERVEXTPROC qglGetInvariantIntegervEXT = NULL;
PFNGLGETINVARIANTFLOATVEXTPROC qglGetInvariantFloatvEXT = NULL;
PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC qglGetLocalConstantBooleanvEXT = NULL;
PFNGLGETLOCALCONSTANTINTEGERVEXTPROC qglGetLocalConstantIntegervEXT = NULL;
PFNGLGETLOCALCONSTANTFLOATVEXTPROC qglGetLocalConstantFloatvEXT = NULL;
PFNGLPNTRIANGLESIATIPROC qglPNTrianglesiATI = NULL;
PFNGLPNTRIANGLESFATIPROC qglPNTrianglesfATI = NULL;
PFNGLSTENCILOPSEPARATEATIPROC qglStencilOpSeparateATI = NULL;
PFNGLSTENCILFUNCSEPARATEATIPROC qglStencilFuncSeparateATI = NULL;
static unsigned int fragment_shaders;
static unsigned int vertex_shaders;
static GLuint lightPos, eyePos; // vertex shader constants
//#define RADEONDEBUG
#ifdef RADEONDEBUG
void Radeon_checkerror()
{
GLuint error = glGetError();
if ( error != GL_NO_ERROR )
{
_asm { int 3 };
}
}
#else
#define Radeon_checkerror() do { } while(0)
#endif
// <AWE> We look up the symbols here, this way we don't need to prototype all the "qgl" functions!
#if defined (__APPLE__) || defined (MACOSX)
extern void * GL_GetProcAddress (const char *theName, qboolean theSafeMode);
qboolean Radeon_LookupSymbols (void)
{
qglGenFragmentShadersATI = GL_GetProcAddress ("glGenFragmentShadersATI", false);
qglBindFragmentShaderATI = GL_GetProcAddress ("glBindFragmentShaderATI", false);
qglDeleteFragmentShaderATI = GL_GetProcAddress ("glDeleteFragmentShaderATI", false);
qglBeginFragmentShaderATI = GL_GetProcAddress ("glBeginFragmentShaderATI", false);
qglEndFragmentShaderATI = GL_GetProcAddress ("glEndFragmentShaderATI", false);
qglPassTexCoordATI = GL_GetProcAddress ("glPassTexCoordATI", false);
qglSampleMapATI = GL_GetProcAddress ("glSampleMapATI", false);
qglColorFragmentOp1ATI = GL_GetProcAddress ("glColorFragmentOp1ATI", false);
qglColorFragmentOp2ATI = GL_GetProcAddress ("glColorFragmentOp2ATI", false);
qglColorFragmentOp3ATI = GL_GetProcAddress ("glColorFragmentOp3ATI", false);
qglAlphaFragmentOp1ATI = GL_GetProcAddress ("glAlphaFragmentOp1ATI", false);
qglAlphaFragmentOp2ATI = GL_GetProcAddress ("glAlphaFragmentOp2ATI", false);
qglAlphaFragmentOp3ATI = GL_GetProcAddress ("glAlphaFragmentOp3ATI", false);
qglSetFragmentShaderConstantATI = GL_GetProcAddress ("glSetFragmentShaderConstantATI", false);
qglBeginVertexShaderEXT = GL_GetProcAddress ("glBeginVertexShaderEXT", false);
qglEndVertexShaderEXT = GL_GetProcAddress ("glEndVertexShaderEXT", false);
qglBindVertexShaderEXT = GL_GetProcAddress ("glBindVertexShaderEXT", false);
qglGenVertexShadersEXT = GL_GetProcAddress ("glGenVertexShadersEXT", false);
qglDeleteVertexShaderEXT = GL_GetProcAddress ("glDeleteVertexShaderEXT", false);
qglShaderOp1EXT = GL_GetProcAddress ("glShaderOp1EXT", false);
qglShaderOp2EXT = GL_GetProcAddress ("glShaderOp2EXT", false);
qglShaderOp3EXT = GL_GetProcAddress ("glShaderOp3EXT", false);
qglSwizzleEXT = GL_GetProcAddress ("glSwizzleEXT", false);
qglWriteMaskEXT = GL_GetProcAddress ("glWriteMaskEXT", false);
qglInsertComponentEXT = GL_GetProcAddress ("glInsertComponentEXT", false);
qglExtractComponentEXT = GL_GetProcAddress ("glExtractComponentEXT", false);
qglGenSymbolsEXT = GL_GetProcAddress ("glGenSymbolsEXT", false);
qglSetInvariantEXT = GL_GetProcAddress ("glSetInvariantEXT", false);
qglSetLocalConstantEXT = GL_GetProcAddress ("glSetLocalConstantEXT", false);
qglVariantbvEXT = GL_GetProcAddress ("glVariantbvEXT", false);
qglVariantsvEXT = GL_GetProcAddress ("glVariantsvEXT", false);
qglVariantivEXT = GL_GetProcAddress ("glVariantivEXT", false);
qglVariantfvEXT = GL_GetProcAddress ("glVariantfvEXT", false);
qglVariantdvEXT = GL_GetProcAddress ("glVariantdvEXT", false);
qglVariantubvEXT = GL_GetProcAddress ("glVariantubvEXT", false);
qglVariantusvEXT = GL_GetProcAddress ("glVariantusvEXT", false);
qglVariantuivEXT = GL_GetProcAddress ("glVariantuivEXT", false);
qglVariantPointerEXT = GL_GetProcAddress ("glVariantPointerEXT", false);
qglEnableVariantClientStateEXT = GL_GetProcAddress ("glEnableVariantClientStateEXT", false);
qglDisableVariantClientStateEXT = GL_GetProcAddress ("glDisableVariantClientStateEXT", false);
qglBindLightParameterEXT = GL_GetProcAddress ("glBindLightParameterEXT", false);
qglBindMaterialParameterEXT = GL_GetProcAddress ("glBindMaterialParameterEXT", false);
qglBindTexGenParameterEXT = GL_GetProcAddress ("glBindTexGenParameterEXT", false);
qglBindTextureUnitParameterEXT = GL_GetProcAddress ("glBindTextureUnitParameterEXT", false);
qglBindParameterEXT = GL_GetProcAddress ("glBindParameterEXT", false);
qglIsVariantEnabledEXT = GL_GetProcAddress ("glIsVariantEnabledEXT", false);
qglGetVariantBooleanvEXT = GL_GetProcAddress ("glGetVariantBooleanvEXT", false);
qglGetVariantIntegervEXT = GL_GetProcAddress ("glGetVariantIntegervEXT", false);
qglGetVariantFloatvEXT = GL_GetProcAddress ("glGetVariantFloatvEXT", false);
qglGetVariantPointervEXT = GL_GetProcAddress ("glGetVariantPointervEXT", false);
qglGetInvariantBooleanvEXT = GL_GetProcAddress ("glGetInvariantBooleanvEXT", false);
qglGetInvariantIntegervEXT = GL_GetProcAddress ("glGetInvariantIntegervEXT", false);
qglGetInvariantFloatvEXT = GL_GetProcAddress ("glGetInvariantFloatvEXT", false);
qglGetLocalConstantBooleanvEXT = GL_GetProcAddress ("glGetLocalConstantBooleanvEXT", false);
qglGetLocalConstantIntegervEXT = GL_GetProcAddress ("glGetLocalConstantIntegervEXT", false);
qglGetLocalConstantFloatvEXT = GL_GetProcAddress ("glGetLocalConstantFloatvEXT", false);
if (qglGenFragmentShadersATI != NULL &&
qglBindFragmentShaderATI != NULL &&
qglDeleteFragmentShaderATI != NULL &&
qglBeginFragmentShaderATI != NULL &&
qglEndFragmentShaderATI != NULL &&
qglPassTexCoordATI != NULL &&
qglSampleMapATI != NULL &&
qglColorFragmentOp1ATI != NULL &&
qglColorFragmentOp2ATI != NULL &&
qglColorFragmentOp3ATI != NULL &&
qglAlphaFragmentOp1ATI != NULL &&
qglAlphaFragmentOp2ATI != NULL &&
qglAlphaFragmentOp3ATI != NULL &&
qglSetFragmentShaderConstantATI != NULL &&
qglBeginVertexShaderEXT != NULL &&
qglEndVertexShaderEXT != NULL &&
qglBindVertexShaderEXT != NULL &&
qglGenVertexShadersEXT != NULL &&
qglDeleteVertexShaderEXT != NULL &&
qglShaderOp1EXT != NULL &&
qglShaderOp2EXT != NULL &&
qglShaderOp3EXT != NULL &&
qglSwizzleEXT != NULL &&
qglWriteMaskEXT != NULL &&
qglInsertComponentEXT != NULL &&
qglExtractComponentEXT != NULL &&
qglGenSymbolsEXT != NULL &&
qglSetInvariantEXT != NULL &&
qglSetLocalConstantEXT != NULL &&
qglVariantbvEXT != NULL &&
qglVariantsvEXT != NULL &&
qglVariantivEXT != NULL &&
qglVariantfvEXT != NULL &&
qglVariantdvEXT != NULL &&
qglVariantubvEXT != NULL &&
qglVariantusvEXT != NULL &&
qglVariantuivEXT != NULL &&
qglVariantPointerEXT != NULL &&
qglEnableVariantClientStateEXT != NULL &&
qglDisableVariantClientStateEXT != NULL &&
qglBindLightParameterEXT != NULL &&
qglBindMaterialParameterEXT != NULL &&
qglBindTexGenParameterEXT != NULL &&
qglBindTextureUnitParameterEXT != NULL &&
qglBindParameterEXT != NULL &&
qglIsVariantEnabledEXT != NULL &&
qglGetVariantBooleanvEXT != NULL &&
qglGetVariantIntegervEXT != NULL &&
qglGetVariantFloatvEXT != NULL &&
qglGetVariantPointervEXT != NULL &&
qglGetInvariantBooleanvEXT != NULL &&
qglGetInvariantIntegervEXT != NULL &&
qglGetInvariantFloatvEXT != NULL &&
qglGetLocalConstantBooleanvEXT != NULL &&
qglGetLocalConstantIntegervEXT != NULL &&
qglGetLocalConstantFloatvEXT != NULL)
{
return (true);
}
return (false);
}
#endif /* __APPLE__ || MACOSX */
void Radeon_CreateShaders()
{
float scaler[4] = {0.5f, 0.5f, 0.5f, 0.5f};
int i;
GLuint mvp, modelview, zcomp, tempvec;
GLuint texturematrix, texturematrix2;
GLuint vertex;
GLuint texcoord0;
GLuint texcoord1;
GLuint texcoord2;
GLuint texcoord3;
GLuint color;
GLuint supportedTmu;
GLuint disttemp, disttemp2;
GLuint fogstart, fogend;
#if !defined(__APPLE__) && !defined (MACOSX)
SAFE_GET_PROC( qglGenFragmentShadersATI, PFNGLGENFRAGMENTSHADERSATIPROC, "glGenFragmentShadersATI");
SAFE_GET_PROC( qglBindFragmentShaderATI, PFNGLBINDFRAGMENTSHADERATIPROC, "glBindFragmentShaderATI");
SAFE_GET_PROC( qglDeleteFragmentShaderATI, PFNGLDELETEFRAGMENTSHADERATIPROC, "glDeleteFragmentShaderATI");
SAFE_GET_PROC( qglBeginFragmentShaderATI, PFNGLBEGINFRAGMENTSHADERATIPROC, "glBeginFragmentShaderATI");
SAFE_GET_PROC( qglEndFragmentShaderATI, PFNGLENDFRAGMENTSHADERATIPROC, "glEndFragmentShaderATI");
SAFE_GET_PROC( qglPassTexCoordATI, PFNGLPASSTEXCOORDATIPROC, "glPassTexCoordATI");
SAFE_GET_PROC( qglSampleMapATI, PFNGLSAMPLEMAPATIPROC, "glSampleMapATI");
SAFE_GET_PROC( qglColorFragmentOp1ATI, PFNGLCOLORFRAGMENTOP1ATIPROC, "glColorFragmentOp1ATI");
SAFE_GET_PROC( qglColorFragmentOp2ATI, PFNGLCOLORFRAGMENTOP2ATIPROC, "glColorFragmentOp2ATI");
SAFE_GET_PROC( qglColorFragmentOp3ATI, PFNGLCOLORFRAGMENTOP3ATIPROC, "glColorFragmentOp3ATI");
SAFE_GET_PROC( qglAlphaFragmentOp1ATI, PFNGLALPHAFRAGMENTOP1ATIPROC, "glAlphaFragmentOp1ATI");
SAFE_GET_PROC( qglAlphaFragmentOp2ATI, PFNGLALPHAFRAGMENTOP2ATIPROC, "glAlphaFragmentOp2ATI");
SAFE_GET_PROC( qglAlphaFragmentOp3ATI, PFNGLALPHAFRAGMENTOP3ATIPROC, "glAlphaFragmentOp3ATI");
SAFE_GET_PROC( qglSetFragmentShaderConstantATI, PFNGLSETFRAGMENTSHADERCONSTANTATIPROC, "glSetFragmentShaderConstantATI");
SAFE_GET_PROC( qglBeginVertexShaderEXT, PFNGLBEGINVERTEXSHADEREXTPROC, "glBeginVertexShaderEXT");
SAFE_GET_PROC( qglEndVertexShaderEXT, PFNGLENDVERTEXSHADEREXTPROC, "glEndVertexShaderEXT");
SAFE_GET_PROC( qglBindVertexShaderEXT, PFNGLBINDVERTEXSHADEREXTPROC, "glBindVertexShaderEXT");
SAFE_GET_PROC( qglGenVertexShadersEXT, PFNGLGENVERTEXSHADERSEXTPROC, "glGenVertexShadersEXT");
SAFE_GET_PROC( qglDeleteVertexShaderEXT, PFNGLDELETEVERTEXSHADEREXTPROC, "glDeleteVertexShaderEXT");
SAFE_GET_PROC( qglShaderOp1EXT, PFNGLSHADEROP1EXTPROC, "glShaderOp1EXT");
SAFE_GET_PROC( qglShaderOp2EXT, PFNGLSHADEROP2EXTPROC, "glShaderOp2EXT");
SAFE_GET_PROC( qglShaderOp3EXT, PFNGLSHADEROP3EXTPROC, "glShaderOp3EXT");
SAFE_GET_PROC( qglSwizzleEXT, PFNGLSWIZZLEEXTPROC, "glSwizzleEXT");
SAFE_GET_PROC( qglWriteMaskEXT, PFNGLWRITEMASKEXTPROC, "glWriteMaskEXT");
SAFE_GET_PROC( qglInsertComponentEXT, PFNGLINSERTCOMPONENTEXTPROC, "glInsertComponentEXT");
SAFE_GET_PROC( qglExtractComponentEXT, PFNGLEXTRACTCOMPONENTEXTPROC, "glExtractComponentEXT");
SAFE_GET_PROC( qglGenSymbolsEXT, PFNGLGENSYMBOLSEXTPROC, "glGenSymbolsEXT");
SAFE_GET_PROC( qglSetInvariantEXT, PFNGLSETINVARIANTEXTPROC, "glSetInvariantEXT");
SAFE_GET_PROC( qglSetLocalConstantEXT, PFNGLSETLOCALCONSTANTEXTPROC, "glSetLocalConstantEXT");
SAFE_GET_PROC( qglVariantbvEXT, PFNGLVARIANTBVEXTPROC, "glVariantbvEXT");
SAFE_GET_PROC( qglVariantsvEXT, PFNGLVARIANTSVEXTPROC, "glVariantsvEXT");
SAFE_GET_PROC( qglVariantivEXT, PFNGLVARIANTIVEXTPROC, "glVariantivEXT");
SAFE_GET_PROC( qglVariantfvEXT, PFNGLVARIANTFVEXTPROC, "glVariantfvEXT");
SAFE_GET_PROC( qglVariantdvEXT, PFNGLVARIANTDVEXTPROC, "glVariantdvEXT");
SAFE_GET_PROC( qglVariantubvEXT, PFNGLVARIANTUBVEXTPROC, "glVariantubvEXT");
SAFE_GET_PROC( qglVariantusvEXT, PFNGLVARIANTUSVEXTPROC, "glVariantusvEXT");
SAFE_GET_PROC( qglVariantuivEXT, PFNGLVARIANTUIVEXTPROC, "glVariantuivEXT");
SAFE_GET_PROC( qglVariantPointerEXT, PFNGLVARIANTPOINTEREXTPROC, "glVariantPointerEXT");
SAFE_GET_PROC( qglEnableVariantClientStateEXT, PFNGLENABLEVARIANTCLIENTSTATEEXTPROC, "glEnableVariantClientStateEXT");
SAFE_GET_PROC( qglDisableVariantClientStateEXT, PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC, "glDisableVariantClientStateEXT");
SAFE_GET_PROC( qglBindLightParameterEXT, PFNGLBINDLIGHTPARAMETEREXTPROC, "glBindLightParameterEXT");
SAFE_GET_PROC( qglBindMaterialParameterEXT, PFNGLBINDMATERIALPARAMETEREXTPROC, "glBindMaterialParameterEXT");
SAFE_GET_PROC( qglBindTexGenParameterEXT, PFNGLBINDTEXGENPARAMETEREXTPROC, "glBindTexGenParameterEXT");
SAFE_GET_PROC( qglBindTextureUnitParameterEXT, PFNGLBINDTEXTUREUNITPARAMETEREXTPROC, "glBindTextureUnitParameterEXT");
SAFE_GET_PROC( qglBindParameterEXT, PFNGLBINDPARAMETEREXTPROC, "glBindParameterEXT");
SAFE_GET_PROC( qglIsVariantEnabledEXT, PFNGLISVARIANTENABLEDEXTPROC, "glIsVariantEnabledEXT");
SAFE_GET_PROC( qglGetVariantBooleanvEXT, PFNGLGETVARIANTBOOLEANVEXTPROC, "glGetVariantBooleanvEXT");
SAFE_GET_PROC( qglGetVariantIntegervEXT, PFNGLGETVARIANTINTEGERVEXTPROC, "glGetVariantIntegervEXT");
SAFE_GET_PROC( qglGetVariantFloatvEXT, PFNGLGETVARIANTFLOATVEXTPROC, "glGetVariantFloatvEXT");
SAFE_GET_PROC( qglGetVariantPointervEXT, PFNGLGETVARIANTPOINTERVEXTPROC, "glGetVariantPointervEXT");
SAFE_GET_PROC( qglGetInvariantBooleanvEXT, PFNGLGETINVARIANTBOOLEANVEXTPROC, "glGetInvariantBooleanvEXT");
SAFE_GET_PROC( qglGetInvariantIntegervEXT, PFNGLGETINVARIANTINTEGERVEXTPROC, "glGetInvariantIntegervEXT");
SAFE_GET_PROC( qglGetInvariantFloatvEXT, PFNGLGETINVARIANTFLOATVEXTPROC, "glGetInvariantFloatvEXT");
SAFE_GET_PROC( qglGetLocalConstantBooleanvEXT, PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC, "glGetLocalConstantBooleanvEXT");
SAFE_GET_PROC( qglGetLocalConstantIntegervEXT, PFNGLGETLOCALCONSTANTINTEGERVEXTPROC, "glGetLocalConstantIntegervEXT");
SAFE_GET_PROC( qglGetLocalConstantFloatvEXT, PFNGLGETLOCALCONSTANTFLOATVEXTPROC, "glGetLocalConstantFloatvEXT");
if ( strstr(gl_extensions, "GL_ATI_pn_triangles") )
{
SAFE_GET_PROC( qglPNTrianglesiATI, PFNGLPNTRIANGLESIATIPROC, "glPNTrianglesiATI");
SAFE_GET_PROC( qglPNTrianglesfATI, PFNGLPNTRIANGLESFATIPROC, "glPNTrianglesfATI");
}
if ( strstr(gl_extensions, "GL_ATI_separate_stencil") )
{
SAFE_GET_PROC( qglStencilOpSeparateATI, PFNGLSTENCILOPSEPARATEATIPROC, "glStencilOpSeparateATI");
SAFE_GET_PROC( qglStencilFuncSeparateATI, PFNGLSTENCILFUNCSEPARATEATIPROC, "glStencilFuncSeparateATI");
}
#endif /* !__APPLE__ && !MACOSX */
glEnable(GL_FRAGMENT_SHADER_ATI);
fragment_shaders = qglGenFragmentShadersATI(2);
// combined diffuse & specular shader w/ vertex color
qglBindFragmentShaderATI(fragment_shaders);
Radeon_checkerror();
qglBeginFragmentShaderATI();
Radeon_checkerror();
qglSetFragmentShaderConstantATI(GL_CON_0_ATI, &scaler[0]);
Radeon_checkerror();
// texld r0, t0
qglSampleMapATI (GL_REG_0_ATI, GL_TEXTURE0_ARB, GL_SWIZZLE_STR_ATI);
Radeon_checkerror();
// texld r1, t1
qglSampleMapATI (GL_REG_1_ATI, GL_TEXTURE1_ARB, GL_SWIZZLE_STR_ATI);
Radeon_checkerror();
// texld r2, t2
qglSampleMapATI (GL_REG_2_ATI, GL_TEXTURE2_ARB, GL_SWIZZLE_STR_ATI);
Radeon_checkerror();
// texld r3, t3
qglSampleMapATI (GL_REG_3_ATI, GL_TEXTURE3_ARB, GL_SWIZZLE_STR_ATI);
Radeon_checkerror();
// texld r4, t4
qglSampleMapATI (GL_REG_4_ATI, GL_TEXTURE4_ARB, GL_SWIZZLE_STR_ATI);
Radeon_checkerror();
// gloss * atten * light color * specular +
// dot * color * atten * light color * self shadow =
// (gloss * specular + dot * color * self shadow ) * atten * light color
// Alpha ops rule :-)
// dp3_sat r2.rgb, r0_bx2.rgb, r2_bx2.rgb // specular
qglColorFragmentOp2ATI(GL_DOT3_ATI,
GL_REG_2_ATI, GL_RED_BIT_ATI|GL_GREEN_BIT_ATI|GL_BLUE_BIT_ATI, GL_SATURATE_BIT_ATI,
GL_REG_0_ATI, GL_NONE, GL_2X_BIT_ATI|GL_BIAS_BIT_ATI,
GL_REG_2_ATI, GL_NONE, GL_2X_BIT_ATI|GL_BIAS_BIT_ATI);
Radeon_checkerror();
// +mov_x8_sat r2.a, r1_bx2.b // self shadow term
qglAlphaFragmentOp1ATI(GL_MOV_ATI,
GL_REG_2_ATI, GL_8X_BIT_ATI|GL_SATURATE_BIT_ATI,
GL_REG_1_ATI, GL_BLUE, GL_2X_BIT_ATI|GL_BIAS_BIT_ATI);
Radeon_checkerror();
// dp3_sat r1.rgb, r0_bx2.rgb, r1_bx2.rgb // diffuse
qglColorFragmentOp2ATI(GL_DOT3_ATI,
GL_REG_1_ATI, GL_RED_BIT_ATI|GL_GREEN_BIT_ATI|GL_BLUE_BIT_ATI, GL_SATURATE_BIT_ATI,
GL_REG_0_ATI, GL_NONE, GL_2X_BIT_ATI|GL_BIAS_BIT_ATI,
GL_REG_1_ATI, GL_NONE, GL_2X_BIT_ATI|GL_BIAS_BIT_ATI);
Radeon_checkerror();
// +mad_x2_sat r1.a, r2.b, r2.b, -c0.b // specular exponent
qglAlphaFragmentOp3ATI(GL_MAD_ATI,
GL_REG_1_ATI, GL_2X_BIT_ATI|GL_SATURATE_BIT_ATI,
GL_REG_2_ATI, GL_BLUE, GL_NONE,
GL_REG_2_ATI, GL_BLUE, GL_NONE,
GL_CON_0_ATI, GL_BLUE, GL_NEGATE_BIT_ATI);
Radeon_checkerror();
// mul r1.rgb, r1.rgb, r3.rgb // diffuse color * diffuse bump
qglColorFragmentOp2ATI(GL_MUL_ATI,
GL_REG_1_ATI, GL_RED_BIT_ATI|GL_GREEN_BIT_ATI|GL_BLUE_BIT_ATI, GL_NONE,
GL_REG_1_ATI, GL_NONE, GL_NONE,
GL_REG_3_ATI, GL_NONE, GL_NONE);
Radeon_checkerror();
// +mul r1.a, r1.a, r1.a // raise exponent
qglAlphaFragmentOp2ATI(GL_MUL_ATI,
GL_REG_1_ATI, GL_NONE,
GL_REG_1_ATI, GL_NONE, GL_NONE,
GL_REG_1_ATI, GL_NONE, GL_NONE);
Radeon_checkerror();
// mul r4.rgb, r4.rgb, v0.rgb // atten * light color
qglColorFragmentOp2ATI(GL_MUL_ATI,
GL_REG_4_ATI, GL_RED_BIT_ATI|GL_GREEN_BIT_ATI|GL_BLUE_BIT_ATI, GL_NONE,
GL_REG_4_ATI, GL_NONE, GL_NONE,
GL_PRIMARY_COLOR_ARB, GL_NONE, GL_NONE);
Radeon_checkerror();
// +mul r1.a, r1.a, r1.a // raise exponent
qglAlphaFragmentOp2ATI(GL_MUL_ATI,
GL_REG_1_ATI, GL_NONE,
GL_REG_1_ATI, GL_NONE, GL_NONE,
GL_REG_1_ATI, GL_NONE, GL_NONE);
Radeon_checkerror();
// mul r1.rgb, r1.rgb, r2.a // self shadow * diffuse
qglColorFragmentOp2ATI(GL_MUL_ATI,
GL_REG_1_ATI, GL_RED_BIT_ATI|GL_GREEN_BIT_ATI|GL_BLUE_BIT_ATI, GL_NONE,
GL_REG_1_ATI, GL_NONE, GL_NONE,
GL_REG_2_ATI, GL_ALPHA, GL_NONE);
Radeon_checkerror();
// +mul r0.a, r1.a, r0.a // specular * gloss map
qglAlphaFragmentOp2ATI(GL_MUL_ATI,
GL_REG_0_ATI, GL_SATURATE_BIT_ATI,
GL_REG_1_ATI, GL_NONE, GL_NONE,
GL_REG_0_ATI, GL_NONE, GL_NONE);
Radeon_checkerror();
// add r0.rgb, r1.rgb, r0.a // diffuse + specular
qglColorFragmentOp2ATI(GL_ADD_ATI,
GL_REG_0_ATI, GL_RED_BIT_ATI|GL_GREEN_BIT_ATI|GL_BLUE_BIT_ATI, GL_NONE,
GL_REG_1_ATI, GL_NONE, GL_NONE,
GL_REG_0_ATI, GL_ALPHA, GL_NONE);
Radeon_checkerror();
// mul_sat r0.rgb, r0.rgb, r4.rgb // (diffuse + specular)*atten*color
qglColorFragmentOp2ATI(GL_MUL_ATI,
GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
GL_REG_0_ATI, GL_NONE, GL_NONE,
GL_REG_4_ATI, GL_NONE, GL_NONE);
Radeon_checkerror();
qglEndFragmentShaderATI();
Radeon_checkerror();
// combined diffuse & specular shader w/ vertex color and colored gloss
qglBindFragmentShaderATI(fragment_shaders+1);
Radeon_checkerror();
qglBeginFragmentShaderATI();
Radeon_checkerror();
qglSetFragmentShaderConstantATI(GL_CON_0_ATI, &scaler[0]);
Radeon_checkerror();
// texld r0, t0
qglSampleMapATI (GL_REG_0_ATI, GL_TEXTURE0_ARB, GL_SWIZZLE_STR_ATI);
Radeon_checkerror();
// texld r1, t1
qglSampleMapATI (GL_REG_1_ATI, GL_TEXTURE1_ARB, GL_SWIZZLE_STR_ATI);
Radeon_checkerror();
// texld r2, t2
qglSampleMapATI (GL_REG_2_ATI, GL_TEXTURE2_ARB, GL_SWIZZLE_STR_ATI);
Radeon_checkerror();
// texld r3, t3
qglSampleMapATI (GL_REG_3_ATI, GL_TEXTURE3_ARB, GL_SWIZZLE_STR_ATI);
Radeon_checkerror();
// texld r4, t4
qglSampleMapATI (GL_REG_4_ATI, GL_TEXTURE4_ARB, GL_SWIZZLE_STR_ATI);
Radeon_checkerror();
// texld r5, t5
qglSampleMapATI (GL_REG_5_ATI, GL_TEXTURE5_ARB, GL_SWIZZLE_STR_ATI);
Radeon_checkerror();
// gloss * atten * light color * specular +
// dot * color * atten * light color * self shadow =
// (gloss * specular + dot * color * self shadow ) * atten * light color
// Alpha ops rule :-)
// dp3_sat r2.rgb, r0_bx2.rgb, r2_bx2.rgb // specular
qglColorFragmentOp2ATI(GL_DOT3_ATI,
GL_REG_2_ATI, GL_RED_BIT_ATI|GL_GREEN_BIT_ATI|GL_BLUE_BIT_ATI, GL_SATURATE_BIT_ATI,
GL_REG_0_ATI, GL_NONE, GL_2X_BIT_ATI|GL_BIAS_BIT_ATI,
GL_REG_2_ATI, GL_NONE, GL_2X_BIT_ATI|GL_BIAS_BIT_ATI);
Radeon_checkerror();
// +mov_x8_sat r2.a, r1_bx2.b // self shadow term
qglAlphaFragmentOp1ATI(GL_MOV_ATI,
GL_REG_2_ATI, GL_8X_BIT_ATI|GL_SATURATE_BIT_ATI,
GL_REG_1_ATI, GL_BLUE, GL_2X_BIT_ATI|GL_BIAS_BIT_ATI);
Radeon_checkerror();
// dp3_sat r1.rgb, r0_bx2.rgb, r1_bx2.rgb // diffuse
qglColorFragmentOp2ATI(GL_DOT3_ATI,
GL_REG_1_ATI, GL_RED_BIT_ATI|GL_GREEN_BIT_ATI|GL_BLUE_BIT_ATI, GL_SATURATE_BIT_ATI,
GL_REG_0_ATI, GL_NONE, GL_2X_BIT_ATI|GL_BIAS_BIT_ATI,
GL_REG_1_ATI, GL_NONE, GL_2X_BIT_ATI|GL_BIAS_BIT_ATI);
Radeon_checkerror();
// +mad_x2_sat r1.a, r2.b, r2.b, -c0.b // specular exponent
qglAlphaFragmentOp3ATI(GL_MAD_ATI,
GL_REG_1_ATI, GL_2X_BIT_ATI|GL_SATURATE_BIT_ATI,
GL_REG_2_ATI, GL_BLUE, GL_NONE,
GL_REG_2_ATI, GL_BLUE, GL_NONE,
GL_CON_0_ATI, GL_BLUE, GL_NEGATE_BIT_ATI);
Radeon_checkerror();
// mul r1.rgb, r1.rgb, r3.rgb // diffuse color * diffuse bump
qglColorFragmentOp2ATI(GL_MUL_ATI,
GL_REG_1_ATI, GL_RED_BIT_ATI|GL_GREEN_BIT_ATI|GL_BLUE_BIT_ATI, GL_NONE,
GL_REG_1_ATI, GL_NONE, GL_NONE,
GL_REG_3_ATI, GL_NONE, GL_NONE);
Radeon_checkerror();
// +mul r1.a, r1.a, r1.a // raise exponent
qglAlphaFragmentOp2ATI(GL_MUL_ATI,
GL_REG_1_ATI, GL_NONE,
GL_REG_1_ATI, GL_NONE, GL_NONE,
GL_REG_1_ATI, GL_NONE, GL_NONE);
Radeon_checkerror();
// mul r4.rgb, r4.rgb, v0.rgb // atten * light color
qglColorFragmentOp2ATI(GL_MUL_ATI,
GL_REG_4_ATI, GL_RED_BIT_ATI|GL_GREEN_BIT_ATI|GL_BLUE_BIT_ATI, GL_NONE,
GL_REG_4_ATI, GL_NONE, GL_NONE,
GL_PRIMARY_COLOR_ARB, GL_NONE, GL_NONE);
Radeon_checkerror();
// +mul r1.a, r1.a, r1.a // raise exponent
qglAlphaFragmentOp2ATI(GL_MUL_ATI,
GL_REG_1_ATI, GL_NONE,
GL_REG_1_ATI, GL_NONE, GL_NONE,
GL_REG_1_ATI, GL_NONE, GL_NONE);
Radeon_checkerror();
// mul r1.rgb, r1.rgb, r2.a // self shadow * diffuse
qglColorFragmentOp2ATI(GL_MUL_ATI,
GL_REG_1_ATI, GL_RED_BIT_ATI|GL_GREEN_BIT_ATI|GL_BLUE_BIT_ATI, GL_NONE,
GL_REG_1_ATI, GL_NONE, GL_NONE,
GL_REG_2_ATI, GL_ALPHA, GL_NONE);
Radeon_checkerror();
// mad_sat r0.rgb, r1.a, r5.rgb, r1.rgb // specular * gloss + diffuse
qglColorFragmentOp3ATI(GL_MAD_ATI,
GL_REG_0_ATI, GL_RED_BIT_ATI|GL_GREEN_BIT_ATI|GL_BLUE_BIT_ATI, GL_SATURATE_BIT_ATI,
GL_REG_1_ATI, GL_ALPHA, GL_NONE,
GL_REG_5_ATI, GL_NONE, GL_NONE,
GL_REG_1_ATI, GL_NONE, GL_NONE);
Radeon_checkerror();
// mul_sat r0.rgb, r0.rgb, r4.rgb // (diffuse + specular)*atten*color
qglColorFragmentOp2ATI(GL_MUL_ATI,
GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
GL_REG_0_ATI, GL_NONE, GL_NONE,
GL_REG_4_ATI, GL_NONE, GL_NONE);
Radeon_checkerror();
qglEndFragmentShaderATI();
Radeon_checkerror();
glDisable(GL_FRAGMENT_SHADER_ATI);
glEnable(GL_VERTEX_SHADER_EXT);
vertex_shaders = qglGenVertexShadersEXT(1);
Radeon_checkerror();
lightPos = qglGenSymbolsEXT(GL_VECTOR_EXT, GL_INVARIANT_EXT,
GL_FULL_RANGE_EXT, 1);
eyePos = qglGenSymbolsEXT(GL_VECTOR_EXT, GL_INVARIANT_EXT,
GL_FULL_RANGE_EXT, 1);
qglBindVertexShaderEXT(vertex_shaders);
Radeon_checkerror();
qglBeginVertexShaderEXT();
Radeon_checkerror();
// Generates a necessary input for the diffuse bumpmapping registers
mvp = qglBindParameterEXT( GL_MVP_MATRIX_EXT );
Radeon_checkerror();
modelview = qglBindParameterEXT( GL_MODELVIEW_MATRIX );
Radeon_checkerror();
vertex = qglBindParameterEXT( GL_CURRENT_VERTEX_EXT );
Radeon_checkerror();
color = qglBindParameterEXT( GL_CURRENT_COLOR );
Radeon_checkerror();
texturematrix = qglBindTextureUnitParameterEXT( GL_TEXTURE4_ARB, GL_TEXTURE_MATRIX );
Radeon_checkerror();
texcoord0 = qglBindTextureUnitParameterEXT( GL_TEXTURE0_ARB, GL_CURRENT_TEXTURE_COORDS );
Radeon_checkerror();
texcoord1 = qglBindTextureUnitParameterEXT( GL_TEXTURE1_ARB, GL_CURRENT_TEXTURE_COORDS );
Radeon_checkerror();
texcoord2 = qglBindTextureUnitParameterEXT( GL_TEXTURE2_ARB, GL_CURRENT_TEXTURE_COORDS );
Radeon_checkerror();
texcoord3 = qglBindTextureUnitParameterEXT( GL_TEXTURE3_ARB, GL_CURRENT_TEXTURE_COORDS );
Radeon_checkerror();
disttemp = qglGenSymbolsEXT(GL_SCALAR_EXT, GL_LOCAL_EXT, GL_FULL_RANGE_EXT, 1);
Radeon_checkerror();
disttemp2 = qglGenSymbolsEXT(GL_SCALAR_EXT, GL_LOCAL_EXT, GL_FULL_RANGE_EXT, 1);
Radeon_checkerror();
zcomp = qglGenSymbolsEXT(GL_VECTOR_EXT, GL_LOCAL_EXT, GL_FULL_RANGE_EXT, 1);
Radeon_checkerror();
tempvec = qglGenSymbolsEXT(GL_VECTOR_EXT, GL_LOCAL_EXT, GL_FULL_RANGE_EXT, 1);
Radeon_checkerror();
fogstart = qglBindParameterEXT( GL_FOG_START );
Radeon_checkerror();
fogend = qglBindParameterEXT( GL_FOG_END );
Radeon_checkerror();
// Transform vertex to view-space
qglShaderOp2EXT( GL_OP_MULTIPLY_MATRIX_EXT, GL_OUTPUT_VERTEX_EXT, mvp, vertex );
Radeon_checkerror();
// Transform vertex by texture matrix and copy to output
qglShaderOp2EXT( GL_OP_MULTIPLY_MATRIX_EXT, GL_OUTPUT_TEXTURE_COORD4_EXT, texturematrix, vertex );
Radeon_checkerror();
// copy tex coords of unit 0 to unit 3
qglShaderOp1EXT( GL_OP_MOV_EXT, GL_OUTPUT_TEXTURE_COORD0_EXT, texcoord0);
Radeon_checkerror();
qglShaderOp1EXT( GL_OP_MOV_EXT, GL_OUTPUT_TEXTURE_COORD3_EXT, texcoord0);
Radeon_checkerror();
qglShaderOp1EXT( GL_OP_MOV_EXT, GL_OUTPUT_TEXTURE_COORD5_EXT, texcoord0);
Radeon_checkerror();
qglShaderOp1EXT( GL_OP_MOV_EXT, GL_OUTPUT_COLOR0_EXT, color);
Radeon_checkerror();
// Transform vertex and take z for fog
qglExtractComponentEXT( zcomp, modelview, 2);
Radeon_checkerror();
qglShaderOp2EXT( GL_OP_DOT4_EXT, disttemp, zcomp, vertex );
Radeon_checkerror();
// calculate fog values end - z and end - start
qglShaderOp2EXT( GL_OP_SUB_EXT, disttemp, fogend, disttemp);
Radeon_checkerror();
qglShaderOp2EXT( GL_OP_SUB_EXT, disttemp2, fogend, fogstart);
Radeon_checkerror();
// divide end - z by end - start, that's it
qglShaderOp1EXT( GL_OP_RECIP_EXT, disttemp2, disttemp2);
Radeon_checkerror();
qglShaderOp2EXT( GL_OP_MUL_EXT, GL_OUTPUT_FOG_EXT, disttemp, disttemp2);
Radeon_checkerror();
// calculate light position
qglShaderOp2EXT( GL_OP_SUB_EXT, tempvec, lightPos, vertex);
Radeon_checkerror();
qglShaderOp2EXT( GL_OP_DOT3_EXT, disttemp, tempvec, tempvec);
Radeon_checkerror();
qglShaderOp1EXT( GL_OP_RECIP_SQRT_EXT, disttemp, disttemp);
Radeon_checkerror();
qglShaderOp2EXT( GL_OP_MUL_EXT, tempvec, tempvec, disttemp);
Radeon_checkerror();
// Normalized light vec now in tempvec, transform to tex1
qglShaderOp2EXT( GL_OP_DOT4_EXT, disttemp, tempvec, texcoord1);
Radeon_checkerror();
qglInsertComponentEXT( GL_OUTPUT_TEXTURE_COORD1_EXT, disttemp, 0);
Radeon_checkerror();
qglShaderOp2EXT( GL_OP_DOT4_EXT, disttemp, tempvec, texcoord2);
Radeon_checkerror();
qglInsertComponentEXT( GL_OUTPUT_TEXTURE_COORD1_EXT, disttemp, 1);
Radeon_checkerror();
qglShaderOp2EXT( GL_OP_DOT4_EXT, disttemp, tempvec, texcoord3);
Radeon_checkerror();
qglInsertComponentEXT( GL_OUTPUT_TEXTURE_COORD1_EXT, disttemp, 2);
Radeon_checkerror();
// Now, calculate halfvec
qglShaderOp2EXT( GL_OP_SUB_EXT, zcomp, eyePos, vertex);
Radeon_checkerror();
qglShaderOp2EXT( GL_OP_ADD_EXT, tempvec, tempvec, zcomp);
Radeon_checkerror();
qglShaderOp2EXT( GL_OP_DOT3_EXT, disttemp, tempvec, tempvec);
Radeon_checkerror();
qglShaderOp1EXT( GL_OP_RECIP_SQRT_EXT, disttemp, disttemp);
Radeon_checkerror();
qglShaderOp2EXT( GL_OP_MUL_EXT, tempvec, tempvec, disttemp);
Radeon_checkerror();
// Normalized half vec now in tempvec, transform to tex1
qglShaderOp2EXT( GL_OP_DOT4_EXT, disttemp, tempvec, texcoord1);
Radeon_checkerror();
qglInsertComponentEXT( GL_OUTPUT_TEXTURE_COORD2_EXT, disttemp, 0);
Radeon_checkerror();
qglShaderOp2EXT( GL_OP_DOT4_EXT, disttemp, tempvec, texcoord2);
Radeon_checkerror();
qglInsertComponentEXT( GL_OUTPUT_TEXTURE_COORD2_EXT, disttemp, 1);
Radeon_checkerror();
qglShaderOp2EXT( GL_OP_DOT4_EXT, disttemp, tempvec, texcoord3);
Radeon_checkerror();
qglInsertComponentEXT( GL_OUTPUT_TEXTURE_COORD2_EXT, disttemp, 2);
qglEndVertexShaderEXT();
Radeon_checkerror();
glDisable(GL_VERTEX_SHADER_EXT);
}
void Radeon_DisableBumpShader(shader_t* shader)
{
//tex 0 = normal map
//tex 1 = normalization cube map (tangent space light vector)
//tex 2 = normalization cube map (tangent space half vector)
//tex 3 = color map
//tex 4 = (attenuation or light filter, depends on light settings)
glDisable(GL_VERTEX_SHADER_EXT);
glDisable(GL_FRAGMENT_SHADER_ATI);
GL_SelectTexture(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
GL_SelectTexture(GL_TEXTURE2_ARB);
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
GL_SelectTexture(GL_TEXTURE3_ARB);
glDisable(GL_TEXTURE_2D);
GL_SelectTexture(GL_TEXTURE4_ARB);
if (currentshadowlight->shader->numstages)
{
if (currentshadowlight->shader->stages[0].texture[0]->gltype == GL_TEXTURE_CUBE_MAP_ARB)
{
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
}
else
{
glDisable(GL_TEXTURE_2D);
}
glPopMatrix();
GL_SelectTexture(GL_TEXTURE5_ARB);
if ( shader->glossstages[0].type == STAGE_GLOSS )
{
glDisable(GL_TEXTURE_2D);
}
}
else
{
glDisable(GL_TEXTURE_3D);
glPopMatrix();
if ( shader->glossstages[0].type == STAGE_GLOSS )
{
GL_SelectTexture(GL_TEXTURE5_ARB);
glDisable(GL_TEXTURE_2D);
}
}
glMatrixMode(GL_MODELVIEW);
GL_SelectTexture(GL_TEXTURE0_ARB);
}
void Radeon_SetupTcMods(stage_t *s);
void Radeon_EnableBumpShader(const transform_t *tr, vec3_t lightOrig,
qboolean alias, shader_t* shader)
{
GLfloat temp[4];
//tex 0 = normal map
//tex 1 = normalization cube map (tangent space light vector)
//tex 2 = normalization cube map (tangent space half vector)
//tex 3 = color map
//tex 4 = (attenuation or light filter, depends on light settings but the actual
//tex 5 = colored gloss if used
glGetError();
GL_SelectTexture(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_CUBE_MAP_ARB);
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, normcube_texture_object);
GL_SelectTexture(GL_TEXTURE2_ARB);
glEnable(GL_TEXTURE_CUBE_MAP_ARB);
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, normcube_texture_object);
GL_SelectTexture(GL_TEXTURE3_ARB);
glEnable(GL_TEXTURE_2D);
glEnable(GL_FRAGMENT_SHADER_ATI);
glEnable(GL_VERTEX_SHADER_EXT);
qglBindVertexShaderEXT( vertex_shaders );
Radeon_checkerror();
GL_SelectTexture(GL_TEXTURE4_ARB);
glMatrixMode(GL_TEXTURE);
glPushMatrix();
glLoadIdentity();
if (currentshadowlight->shader->numstages)
{
if (currentshadowlight->shader->stages[0].texture[0]->gltype == GL_TEXTURE_CUBE_MAP_ARB)
{
glEnable(GL_TEXTURE_CUBE_MAP_ARB);
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, currentshadowlight->shader->stages[0].texture[0]->texnum);
}
else
{
// 2D filter
glEnable(GL_TEXTURE_2D);
GL_BindAdvanced(currentshadowlight->shader->stages[0].texture[0]);
//Default = repeat the texture one time in the light's sphere
//Can be modified with the tcMod shader commands
glTranslatef(0.5,0.5,0.5);
glScalef(0.5,0.5,0.5);
glScalef(1.0f/(currentshadowlight->radiusv[0]),
1.0f/(currentshadowlight->radiusv[1]),
1.0f/(currentshadowlight->radiusv[2]));
}
Radeon_SetupTcMods(&currentshadowlight->shader->stages[0]);
GL_SetupCubeMapMatrix(tr);
GL_SelectTexture(GL_TEXTURE5_ARB);
if ( shader->glossstages[0].type == STAGE_GLOSS )
{
GL_BindAdvanced(shader->glossstages[0].texture[0]);
glEnable(GL_TEXTURE_2D);
qglBindFragmentShaderATI( fragment_shaders + 1 );
Radeon_checkerror();
}
else
{
qglBindFragmentShaderATI( fragment_shaders );
Radeon_checkerror();
}
}
else
{
glEnable(GL_TEXTURE_3D);
glBindTexture(GL_TEXTURE_3D, atten3d_texture_object);
glTranslatef(0.5,0.5,0.5);
glScalef(0.5,0.5,0.5);
glScalef(1.0f/(currentshadowlight->radiusv[0]),
1.0f/(currentshadowlight->radiusv[1]),
1.0f/(currentshadowlight->radiusv[2]));
GL_SetupAttenMatrix(tr);
if ( shader->glossstages[0].type == STAGE_GLOSS )
{
GL_SelectTexture(GL_TEXTURE5_ARB);
GL_BindAdvanced(shader->glossstages[0].texture[0]);
glEnable(GL_TEXTURE_2D);
qglBindFragmentShaderATI( fragment_shaders + 1 );
Radeon_checkerror();
}
else
{
qglBindFragmentShaderATI( fragment_shaders );
Radeon_checkerror();
}
}
GL_SelectTexture(GL_TEXTURE0_ARB);
temp[0] = currentshadowlight->origin[0];
temp[1] = currentshadowlight->origin[1];
temp[2] = currentshadowlight->origin[2];
temp[3] = 1.0f;
qglSetInvariantEXT(lightPos, GL_FLOAT, &temp[0]);
temp[0] = r_refdef.vieworg[0];
temp[1] = r_refdef.vieworg[1];
temp[2] = r_refdef.vieworg[2];
qglSetInvariantEXT(eyePos, GL_FLOAT, &temp[0]);
}
void Radeon_EnableAttentShader(const transform_t *tr) {
float invrad = 1/currentshadowlight->radius;
GL_SelectTexture(GL_TEXTURE0_ARB);
glMatrixMode(GL_TEXTURE);
glPushMatrix();
glLoadIdentity();
glTranslatef(0.5,0.5,0.5);
glScalef(0.5,0.5,0.5);
glScalef(1.0f/(currentshadowlight->radiusv[0]),
1.0f/(currentshadowlight->radiusv[1]),
1.0f/(currentshadowlight->radiusv[2]));
GL_SetupAttenMatrix(tr);
glDisable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_3D);
glBindTexture(GL_TEXTURE_3D, atten3d_texture_object);
}
void Radeon_DisableAttentShader() {
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glDisable(GL_TEXTURE_3D);
glEnable(GL_TEXTURE_2D);
}
/************************
Shader utility routines
*************************/
void Radeon_SetupTcMod(tcmod_t *tc)
{
switch (tc->type)
{
case TCMOD_ROTATE:
glTranslatef(0.5,0.5,0.0);
glRotatef(realtime * tc->params[0],0,0,1);
glTranslatef(-0.5, -0.5, 0.0);
break;
case TCMOD_SCROLL:
glTranslatef(realtime * tc->params[0], realtime * tc->params[1], 0.0);
break;
case TCMOD_SCALE:
glScalef(tc->params[0],tc->params[1],1.0);
break;
case TCMOD_STRETCH:
//PENTA: fixme
glScalef(1.0, 1.0, 1.0);
break;
}
}
void Radeon_SetupTcMods(stage_t *s)
{
int i;
for (i = 0; i < s->numtcmods; i++)
Radeon_SetupTcMod(&s->tcmods[i]);
}
void Radeon_SetupSimpleStage(stage_t *s)
{
tcmod_t *tc;
int i;
if (s->type != STAGE_SIMPLE)
{
Con_Printf("Non simple stage, in simple stage list");
return;
}
glMatrixMode(GL_TEXTURE);
glPushMatrix();
for (i=0; i<s->numtcmods; i++)
{
Radeon_SetupTcMod(&s->tcmods[i]);
}
if (s->src_blend > -1)
{
glBlendFunc(s->src_blend, s->dst_blend);
glEnable(GL_BLEND);
}
if (s->alphatresh > 0)
{
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, s->alphatresh);
}
if ((s->numtextures > 0) && (s->texture[0]))
GL_BindAdvanced(s->texture[0]);
}
/************************
Generic triangle list routines
*************************/
void FormatError(); // In gl_bumpgf.c
void Radeon_sendTriangleListWV(const vertexdef_t *verts, int *indecies,
int numIndecies)
{
GL_VertexPointer(3, GL_FLOAT, verts->vertexstride, verts->vertices);
glEnableClientState(GL_VERTEX_ARRAY);
qglClientActiveTextureARB(GL_TEXTURE0_ARB);
GL_TexCoordPointer(3, GL_FLOAT, verts->vertexstride, verts->vertices);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
//draw them
glDrawElements(GL_TRIANGLES, numIndecies, GL_UNSIGNED_INT, indecies);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
void Radeon_sendTriangleListTA(const vertexdef_t *verts, int *indecies,
int numIndecies)
{
GL_VertexPointer(3, GL_FLOAT, verts->vertexstride, verts->vertices);
glEnableClientState(GL_VERTEX_ARRAY);
//Check the input vertices
if (IsNullDriver(verts->texcoords)) FormatError();
if (IsNullDriver(verts->binormals)) FormatError();
if (IsNullDriver(verts->tangents)) FormatError();
if (IsNullDriver(verts->normals)) FormatError();
qglClientActiveTextureARB(GL_TEXTURE0_ARB);
GL_TexCoordPointer(2, GL_FLOAT, verts->texcoordstride, verts->texcoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
qglClientActiveTextureARB(GL_TEXTURE1_ARB);
GL_TexCoordPointer(3, GL_FLOAT, verts->tangentstride, verts->tangents);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
qglClientActiveTextureARB(GL_TEXTURE2_ARB);
GL_TexCoordPointer(3, GL_FLOAT, verts->binormalstride, verts->binormals);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
qglClientActiveTextureARB(GL_TEXTURE3_ARB);
GL_TexCoordPointer(3, GL_FLOAT, verts->normalstride, verts->normals);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
//draw them
glDrawElements(GL_TRIANGLES, numIndecies, GL_UNSIGNED_INT, indecies);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
qglClientActiveTextureARB(GL_TEXTURE2_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
qglClientActiveTextureARB(GL_TEXTURE1_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
qglClientActiveTextureARB(GL_TEXTURE0_ARB);
GL_SelectTexture(GL_TEXTURE0_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
void Radeon_drawTriangleListBump (const vertexdef_t *verts, int *indecies,
int numIndecies, shader_t *shader,
const transform_t *tr, const lightobject_t *lo)
{
if (!(shader->flags & SURF_PPLIGHT)) return;
if (currentshadowlight->shader->numstages )
{
//draw attent into dest alpha
GL_DrawAlpha();
Radeon_EnableAttentShader(tr);
Radeon_sendTriangleListWV(verts,indecies,numIndecies);
Radeon_DisableAttentShader();
GL_ModulateAlphaDrawColor();
} else {
GL_AddColor();
}
glColor3fv(&currentshadowlight->color[0]);
Radeon_EnableBumpShader(tr,currentshadowlight->origin, true, shader);
//bind the correct texture
GL_SelectTexture(GL_TEXTURE0_ARB);
if (shader->numbumpstages > 0)
GL_BindAdvanced(shader->bumpstages[0].texture[0]);
GL_SelectTexture(GL_TEXTURE3_ARB);
if (shader->numcolorstages > 0)
GL_BindAdvanced(shader->colorstages[0].texture[0]);
Radeon_sendTriangleListTA(verts,indecies,numIndecies);
Radeon_DisableBumpShader(shader);
}
void Radeon_drawTriangleListBase (vertexdef_t *verts, int *indecies,
int numIndecies, shader_t *shader,
int lightMapIndex)
{
int i;
GL_VertexPointer(3, GL_FLOAT, verts->vertexstride, verts->vertices);
glEnableClientState(GL_VERTEX_ARRAY);
qglClientActiveTextureARB(GL_TEXTURE0_ARB);
GL_TexCoordPointer(2, GL_FLOAT, verts->texcoordstride, verts->texcoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
if (!shader->cull)
{
glDisable(GL_CULL_FACE);
}
//PENTA: Added fix
glColor3ub(255,255,255);
for ( i = 0; i < shader->numstages; i++)
{
Radeon_SetupSimpleStage(&shader->stages[i]);
glDrawElements(GL_TRIANGLES,numIndecies,GL_UNSIGNED_INT,indecies);
glPopMatrix();
}
glMatrixMode(GL_MODELVIEW);
if (!IsNullDriver(verts->colors) && (shader->flags & SURF_PPLIGHT))
{
GL_ColorPointer(3, GL_UNSIGNED_BYTE, verts->colorstride, verts->colors);
glEnableClientState(GL_COLOR_ARRAY);
glShadeModel(GL_SMOOTH);
if (shader->numstages && shader->numcolorstages)
{
if (shader->colorstages[0].src_blend >= 0)
{
glEnable(GL_BLEND);
glBlendFunc(shader->colorstages[0].src_blend,
shader->colorstages[0].dst_blend);
}
else
{
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
}
}
else
{
glDisable(GL_BLEND);
}
if (shader->numcolorstages)
{
if (shader->colorstages[0].numtextures)
GL_BindAdvanced(shader->colorstages[0].texture[0]);
if (shader->colorstages[0].alphatresh > 0)
{
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GEQUAL, shader->colorstages[0].alphatresh);
}
}
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glDrawElements(GL_TRIANGLES,numIndecies,GL_UNSIGNED_INT,indecies);
glDisableClientState(GL_COLOR_ARRAY);
}
else if (shader->flags & SURF_PPLIGHT)
{
//PENTA: added fix
if (shader->colorstages[0].src_blend >= 0) {
glBlendFunc(shader->colorstages[0].src_blend, shader->colorstages[0].dst_blend);
glEnable(GL_BLEND);
} else {
glDisable(GL_BLEND);
}
glColor3f(0,0,0);
glDisable(GL_TEXTURE_2D);
glDrawElements(GL_TRIANGLES,numIndecies,GL_UNSIGNED_INT,indecies);
glEnable(GL_TEXTURE_2D);
}
if (!shader->cull)
{
glEnable(GL_CULL_FACE);
}
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
}
/*************************
Generic world surfaces routines
**************************/
void Radeon_sendSurfacesBase(msurface_t **surfs, int numSurfaces,
qboolean bindLightmap)
{
int i;
glpoly_t *p;
msurface_t *surf;
for ( i = 0; i < numSurfaces; i++)
{
surf = surfs[i];
if (surf->visframe != r_framecount)
continue;
p = surf->polys;
if (bindLightmap)
{
if (surf->lightmaptexturenum < 0)
continue;
GL_Bind(lightmap_textures+surf->lightmaptexturenum);
}
glDrawElements(GL_TRIANGLES, p->numindecies, GL_UNSIGNED_INT,
&p->indecies[0]);
}
}
void Radeon_drawSurfaceListBase (vertexdef_t* verts, msurface_t** surfs,
int numSurfaces, shader_t* shader)
{
int i;
GL_VertexPointer(3, GL_FLOAT, verts->vertexstride, verts->vertices);
glEnableClientState(GL_VERTEX_ARRAY);
qglClientActiveTextureARB(GL_TEXTURE0_ARB);
GL_TexCoordPointer(2, GL_FLOAT, verts->texcoordstride, verts->texcoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glColor3ub(255,255,255);
if (!shader->cull)
{
glDisable(GL_CULL_FACE);
//Con_Printf("Cullstuff %s\n",shader->name);
}
for (i = 0; i < shader->numstages; i++)
{
Radeon_SetupSimpleStage(&shader->stages[i]);
Radeon_sendSurfacesBase(surfs, numSurfaces, false);
glPopMatrix();
}
if (!IsNullDriver(verts->lightmapcoords) && (shader->flags & SURF_PPLIGHT))
{
qglClientActiveTextureARB(GL_TEXTURE1_ARB);
GL_TexCoordPointer(2, GL_FLOAT, verts->lightmapstride,
verts->lightmapcoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
if (shader->numstages && shader->numcolorstages)
{
if (shader->colorstages[0].src_blend >= 0)
{
glEnable(GL_BLEND);
glBlendFunc(shader->colorstages[0].src_blend,
shader->colorstages[0].dst_blend);
}
else
{
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
}
}
else
{
glDisable(GL_BLEND);
}
if (shader->numcolorstages)
{
if (shader->colorstages[0].numtextures)
GL_BindAdvanced(shader->colorstages[0].texture[0]);
if (shader->colorstages[0].alphatresh > 0)
{
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GEQUAL, shader->colorstages[0].alphatresh);
}
}
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
GL_EnableMultitexture();
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glColor3f(sh_lightmapbright.value, sh_lightmapbright.value,
sh_lightmapbright.value);
Radeon_sendSurfacesBase(surfs, numSurfaces, true);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
GL_DisableMultitexture();
qglClientActiveTextureARB(GL_TEXTURE0_ARB);
}
if (!shader->cull)
{
glEnable(GL_CULL_FACE);
}
glDisable(GL_ALPHA_TEST);
glMatrixMode(GL_MODELVIEW);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glDisable(GL_BLEND);
}
void Radeon_sendSurfacesTA(msurface_t** surfs, int numSurfaces, const transform_t *tr, const lightobject_t *lo)
{
int i,j;
glpoly_t *p;
msurface_t *surf;
shader_t *shader, *lastshader;
float *v;
qboolean cull;
lastshader = NULL;
cull = true;
for ( i = 0; i < numSurfaces; i++)
{
surf = surfs[i];
if (surf->visframe != r_framecount)
continue;
if (!(surf->flags & SURF_PPLIGHT))
continue;
p = surf->polys;
shader = surfs[i]->shader->shader;
//less state changes
if (lastshader != shader)
{
if ( lastshader && lastshader->glossstages[0].type != shader->glossstages[0].type )
{
// disable previous shader if switching between colored and mono gloss
Radeon_DisableBumpShader(lastshader);
Radeon_EnableBumpShader(tr, lo, true, shader);
}
else
{
if ( !lastshader )
{
// Enable shader for the first surface
Radeon_EnableBumpShader(tr, lo, true, shader);
}
}
if (!shader->cull)
{
glDisable(GL_CULL_FACE);
cull = false;
}
else
{
if (!cull)
glEnable(GL_CULL_FACE);
cull = true;
}
//bind the correct texture
GL_SelectTexture(GL_TEXTURE0_ARB);
if (shader->numbumpstages > 0)
GL_BindAdvanced(shader->bumpstages[0].texture[0]);
GL_SelectTexture(GL_TEXTURE3_ARB);
if (shader->numcolorstages > 0)
GL_BindAdvanced(shader->colorstages[0].texture[0]);
if ( shader->glossstages > 0 )
{
// Bind colored gloss
GL_SelectTexture(GL_TEXTURE5_ARB);
GL_BindAdvanced(shader->glossstages[0].texture[0]);
}
lastshader = shader;
}
//Note: texture coords out of begin-end are not a problem...
qglMultiTexCoord3fvARB(GL_TEXTURE1_ARB, &surf->tangent[0]);
qglMultiTexCoord3fvARB(GL_TEXTURE2_ARB, &surf->binormal[0]);
qglMultiTexCoord3fvARB(GL_TEXTURE3_ARB, &surf->plane->normal[0]);
glDrawElements(GL_TRIANGLES, p->numindecies, GL_UNSIGNED_INT, &p->indecies[0]);
}
if (!cull)
glEnable(GL_CULL_FACE);
if ( lastshader )
Radeon_DisableBumpShader(lastshader);
}
void Radeon_sendSurfacesPlain(msurface_t** surfs, int numSurfaces)
{
int i,j;
glpoly_t *p;
msurface_t *surf;
shader_t *shader, *lastshader;
float *v;
qboolean cull;
lastshader = NULL;
cull = true;
for (i = 0; i < numSurfaces; i++)
{
surf = surfs[i];
if (surf->visframe != r_framecount)
continue;
if (!(surf->flags & SURF_PPLIGHT))
continue;
p = surf->polys;
shader = surf->shader->shader;
//less state changes
if (lastshader != shader)
{
if (!shader->cull)
{
glDisable(GL_CULL_FACE);
cull = false;
}
else
{
if (!cull)
glEnable(GL_CULL_FACE);
cull = true;
}
lastshader = shader;
}
glDrawElements(GL_TRIANGLES, p->numindecies, GL_UNSIGNED_INT,
&p->indecies[0]);
}
if (!cull)
glEnable(GL_CULL_FACE);
}
void Radeon_drawSurfaceListBump (vertexdef_t *verts, msurface_t **surfs,
int numSurfaces, const transform_t *tr,
const lightobject_t *lo)
{
GL_VertexPointer(3, GL_FLOAT, verts->vertexstride, verts->vertices);
glEnableClientState(GL_VERTEX_ARRAY);
qglClientActiveTextureARB(GL_TEXTURE0_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
if (currentshadowlight->shader->numstages)
{
//draw attent into dest alpha
GL_DrawAlpha();
Radeon_EnableAttentShader(tr);
GL_TexCoordPointer(3, GL_FLOAT, verts->vertexstride, verts->vertices);
Radeon_sendSurfacesPlain(surfs,numSurfaces);
Radeon_DisableAttentShader();
GL_ModulateAlphaDrawColor();
}
else
{
GL_AddColor();
}
glColor3fv(&currentshadowlight->color[0]);
GL_TexCoordPointer(2, GL_FLOAT, verts->texcoordstride, verts->texcoords);
Radeon_sendSurfacesTA(surfs, numSurfaces, tr, lo);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
void Radeon_freeDriver(void)
{
//nothing here...
}
void BUMP_InitRadeon(void)
{
GLint errPos, errCode;
const GLubyte *errString;
if ( gl_cardtype != RADEON ) return;
Radeon_CreateShaders();
//bind the correct stuff to the bump mapping driver
gl_bumpdriver.drawSurfaceListBase = Radeon_drawSurfaceListBase;
gl_bumpdriver.drawSurfaceListBump = Radeon_drawSurfaceListBump;
gl_bumpdriver.drawTriangleListBase = Radeon_drawTriangleListBase;
gl_bumpdriver.drawTriangleListBump = Radeon_drawTriangleListBump;
gl_bumpdriver.freeDriver = Radeon_freeDriver;
}