draw_r200.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. /*
  2. ===========================================================================
  3. Doom 3 GPL Source Code
  4. Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
  6. Doom 3 Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. 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.
  17. 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.
  18. ===========================================================================
  19. */
  20. #include "../idlib/precompiled.h"
  21. #pragma hdrstop
  22. #include "tr_local.h"
  23. /*
  24. There are not enough vertex program texture coordinate outputs
  25. to have unique texture coordinates for bump, specular, and diffuse,
  26. so diffuse and specular are assumed to be the same mapping.
  27. To handle properly, those cases with different diffuse and specular
  28. mapping will need to be run as two passes.
  29. */
  30. // changed from 1 to 255 to not conflict with ARB2 program names
  31. static int FPROG_FAST_PATH = 255;
  32. typedef struct {
  33. GLint numFragmentRegisters; // 6
  34. GLint numFragmentConstants; // 8
  35. GLint numPasses; // 2
  36. GLint numInstructionsPerPass; // 8
  37. GLint numInstructionsTotal; // 16
  38. GLint colorAlphaPairing; // 1
  39. GLint numLoopbackComponenets; // 3
  40. GLint numInputInterpolatorComponents; // 3
  41. } atiFragmentShaderInfo_t;
  42. static atiFragmentShaderInfo_t fsi;
  43. typedef struct {
  44. // vertex shader invariants
  45. int lightPos; // light position in object coordinates
  46. int viewerPos; // viewer position in object coordinates
  47. int lightProjectS; // projected light s texgen
  48. int lightProjectT; // projected light t texgen
  49. int lightProjectQ; // projected light q texgen
  50. int lightFalloffS; // projected light falloff s texgen
  51. int bumpTransformS; // bump TEX0 S transformation
  52. int bumpTransformT; // bump TEX0 T transformation
  53. int colorTransformS; // diffuse/specular texture matrix
  54. int colorTransformT; // diffuse/specular texture matrix
  55. // vertex shader variants
  56. int texCoords;
  57. int vertexColors;
  58. int normals;
  59. int tangents;
  60. int biTangents;
  61. } atiVertexShaderInfo_t;
  62. static atiVertexShaderInfo_t vsi;
  63. /*
  64. ===================
  65. RB_R200_ARB_DrawInteraction
  66. ===================
  67. */
  68. static void RB_R200_ARB_DrawInteraction( const drawInteraction_t *din ) {
  69. // check for the case we can't handle in a single pass (we could calculate this at shader parse time to optimize)
  70. if ( din->diffuseImage != globalImages->blackImage && din->specularImage != globalImages->blackImage
  71. && memcmp( din->specularMatrix, din->diffuseMatrix, sizeof( din->diffuseMatrix ) ) ) {
  72. // common->Printf( "Note: Shader %s drawn as two pass on R200\n", din->surf->shader->getName() );
  73. // draw the specular as a separate pass with a black diffuse map
  74. drawInteraction_t d;
  75. d = *din;
  76. d.diffuseImage = globalImages->blackImage;
  77. memcpy( d.diffuseMatrix, d.specularMatrix, sizeof( d.diffuseMatrix ) );
  78. RB_R200_ARB_DrawInteraction( &d );
  79. // now fall through and draw the diffuse pass with a black specular map
  80. d = *din;
  81. din = &d;
  82. d.specularImage = globalImages->blackImage;
  83. }
  84. // load all the vertex program parameters
  85. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_ORIGIN, din->localLightOrigin.ToFloatPtr() );
  86. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_VIEW_ORIGIN, din->localViewOrigin.ToFloatPtr() );
  87. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_PROJECT_S, din->lightProjection[0].ToFloatPtr() );
  88. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_PROJECT_T, din->lightProjection[1].ToFloatPtr() );
  89. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_PROJECT_Q, din->lightProjection[2].ToFloatPtr() );
  90. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_FALLOFF_S, din->lightProjection[3].ToFloatPtr() );
  91. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_BUMP_MATRIX_S, din->bumpMatrix[0].ToFloatPtr() );
  92. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_BUMP_MATRIX_T, din->bumpMatrix[1].ToFloatPtr() );
  93. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_DIFFUSE_MATRIX_S, din->diffuseMatrix[0].ToFloatPtr() );
  94. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_DIFFUSE_MATRIX_T, din->diffuseMatrix[1].ToFloatPtr() );
  95. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_SPECULAR_MATRIX_S, din->diffuseMatrix[0].ToFloatPtr() );
  96. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_SPECULAR_MATRIX_T, din->diffuseMatrix[1].ToFloatPtr() );
  97. const srfTriangles_t *tri = din->surf->geo;
  98. idDrawVert *ac = (idDrawVert *)vertexCache.Position( tri->ambientCache );
  99. qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), (void *)&ac->xyz );
  100. static const float zero[4] = { 0, 0, 0, 0 };
  101. static const float one[4] = { 1, 1, 1, 1 };
  102. static const float negOne[4] = { -1, -1, -1, -1 };
  103. switch ( din->vertexColor ) {
  104. case SVC_IGNORE:
  105. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_MODULATE, zero );
  106. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_ADD, one );
  107. break;
  108. case SVC_MODULATE:
  109. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_MODULATE, one );
  110. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_ADD, zero );
  111. break;
  112. case SVC_INVERSE_MODULATE:
  113. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_MODULATE, negOne );
  114. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_ADD, one );
  115. break;
  116. }
  117. // texture 0 = light projection
  118. // texture 1 = light falloff
  119. // texture 2 = surface diffuse
  120. // texture 3 = surface specular
  121. // texture 4 = surface bump
  122. // texture 5 = normalization cube map
  123. GL_SelectTexture( 5 );
  124. if ( din->ambientLight ) {
  125. globalImages->ambientNormalMap->Bind();
  126. } else {
  127. globalImages->normalCubeMapImage->Bind();
  128. }
  129. GL_SelectTexture( 4 );
  130. din->bumpImage->Bind();
  131. GL_SelectTexture( 3 );
  132. din->specularImage->Bind();
  133. qglTexCoordPointer( 3, GL_FLOAT, sizeof( idDrawVert ), (void *)&ac->normal );
  134. GL_SelectTexture( 2 );
  135. din->diffuseImage->Bind();
  136. qglTexCoordPointer( 3, GL_FLOAT, sizeof( idDrawVert ), (void *)&ac->tangents[1][0] );
  137. GL_SelectTexture( 1 );
  138. din->lightFalloffImage->Bind();
  139. qglTexCoordPointer( 3, GL_FLOAT, sizeof( idDrawVert ), (void *)&ac->tangents[0][0] );
  140. GL_SelectTexture( 0 );
  141. din->lightImage->Bind();
  142. qglTexCoordPointer( 2, GL_FLOAT, sizeof( idDrawVert ), (void *)&ac->st[0] );
  143. qglSetFragmentShaderConstantATI( GL_CON_0_ATI, din->diffuseColor.ToFloatPtr() );
  144. qglSetFragmentShaderConstantATI( GL_CON_1_ATI, din->specularColor.ToFloatPtr() );
  145. if ( din->vertexColor != SVC_IGNORE ) {
  146. qglColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(idDrawVert), (void *)&ac->color );
  147. qglEnableClientState( GL_COLOR_ARRAY );
  148. RB_DrawElementsWithCounters( tri );
  149. qglDisableClientState( GL_COLOR_ARRAY );
  150. qglColor4f( 1, 1, 1, 1 );
  151. } else {
  152. RB_DrawElementsWithCounters( tri );
  153. }
  154. }
  155. /*
  156. ==================
  157. RB_R200_ARB_CreateDrawInteractions
  158. ==================
  159. */
  160. static void RB_R200_ARB_CreateDrawInteractions( const drawSurf_t *surf ) {
  161. if ( !surf ) {
  162. return;
  163. }
  164. // force a space calculation for light vectors
  165. backEnd.currentSpace = NULL;
  166. // set the depth test
  167. if ( surf->material->Coverage() == MC_TRANSLUCENT /* != C_PERFORATED */ ) {
  168. GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | GLS_DEPTHFUNC_LESS );
  169. } else {
  170. // only draw on the alpha tested pixels that made it to the depth buffer
  171. GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | GLS_DEPTHFUNC_EQUAL );
  172. }
  173. // start the vertex shader
  174. qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_R200_INTERACTION );
  175. qglEnable(GL_VERTEX_PROGRAM_ARB);
  176. // start the fragment shader
  177. qglBindFragmentShaderATI( FPROG_FAST_PATH );
  178. #if defined( MACOS_X )
  179. qglEnable( GL_TEXT_FRAGMENT_SHADER_ATI );
  180. #else
  181. qglEnable( GL_FRAGMENT_SHADER_ATI );
  182. #endif
  183. qglColor4f( 1, 1, 1, 1 );
  184. GL_SelectTexture( 1 );
  185. qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
  186. GL_SelectTexture( 2 );
  187. qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
  188. GL_SelectTexture( 3 );
  189. qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
  190. for ( ; surf ; surf=surf->nextOnLight ) {
  191. RB_CreateSingleDrawInteractions( surf, RB_R200_ARB_DrawInteraction );
  192. }
  193. GL_SelectTexture( 5 );
  194. globalImages->BindNull();
  195. GL_SelectTexture( 4 );
  196. globalImages->BindNull();
  197. GL_SelectTexture( 3 );
  198. globalImages->BindNull();
  199. qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
  200. GL_SelectTexture( 2 );
  201. globalImages->BindNull();
  202. qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
  203. GL_SelectTexture( 1 );
  204. globalImages->BindNull();
  205. qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
  206. GL_SelectTexture( 0 );
  207. qglDisable( GL_VERTEX_PROGRAM_ARB );
  208. #if defined( MACOS_X )
  209. qglDisable( GL_TEXT_FRAGMENT_SHADER_ATI );
  210. #else
  211. qglDisable( GL_FRAGMENT_SHADER_ATI );
  212. #endif
  213. }
  214. /*
  215. ==================
  216. RB_R200_DrawInteractions
  217. ==================
  218. */
  219. void RB_R200_DrawInteractions( void ) {
  220. qglEnable( GL_STENCIL_TEST );
  221. for ( viewLight_t *vLight = backEnd.viewDef->viewLights ; vLight ; vLight = vLight->next ) {
  222. // do fogging later
  223. if ( vLight->lightShader->IsFogLight() ) {
  224. continue;
  225. }
  226. if ( vLight->lightShader->IsBlendLight() ) {
  227. continue;
  228. }
  229. backEnd.vLight = vLight;
  230. RB_LogComment( "---------- RB_RenderViewLight 0x%p ----------\n", vLight );
  231. // clear the stencil buffer if needed
  232. if ( vLight->globalShadows || vLight->localShadows ) {
  233. backEnd.currentScissor = vLight->scissorRect;
  234. if ( r_useScissor.GetBool() ) {
  235. qglScissor( backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1,
  236. backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1,
  237. backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1,
  238. backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1 );
  239. }
  240. qglClear( GL_STENCIL_BUFFER_BIT );
  241. } else {
  242. // no shadows, so no need to read or write the stencil buffer
  243. // we might in theory want to use GL_ALWAYS instead of disabling
  244. // completely, to satisfy the invarience rules
  245. qglStencilFunc( GL_ALWAYS, 128, 255 );
  246. }
  247. if ( r_useShadowVertexProgram.GetBool() ) {
  248. qglEnable( GL_VERTEX_PROGRAM_ARB );
  249. qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_STENCIL_SHADOW );
  250. RB_StencilShadowPass( vLight->globalShadows );
  251. RB_R200_ARB_CreateDrawInteractions( vLight->localInteractions );
  252. qglEnable( GL_VERTEX_PROGRAM_ARB );
  253. qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_STENCIL_SHADOW );
  254. RB_StencilShadowPass( vLight->localShadows );
  255. RB_R200_ARB_CreateDrawInteractions( vLight->globalInteractions );
  256. qglDisable( GL_VERTEX_PROGRAM_ARB ); // if there weren't any globalInteractions, it would have stayed on
  257. } else {
  258. RB_StencilShadowPass( vLight->globalShadows );
  259. RB_R200_ARB_CreateDrawInteractions( vLight->localInteractions );
  260. RB_StencilShadowPass( vLight->localShadows );
  261. RB_R200_ARB_CreateDrawInteractions( vLight->globalInteractions );
  262. }
  263. if ( r_skipTranslucent.GetBool() ) {
  264. continue;
  265. }
  266. // disable stencil testing for translucent interactions, because
  267. // the shadow isn't calculated at their point, and the shadow
  268. // behind them may be depth fighting with a back side, so there
  269. // isn't any reasonable thing to do
  270. qglStencilFunc( GL_ALWAYS, 128, 255 );
  271. RB_R200_ARB_CreateDrawInteractions( vLight->translucentInteractions );
  272. }
  273. }
  274. /*
  275. =================
  276. R_BuildSurfaceFragmentProgram
  277. =================
  278. */
  279. static void R_BuildSurfaceFragmentProgram( int programNum ) {
  280. qglBindFragmentShaderATI( programNum );
  281. qglBeginFragmentShaderATI();
  282. // texture 0 = light projection
  283. // texture 1 = light falloff
  284. // texture 2 = surface diffuse
  285. // texture 3 = surface specular
  286. // texture 4 = surface bump
  287. // texture 5 = normalization cube map
  288. // texcoord 0 = light projection texGen
  289. // texcoord 1 = light falloff texGen
  290. // texcoord 2 = bumpmap texCoords
  291. // texcoord 3 = specular / diffuse texCoords
  292. // texcoord 4 = halfangle vector in local tangent space
  293. // texcoord 5 = vector to light in local tangent space
  294. // constant 0 = diffuse modulate
  295. // constant 1 = specular modulate
  296. // constant 5 = internal use for 0.75 constant
  297. qglSampleMapATI( GL_REG_0_ATI, GL_TEXTURE0_ARB, GL_SWIZZLE_STQ_DQ_ATI );
  298. qglSampleMapATI( GL_REG_1_ATI, GL_TEXTURE1_ARB, GL_SWIZZLE_STR_ATI );
  299. qglSampleMapATI( GL_REG_4_ATI, GL_TEXTURE2_ARB, GL_SWIZZLE_STR_ATI );
  300. qglSampleMapATI( GL_REG_5_ATI, GL_TEXTURE5_ARB, GL_SWIZZLE_STR_ATI );
  301. // move the alpha component to the red channel to support rxgb normal map compression
  302. if ( globalImages->image_useNormalCompression.GetInteger() == 2 ) {
  303. qglColorFragmentOp1ATI( GL_MOV_ATI, GL_REG_4_ATI, GL_RED_BIT_ATI, GL_NONE,
  304. GL_REG_4_ATI, GL_ALPHA, GL_NONE );
  305. }
  306. // light projection * light falloff
  307. qglColorFragmentOp2ATI( GL_MUL_ATI, GL_REG_0_ATI, GL_NONE, GL_NONE,
  308. GL_REG_0_ATI, GL_NONE, GL_NONE,
  309. GL_REG_1_ATI, GL_NONE, GL_NONE );
  310. // vectorToLight dot bumpMap
  311. qglColorFragmentOp2ATI( GL_DOT3_ATI, GL_REG_1_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
  312. GL_REG_4_ATI, GL_NONE, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI,
  313. GL_REG_5_ATI, GL_NONE, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI );
  314. // bump * light
  315. qglColorFragmentOp2ATI( GL_MUL_ATI, GL_REG_0_ATI, GL_NONE, GL_NONE,
  316. GL_REG_0_ATI, GL_NONE, GL_NONE,
  317. GL_REG_1_ATI, GL_NONE, GL_NONE );
  318. //-------------------
  319. // carry over the incomingLight calculation
  320. qglPassTexCoordATI( GL_REG_0_ATI, GL_REG_0_ATI, GL_SWIZZLE_STR_ATI );
  321. // sample the diffuse surface map
  322. qglSampleMapATI( GL_REG_2_ATI, GL_TEXTURE3_ARB, GL_SWIZZLE_STR_ATI );
  323. // sample the specular surface map
  324. qglSampleMapATI( GL_REG_3_ATI, GL_TEXTURE3_ARB, GL_SWIZZLE_STR_ATI );
  325. // we will use the surface bump map again
  326. qglPassTexCoordATI( GL_REG_4_ATI, GL_REG_4_ATI, GL_SWIZZLE_STR_ATI );
  327. // normalize the specular halfangle
  328. qglSampleMapATI( GL_REG_5_ATI, GL_TEXTURE4_ARB, GL_SWIZZLE_STR_ATI );
  329. // R1 = halfangle dot surfaceNormal
  330. qglColorFragmentOp2ATI( GL_DOT3_ATI, GL_REG_1_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
  331. GL_REG_4_ATI, GL_NONE, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI,
  332. GL_REG_5_ATI, GL_NONE, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI );
  333. // R1 = 4 * ( R1 - 0.75 )
  334. // subtract 0.75 and quadruple to tighten the specular spot
  335. float data[4] = { 0.75, 0.75, 0.75, 0.75 };
  336. qglSetFragmentShaderConstantATI( GL_CON_5_ATI, data );
  337. qglColorFragmentOp2ATI( GL_SUB_ATI, GL_REG_1_ATI, GL_NONE, GL_4X_BIT_ATI | GL_SATURATE_BIT_ATI,
  338. GL_REG_1_ATI, GL_NONE, GL_NONE,
  339. GL_CON_5_ATI, GL_NONE, GL_NONE );
  340. // R1 = R1 * R1
  341. // sqare the stretched specular result
  342. qglColorFragmentOp2ATI( GL_MUL_ATI, GL_REG_1_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
  343. GL_REG_1_ATI, GL_NONE, GL_NONE,
  344. GL_REG_1_ATI, GL_NONE, GL_NONE );
  345. // R1 = R1 * R3
  346. // R1 = specular power * specular texture * 2
  347. qglColorFragmentOp2ATI( GL_MUL_ATI, GL_REG_1_ATI, GL_NONE, GL_2X_BIT_ATI | GL_SATURATE_BIT_ATI,
  348. GL_REG_1_ATI, GL_NONE, GL_NONE,
  349. GL_REG_3_ATI, GL_NONE, GL_NONE );
  350. // R2 = R2 * CONST0
  351. // down modulate the diffuse map
  352. qglColorFragmentOp2ATI( GL_MUL_ATI, GL_REG_2_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
  353. GL_REG_2_ATI, GL_NONE, GL_NONE,
  354. GL_CON_0_ATI, GL_NONE, GL_NONE );
  355. // R2 = R2 + R1 * CONST1
  356. // diffuse + specular * specular color
  357. qglColorFragmentOp3ATI( GL_MAD_ATI, GL_REG_2_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
  358. GL_REG_1_ATI, GL_NONE, GL_NONE,
  359. GL_CON_1_ATI, GL_NONE, GL_NONE,
  360. GL_REG_2_ATI, GL_NONE, GL_NONE );
  361. // out = reflectance * incoming light
  362. qglColorFragmentOp2ATI( GL_MUL_ATI, GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
  363. GL_REG_0_ATI, GL_NONE, GL_NONE,
  364. GL_REG_2_ATI, GL_NONE, GL_NONE );
  365. // out * vertex color
  366. qglColorFragmentOp2ATI( GL_MUL_ATI, GL_REG_0_ATI, GL_NONE, GL_NONE,
  367. GL_REG_0_ATI, GL_NONE, GL_NONE,
  368. GL_PRIMARY_COLOR_ARB, GL_NONE, GL_NONE );
  369. // out alpha = 0 to allow blending optimization
  370. qglAlphaFragmentOp1ATI( GL_MOV_ATI, GL_REG_0_ATI, GL_NONE,
  371. GL_ZERO, GL_NONE, GL_NONE );
  372. qglEndFragmentShaderATI();
  373. GL_CheckErrors();
  374. }
  375. /*
  376. =================
  377. R_R200_Init
  378. =================
  379. */
  380. void R_R200_Init( void ) {
  381. glConfig.allowR200Path = false;
  382. common->Printf( "----------- R200_Init -----------\n" );
  383. if ( !glConfig.atiFragmentShaderAvailable || !glConfig.ARBVertexProgramAvailable || !glConfig.ARBVertexBufferObjectAvailable ) {
  384. common->Printf( "Not available.\n" );
  385. return;
  386. }
  387. GL_CheckErrors();
  388. qglGetIntegerv( GL_NUM_FRAGMENT_REGISTERS_ATI, &fsi.numFragmentRegisters );
  389. qglGetIntegerv( GL_NUM_FRAGMENT_CONSTANTS_ATI, &fsi.numFragmentConstants );
  390. qglGetIntegerv( GL_NUM_PASSES_ATI, &fsi.numPasses );
  391. qglGetIntegerv( GL_NUM_INSTRUCTIONS_PER_PASS_ATI, &fsi.numInstructionsPerPass );
  392. qglGetIntegerv( GL_NUM_INSTRUCTIONS_TOTAL_ATI, &fsi.numInstructionsTotal );
  393. qglGetIntegerv( GL_COLOR_ALPHA_PAIRING_ATI, &fsi.colorAlphaPairing );
  394. qglGetIntegerv( GL_NUM_LOOPBACK_COMPONENTS_ATI, &fsi.numLoopbackComponenets );
  395. qglGetIntegerv( GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI, &fsi.numInputInterpolatorComponents );
  396. common->Printf( "GL_NUM_FRAGMENT_REGISTERS_ATI: %i\n", fsi.numFragmentRegisters );
  397. common->Printf( "GL_NUM_FRAGMENT_CONSTANTS_ATI: %i\n", fsi.numFragmentConstants );
  398. common->Printf( "GL_NUM_PASSES_ATI: %i\n", fsi.numPasses );
  399. common->Printf( "GL_NUM_INSTRUCTIONS_PER_PASS_ATI: %i\n", fsi.numInstructionsPerPass );
  400. common->Printf( "GL_NUM_INSTRUCTIONS_TOTAL_ATI: %i\n", fsi.numInstructionsTotal );
  401. common->Printf( "GL_COLOR_ALPHA_PAIRING_ATI: %i\n", fsi.colorAlphaPairing );
  402. common->Printf( "GL_NUM_LOOPBACK_COMPONENTS_ATI: %i\n", fsi.numLoopbackComponenets );
  403. common->Printf( "GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI: %i\n", fsi.numInputInterpolatorComponents );
  404. common->Printf( "FPROG_FAST_PATH\n" );
  405. R_BuildSurfaceFragmentProgram( FPROG_FAST_PATH );
  406. common->Printf( "---------------------\n" );
  407. glConfig.allowR200Path = true;
  408. }