tenebrae2/gl_bumpradeon.c
2003-01-17 21:18:53 +00:00

1077 lines
45 KiB
C

/*
Copyright (C) 2001-2002 Charles Hollemeersch
Radeon Version (C) 2002 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;
static unsigned int fragment_shaders;
static unsigned int vertex_shaders;
//#define RADEONDEBUG
#ifdef RADEONDEBUG
void checkerror()
{
GLuint error = glGetError();
if ( error != GL_NO_ERROR )
{
_asm { int 3 };
}
}
#else
#define 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 GL_LookupRadeonSymbols (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 GL_CreateShadersRadeon()
{
float scaler[4] = {0.5f, 0.5f, 0.5f, 0.5f};
int i;
GLuint mvp, modelview, zcomp;
GLuint texturematrix, texturematrix2;
GLuint vertex;
GLuint texcoord0;
GLuint texcoord1;
GLuint texcoord2;
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");
SAFE_GET_PROC( qglPNTrianglesiATI, PFNGLPNTRIANGLESIATIPROC, "glPNTrianglesiATI");
SAFE_GET_PROC( qglPNTrianglesfATI, PFNGLPNTRIANGLESFATIPROC, "glPNTrianglesfATI");
#endif /* !__APPLE__ && !MACOSX */
glEnable(GL_FRAGMENT_SHADER_ATI);
fragment_shaders = qglGenFragmentShadersATI(2);
// combined diffuse & specular shader w/ vertex color
qglBindFragmentShaderATI(fragment_shaders);
checkerror();
qglBeginFragmentShaderATI();
checkerror();
qglSetFragmentShaderConstantATI(GL_CON_0_ATI, &scaler[0]);
checkerror();
// texld r0, t0
qglSampleMapATI (GL_REG_0_ATI, GL_TEXTURE0_ARB, GL_SWIZZLE_STR_ATI);
checkerror();
// texld r1, t1
qglSampleMapATI (GL_REG_1_ATI, GL_TEXTURE1_ARB, GL_SWIZZLE_STR_ATI);
checkerror();
// texld r2, t2
qglSampleMapATI (GL_REG_2_ATI, GL_TEXTURE2_ARB, GL_SWIZZLE_STR_ATI);
checkerror();
// texld r3, t3
qglSampleMapATI (GL_REG_3_ATI, GL_TEXTURE3_ARB, GL_SWIZZLE_STR_ATI);
checkerror();
// texld r4, t4
qglSampleMapATI (GL_REG_4_ATI, GL_TEXTURE4_ARB, GL_SWIZZLE_STR_ATI);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
checkerror();
qglEndFragmentShaderATI();
checkerror();
// Second shader with cube filter
qglBindFragmentShaderATI(fragment_shaders+1);
checkerror();
qglBeginFragmentShaderATI();
checkerror();
qglSetFragmentShaderConstantATI(GL_CON_0_ATI, &scaler[0]);
checkerror();
// texld r0, t0
qglSampleMapATI (GL_REG_0_ATI, GL_TEXTURE0_ARB, GL_SWIZZLE_STR_ATI);
checkerror();
// texld r1, t1
qglSampleMapATI (GL_REG_1_ATI, GL_TEXTURE1_ARB, GL_SWIZZLE_STR_ATI);
checkerror();
// texld r2, t2
qglSampleMapATI (GL_REG_2_ATI, GL_TEXTURE2_ARB, GL_SWIZZLE_STR_ATI);
checkerror();
// texld r3, t3
qglSampleMapATI (GL_REG_3_ATI, GL_TEXTURE3_ARB, GL_SWIZZLE_STR_ATI);
checkerror();
// texld r4, t4
qglSampleMapATI (GL_REG_4_ATI, GL_TEXTURE4_ARB, GL_SWIZZLE_STR_ATI);
checkerror();
// texld r5, t5
qglSampleMapATI (GL_REG_5_ATI, GL_TEXTURE5_ARB, GL_SWIZZLE_STR_ATI);
checkerror();
// gloss * atten * light color * specular +
// dot * color * atten * light color * self shadow =
// (gloss * specular + dot * color * self shadow ) * atten * light color * filter
// 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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
checkerror();
// add r0.rgb, r0.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);
checkerror();
// mul r0.rgb, r0.rgb, r4.rgb // (diffuse + specular)*atten*color
qglColorFragmentOp2ATI(GL_MUL_ATI,
GL_REG_0_ATI, GL_NONE, GL_NONE,
GL_REG_0_ATI, GL_NONE, GL_NONE,
GL_REG_4_ATI, GL_NONE, GL_NONE);
checkerror();
// mul_sat r0.rgb, r0.rgb, r5.rgb // (diffuse + specular)*atten*color*filter
qglColorFragmentOp2ATI(GL_MUL_ATI,
GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
GL_REG_0_ATI, GL_NONE, GL_NONE,
GL_REG_5_ATI, GL_NONE, GL_NONE);
checkerror();
qglEndFragmentShaderATI();
checkerror();
glDisable(GL_FRAGMENT_SHADER_ATI);
glEnable(GL_VERTEX_SHADER_EXT);
vertex_shaders = qglGenVertexShadersEXT(2);
checkerror();
qglBindVertexShaderEXT(vertex_shaders);
checkerror();
qglBeginVertexShaderEXT();
checkerror();
// Generates a necessary input for the diffuse bumpmapping registers
mvp = qglBindParameterEXT( GL_MVP_MATRIX_EXT );
checkerror();
modelview = qglBindParameterEXT( GL_MODELVIEW_MATRIX );
checkerror();
vertex = qglBindParameterEXT( GL_CURRENT_VERTEX_EXT );
checkerror();
color = qglBindParameterEXT( GL_CURRENT_COLOR );
checkerror();
texturematrix = qglBindTextureUnitParameterEXT( GL_TEXTURE4_ARB, GL_TEXTURE_MATRIX );
checkerror();
texcoord0 = qglBindTextureUnitParameterEXT( GL_TEXTURE0_ARB, GL_CURRENT_TEXTURE_COORDS );
checkerror();
texcoord1 = qglBindTextureUnitParameterEXT( GL_TEXTURE1_ARB, GL_CURRENT_TEXTURE_COORDS );
checkerror();
texcoord2 = qglBindTextureUnitParameterEXT( GL_TEXTURE2_ARB, GL_CURRENT_TEXTURE_COORDS );
checkerror();
disttemp = qglGenSymbolsEXT(GL_SCALAR_EXT, GL_LOCAL_EXT, GL_FULL_RANGE_EXT, 1);
checkerror();
disttemp2 = qglGenSymbolsEXT(GL_SCALAR_EXT, GL_LOCAL_EXT, GL_FULL_RANGE_EXT, 1);
checkerror();
zcomp = qglGenSymbolsEXT(GL_VECTOR_EXT, GL_LOCAL_EXT, GL_FULL_RANGE_EXT, 1);
checkerror();
fogstart = qglBindParameterEXT( GL_FOG_START );
checkerror();
fogend = qglBindParameterEXT( GL_FOG_END );
checkerror();
// Transform vertex to view-space
qglShaderOp2EXT( GL_OP_MULTIPLY_MATRIX_EXT, GL_OUTPUT_VERTEX_EXT, mvp, vertex );
checkerror();
// Transform vertex by texture matrix and copy to output
qglShaderOp2EXT( GL_OP_MULTIPLY_MATRIX_EXT, GL_OUTPUT_TEXTURE_COORD4_EXT, texturematrix, vertex );
checkerror();
// copy tex coords of unit 0 to unit 3
qglShaderOp1EXT( GL_OP_MOV_EXT, GL_OUTPUT_TEXTURE_COORD0_EXT, texcoord0);
checkerror();
qglShaderOp1EXT( GL_OP_MOV_EXT, GL_OUTPUT_TEXTURE_COORD1_EXT, texcoord1);
checkerror();
qglShaderOp1EXT( GL_OP_MOV_EXT, GL_OUTPUT_TEXTURE_COORD2_EXT, texcoord2);
checkerror();
qglShaderOp1EXT( GL_OP_MOV_EXT, GL_OUTPUT_TEXTURE_COORD3_EXT, texcoord0);
checkerror();
qglShaderOp1EXT( GL_OP_MOV_EXT, GL_OUTPUT_COLOR0_EXT, color);
checkerror();
// Transform vertex and take z for fog
qglExtractComponentEXT( zcomp, modelview, 2);
checkerror();
qglShaderOp2EXT( GL_OP_DOT4_EXT, disttemp, zcomp, vertex );
checkerror();
// calculate fog values end - z and end - start
qglShaderOp2EXT( GL_OP_SUB_EXT, disttemp, fogend, disttemp);
checkerror();
qglShaderOp2EXT( GL_OP_SUB_EXT, disttemp2, fogend, fogstart);
checkerror();
// divide end - z by end - start, that's it
qglShaderOp1EXT( GL_OP_RECIP_EXT, disttemp2, disttemp2);
checkerror();
qglShaderOp2EXT( GL_OP_MUL_EXT, GL_OUTPUT_FOG_EXT, disttemp, disttemp2);
checkerror();
qglEndVertexShaderEXT();
checkerror();
// Two transformed textures
qglBindVertexShaderEXT(vertex_shaders+1);
checkerror();
qglBeginVertexShaderEXT();
checkerror();
// Generates a necessary input for the diffuse bumpmapping registers
mvp = qglBindParameterEXT( GL_MVP_MATRIX_EXT );
checkerror();
modelview = qglBindParameterEXT( GL_MODELVIEW_MATRIX );
checkerror();
vertex = qglBindParameterEXT( GL_CURRENT_VERTEX_EXT );
checkerror();
color = qglBindParameterEXT( GL_CURRENT_COLOR );
checkerror();
texturematrix = qglBindTextureUnitParameterEXT( GL_TEXTURE4_ARB, GL_TEXTURE_MATRIX );
checkerror();
texturematrix2 = qglBindTextureUnitParameterEXT( GL_TEXTURE5_ARB, GL_TEXTURE_MATRIX );
checkerror();
texcoord0 = qglBindTextureUnitParameterEXT( GL_TEXTURE0_ARB, GL_CURRENT_TEXTURE_COORDS );
checkerror();
texcoord1 = qglBindTextureUnitParameterEXT( GL_TEXTURE1_ARB, GL_CURRENT_TEXTURE_COORDS );
checkerror();
texcoord2 = qglBindTextureUnitParameterEXT( GL_TEXTURE2_ARB, GL_CURRENT_TEXTURE_COORDS );
checkerror();
disttemp = qglGenSymbolsEXT(GL_SCALAR_EXT, GL_LOCAL_EXT, GL_FULL_RANGE_EXT, 1);
checkerror();
disttemp2 = qglGenSymbolsEXT(GL_SCALAR_EXT, GL_LOCAL_EXT, GL_FULL_RANGE_EXT, 1);
checkerror();
zcomp = qglGenSymbolsEXT(GL_VECTOR_EXT, GL_LOCAL_EXT, GL_FULL_RANGE_EXT, 1);
checkerror();
fogstart = qglBindParameterEXT( GL_FOG_START );
checkerror();
fogend = qglBindParameterEXT( GL_FOG_END );
checkerror();
// Transform vertex to view-space
qglShaderOp2EXT( GL_OP_MULTIPLY_MATRIX_EXT, GL_OUTPUT_VERTEX_EXT, mvp, vertex );
checkerror();
// Transform vertex by texture matrix and copy to output
qglShaderOp2EXT( GL_OP_MULTIPLY_MATRIX_EXT, GL_OUTPUT_TEXTURE_COORD4_EXT, texturematrix, vertex );
checkerror();
// Transform vertex by texture matrix and copy to output
qglShaderOp2EXT( GL_OP_MULTIPLY_MATRIX_EXT, GL_OUTPUT_TEXTURE_COORD5_EXT, texturematrix2, vertex );
checkerror();
// copy tex coords of unit 0 to unit 3
qglShaderOp1EXT( GL_OP_MOV_EXT, GL_OUTPUT_TEXTURE_COORD0_EXT, texcoord0);
checkerror();
qglShaderOp1EXT( GL_OP_MOV_EXT, GL_OUTPUT_TEXTURE_COORD1_EXT, texcoord1);
checkerror();
qglShaderOp1EXT( GL_OP_MOV_EXT, GL_OUTPUT_TEXTURE_COORD2_EXT, texcoord2);
checkerror();
qglShaderOp1EXT( GL_OP_MOV_EXT, GL_OUTPUT_TEXTURE_COORD3_EXT, texcoord0);
checkerror();
qglShaderOp1EXT( GL_OP_MOV_EXT, GL_OUTPUT_COLOR0_EXT, color);
checkerror();
// Transform vertex and take z for fog
qglExtractComponentEXT( zcomp, modelview, 2);
checkerror();
qglShaderOp2EXT( GL_OP_DOT4_EXT, disttemp, zcomp, vertex );
checkerror();
// calculate fog values end - z and end - start
qglShaderOp2EXT( GL_OP_SUB_EXT, disttemp, fogend, disttemp);
checkerror();
qglShaderOp2EXT( GL_OP_SUB_EXT, disttemp2, fogend, fogstart);
checkerror();
// divide end - z by end - start, that's it
qglShaderOp1EXT( GL_OP_RECIP_EXT, disttemp2, disttemp2);
checkerror();
qglShaderOp2EXT( GL_OP_MUL_EXT, GL_OUTPUT_FOG_EXT, disttemp, disttemp2);
checkerror();
qglEndVertexShaderEXT();
checkerror();
glDisable(GL_VERTEX_SHADER_EXT);
}
void GL_DisableDiffuseShaderRadeon()
{
//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->filtercube)
{
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
glPopMatrix();
GL_SelectTexture(GL_TEXTURE5_ARB);
}
glDisable(GL_TEXTURE_3D);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
GL_SelectTexture(GL_TEXTURE0_ARB);
}
void GL_EnableDiffuseSpecularShaderRadeon(qboolean world, vec3_t lightOrig)
{
float invrad = 1/currentshadowlight->radius;
//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
// register combiner setup does not change only the bound texture)
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);
GL_SelectTexture(GL_TEXTURE4_ARB);
glMatrixMode(GL_TEXTURE);
glPushMatrix();
glLoadIdentity();
if (currentshadowlight->filtercube)
{
glGetError();
qglBindFragmentShaderATI( fragment_shaders + 1 );
checkerror();
qglBindVertexShaderEXT( vertex_shaders + 1);
checkerror();
glEnable(GL_TEXTURE_CUBE_MAP_ARB);
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, currentshadowlight->filtercube);
GL_SetupCubeMapMatrix(world);
GL_SelectTexture(GL_TEXTURE5_ARB);
glMatrixMode(GL_TEXTURE);
glPushMatrix();
glLoadIdentity();
}
else
{
glGetError();
qglBindFragmentShaderATI( fragment_shaders );
checkerror();
qglBindVertexShaderEXT( vertex_shaders );
checkerror();
}
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(invrad, invrad, invrad);
glTranslatef(-lightOrig[0], -lightOrig[1], -lightOrig[2]);
GL_SelectTexture(GL_TEXTURE0_ARB);
}
void R_DrawWorldRadeonDiffuseSpecular(lightcmd_t *lightCmds)
{
int command, num, i;
int lightPos = 0;
vec3_t lightOr;
msurface_t *surf;
float *v;
float* lightP;
vec3_t lightDir;
vec3_t tsH,H;
texture_t *t;//XYZ
//support flickering lights
VectorCopy(currentshadowlight->origin,lightOr);
while (1)
{
command = lightCmds[lightPos++].asInt;
if (command == 0) break; //end of list
surf = lightCmds[lightPos++].asVoid;
if (surf->visframe != r_framecount) {
lightPos+=(4+surf->polys->numverts*(2+3));
continue;
}
num = surf->polys->numverts;
lightPos+=4;//skip color
//XYZ
t = R_TextureAnimation (surf->texinfo->texture);
GL_SelectTexture(GL_TEXTURE0_ARB);
GL_Bind(t->gl_texturenum+1);
GL_SelectTexture(GL_TEXTURE3_ARB);
GL_Bind(t->gl_texturenum);
glBegin(command);
//v = surf->polys->verts[0];
v = (float *)(&globalVertexTable[surf->polys->firstvertex]);
for (i=0; i<num; i++, v+= VERTEXSIZE)
{
//skip attent texture coord.
lightPos += 2;
lightP = &lightCmds[lightPos].asFloat;
lightPos += 3;
VectorCopy(lightP, lightDir);
VectorNormalize(lightDir);
//calculate local H vector and put it into tangent space
//r_origin = camera position
VectorSubtract(r_refdef.vieworg,v,H);
VectorNormalize(H);
//put H in tangent space first since lightDir (precalc) is already in tang space
if (surf->flags & SURF_PLANEBACK)
{
tsH[2] = -DotProduct(H,surf->plane->normal);
}
else
{
tsH[2] = DotProduct(H,surf->plane->normal);
}
tsH[1] = -DotProduct(H,surf->texinfo->vecs[1]);
tsH[0] = DotProduct(H,surf->texinfo->vecs[0]);
VectorAdd(lightDir,tsH,tsH);
// diffuse
qglMultiTexCoord2fARB(GL_TEXTURE0_ARB, v[3], v[4]);
qglMultiTexCoord3fvARB(GL_TEXTURE1_ARB, lightP);
// half vector for specular
qglMultiTexCoord3fvARB(GL_TEXTURE2_ARB,&tsH[0]);
glVertex3fv(&v[0]);
}
glEnd();
}
GL_SelectTexture(GL_TEXTURE0_ARB);
}
void R_DrawBrushRadeonDiffuseSpecular(entity_t *e)
{
model_t *model = e->model;
msurface_t *surf;
glpoly_t *poly;
int i, j, count;
brushlightinstant_t *ins = e->brushlightinstant;
float *v;
texture_t *t;//XYZ
count = 0;
surf = &model->surfaces[model->firstmodelsurface];
for (i=0; i<model->nummodelsurfaces; i++, surf++)
{
if (!ins->polygonVis[i]) continue;
poly = surf->polys;
//XYZ
t = R_TextureAnimation (surf->texinfo->texture);
GL_SelectTexture(GL_TEXTURE0_ARB);
GL_Bind(t->gl_texturenum+1);
GL_SelectTexture(GL_TEXTURE3_ARB);
GL_Bind(t->gl_texturenum);
glBegin(GL_TRIANGLE_FAN);
//v = poly->verts[0];
v = (float *)(&globalVertexTable[poly->firstvertex]);
for (j=0 ; j<poly->numverts ; j++, v+= VERTEXSIZE)
{
qglMultiTexCoord2fARB(GL_TEXTURE0_ARB, v[3], v[4]);
qglMultiTexCoord3fvARB(GL_TEXTURE1_ARB,&ins->tslights[count+j][0]);
qglMultiTexCoord3fvARB(GL_TEXTURE2_ARB,&ins->tshalfangles[count+j][0]);
glVertex3fv(v);
}
glEnd();
count+=surf->numedges;
}
}
void R_DrawAliasFrameRadeonDiffuseSpecular (aliashdr_t *paliashdr, aliasframeinstant_t *instant)
{
mtriangle_t *tris;
fstvert_t *texcoords;
int anim;
int *indecies;
aliaslightinstant_t *linstant = instant->lightinstant;
tris = (mtriangle_t *)((byte *)paliashdr + paliashdr->triangles);
texcoords = (fstvert_t *)((byte *)paliashdr + paliashdr->texcoords);
//bind normal map
anim = (int)(cl.time*10) & 3;
GL_SelectTexture(GL_TEXTURE0_ARB);
GL_Bind(paliashdr->gl_texturenum[currententity->skinnum][anim]+1);
GL_SelectTexture(GL_TEXTURE3_ARB);
GL_Bind(paliashdr->gl_texturenum[currententity->skinnum][anim]);
indecies = (int *)((byte *)paliashdr + paliashdr->indecies);
glVertexPointer(3, GL_FLOAT, 0, instant->vertices);
glEnableClientState(GL_VERTEX_ARRAY);
glNormalPointer(GL_FLOAT, 0, instant->normals);
glEnableClientState(GL_NORMAL_ARRAY);
qglClientActiveTextureARB(GL_TEXTURE0_ARB);
glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
qglClientActiveTextureARB(GL_TEXTURE1_ARB);
glTexCoordPointer(3, GL_FLOAT, 0, linstant->tslights);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
qglClientActiveTextureARB(GL_TEXTURE2_ARB);
glTexCoordPointer(3, GL_FLOAT, 0, linstant->tshalfangles);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
//glDrawElements(GL_TRIANGLES,paliashdr->numtris*3,GL_UNSIGNED_INT,indecies);
glDrawElements(GL_TRIANGLES,linstant->numtris*3,GL_UNSIGNED_INT,&linstant->indecies[0]);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
qglClientActiveTextureARB(GL_TEXTURE0_ARB);
GL_SelectTexture(GL_TEXTURE0_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
void R_DrawWorldBumpedRadeon()
{
if (!currentshadowlight->visible)
return;
glDepthMask (0);
glShadeModel (GL_SMOOTH);
GL_AddColor();
glColor3fv(&currentshadowlight->color[0]);
GL_EnableDiffuseSpecularShaderRadeon(true,currentshadowlight->origin);
R_DrawWorldRadeonDiffuseSpecular(currentshadowlight->lightCmds);
GL_DisableDiffuseShaderRadeon();
glColor3f (1,1,1);
glDisable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthMask (1);
}
void R_DrawBrushBumpedRadeon(entity_t *e)
{
GL_AddColor();
glColor3fv(&currentshadowlight->color[0]);
GL_EnableDiffuseSpecularShaderRadeon(false,((brushlightinstant_t *)e->brushlightinstant)->lightpos);
R_DrawBrushRadeonDiffuseSpecular(e);
GL_DisableDiffuseShaderRadeon();
}
void R_DrawAliasBumpedRadeon(aliashdr_t *paliashdr, aliasframeinstant_t *instant)
{
if ( gl_truform.value )
{
glEnable(GL_PN_TRIANGLES_ATI);
qglPNTrianglesiATI(GL_PN_TRIANGLES_POINT_MODE_ATI, GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI);
qglPNTrianglesiATI(GL_PN_TRIANGLES_NORMAL_MODE_ATI, GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI);
qglPNTrianglesiATI(GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI, gl_truform_tesselation.value);
}
GL_AddColor();
glColor3fv(&currentshadowlight->color[0]);
GL_EnableDiffuseSpecularShaderRadeon(false,instant->lightinstant->lightpos);
R_DrawAliasFrameRadeonDiffuseSpecular(paliashdr,instant);
GL_DisableDiffuseShaderRadeon();
if ( gl_truform.value )
{
glDisable(GL_PN_TRIANGLES_ATI);
}
}