Guest User

Untitled

a guest
Jul 11th, 2012
175
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 28.53 KB | None | 0 0
  1. /*
  2. ===========================================================================
  3.  
  4. Doom 3 GPL Source Code
  5. Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
  6.  
  7. This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
  8.  
  9. Doom 3 Source Code is free software: you can redistribute it and/or modify
  10. it under the terms of the GNU General Public License as published by
  11. the Free Software Foundation, either version 3 of the License, or
  12. (at your option) any later version.
  13.  
  14. Doom 3 Source Code is distributed in the hope that it will be useful,
  15. but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17. GNU General Public License for more details.
  18.  
  19. You should have received a copy of the GNU General Public License
  20. along with Doom 3 Source Code.  If not, see <http://www.gnu.org/licenses/>.
  21.  
  22. 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.
  23.  
  24. 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.
  25.  
  26. ===========================================================================
  27. */
  28.  
  29. #include "../idlib/precompiled.h"
  30. #include "tr_local.h"
  31.  
  32. #define GLSL_INPUT_ATTRIBS \
  33.     "in vec4 attrTexCoords;\n" \
  34.     "in vec3 attrTangents0;\n" \
  35.     "in vec3 attrTangents1;\n" \
  36.     "in vec3 attrNormal;\n" \
  37.     "mat3x3 u_lightMatrix = mat3x3 (attrTangents0, attrTangents1, attrNormal);\n\n"
  38.  
  39. #define GLSL_UNIFORMS \
  40.     "uniform vec4 u_light_origin;\n" \
  41.     "uniform vec4 u_view_origin;\n" \
  42.     "uniform vec4 u_color_modulate;\n" \
  43.     "uniform vec4 u_color_add;\n" \
  44.     "uniform mat2x4 u_diffMatrix;\n" \
  45.     "uniform mat2x4 u_bumpMatrix;\n" \
  46.     "uniform mat2x4 u_specMatrix;\n" \
  47.     "uniform mat4x4 u_projMatrix;\n" \
  48.     "uniform mat4x4 u_fallMatrix;\n" \
  49.     "uniform sampler2D bumpImage;\n" \
  50.     "uniform sampler2D lightFalloffImage;\n" \
  51.     "uniform sampler2D lightImage;\n" \
  52.     "uniform sampler2D diffuseImage;\n" \
  53.     "uniform sampler2D specularImage;\n" \
  54.     "uniform vec4 u_constant_diffuse;\n" \
  55.     "uniform vec4 u_constant_specular;\n\n"
  56.  
  57. #define GLSL_VARYINGS \
  58.     "varying vec2 diffCoords;\n" \
  59.     "varying vec2 bumpCoords;\n" \
  60.     "varying vec2 specCoords;\n" \
  61.     "varying vec4 projCoords;\n" \
  62.     "varying vec4 fallCoords;\n" \
  63.     "varying vec3 lightDir;\n" \
  64.     "varying vec3 halfAngle;\n" \
  65.     "varying vec4 Color;\n"
  66.  
  67.  
  68. // these are our GLSL interaction shaders
  69. #define interaction_vs \
  70.     GLSL_INPUT_ATTRIBS \
  71.     GLSL_UNIFORMS \
  72.     GLSL_VARYINGS \
  73.     "void main ()\n" \
  74.     "{\n" \
  75.     "   // we must use ftransform as Doom 3 needs invariant position\n" \
  76.     "   gl_Position = ftransform ();\n" \
  77.     "\n" \
  78.     "   diffCoords = attrTexCoords * u_diffMatrix;\n" \
  79.     "   bumpCoords = attrTexCoords * u_bumpMatrix;\n" \
  80.     "   specCoords = attrTexCoords * u_specMatrix;\n" \
  81.     "\n" \
  82.     "   projCoords = gl_Vertex * u_projMatrix;\n" \
  83.     "   fallCoords = gl_Vertex * u_fallMatrix;\n" \
  84.     "\n" \
  85.     "   Color = (gl_Color * u_color_modulate) + u_color_add;\n" \
  86.     "\n" \
  87.     "   vec3 OffsetViewOrigin = (u_view_origin - gl_Vertex).xyz;\n" \
  88.     "   vec3 OffsetLightOrigin = (u_light_origin - gl_Vertex).xyz;\n" \
  89.     "\n" \
  90.     "   lightDir = OffsetLightOrigin * u_lightMatrix;\n" \
  91.     "   halfAngle = (normalize (OffsetViewOrigin) + normalize (OffsetLightOrigin)) * u_lightMatrix;\n" \
  92.     "}\n\n"
  93.  
  94.  
  95. #define interaction_fs \
  96.     GLSL_UNIFORMS \
  97.     GLSL_VARYINGS \
  98.     "void main ()\n" \
  99.     "{\n" \
  100.     "   vec3 normalMap = texture2D (bumpImage, bumpCoords).agb * 2.0 - 1.0;\n" \
  101.     "   vec4 lightMap = texture2DProj (lightImage, projCoords);\n" \
  102.     "\n" \
  103.     "   lightMap *= dot (normalize (lightDir), normalMap);\n" \
  104.     "   lightMap *= texture2DProj (lightFalloffImage, fallCoords);\n" \
  105.     "   lightMap *= Color;\n" \
  106.     "\n" \
  107.     "   vec4 diffuseMap = texture2D (diffuseImage, diffCoords) * u_constant_diffuse;\n" \
  108.     "   float specularComponent = clamp ((dot (normalize (halfAngle), normalMap) - 0.75) * 4.0, 0.0, 1.0);\n" \
  109.     "\n" \
  110.     "   vec4 specularResult = u_constant_specular * (specularComponent * specularComponent);\n" \
  111.     "   vec4 specularMap = texture2D (specularImage, specCoords) * 2.0;\n" \
  112.     "\n" \
  113.     "   gl_FragColor = (diffuseMap + (specularResult * specularMap)) * lightMap;\n" \
  114.     "}\n\n"
  115.  
  116.  
  117. GLuint u_light_origin = 0;
  118. GLuint u_view_origin = 0;
  119.  
  120. GLuint u_color_modulate = 0;
  121. GLuint u_color_add = 0;
  122.  
  123. GLuint u_constant_diffuse = 0;
  124. GLuint u_constant_specular = 0;
  125.  
  126. GLuint u_diffMatrix = 0;
  127. GLuint u_bumpMatrix = 0;
  128. GLuint u_specMatrix = 0;
  129.  
  130. GLuint u_projMatrix = 0;
  131. GLuint u_fallMatrix = 0;
  132.  
  133. struct glsltable_t
  134. {
  135.     GLuint slot;
  136.     GLchar *name;
  137. };
  138.  
  139.  
  140. glsltable_t interactionAttribs[] =
  141. {
  142.     {8, "attrTexCoords"},
  143.     {9, "attrTangents0"},
  144.     {10, "attrTangents1"},
  145.     {11, "attrNormal"}
  146. };
  147.  
  148.  
  149. GLuint rb_glsl_interaction_program = 0;
  150. idCVar r_useGLSL ("r_useGLSL", "1", CVAR_RENDERER | CVAR_BOOL, "use GLSL backend for interaction passes");
  151.  
  152.  
  153. /*
  154. =========================================================================================
  155.  
  156. GENERAL INTERACTION RENDERING
  157.  
  158. =========================================================================================
  159. */
  160.  
  161.  
  162. void RB_ARB2_BindTexture (int unit, idImage *tex)
  163. {
  164.     backEnd.glState.currenttmu = unit;
  165.     glActiveTextureARB (GL_TEXTURE0_ARB + unit);
  166.  
  167.     tex->Bind ();
  168. }
  169.  
  170.  
  171. void RB_ARB2_UnbindTexture (int unit)
  172. {
  173.     backEnd.glState.currenttmu = unit;
  174.     glActiveTextureARB (GL_TEXTURE0_ARB + unit);
  175.  
  176.     globalImages->BindNull ();
  177. }
  178.  
  179.  
  180. void RB_ARB2_BindInteractionTextureSet (const drawInteraction_t *din)
  181. {
  182.     // texture 1 will be the per-surface bump map
  183.     RB_ARB2_BindTexture (1, din->bumpImage);
  184.  
  185.     // texture 2 will be the light falloff texture
  186.     RB_ARB2_BindTexture (2, din->lightFalloffImage);
  187.  
  188.     // texture 3 will be the light projection texture
  189.     RB_ARB2_BindTexture (3, din->lightImage);
  190.  
  191.     // texture 4 is the per-surface diffuse map
  192.     RB_ARB2_BindTexture (4, din->diffuseImage);
  193.  
  194.     // texture 5 is the per-surface specular map
  195.     RB_ARB2_BindTexture (5, din->specularImage);
  196. }
  197.  
  198.  
  199. static float *RB_GLSL_MakeMatrix (const float *in1, const float *in2, const float *in3 = NULL, const float *in4 = NULL)
  200. {
  201.     static float m[8];
  202.    
  203.     if (in1) memcpy (&m[0], in1, sizeof (float) * 4);
  204.     if (in2) memcpy (&m[4], in2, sizeof (float) * 4);
  205.     if (in3) memcpy (&m[8], in3, sizeof (float) * 4);
  206.     if (in4) memcpy (&m[12], in4, sizeof (float) * 4);
  207.  
  208.     return m;
  209. }
  210.  
  211.  
  212. #define DIFFMATRIX(ofs) din->diffuseMatrix[ofs].ToFloatPtr ()
  213. #define BUMPMATRIX(ofs) din->bumpMatrix[ofs].ToFloatPtr ()
  214. #define SPECMATRIX(ofs) din->specularMatrix[ofs].ToFloatPtr ()
  215. #define PROJMATRIX(ofs) din->lightProjection[ofs].ToFloatPtr ()
  216.  
  217. void RB_GLSL_DrawInteraction (const drawInteraction_t *din)
  218. {
  219.     static const float whalf[] = {0.0, 0.0, 0.0, 0.5};
  220.     static const float wzero[] = {0.0, 0.0, 0.0, 0.0};
  221.     static const float wone[] = {0.0, 0.0, 0.0, 1.0};
  222.  
  223.     glUniform4fv (u_light_origin, 1, din->localLightOrigin.ToFloatPtr ());
  224.     glUniform4fv (u_view_origin, 1, din->localViewOrigin.ToFloatPtr ());
  225.  
  226.     glUniformMatrix2x4fv (u_diffMatrix, 1, GL_FALSE, RB_GLSL_MakeMatrix (DIFFMATRIX (0), DIFFMATRIX (1)));
  227.     glUniformMatrix2x4fv (u_bumpMatrix, 1, GL_FALSE, RB_GLSL_MakeMatrix (BUMPMATRIX (0), BUMPMATRIX (1)));
  228.     glUniformMatrix2x4fv (u_specMatrix, 1, GL_FALSE, RB_GLSL_MakeMatrix (SPECMATRIX (0), SPECMATRIX (1)));
  229.  
  230.     glUniformMatrix4fv (u_projMatrix, 1, GL_FALSE, RB_GLSL_MakeMatrix (PROJMATRIX (0), PROJMATRIX (1), wzero, PROJMATRIX (2)));
  231.     glUniformMatrix4fv (u_fallMatrix, 1, GL_FALSE, RB_GLSL_MakeMatrix (PROJMATRIX (3), whalf, wzero, wone));
  232.  
  233.     static const float zero[4] = {0, 0, 0, 0};
  234.     static const float one[4] = {1, 1, 1, 1};
  235.     static const float negOne[4] = {-1, -1, -1, -1};
  236.  
  237.     switch (din->vertexColor)
  238.     {
  239.     case SVC_IGNORE:
  240.         glUniform4fv (u_color_modulate, 1, zero);
  241.         glUniform4fv (u_color_add, 1, one);
  242.         break;
  243.  
  244.     case SVC_MODULATE:
  245.         glUniform4fv (u_color_modulate, 1, one);
  246.         glUniform4fv (u_color_add, 1, zero);
  247.         break;
  248.  
  249.     case SVC_INVERSE_MODULATE:
  250.         glUniform4fv (u_color_modulate, 1, negOne);
  251.         glUniform4fv (u_color_add, 1, one);
  252.         break;
  253.     }
  254.  
  255.     // set the constant colors
  256.     glUniform4fv (u_constant_diffuse, 1, din->diffuseColor.ToFloatPtr ());
  257.     glUniform4fv (u_constant_specular, 1, din->specularColor.ToFloatPtr ());
  258.  
  259.     // set the textures
  260.     RB_ARB2_BindInteractionTextureSet (din);
  261.  
  262.     // draw it
  263.     RB_DrawElementsWithCounters (din->surf->geo);
  264. }
  265.  
  266.  
  267. /*
  268. ==================
  269. RB_ARB2_DrawInteraction
  270. ==================
  271. */
  272. void RB_ARB2_DrawInteraction (const drawInteraction_t *din)
  273. {
  274.     // load all the vertex program parameters
  275.     glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_LIGHT_ORIGIN, din->localLightOrigin.ToFloatPtr ());
  276.     glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_VIEW_ORIGIN, din->localViewOrigin.ToFloatPtr ());
  277.     glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_LIGHT_PROJECT_S, din->lightProjection[0].ToFloatPtr ());
  278.     glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_LIGHT_PROJECT_T, din->lightProjection[1].ToFloatPtr ());
  279.     glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_LIGHT_PROJECT_Q, din->lightProjection[2].ToFloatPtr ());
  280.     glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_LIGHT_FALLOFF_S, din->lightProjection[3].ToFloatPtr ());
  281.     glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_BUMP_MATRIX_S, din->bumpMatrix[0].ToFloatPtr ());
  282.     glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_BUMP_MATRIX_T, din->bumpMatrix[1].ToFloatPtr ());
  283.     glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_DIFFUSE_MATRIX_S, din->diffuseMatrix[0].ToFloatPtr ());
  284.     glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_DIFFUSE_MATRIX_T, din->diffuseMatrix[1].ToFloatPtr ());
  285.     glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_SPECULAR_MATRIX_S, din->specularMatrix[0].ToFloatPtr ());
  286.     glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_SPECULAR_MATRIX_T, din->specularMatrix[1].ToFloatPtr ());
  287.  
  288.     // testing fragment based normal mapping
  289.     if (r_testARBProgram.GetBool ())
  290.     {
  291.         glProgramEnvParameter4fvARB (GL_FRAGMENT_PROGRAM_ARB, 2, din->localLightOrigin.ToFloatPtr ());
  292.         glProgramEnvParameter4fvARB (GL_FRAGMENT_PROGRAM_ARB, 3, din->localViewOrigin.ToFloatPtr ());
  293.     }
  294.  
  295.     static const float zero[4] = {0, 0, 0, 0};
  296.     static const float one[4] = {1, 1, 1, 1};
  297.     static const float negOne[4] = {-1, -1, -1, -1};
  298.  
  299.     switch (din->vertexColor)
  300.     {
  301.     case SVC_IGNORE:
  302.         glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_COLOR_MODULATE, zero);
  303.         glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_COLOR_ADD, one);
  304.         break;
  305.  
  306.     case SVC_MODULATE:
  307.         glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_COLOR_MODULATE, one);
  308.         glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_COLOR_ADD, zero);
  309.         break;
  310.  
  311.     case SVC_INVERSE_MODULATE:
  312.         glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_COLOR_MODULATE, negOne);
  313.         glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, PP_COLOR_ADD, one);
  314.         break;
  315.     }
  316.  
  317.     // set the constant colors
  318.     glProgramEnvParameter4fvARB (GL_FRAGMENT_PROGRAM_ARB, 0, din->diffuseColor.ToFloatPtr ());
  319.     glProgramEnvParameter4fvARB (GL_FRAGMENT_PROGRAM_ARB, 1, din->specularColor.ToFloatPtr ());
  320.  
  321.     // set the textures
  322.     RB_ARB2_BindInteractionTextureSet (din);
  323.  
  324.     // draw it
  325.     RB_DrawElementsWithCounters (din->surf->geo);
  326. }
  327.  
  328.  
  329. void RB_ARB2_SharedSurfaceSetup (const drawSurf_t *surf)
  330. {
  331.     // set the vertex pointers
  332.     idDrawVert *ac = (idDrawVert *) vertexCache.Position (surf->geo->ambientCache);
  333.  
  334.     glColorPointer (4, GL_UNSIGNED_BYTE, sizeof (idDrawVert), ac->color);
  335.     glVertexAttribPointerARB (11, 3, GL_FLOAT, false, sizeof (idDrawVert), ac->normal.ToFloatPtr ());
  336.     glVertexAttribPointerARB (10, 3, GL_FLOAT, false, sizeof (idDrawVert), ac->tangents[1].ToFloatPtr ());
  337.     glVertexAttribPointerARB (9, 3, GL_FLOAT, false, sizeof (idDrawVert), ac->tangents[0].ToFloatPtr ());
  338.     glVertexAttribPointerARB (8, 2, GL_FLOAT, false, sizeof (idDrawVert), ac->st.ToFloatPtr ());
  339.     glVertexPointer (3, GL_FLOAT, sizeof (idDrawVert), ac->xyz.ToFloatPtr ());
  340. }
  341.  
  342.  
  343. /*
  344. =============
  345. RB_ARB2_CreateDrawInteractions
  346.  
  347. =============
  348. */
  349. void RB_ARB2_CreateDrawInteractions (const drawSurf_t *surf)
  350. {
  351.     if (!surf) return;
  352.  
  353.     // perform setup here that will be constant for all interactions
  354.     GL_State (GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | backEnd.depthFunc);
  355.  
  356.     // enable the vertex arrays
  357.     glEnableVertexAttribArrayARB (8);
  358.     glEnableVertexAttribArrayARB (9);
  359.     glEnableVertexAttribArrayARB (10);
  360.     glEnableVertexAttribArrayARB (11);
  361.     glEnableClientState (GL_COLOR_ARRAY);
  362.  
  363.     if (r_useGLSL.GetBool () && glConfig.glVersion >= 2.0 && rb_glsl_interaction_program)
  364.     {
  365.         glUseProgram (rb_glsl_interaction_program);
  366.  
  367.         for (; surf; surf = surf->nextOnLight)
  368.         {
  369.             // perform setup here that will not change over multiple interaction passes
  370.             RB_ARB2_SharedSurfaceSetup (surf);
  371.  
  372.             // this may cause RB_ARB2_DrawInteraction to be exacuted multiple
  373.             // times with different colors and images if the surface or light have multiple layers
  374.             RB_CreateSingleDrawInteractions (surf, RB_GLSL_DrawInteraction);
  375.         }
  376.  
  377.         // back to fixed (or ARB program)
  378.         glUseProgram (0);
  379.     }
  380.     else
  381.     {
  382.         glEnable (GL_VERTEX_PROGRAM_ARB);
  383.         glEnable (GL_FRAGMENT_PROGRAM_ARB);
  384.  
  385.         // texture 0 is the normalization cube map for the vector towards the light
  386.         if (backEnd.vLight->lightShader->IsAmbientLight ())
  387.             RB_ARB2_BindTexture (0, globalImages->ambientNormalMap);
  388.         else RB_ARB2_BindTexture (0, globalImages->normalCubeMapImage);
  389.  
  390.         // texture 6 is the specular lookup table
  391.         if (r_testARBProgram.GetBool ())
  392.             RB_ARB2_BindTexture (6, globalImages->specular2DTableImage);
  393.         else RB_ARB2_BindTexture (6, globalImages->specularTableImage);
  394.  
  395.         // bind the vertex program
  396.         if (r_testARBProgram.GetBool ())
  397.         {
  398.             glBindProgramARB (GL_VERTEX_PROGRAM_ARB, VPROG_TEST);
  399.             glBindProgramARB (GL_FRAGMENT_PROGRAM_ARB, FPROG_TEST);
  400.         }
  401.         else
  402.         {
  403.             glBindProgramARB (GL_VERTEX_PROGRAM_ARB, VPROG_INTERACTION);
  404.             glBindProgramARB (GL_FRAGMENT_PROGRAM_ARB, FPROG_INTERACTION);
  405.         }
  406.  
  407.         for (; surf; surf = surf->nextOnLight)
  408.         {
  409.             // perform setup here that will not change over multiple interaction passes
  410.             RB_ARB2_SharedSurfaceSetup (surf);
  411.  
  412.             // this may cause RB_ARB2_DrawInteraction to be exacuted multiple
  413.             // times with different colors and images if the surface or light have multiple layers
  414.             RB_CreateSingleDrawInteractions (surf, RB_ARB2_DrawInteraction);
  415.         }
  416.  
  417.         glBindProgramARB (GL_VERTEX_PROGRAM_ARB, 0);
  418.         glDisable (GL_VERTEX_PROGRAM_ARB);
  419.         glDisable (GL_FRAGMENT_PROGRAM_ARB);
  420.     }
  421.  
  422.     glDisableVertexAttribArrayARB (8);
  423.     glDisableVertexAttribArrayARB (9);
  424.     glDisableVertexAttribArrayARB (10);
  425.     glDisableVertexAttribArrayARB (11);
  426.     glDisableClientState (GL_COLOR_ARRAY);
  427.  
  428.     // disable features
  429.     RB_ARB2_UnbindTexture (6);
  430.     RB_ARB2_UnbindTexture (5);
  431.     RB_ARB2_UnbindTexture (4);
  432.     RB_ARB2_UnbindTexture (3);
  433.     RB_ARB2_UnbindTexture (2);
  434.     RB_ARB2_UnbindTexture (1);
  435.  
  436.     backEnd.glState.currenttmu = -1;
  437.     GL_SelectTexture (0);
  438. }
  439.  
  440.  
  441. void RB_ARB2_InteractionPass (const drawSurf_t *shadowSurfs, const drawSurf_t *lightSurfs)
  442. {
  443.     // save on state changes by not bothering to setup/takedown all the messy state when there are no surfs to draw
  444.     if (shadowSurfs)
  445.     {
  446.         if (r_useShadowVertexProgram.GetBool ())
  447.         {
  448.             glEnable (GL_VERTEX_PROGRAM_ARB);
  449.             glBindProgramARB (GL_VERTEX_PROGRAM_ARB, VPROG_STENCIL_SHADOW);
  450.  
  451.             RB_StencilShadowPass (shadowSurfs);
  452.  
  453.             // need to disable ASM programs when switching to GLSL
  454.             if (r_useGLSL.GetBool () && glConfig.glVersion >= 2.0 && rb_glsl_interaction_program)
  455.             {
  456.                 glBindProgramARB (GL_VERTEX_PROGRAM_ARB, 0);
  457.                 glDisable (GL_VERTEX_PROGRAM_ARB);
  458.             }
  459.         }
  460.         else RB_StencilShadowPass (shadowSurfs);
  461.     }
  462.  
  463.     if (lightSurfs) RB_ARB2_CreateDrawInteractions (lightSurfs);
  464. }
  465.  
  466.  
  467. /*
  468. ==================
  469. RB_ARB2_DrawInteractions
  470. ==================
  471. */
  472. void RB_ARB2_DrawInteractions (void)
  473. {
  474.     viewLight_t     *vLight;
  475.     const idMaterial    *lightShader;
  476.  
  477.     GL_SelectTexture (0);
  478.     glDisableClientState (GL_TEXTURE_COORD_ARRAY);
  479.  
  480.     // for each light, perform adding and shadowing
  481.     for (vLight = backEnd.viewDef->viewLights; vLight; vLight = vLight->next)
  482.     {
  483.         backEnd.vLight = vLight;
  484.  
  485.         // do fogging later
  486.         if (vLight->lightShader->IsFogLight ()) continue;
  487.         if (vLight->lightShader->IsBlendLight ()) continue;
  488.  
  489.         // nothing to see here; these aren't the surfaces you're looking for; move along
  490.         if (!vLight->localInteractions &&
  491.             !vLight->globalInteractions &&
  492.             !vLight->globalShadows &&
  493.             !vLight->localShadows &&
  494.             !vLight->translucentInteractions) continue;
  495.  
  496.         lightShader = vLight->lightShader;
  497.  
  498.         // clear the stencil buffer if needed
  499.         if (vLight->globalShadows || vLight->localShadows)
  500.         {
  501.             backEnd.currentScissor = vLight->scissorRect;
  502.  
  503.             if (r_useScissor.GetBool ())
  504.             {
  505.                 glScissor (backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1,
  506.                     backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1,
  507.                     backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1,
  508.                     backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1);
  509.             }
  510.  
  511.             glClear (GL_STENCIL_BUFFER_BIT);
  512.         }
  513.         else
  514.         {
  515.             // no shadows, so no need to read or write the stencil buffer
  516.             // we might in theory want to use GL_ALWAYS instead of disabling
  517.             // completely, to satisfy the invarience rules
  518.             glStencilFunc (GL_ALWAYS, 128, 255);
  519.         }
  520.  
  521.         // run our passes for global and local
  522.         RB_ARB2_InteractionPass (vLight->globalShadows, vLight->localInteractions);
  523.         RB_ARB2_InteractionPass (vLight->localShadows, vLight->globalInteractions);
  524.  
  525.         // translucent surfaces never get stencil shadowed
  526.         if (r_skipTranslucent.GetBool ()) continue;
  527.  
  528.         glStencilFunc (GL_ALWAYS, 128, 255);
  529.  
  530.         backEnd.depthFunc = GLS_DEPTHFUNC_LESS;
  531.         RB_ARB2_CreateDrawInteractions (vLight->translucentInteractions);
  532.         backEnd.depthFunc = GLS_DEPTHFUNC_EQUAL;
  533.     }
  534.  
  535.     // ensure that these are down
  536.     glBindProgramARB (GL_VERTEX_PROGRAM_ARB, 0);
  537.     glDisable (GL_VERTEX_PROGRAM_ARB);
  538.     glUseProgram (0);
  539.  
  540.     // disable stencil shadow test
  541.     glStencilFunc (GL_ALWAYS, 128, 255);
  542.  
  543.     GL_SelectTexture (0);
  544.     glEnableClientState (GL_TEXTURE_COORD_ARRAY);
  545. }
  546.  
  547. //===================================================================================
  548.  
  549.  
  550. typedef struct
  551. {
  552.     GLenum          target;
  553.     GLuint          ident;
  554.     char            name[64];
  555. } progDef_t;
  556.  
  557. static  const int   MAX_GLPROGS = 200;
  558.  
  559. // a single file can have both a vertex program and a fragment program
  560. static progDef_t    progs[MAX_GLPROGS] =
  561. {
  562.     { GL_VERTEX_PROGRAM_ARB, VPROG_TEST, "test.vfp" },
  563.     { GL_FRAGMENT_PROGRAM_ARB, FPROG_TEST, "test.vfp" },
  564.     { GL_VERTEX_PROGRAM_ARB, VPROG_INTERACTION, "interaction.vfp" },
  565.     { GL_FRAGMENT_PROGRAM_ARB, FPROG_INTERACTION, "interaction.vfp" },
  566.     { GL_VERTEX_PROGRAM_ARB, VPROG_BUMPY_ENVIRONMENT, "bumpyEnvironment.vfp" },
  567.     { GL_FRAGMENT_PROGRAM_ARB, FPROG_BUMPY_ENVIRONMENT, "bumpyEnvironment.vfp" },
  568.     { GL_VERTEX_PROGRAM_ARB, VPROG_AMBIENT, "ambientLight.vfp" },
  569.     { GL_FRAGMENT_PROGRAM_ARB, FPROG_AMBIENT, "ambientLight.vfp" },
  570.     { GL_VERTEX_PROGRAM_ARB, VPROG_STENCIL_SHADOW, "shadow.vp" },
  571.     { GL_VERTEX_PROGRAM_ARB, VPROG_R200_INTERACTION, "R200_interaction.vp" },
  572.     { GL_VERTEX_PROGRAM_ARB, VPROG_NV20_BUMP_AND_LIGHT, "nv20_bumpAndLight.vp" },
  573.     { GL_VERTEX_PROGRAM_ARB, VPROG_NV20_DIFFUSE_COLOR, "nv20_diffuseColor.vp" },
  574.     { GL_VERTEX_PROGRAM_ARB, VPROG_NV20_SPECULAR_COLOR, "nv20_specularColor.vp" },
  575.     { GL_VERTEX_PROGRAM_ARB, VPROG_NV20_DIFFUSE_AND_SPECULAR_COLOR, "nv20_diffuseAndSpecularColor.vp" },
  576.     { GL_VERTEX_PROGRAM_ARB, VPROG_ENVIRONMENT, "environment.vfp" },
  577.     { GL_FRAGMENT_PROGRAM_ARB, FPROG_ENVIRONMENT, "environment.vfp" },
  578.     { GL_VERTEX_PROGRAM_ARB, VPROG_GLASSWARP, "arbVP_glasswarp.txt" },
  579.     { GL_FRAGMENT_PROGRAM_ARB, FPROG_GLASSWARP, "arbFP_glasswarp.txt" },
  580.  
  581.     // additional programs can be dynamically specified in materials
  582. };
  583.  
  584. /*
  585. =================
  586. R_LoadARBProgram
  587. =================
  588. */
  589. void R_LoadARBProgram (int progIndex)
  590. {
  591.     int     ofs;
  592.     int     err;
  593.     idStr   fullPath = "glprogs/";
  594.     fullPath += progs[progIndex].name;
  595.     char    *fileBuffer;
  596.     char    *buffer;
  597.     char    *start, *end;
  598.  
  599.     common->Printf ("%s", fullPath.c_str());
  600.  
  601.     // load the program even if we don't support it, so
  602.     // fs_copyfiles can generate cross-platform data dumps
  603.     fileSystem->ReadFile (fullPath.c_str(), (void **) &fileBuffer, NULL);
  604.  
  605.     if (!fileBuffer)
  606.     {
  607.         common->Printf (": File not found\n");
  608.         return;
  609.     }
  610.  
  611.     // copy to stack memory and free
  612.     buffer = (char *) _alloca (strlen (fileBuffer) + 1);
  613.     strcpy (buffer, fileBuffer);
  614.     fileSystem->FreeFile (fileBuffer);
  615.  
  616.     if (!glConfig.isInitialized) return;
  617.  
  618.     // submit the program string at start to GL
  619.     if (progs[progIndex].ident == 0)
  620.     {
  621.         // allocate a new identifier for this program
  622.         progs[progIndex].ident = PROG_USER + progIndex;
  623.     }
  624.  
  625.     // vertex and fragment programs can both be present in a single file, so
  626.     // scan for the proper header to be the start point, and stamp a 0 in after the end
  627.  
  628.     if (progs[progIndex].target == GL_VERTEX_PROGRAM_ARB)
  629.     {
  630.         if (!glConfig.ARBVertexProgramAvailable)
  631.         {
  632.             common->Printf (": GL_VERTEX_PROGRAM_ARB not available\n");
  633.             return;
  634.         }
  635.  
  636.         start = strstr ((char *) buffer, "!!ARBvp");
  637.     }
  638.  
  639.     if (progs[progIndex].target == GL_FRAGMENT_PROGRAM_ARB)
  640.     {
  641.         if (!glConfig.ARBFragmentProgramAvailable)
  642.         {
  643.             common->Printf (": GL_FRAGMENT_PROGRAM_ARB not available\n");
  644.             return;
  645.         }
  646.  
  647.         start = strstr ((char *) buffer, "!!ARBfp");
  648.     }
  649.  
  650.     if (!start)
  651.     {
  652.         common->Printf (": !!ARB not found\n");
  653.         return;
  654.     }
  655.  
  656.     end = strstr (start, "END");
  657.  
  658.     if (!end)
  659.     {
  660.         common->Printf (": END not found\n");
  661.         return;
  662.     }
  663.  
  664.     end[3] = 0;
  665.  
  666.     glBindProgramARB (progs[progIndex].target, progs[progIndex].ident);
  667.     glGetError();
  668.  
  669.     glProgramStringARB (progs[progIndex].target, GL_PROGRAM_FORMAT_ASCII_ARB, strlen (start), (unsigned char *) start);
  670.  
  671.     err = glGetError();
  672.     glGetIntegerv (GL_PROGRAM_ERROR_POSITION_ARB, (GLint *) &ofs);
  673.  
  674.     if (err == GL_INVALID_OPERATION)
  675.     {
  676.         const GLubyte *str = glGetString (GL_PROGRAM_ERROR_STRING_ARB);
  677.         common->Printf ("\nGL_PROGRAM_ERROR_STRING_ARB: %s\n", str);
  678.  
  679.         if (ofs < 0)
  680.             common->Printf ("GL_PROGRAM_ERROR_POSITION_ARB < 0 with error\n");
  681.         else if (ofs >= (int) strlen ((char *) start))
  682.             common->Printf ("error at end of program\n");
  683.         else common->Printf ("error at %i:\n%s", ofs, start + ofs);
  684.  
  685.         return;
  686.     }
  687.  
  688.     if (ofs != -1)
  689.     {
  690.         common->Printf ("\nGL_PROGRAM_ERROR_POSITION_ARB != -1 without error\n");
  691.         return;
  692.     }
  693.  
  694.     common->Printf ("\n");
  695. }
  696.  
  697. /*
  698. ==================
  699. R_FindARBProgram
  700.  
  701. Returns a GL identifier that can be bound to the given target, parsing
  702. a text file if it hasn't already been loaded.
  703. ==================
  704. */
  705. int R_FindARBProgram (GLenum target, const char *program)
  706. {
  707.     int     i;
  708.     idStr   stripped = program;
  709.  
  710.     stripped.StripFileExtension();
  711.  
  712.     // see if it is already loaded
  713.     for (i = 0; progs[i].name[0]; i++)
  714.     {
  715.         if (progs[i].target != target) continue;
  716.  
  717.         idStr   compare = progs[i].name;
  718.         compare.StripFileExtension();
  719.  
  720.         if (!idStr::Icmp (stripped.c_str(), compare.c_str()))
  721.             return progs[i].ident;
  722.     }
  723.  
  724.     if (i == MAX_GLPROGS) common->Error ("R_FindARBProgram: MAX_GLPROGS");
  725.  
  726.     // add it to the list and load it
  727.     progs[i].ident = (program_t) 0; // will be gen'd by R_LoadARBProgram
  728.     progs[i].target = target;
  729.     strncpy (progs[i].name, program, sizeof (progs[i].name) - 1);
  730.  
  731.     R_LoadARBProgram (i);
  732.  
  733.     return progs[i].ident;
  734. }
  735.  
  736.  
  737. void GL_GetShaderInfoLog (GLuint s, char *src, bool isprog)
  738. {
  739.     static char infolog[4096];
  740.     int outlen = 0;
  741.  
  742.     infolog[0] = 0;
  743.  
  744.     if (isprog)
  745.         glGetProgramInfoLog (s, 4095, &outlen, infolog);
  746.     else glGetShaderInfoLog (s, 4095, &outlen, infolog);
  747.  
  748.     common->Warning ("Shader Source:\n\n%s\n\n%s\n\n", src, infolog);
  749. }
  750.  
  751.  
  752. bool GL_CompileShader (GLuint sh, char *src)
  753. {
  754.     if (sh && src)
  755.     {
  756.         int result = 0;
  757.  
  758.         glGetError ();
  759.  
  760.         glShaderSource (sh, 1, (const GLchar **) &src, NULL);
  761.         glCompileShader (sh);
  762.         glGetShaderiv (sh, GL_COMPILE_STATUS, &result);
  763.  
  764.         if (result != GL_TRUE)
  765.         {
  766.             GL_GetShaderInfoLog (sh, src, false);
  767.             return false;
  768.         }
  769.         else if (glGetError () != GL_NO_ERROR)
  770.             GL_GetShaderInfoLog (sh, src, false);
  771.     }
  772.  
  773.     return true;
  774. }
  775.  
  776.  
  777. GLuint GL_CreateGLSLProgram (char *vssrc, char *fssrc, glsltable_t *attribs, int numattribs)
  778. {
  779.     GLuint progid = 0;
  780.     int result = 0;
  781.     GLenum err = GL_NONE;
  782.  
  783.     GLuint vs = vssrc ? glCreateShader (GL_VERTEX_SHADER) : 0;
  784.     GLuint fs = fssrc ? glCreateShader (GL_FRAGMENT_SHADER) : 0;
  785.  
  786.     glGetError ();
  787.  
  788.     if (vs && vssrc && !GL_CompileShader (vs, vssrc)) return 0;
  789.     if (fs && fssrc && !GL_CompileShader (fs, fssrc)) return 0;
  790.  
  791.     progid = glCreateProgram ();
  792.  
  793.     if (vs && vssrc) glAttachShader (progid, vs);
  794.     if (fs && fssrc) glAttachShader (progid, fs);
  795.  
  796.     if (attribs && numattribs)
  797.         for (int i = 0; i < numattribs; i++)
  798.             glBindAttribLocation (progid, attribs[i].slot, attribs[i].name);
  799.  
  800.     glLinkProgram (progid);
  801.     glGetProgramiv (progid, GL_LINK_STATUS, &result);
  802.  
  803.     glDeleteShader (vs);
  804.     glDeleteShader (fs);
  805.  
  806.     if (result != GL_TRUE)
  807.     {
  808.         GL_GetShaderInfoLog (progid, "", true);
  809.         return 0;
  810.     }
  811.  
  812.     return progid;
  813. }
  814.  
  815.  
  816. char *GL_GetGLSLFromFile (const char *name)
  817. {
  818.     idStr   fullPath = "glprogs/";
  819.     fullPath += name;
  820.     char    *fileBuffer;
  821.     char    *buffer;
  822.  
  823.     common->Printf ("%s", fullPath.c_str ());
  824.     fileSystem->ReadFile (fullPath.c_str (), (void **) &fileBuffer, NULL);
  825.  
  826.     if (!fileBuffer)
  827.     {
  828.         common->Printf (": File not found\n");
  829.         return NULL;
  830.     }
  831.  
  832.     // copy to main memory and free
  833.     buffer = (char *) malloc (strlen (fileBuffer) + 1);
  834.     strcpy (buffer, fileBuffer);
  835.     fileSystem->FreeFile (fileBuffer);
  836.  
  837.     common->Printf ("\n");
  838.  
  839.     return buffer;
  840. }
  841.  
  842.  
  843. /*
  844. ==================
  845. R_ReloadARBPrograms_f
  846. ==================
  847. */
  848. void R_ReloadARBPrograms_f (const idCmdArgs &args)
  849. {
  850.     common->Printf ("----- R_ReloadARBPrograms -----\n");
  851.  
  852.     for (int i = 0; progs[i].name[0]; i++)
  853.         R_LoadARBProgram (i);
  854.  
  855.     common->Printf ("-------------------------------\n");
  856.  
  857.     if (glConfig.glVersion >= 2.0)
  858.     {
  859.         // load GLSL programs
  860.         glDeleteProgram (rb_glsl_interaction_program);
  861.  
  862.         char *vs = GL_GetGLSLFromFile ("interaction_vs.glsl");
  863.         char *fs = GL_GetGLSLFromFile ("interaction_fs.glsl");
  864.  
  865.         rb_glsl_interaction_program = GL_CreateGLSLProgram (vs ? vs : interaction_vs,
  866.             fs ? fs : interaction_fs,
  867.             interactionAttribs,
  868.             sizeof (interactionAttribs) / sizeof (interactionAttribs[0]));
  869.  
  870.         if (vs) free (vs);
  871.         if (fs) free (fs);
  872.  
  873.         if (rb_glsl_interaction_program)
  874.         {
  875.             // setup uniform locations - ATI used to need glUseProgram here - is this still the case???
  876.             glUseProgram (rb_glsl_interaction_program);
  877.  
  878.             glUniform1i (glGetUniformLocation (rb_glsl_interaction_program, "bumpImage"), 1);
  879.             glUniform1i (glGetUniformLocation (rb_glsl_interaction_program, "lightFalloffImage"), 2);
  880.             glUniform1i (glGetUniformLocation (rb_glsl_interaction_program, "lightImage"), 3);
  881.             glUniform1i (glGetUniformLocation (rb_glsl_interaction_program, "diffuseImage"), 4);
  882.             glUniform1i (glGetUniformLocation (rb_glsl_interaction_program, "specularImage"), 5);
  883.  
  884.             u_light_origin = glGetUniformLocation (rb_glsl_interaction_program, "u_light_origin");
  885.             u_view_origin = glGetUniformLocation (rb_glsl_interaction_program, "u_view_origin");
  886.  
  887.             u_color_modulate = glGetUniformLocation (rb_glsl_interaction_program, "u_color_modulate");
  888.             u_color_add = glGetUniformLocation (rb_glsl_interaction_program, "u_color_add");
  889.  
  890.             u_constant_diffuse = glGetUniformLocation (rb_glsl_interaction_program, "u_constant_diffuse");
  891.             u_constant_specular = glGetUniformLocation (rb_glsl_interaction_program, "u_constant_specular");
  892.  
  893.             u_diffMatrix = glGetUniformLocation (rb_glsl_interaction_program, "u_diffMatrix");
  894.             u_bumpMatrix = glGetUniformLocation (rb_glsl_interaction_program, "u_bumpMatrix");
  895.             u_specMatrix = glGetUniformLocation (rb_glsl_interaction_program, "u_specMatrix");
  896.  
  897.             u_projMatrix = glGetUniformLocation (rb_glsl_interaction_program, "u_projMatrix");
  898.             u_fallMatrix = glGetUniformLocation (rb_glsl_interaction_program, "u_fallMatrix");
  899.         }
  900.  
  901.         glUseProgram (0);
  902.     }
  903. }
  904.  
  905. /*
  906. ==================
  907. R_ARB2_Init
  908.  
  909. ==================
  910. */
  911. void R_ARB2_Init (void)
  912. {
  913.     glConfig.allowARB2Path = false;
  914.  
  915.     common->Printf ("---------- R_ARB2_Init ----------\n");
  916.  
  917.     if (!glConfig.ARBVertexProgramAvailable || !glConfig.ARBFragmentProgramAvailable)
  918.     {
  919.         common->Printf ("Not available.\n");
  920.         return;
  921.     }
  922.  
  923.     common->Printf ("Available.\n");
  924.     common->Printf ("---------------------------------\n");
  925.  
  926.     glConfig.allowARB2Path = true;
  927. }
Advertisement
Add Comment
Please, Sign In to add comment