Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- ===========================================================================
- Doom 3 GPL Source Code
- Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
- This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
- Doom 3 Source Code 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 3 of the License, or
- (at your option) any later version.
- Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
- In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
- If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
- ===========================================================================
- */
- #include "../idlib/precompiled.h"
- #include "tr_local.h"
- #define GLSL_INPUT_ATTRIBS \
- "in vec4 attrTexCoords;\n" \
- "in vec3 attrTangents0;\n" \
- "in vec3 attrTangents1;\n" \
- "in vec3 attrNormal;\n" \
- "mat3x3 u_lightMatrix = mat3x3 (attrTangents0, attrTangents1, attrNormal);\n\n"
- #define GLSL_UNIFORMS \
- "uniform vec4 u_light_origin;\n" \
- "uniform vec4 u_view_origin;\n" \
- "uniform vec4 u_color_modulate;\n" \
- "uniform vec4 u_color_add;\n" \
- "uniform mat2x4 u_diffMatrix;\n" \
- "uniform mat2x4 u_bumpMatrix;\n" \
- "uniform mat2x4 u_specMatrix;\n" \
- "uniform mat4x4 u_projMatrix;\n" \
- "uniform mat4x4 u_fallMatrix;\n" \
- "uniform sampler2D bumpImage;\n" \
- "uniform sampler2D lightFalloffImage;\n" \
- "uniform sampler2D lightImage;\n" \
- "uniform sampler2D diffuseImage;\n" \
- "uniform sampler2D specularImage;\n" \
- "uniform vec4 u_constant_diffuse;\n" \
- "uniform vec4 u_constant_specular;\n\n"
- #define GLSL_VARYINGS \
- "varying vec2 diffCoords;\n" \
- "varying vec2 bumpCoords;\n" \
- "varying vec2 specCoords;\n" \
- "varying vec4 projCoords;\n" \
- "varying vec4 fallCoords;\n" \
- "varying vec3 lightDir;\n" \
- "varying vec3 halfAngle;\n" \
- "varying vec4 Color;\n"
- // these are our GLSL interaction shaders
- #define interaction_vs \
- GLSL_INPUT_ATTRIBS \
- GLSL_UNIFORMS \
- GLSL_VARYINGS \
- "void main ()\n" \
- "{\n" \
- " // we must use ftransform as Doom 3 needs invariant position\n" \
- " gl_Position = ftransform ();\n" \
- "\n" \
- " diffCoords = attrTexCoords * u_diffMatrix;\n" \
- " bumpCoords = attrTexCoords * u_bumpMatrix;\n" \
- " specCoords = attrTexCoords * u_specMatrix;\n" \
- "\n" \
- " projCoords = gl_Vertex * u_projMatrix;\n" \
- " fallCoords = gl_Vertex * u_fallMatrix;\n" \
- "\n" \
- " Color = (gl_Color * u_color_modulate) + u_color_add;\n" \
- "\n" \
- " vec3 OffsetViewOrigin = (u_view_origin - gl_Vertex).xyz;\n" \
- " vec3 OffsetLightOrigin = (u_light_origin - gl_Vertex).xyz;\n" \
- "\n" \
- " lightDir = OffsetLightOrigin * u_lightMatrix;\n" \
- " halfAngle = (normalize (OffsetViewOrigin) + normalize (OffsetLightOrigin)) * u_lightMatrix;\n" \
- "}\n\n"
- #define interaction_fs \
- GLSL_UNIFORMS \
- GLSL_VARYINGS \
- "void main ()\n" \
- "{\n" \
- " vec3 normalMap = texture2D (bumpImage, bumpCoords).agb * 2.0 - 1.0;\n" \
- " vec4 lightMap = texture2DProj (lightImage, projCoords);\n" \
- "\n" \
- " lightMap *= dot (normalize (lightDir), normalMap);\n" \
- " lightMap *= texture2DProj (lightFalloffImage, fallCoords);\n" \
- " lightMap *= Color;\n" \
- "\n" \
- " vec4 diffuseMap = texture2D (diffuseImage, diffCoords) * u_constant_diffuse;\n" \
- " float specularComponent = clamp ((dot (normalize (halfAngle), normalMap) - 0.75) * 4.0, 0.0, 1.0);\n" \
- "\n" \
- " vec4 specularResult = u_constant_specular * (specularComponent * specularComponent);\n" \
- " vec4 specularMap = texture2D (specularImage, specCoords) * 2.0;\n" \
- "\n" \
- " gl_FragColor = (diffuseMap + (specularResult * specularMap)) * lightMap;\n" \
- "}\n\n"
- GLuint u_light_origin = 0;
- GLuint u_view_origin = 0;
- GLuint u_color_modulate = 0;
- GLuint u_color_add = 0;
- GLuint u_constant_diffuse = 0;
- GLuint u_constant_specular = 0;
- GLuint u_diffMatrix = 0;
- GLuint u_bumpMatrix = 0;
- GLuint u_specMatrix = 0;
- GLuint u_projMatrix = 0;
- GLuint u_fallMatrix = 0;
- struct glsltable_t
- {
- GLuint slot;
- GLchar *name;
- };
- glsltable_t interactionAttribs[] =
- {
- {8, "attrTexCoords"},
- {9, "attrTangents0"},
- {10, "attrTangents1"},
- {11, "attrNormal"}
- };
- GLuint rb_glsl_interaction_program = 0;
- idCVar r_useGLSL ("r_useGLSL", "1", CVAR_RENDERER | CVAR_BOOL, "use GLSL backend for interaction passes");
- /*
- =========================================================================================
- GENERAL INTERACTION RENDERING
- =========================================================================================
- */
- void RB_ARB2_BindTexture (int unit, idImage *tex)
- {
- backEnd.glState.currenttmu = unit;
- glActiveTextureARB (GL_TEXTURE0_ARB + unit);
- tex->Bind ();
- }
- void RB_ARB2_UnbindTexture (int unit)
- {
- backEnd.glState.currenttmu = unit;
- glActiveTextureARB (GL_TEXTURE0_ARB + unit);
- globalImages->BindNull ();
- }
- void RB_ARB2_BindInteractionTextureSet (const drawInteraction_t *din)
- {
- // texture 1 will be the per-surface bump map
- RB_ARB2_BindTexture (1, din->bumpImage);
- // texture 2 will be the light falloff texture
- RB_ARB2_BindTexture (2, din->lightFalloffImage);
- // texture 3 will be the light projection texture
- RB_ARB2_BindTexture (3, din->lightImage);
- // texture 4 is the per-surface diffuse map
- RB_ARB2_BindTexture (4, din->diffuseImage);
- // texture 5 is the per-surface specular map
- RB_ARB2_BindTexture (5, din->specularImage);
- }
- static float *RB_GLSL_MakeMatrix (const float *in1, const float *in2, const float *in3 = NULL, const float *in4 = NULL)
- {
- static float m[8];
- if (in1) memcpy (&m[0], in1, sizeof (float) * 4);
- if (in2) memcpy (&m[4], in2, sizeof (float) * 4);
- if (in3) memcpy (&m[8], in3, sizeof (float) * 4);
- if (in4) memcpy (&m[12], in4, sizeof (float) * 4);
- return m;
- }
- #define DIFFMATRIX(ofs) din->diffuseMatrix[ofs].ToFloatPtr ()
- #define BUMPMATRIX(ofs) din->bumpMatrix[ofs].ToFloatPtr ()
- #define SPECMATRIX(ofs) din->specularMatrix[ofs].ToFloatPtr ()
- #define PROJMATRIX(ofs) din->lightProjection[ofs].ToFloatPtr ()
- void RB_GLSL_DrawInteraction (const drawInteraction_t *din)
- {
- static const float whalf[] = {0.0, 0.0, 0.0, 0.5};
- static const float wzero[] = {0.0, 0.0, 0.0, 0.0};
- static const float wone[] = {0.0, 0.0, 0.0, 1.0};
- glUniform4fv (u_light_origin, 1, din->localLightOrigin.ToFloatPtr ());
- glUniform4fv (u_view_origin, 1, din->localViewOrigin.ToFloatPtr ());
- glUniformMatrix2x4fv (u_diffMatrix, 1, GL_FALSE, RB_GLSL_MakeMatrix (DIFFMATRIX (0), DIFFMATRIX (1)));
- glUniformMatrix2x4fv (u_bumpMatrix, 1, GL_FALSE, RB_GLSL_MakeMatrix (BUMPMATRIX (0), BUMPMATRIX (1)));
- glUniformMatrix2x4fv (u_specMatrix, 1, GL_FALSE, RB_GLSL_MakeMatrix (SPECMATRIX (0), SPECMATRIX (1)));
- glUniformMatrix4fv (u_projMatrix, 1, GL_FALSE, RB_GLSL_MakeMatrix (PROJMATRIX (0), PROJMATRIX (1), wzero, PROJMATRIX (2)));
- glUniformMatrix4fv (u_fallMatrix, 1, GL_FALSE, RB_GLSL_MakeMatrix (PROJMATRIX (3), whalf, wzero, wone));
- static const float zero[4] = {0, 0, 0, 0};
- static const float one[4] = {1, 1, 1, 1};
- static const float negOne[4] = {-1, -1, -1, -1};
- switch (din->vertexColor)
- {
- case SVC_IGNORE:
- glUniform4fv (u_color_modulate, 1, zero);
- glUniform4fv (u_color_add, 1, one);
- break;
- case SVC_MODULATE:
- glUniform4fv (u_color_modulate, 1, one);
- glUniform4fv (u_color_add, 1, zero);
- break;
- case SVC_INVERSE_MODULATE:
- glUniform4fv (u_color_modulate, 1, negOne);
- glUniform4fv (u_color_add, 1, one);
- break;
- }
- // set the constant colors
- glUniform4fv (u_constant_diffuse, 1, din->diffuseColor.ToFloatPtr ());
- glUniform4fv (u_constant_specular, 1, din->specularColor.ToFloatPtr ());
- // set the textures
- RB_ARB2_BindInteractionTextureSet (din);
- // draw it
- RB_DrawElementsWithCounters (din->surf->geo);
- }
- /*
- ==================
- RB_ARB2_DrawInteraction
- ==================
- */
- void RB_ARB2_DrawInteraction (const drawInteraction_t *din)
- {
- // load all the vertex program parameters
- glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_LIGHT_ORIGIN, din->localLightOrigin.ToFloatPtr ());
- glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_VIEW_ORIGIN, din->localViewOrigin.ToFloatPtr ());
- glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_LIGHT_PROJECT_S, din->lightProjection[0].ToFloatPtr ());
- glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_LIGHT_PROJECT_T, din->lightProjection[1].ToFloatPtr ());
- glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_LIGHT_PROJECT_Q, din->lightProjection[2].ToFloatPtr ());
- glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_LIGHT_FALLOFF_S, din->lightProjection[3].ToFloatPtr ());
- glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_BUMP_MATRIX_S, din->bumpMatrix[0].ToFloatPtr ());
- glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_BUMP_MATRIX_T, din->bumpMatrix[1].ToFloatPtr ());
- glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_DIFFUSE_MATRIX_S, din->diffuseMatrix[0].ToFloatPtr ());
- glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_DIFFUSE_MATRIX_T, din->diffuseMatrix[1].ToFloatPtr ());
- glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_SPECULAR_MATRIX_S, din->specularMatrix[0].ToFloatPtr ());
- glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_SPECULAR_MATRIX_T, din->specularMatrix[1].ToFloatPtr ());
- // testing fragment based normal mapping
- if (r_testARBProgram.GetBool ())
- {
- glProgramEnvParameter4fvARB (GL_FRAGMENT_PROGRAM_ARB, 2, din->localLightOrigin.ToFloatPtr ());
- glProgramEnvParameter4fvARB (GL_FRAGMENT_PROGRAM_ARB, 3, din->localViewOrigin.ToFloatPtr ());
- }
- static const float zero[4] = {0, 0, 0, 0};
- static const float one[4] = {1, 1, 1, 1};
- static const float negOne[4] = {-1, -1, -1, -1};
- switch (din->vertexColor)
- {
- case SVC_IGNORE:
- glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_COLOR_MODULATE, zero);
- glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_COLOR_ADD, one);
- break;
- case SVC_MODULATE:
- glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_COLOR_MODULATE, one);
- glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_COLOR_ADD, zero);
- break;
- case SVC_INVERSE_MODULATE:
- glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_COLOR_MODULATE, negOne);
- glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_COLOR_ADD, one);
- break;
- }
- // set the constant colors
- glProgramEnvParameter4fvARB (GL_FRAGMENT_PROGRAM_ARB, 0, din->diffuseColor.ToFloatPtr ());
- glProgramEnvParameter4fvARB (GL_FRAGMENT_PROGRAM_ARB, 1, din->specularColor.ToFloatPtr ());
- // set the textures
- RB_ARB2_BindInteractionTextureSet (din);
- // draw it
- RB_DrawElementsWithCounters (din->surf->geo);
- }
- void RB_ARB2_SharedSurfaceSetup (const drawSurf_t *surf)
- {
- // set the vertex pointers
- idDrawVert *ac = (idDrawVert *) vertexCache.Position (surf->geo->ambientCache);
- glColorPointer (4, GL_UNSIGNED_BYTE, sizeof (idDrawVert), ac->color);
- glVertexAttribPointerARB (11, 3, GL_FLOAT, false, sizeof (idDrawVert), ac->normal.ToFloatPtr ());
- glVertexAttribPointerARB (10, 3, GL_FLOAT, false, sizeof (idDrawVert), ac->tangents[1].ToFloatPtr ());
- glVertexAttribPointerARB (9, 3, GL_FLOAT, false, sizeof (idDrawVert), ac->tangents[0].ToFloatPtr ());
- glVertexAttribPointerARB (8, 2, GL_FLOAT, false, sizeof (idDrawVert), ac->st.ToFloatPtr ());
- glVertexPointer (3, GL_FLOAT, sizeof (idDrawVert), ac->xyz.ToFloatPtr ());
- }
- /*
- =============
- RB_ARB2_CreateDrawInteractions
- =============
- */
- void RB_ARB2_CreateDrawInteractions (const drawSurf_t *surf)
- {
- if (!surf) return;
- // perform setup here that will be constant for all interactions
- GL_State (GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | backEnd.depthFunc);
- // enable the vertex arrays
- glEnableVertexAttribArrayARB (8);
- glEnableVertexAttribArrayARB (9);
- glEnableVertexAttribArrayARB (10);
- glEnableVertexAttribArrayARB (11);
- glEnableClientState (GL_COLOR_ARRAY);
- if (r_useGLSL.GetBool () && glConfig.glVersion >= 2.0 && rb_glsl_interaction_program)
- {
- glUseProgram (rb_glsl_interaction_program);
- for (; surf; surf = surf->nextOnLight)
- {
- // perform setup here that will not change over multiple interaction passes
- RB_ARB2_SharedSurfaceSetup (surf);
- // this may cause RB_ARB2_DrawInteraction to be exacuted multiple
- // times with different colors and images if the surface or light have multiple layers
- RB_CreateSingleDrawInteractions (surf, RB_GLSL_DrawInteraction);
- }
- // back to fixed (or ARB program)
- glUseProgram (0);
- }
- else
- {
- glEnable (GL_VERTEX_PROGRAM_ARB);
- glEnable (GL_FRAGMENT_PROGRAM_ARB);
- // texture 0 is the normalization cube map for the vector towards the light
- if (backEnd.vLight->lightShader->IsAmbientLight ())
- RB_ARB2_BindTexture (0, globalImages->ambientNormalMap);
- else RB_ARB2_BindTexture (0, globalImages->normalCubeMapImage);
- // texture 6 is the specular lookup table
- if (r_testARBProgram.GetBool ())
- RB_ARB2_BindTexture (6, globalImages->specular2DTableImage);
- else RB_ARB2_BindTexture (6, globalImages->specularTableImage);
- // bind the vertex program
- if (r_testARBProgram.GetBool ())
- {
- glBindProgramARB (GL_VERTEX_PROGRAM_ARB, VPROG_TEST);
- glBindProgramARB (GL_FRAGMENT_PROGRAM_ARB, FPROG_TEST);
- }
- else
- {
- glBindProgramARB (GL_VERTEX_PROGRAM_ARB, VPROG_INTERACTION);
- glBindProgramARB (GL_FRAGMENT_PROGRAM_ARB, FPROG_INTERACTION);
- }
- for (; surf; surf = surf->nextOnLight)
- {
- // perform setup here that will not change over multiple interaction passes
- RB_ARB2_SharedSurfaceSetup (surf);
- // this may cause RB_ARB2_DrawInteraction to be exacuted multiple
- // times with different colors and images if the surface or light have multiple layers
- RB_CreateSingleDrawInteractions (surf, RB_ARB2_DrawInteraction);
- }
- glBindProgramARB (GL_VERTEX_PROGRAM_ARB, 0);
- glDisable (GL_VERTEX_PROGRAM_ARB);
- glDisable (GL_FRAGMENT_PROGRAM_ARB);
- }
- glDisableVertexAttribArrayARB (8);
- glDisableVertexAttribArrayARB (9);
- glDisableVertexAttribArrayARB (10);
- glDisableVertexAttribArrayARB (11);
- glDisableClientState (GL_COLOR_ARRAY);
- // disable features
- RB_ARB2_UnbindTexture (6);
- RB_ARB2_UnbindTexture (5);
- RB_ARB2_UnbindTexture (4);
- RB_ARB2_UnbindTexture (3);
- RB_ARB2_UnbindTexture (2);
- RB_ARB2_UnbindTexture (1);
- backEnd.glState.currenttmu = -1;
- GL_SelectTexture (0);
- }
- void RB_ARB2_InteractionPass (const drawSurf_t *shadowSurfs, const drawSurf_t *lightSurfs)
- {
- // save on state changes by not bothering to setup/takedown all the messy state when there are no surfs to draw
- if (shadowSurfs)
- {
- if (r_useShadowVertexProgram.GetBool ())
- {
- glEnable (GL_VERTEX_PROGRAM_ARB);
- glBindProgramARB (GL_VERTEX_PROGRAM_ARB, VPROG_STENCIL_SHADOW);
- RB_StencilShadowPass (shadowSurfs);
- // need to disable ASM programs when switching to GLSL
- if (r_useGLSL.GetBool () && glConfig.glVersion >= 2.0 && rb_glsl_interaction_program)
- {
- glBindProgramARB (GL_VERTEX_PROGRAM_ARB, 0);
- glDisable (GL_VERTEX_PROGRAM_ARB);
- }
- }
- else RB_StencilShadowPass (shadowSurfs);
- }
- if (lightSurfs) RB_ARB2_CreateDrawInteractions (lightSurfs);
- }
- /*
- ==================
- RB_ARB2_DrawInteractions
- ==================
- */
- void RB_ARB2_DrawInteractions (void)
- {
- viewLight_t *vLight;
- const idMaterial *lightShader;
- GL_SelectTexture (0);
- glDisableClientState (GL_TEXTURE_COORD_ARRAY);
- // for each light, perform adding and shadowing
- for (vLight = backEnd.viewDef->viewLights; vLight; vLight = vLight->next)
- {
- backEnd.vLight = vLight;
- // do fogging later
- if (vLight->lightShader->IsFogLight ()) continue;
- if (vLight->lightShader->IsBlendLight ()) continue;
- // nothing to see here; these aren't the surfaces you're looking for; move along
- if (!vLight->localInteractions &&
- !vLight->globalInteractions &&
- !vLight->globalShadows &&
- !vLight->localShadows &&
- !vLight->translucentInteractions) continue;
- lightShader = vLight->lightShader;
- // clear the stencil buffer if needed
- if (vLight->globalShadows || vLight->localShadows)
- {
- backEnd.currentScissor = vLight->scissorRect;
- if (r_useScissor.GetBool ())
- {
- glScissor (backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1,
- backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1,
- backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1,
- backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1);
- }
- glClear (GL_STENCIL_BUFFER_BIT);
- }
- else
- {
- // no shadows, so no need to read or write the stencil buffer
- // we might in theory want to use GL_ALWAYS instead of disabling
- // completely, to satisfy the invarience rules
- glStencilFunc (GL_ALWAYS, 128, 255);
- }
- // run our passes for global and local
- RB_ARB2_InteractionPass (vLight->globalShadows, vLight->localInteractions);
- RB_ARB2_InteractionPass (vLight->localShadows, vLight->globalInteractions);
- // translucent surfaces never get stencil shadowed
- if (r_skipTranslucent.GetBool ()) continue;
- glStencilFunc (GL_ALWAYS, 128, 255);
- backEnd.depthFunc = GLS_DEPTHFUNC_LESS;
- RB_ARB2_CreateDrawInteractions (vLight->translucentInteractions);
- backEnd.depthFunc = GLS_DEPTHFUNC_EQUAL;
- }
- // ensure that these are down
- glBindProgramARB (GL_VERTEX_PROGRAM_ARB, 0);
- glDisable (GL_VERTEX_PROGRAM_ARB);
- glUseProgram (0);
- // disable stencil shadow test
- glStencilFunc (GL_ALWAYS, 128, 255);
- GL_SelectTexture (0);
- glEnableClientState (GL_TEXTURE_COORD_ARRAY);
- }
- //===================================================================================
- typedef struct
- {
- GLenum target;
- GLuint ident;
- char name[64];
- } progDef_t;
- static const int MAX_GLPROGS = 200;
- // a single file can have both a vertex program and a fragment program
- static progDef_t progs[MAX_GLPROGS] =
- {
- { GL_VERTEX_PROGRAM_ARB, VPROG_TEST, "test.vfp" },
- { GL_FRAGMENT_PROGRAM_ARB, FPROG_TEST, "test.vfp" },
- { GL_VERTEX_PROGRAM_ARB, VPROG_INTERACTION, "interaction.vfp" },
- { GL_FRAGMENT_PROGRAM_ARB, FPROG_INTERACTION, "interaction.vfp" },
- { GL_VERTEX_PROGRAM_ARB, VPROG_BUMPY_ENVIRONMENT, "bumpyEnvironment.vfp" },
- { GL_FRAGMENT_PROGRAM_ARB, FPROG_BUMPY_ENVIRONMENT, "bumpyEnvironment.vfp" },
- { GL_VERTEX_PROGRAM_ARB, VPROG_AMBIENT, "ambientLight.vfp" },
- { GL_FRAGMENT_PROGRAM_ARB, FPROG_AMBIENT, "ambientLight.vfp" },
- { GL_VERTEX_PROGRAM_ARB, VPROG_STENCIL_SHADOW, "shadow.vp" },
- { GL_VERTEX_PROGRAM_ARB, VPROG_R200_INTERACTION, "R200_interaction.vp" },
- { GL_VERTEX_PROGRAM_ARB, VPROG_NV20_BUMP_AND_LIGHT, "nv20_bumpAndLight.vp" },
- { GL_VERTEX_PROGRAM_ARB, VPROG_NV20_DIFFUSE_COLOR, "nv20_diffuseColor.vp" },
- { GL_VERTEX_PROGRAM_ARB, VPROG_NV20_SPECULAR_COLOR, "nv20_specularColor.vp" },
- { GL_VERTEX_PROGRAM_ARB, VPROG_NV20_DIFFUSE_AND_SPECULAR_COLOR, "nv20_diffuseAndSpecularColor.vp" },
- { GL_VERTEX_PROGRAM_ARB, VPROG_ENVIRONMENT, "environment.vfp" },
- { GL_FRAGMENT_PROGRAM_ARB, FPROG_ENVIRONMENT, "environment.vfp" },
- { GL_VERTEX_PROGRAM_ARB, VPROG_GLASSWARP, "arbVP_glasswarp.txt" },
- { GL_FRAGMENT_PROGRAM_ARB, FPROG_GLASSWARP, "arbFP_glasswarp.txt" },
- // additional programs can be dynamically specified in materials
- };
- /*
- =================
- R_LoadARBProgram
- =================
- */
- void R_LoadARBProgram (int progIndex)
- {
- int ofs;
- int err;
- idStr fullPath = "glprogs/";
- fullPath += progs[progIndex].name;
- char *fileBuffer;
- char *buffer;
- char *start, *end;
- common->Printf ("%s", fullPath.c_str());
- // load the program even if we don't support it, so
- // fs_copyfiles can generate cross-platform data dumps
- fileSystem->ReadFile (fullPath.c_str(), (void **) &fileBuffer, NULL);
- if (!fileBuffer)
- {
- common->Printf (": File not found\n");
- return;
- }
- // copy to stack memory and free
- buffer = (char *) _alloca (strlen (fileBuffer) + 1);
- strcpy (buffer, fileBuffer);
- fileSystem->FreeFile (fileBuffer);
- if (!glConfig.isInitialized) return;
- // submit the program string at start to GL
- if (progs[progIndex].ident == 0)
- {
- // allocate a new identifier for this program
- progs[progIndex].ident = PROG_USER + progIndex;
- }
- // vertex and fragment programs can both be present in a single file, so
- // scan for the proper header to be the start point, and stamp a 0 in after the end
- if (progs[progIndex].target == GL_VERTEX_PROGRAM_ARB)
- {
- if (!glConfig.ARBVertexProgramAvailable)
- {
- common->Printf (": GL_VERTEX_PROGRAM_ARB not available\n");
- return;
- }
- start = strstr ((char *) buffer, "!!ARBvp");
- }
- if (progs[progIndex].target == GL_FRAGMENT_PROGRAM_ARB)
- {
- if (!glConfig.ARBFragmentProgramAvailable)
- {
- common->Printf (": GL_FRAGMENT_PROGRAM_ARB not available\n");
- return;
- }
- start = strstr ((char *) buffer, "!!ARBfp");
- }
- if (!start)
- {
- common->Printf (": !!ARB not found\n");
- return;
- }
- end = strstr (start, "END");
- if (!end)
- {
- common->Printf (": END not found\n");
- return;
- }
- end[3] = 0;
- glBindProgramARB (progs[progIndex].target, progs[progIndex].ident);
- glGetError();
- glProgramStringARB (progs[progIndex].target, GL_PROGRAM_FORMAT_ASCII_ARB, strlen (start), (unsigned char *) start);
- err = glGetError();
- glGetIntegerv (GL_PROGRAM_ERROR_POSITION_ARB, (GLint *) &ofs);
- if (err == GL_INVALID_OPERATION)
- {
- const GLubyte *str = glGetString (GL_PROGRAM_ERROR_STRING_ARB);
- common->Printf ("\nGL_PROGRAM_ERROR_STRING_ARB: %s\n", str);
- if (ofs < 0)
- common->Printf ("GL_PROGRAM_ERROR_POSITION_ARB < 0 with error\n");
- else if (ofs >= (int) strlen ((char *) start))
- common->Printf ("error at end of program\n");
- else common->Printf ("error at %i:\n%s", ofs, start + ofs);
- return;
- }
- if (ofs != -1)
- {
- common->Printf ("\nGL_PROGRAM_ERROR_POSITION_ARB != -1 without error\n");
- return;
- }
- common->Printf ("\n");
- }
- /*
- ==================
- R_FindARBProgram
- Returns a GL identifier that can be bound to the given target, parsing
- a text file if it hasn't already been loaded.
- ==================
- */
- int R_FindARBProgram (GLenum target, const char *program)
- {
- int i;
- idStr stripped = program;
- stripped.StripFileExtension();
- // see if it is already loaded
- for (i = 0; progs[i].name[0]; i++)
- {
- if (progs[i].target != target) continue;
- idStr compare = progs[i].name;
- compare.StripFileExtension();
- if (!idStr::Icmp (stripped.c_str(), compare.c_str()))
- return progs[i].ident;
- }
- if (i == MAX_GLPROGS) common->Error ("R_FindARBProgram: MAX_GLPROGS");
- // add it to the list and load it
- progs[i].ident = (program_t) 0; // will be gen'd by R_LoadARBProgram
- progs[i].target = target;
- strncpy (progs[i].name, program, sizeof (progs[i].name) - 1);
- R_LoadARBProgram (i);
- return progs[i].ident;
- }
- void GL_GetShaderInfoLog (GLuint s, char *src, bool isprog)
- {
- static char infolog[4096];
- int outlen = 0;
- infolog[0] = 0;
- if (isprog)
- glGetProgramInfoLog (s, 4095, &outlen, infolog);
- else glGetShaderInfoLog (s, 4095, &outlen, infolog);
- common->Warning ("Shader Source:\n\n%s\n\n%s\n\n", src, infolog);
- }
- bool GL_CompileShader (GLuint sh, char *src)
- {
- if (sh && src)
- {
- int result = 0;
- glGetError ();
- glShaderSource (sh, 1, (const GLchar **) &src, NULL);
- glCompileShader (sh);
- glGetShaderiv (sh, GL_COMPILE_STATUS, &result);
- if (result != GL_TRUE)
- {
- GL_GetShaderInfoLog (sh, src, false);
- return false;
- }
- else if (glGetError () != GL_NO_ERROR)
- GL_GetShaderInfoLog (sh, src, false);
- }
- return true;
- }
- GLuint GL_CreateGLSLProgram (char *vssrc, char *fssrc, glsltable_t *attribs, int numattribs)
- {
- GLuint progid = 0;
- int result = 0;
- GLenum err = GL_NONE;
- GLuint vs = vssrc ? glCreateShader (GL_VERTEX_SHADER) : 0;
- GLuint fs = fssrc ? glCreateShader (GL_FRAGMENT_SHADER) : 0;
- glGetError ();
- if (vs && vssrc && !GL_CompileShader (vs, vssrc)) return 0;
- if (fs && fssrc && !GL_CompileShader (fs, fssrc)) return 0;
- progid = glCreateProgram ();
- if (vs && vssrc) glAttachShader (progid, vs);
- if (fs && fssrc) glAttachShader (progid, fs);
- if (attribs && numattribs)
- for (int i = 0; i < numattribs; i++)
- glBindAttribLocation (progid, attribs[i].slot, attribs[i].name);
- glLinkProgram (progid);
- glGetProgramiv (progid, GL_LINK_STATUS, &result);
- glDeleteShader (vs);
- glDeleteShader (fs);
- if (result != GL_TRUE)
- {
- GL_GetShaderInfoLog (progid, "", true);
- return 0;
- }
- return progid;
- }
- char *GL_GetGLSLFromFile (const char *name)
- {
- idStr fullPath = "glprogs/";
- fullPath += name;
- char *fileBuffer;
- char *buffer;
- common->Printf ("%s", fullPath.c_str ());
- fileSystem->ReadFile (fullPath.c_str (), (void **) &fileBuffer, NULL);
- if (!fileBuffer)
- {
- common->Printf (": File not found\n");
- return NULL;
- }
- // copy to main memory and free
- buffer = (char *) malloc (strlen (fileBuffer) + 1);
- strcpy (buffer, fileBuffer);
- fileSystem->FreeFile (fileBuffer);
- common->Printf ("\n");
- return buffer;
- }
- /*
- ==================
- R_ReloadARBPrograms_f
- ==================
- */
- void R_ReloadARBPrograms_f (const idCmdArgs &args)
- {
- common->Printf ("----- R_ReloadARBPrograms -----\n");
- for (int i = 0; progs[i].name[0]; i++)
- R_LoadARBProgram (i);
- common->Printf ("-------------------------------\n");
- if (glConfig.glVersion >= 2.0)
- {
- // load GLSL programs
- glDeleteProgram (rb_glsl_interaction_program);
- char *vs = GL_GetGLSLFromFile ("interaction_vs.glsl");
- char *fs = GL_GetGLSLFromFile ("interaction_fs.glsl");
- rb_glsl_interaction_program = GL_CreateGLSLProgram (vs ? vs : interaction_vs,
- fs ? fs : interaction_fs,
- interactionAttribs,
- sizeof (interactionAttribs) / sizeof (interactionAttribs[0]));
- if (vs) free (vs);
- if (fs) free (fs);
- if (rb_glsl_interaction_program)
- {
- // setup uniform locations - ATI used to need glUseProgram here - is this still the case???
- glUseProgram (rb_glsl_interaction_program);
- glUniform1i (glGetUniformLocation (rb_glsl_interaction_program, "bumpImage"), 1);
- glUniform1i (glGetUniformLocation (rb_glsl_interaction_program, "lightFalloffImage"), 2);
- glUniform1i (glGetUniformLocation (rb_glsl_interaction_program, "lightImage"), 3);
- glUniform1i (glGetUniformLocation (rb_glsl_interaction_program, "diffuseImage"), 4);
- glUniform1i (glGetUniformLocation (rb_glsl_interaction_program, "specularImage"), 5);
- u_light_origin = glGetUniformLocation (rb_glsl_interaction_program, "u_light_origin");
- u_view_origin = glGetUniformLocation (rb_glsl_interaction_program, "u_view_origin");
- u_color_modulate = glGetUniformLocation (rb_glsl_interaction_program, "u_color_modulate");
- u_color_add = glGetUniformLocation (rb_glsl_interaction_program, "u_color_add");
- u_constant_diffuse = glGetUniformLocation (rb_glsl_interaction_program, "u_constant_diffuse");
- u_constant_specular = glGetUniformLocation (rb_glsl_interaction_program, "u_constant_specular");
- u_diffMatrix = glGetUniformLocation (rb_glsl_interaction_program, "u_diffMatrix");
- u_bumpMatrix = glGetUniformLocation (rb_glsl_interaction_program, "u_bumpMatrix");
- u_specMatrix = glGetUniformLocation (rb_glsl_interaction_program, "u_specMatrix");
- u_projMatrix = glGetUniformLocation (rb_glsl_interaction_program, "u_projMatrix");
- u_fallMatrix = glGetUniformLocation (rb_glsl_interaction_program, "u_fallMatrix");
- }
- glUseProgram (0);
- }
- }
- /*
- ==================
- R_ARB2_Init
- ==================
- */
- void R_ARB2_Init (void)
- {
- glConfig.allowARB2Path = false;
- common->Printf ("---------- R_ARB2_Init ----------\n");
- if (!glConfig.ARBVertexProgramAvailable || !glConfig.ARBFragmentProgramAvailable)
- {
- common->Printf ("Not available.\n");
- return;
- }
- common->Printf ("Available.\n");
- common->Printf ("---------------------------------\n");
- glConfig.allowARB2Path = true;
- }
Advertisement
Add Comment
Please, Sign In to add comment