diff --git a/client/client.plg b/client/client.plg deleted file mode 100644 index 33666b63..00000000 --- a/client/client.plg +++ /dev/null @@ -1,16 +0,0 @@ - - -
-

Build Log

-

---------------------Configuration: client - Win32 Debug-------------------- -

-

Command Lines

- - - -

Results

-client.dll - 0 error(s), 0 warning(s) -
- - diff --git a/engine/engine.plg b/engine/engine.plg deleted file mode 100644 index 45d2c2f7..00000000 --- a/engine/engine.plg +++ /dev/null @@ -1,16 +0,0 @@ - - -
-

Build Log

-

---------------------Configuration: engine - Win32 Debug-------------------- -

-

Command Lines

- - - -

Results

-engine.dll - 0 error(s), 0 warning(s) -
- - diff --git a/launch/launch.plg b/launch/launch.plg deleted file mode 100644 index 67644887..00000000 --- a/launch/launch.plg +++ /dev/null @@ -1,64 +0,0 @@ - - -
-

Build Log

-

---------------------Configuration: launch - Win32 Release-------------------- -

-

Command Lines

-Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSPC7.tmp" with contents -[ -/nologo /MD /W3 /GX /O2 /I "./" /I "imagelib" /I "../public" /I "../common" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /Fo"..\temp\launch\!release/" /Fd"..\temp\launch\!release/" /FD /c -"D:\Xash3D\src_main\launch\memlib.c" -] -Creating command line "cl.exe @C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSPC7.tmp" -Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSPC8.tmp" with contents -[ -zlib.lib png.lib user32.lib gdi32.lib advapi32.lib winmm.lib /nologo /dll /pdb:none /machine:I386 /nodefaultlib:"libc.lib" /out:"..\temp\launch\!release/launch.dll" /implib:"..\temp\launch\!release/launch.lib" /libpath:"./imagelib" /opt:nowin98 -"\Xash3D\src_main\temp\launch\!release\cmd.obj" -"\Xash3D\src_main\temp\launch\!release\console.obj" -"\Xash3D\src_main\temp\launch\!release\cpuinfo.obj" -"\Xash3D\src_main\temp\launch\!release\crclib.obj" -"\Xash3D\src_main\temp\launch\!release\cvar.obj" -"\Xash3D\src_main\temp\launch\!release\export.obj" -"\Xash3D\src_main\temp\launch\!release\filesystem.obj" -"\Xash3D\src_main\temp\launch\!release\img_bmp.obj" -"\Xash3D\src_main\temp\launch\!release\img_dds.obj" -"\Xash3D\src_main\temp\launch\!release\img_jpg.obj" -"\Xash3D\src_main\temp\launch\!release\img_main.obj" -"\Xash3D\src_main\temp\launch\!release\img_pcx.obj" -"\Xash3D\src_main\temp\launch\!release\img_png.obj" -"\Xash3D\src_main\temp\launch\!release\img_tga.obj" -"\Xash3D\src_main\temp\launch\!release\img_utils.obj" -"\Xash3D\src_main\temp\launch\!release\img_vtf.obj" -"\Xash3D\src_main\temp\launch\!release\img_wad.obj" -"\Xash3D\src_main\temp\launch\!release\memlib.obj" -"\Xash3D\src_main\temp\launch\!release\network.obj" -"\Xash3D\src_main\temp\launch\!release\parselib.obj" -"\Xash3D\src_main\temp\launch\!release\patch.obj" -"\Xash3D\src_main\temp\launch\!release\stdlib.obj" -"\Xash3D\src_main\temp\launch\!release\system.obj" -"\Xash3D\src_main\temp\launch\!release\utils.obj" -] -Creating command line "link.exe @C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSPC8.tmp" -Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSPC9.bat" with contents -[ -@echo off -copy \Xash3D\src_main\temp\launch\!release\launch.dll "D:\Xash3D\bin\launch.dll" -] -Creating command line "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSPC9.bat" -Compiling... -memlib.c -Linking... - Creating library ..\temp\launch\!release/launch.lib and object ..\temp\launch\!release/launch.exp -

Output Window

-Performing Custom Build Step on \Xash3D\src_main\temp\launch\!release\launch.dll -Скопировано файлов: 1. - - - -

Results

-launch.dll - 0 error(s), 0 warning(s) -
- - diff --git a/render/r_backend.c b/render/r_backend.c index a1777124..c202a43d 100644 --- a/render/r_backend.c +++ b/render/r_backend.c @@ -33,6 +33,10 @@ static float r_triangletable[FTABLE_SIZE]; static float r_squaretable[FTABLE_SIZE]; static float r_sawtoothtable[FTABLE_SIZE]; static float r_inversesawtoothtable[FTABLE_SIZE]; +static float r_warpsintable[256] = +{ +#include "warpsin.h" +}; #define NOISE_SIZE 256 #define NOISE_VAL( a ) r_noiseperm[( a ) & ( NOISE_SIZE - 1 )] @@ -59,10 +63,10 @@ vec2_t *coordsArray; vec2_t *lightmapCoordsArray[LM_STYLES]; rgba_t colorArray[MAX_ARRAY_VERTS]; -ref_globals_t tr; -ref_backacc_t r_backacc; +ref_globals_t tr; +ref_backacc_t r_backacc; -bool r_triangleOutlines; +bool r_triangleOutlines; static vec4_t colorWhite = { 1.0f, 1.0f, 1.0f, 1.0f }; static vec4_t colorRed = { 1.0f, 0.0f, 0.0f, 1.0f }; @@ -109,25 +113,24 @@ R_BackendInit */ void R_BackendInit( void ) { - int i; - float t; + int i; + float t; r_numAccumPasses = 0; r_arraysLocked = false; r_triangleOutlines = false; + tr.iRenderMode = kRenderNormal; R_ClearArrays(); R_InitVertexBuffers(); - R_BackendResetPassMask(); pglEnableClientState( GL_VERTEX_ARRAY ); if( !r_ignorehwgamma->integer ) - r_identityLighting = (int)( 255.0f / pow( 2, max( 0, floor( r_overbrightbits->value ) ) ) ); - else - r_identityLighting = 255; + r_identityLighting = (int)( 255.0f / pow( 2, max( 0, floor( r_overbrightbits->value )))); + else r_identityLighting = 255; // build lookup tables for( i = 0; i < FTABLE_SIZE; i++ ) @@ -136,41 +139,34 @@ void R_BackendInit( void ) r_sintable[i] = sin( t * M_PI2 ); - if( t < 0.25 ) - r_triangletable[i] = t * 4.0; - else if( t < 0.75 ) - r_triangletable[i] = 2 - 4.0 * t; - else - r_triangletable[i] = ( t - 0.75 ) * 4.0 - 1.0; + if( t < 0.25f ) r_triangletable[i] = t * 4.0f; + else if( t < 0.75f ) r_triangletable[i] = 2 - 4.0f * t; + else r_triangletable[i] = ( t - 0.75f ) * 4.0f - 1.0f; - if( t < 0.5 ) - r_squaretable[i] = 1.0f; - else - r_squaretable[i] = -1.0f; + if( t < 0.5f ) r_squaretable[i] = 1.0f; + else r_squaretable[i] = -1.0f; r_sawtoothtable[i] = t; - r_inversesawtoothtable[i] = 1.0 - t; + r_inversesawtoothtable[i] = 1.0f - t; } for( i = 0; i < 256; i++ ) - r_sintableByte[i] = sin( (float)i / 255.0 * M_PI2 ); + r_sintableByte[i] = sin((float)i / 255.0f * M_PI2 ); // init the noise table - srand( 1001 ); - for( i = 0; i < NOISE_SIZE; i++ ) { - r_noisetable[i] = (float)( ( ( rand() / (float)RAND_MAX ) * 2.0 - 1.0 ) ); - r_noiseperm[i] = (unsigned char)( rand() / (float)RAND_MAX * 255 ); + r_noisetable[i] = Com_RandomFloat( -1.0f, 1.0f ); + r_noiseperm[i] = Com_RandomLong( 0, 255 ); } // init dynamic lights pass - memset( &r_dlightsPass, 0, sizeof( ref_stage_t ) ); + Mem_Set( &r_dlightsPass, 0, sizeof( ref_stage_t ) ); r_dlightsPass.flags = SHADERSTAGE_DLIGHT; r_dlightsPass.glState = GLSTATE_DEPTHFUNC_EQ|GLSTATE_SRCBLEND_DST_COLOR|GLSTATE_DSTBLEND_ONE; // init fog pass - memset( &r_fogPass, 0, sizeof( ref_stage_t ) ); + Mem_Set( &r_fogPass, 0, sizeof( ref_stage_t ) ); r_fogPass.tcgen = TCGEN_FOG; r_fogPass.rgbGen.type = RGBGEN_FOG; r_fogPass.alphaGen.type = ALPHAGEN_IDENTITY; @@ -192,7 +188,7 @@ void R_BackendInit( void ) } // init optional GLSL program passes - memset( r_GLSLpasses, 0, sizeof( r_GLSLpasses ) ); + Mem_Set( r_GLSLpasses, 0, sizeof( r_GLSLpasses ) ); r_GLSLpasses[0].flags = SHADERSTAGE_DLIGHT|SHADERSTAGE_BLEND_ADD; r_GLSLpasses[0].glState = GLSTATE_DEPTHFUNC_EQ|GLSTATE_SRCBLEND_ONE|GLSTATE_DSTBLEND_ONE; @@ -248,11 +244,11 @@ R_LatLongToNorm */ void R_LatLongToNorm( const byte latlong[2], vec3_t out ) { - float sin_a, sin_b, cos_a, cos_b; + float sin_a, sin_b, cos_a, cos_b; - cos_a = r_sintableByte[( latlong[0] + 64 ) & 255]; + cos_a = r_sintableByte[(latlong[0] + 64) & 255]; sin_a = r_sintableByte[latlong[0]]; - cos_b = r_sintableByte[( latlong[1] + 64 ) & 255]; + cos_b = r_sintableByte[(latlong[1] + 64) & 255]; sin_b = r_sintableByte[latlong[1]]; VectorSet( out, cos_b * sin_a, sin_b * sin_a, cos_a ); @@ -263,7 +259,7 @@ void R_LatLongToNorm( const byte latlong[2], vec3_t out ) R_TableForFunc ============== */ -static float *R_TableForFunc( unsigned int func ) +static float *R_TableForFunc( uint func ) { switch( func ) { @@ -277,17 +273,26 @@ static float *R_TableForFunc( unsigned int func ) return r_sawtoothtable; case WAVEFORM_INVERSESAWTOOTH: return r_inversesawtoothtable; - case WAVEFORM_NOISE: return r_sintable; // default to sintable + default: + return NULL; } - - // assume error - Host_Error( "R_TableForFunc: unknown function\n" ); - - return NULL; } +static float R_TableEvaluate( waveFunc_t func, float index ) +{ + float *table = R_TableForFunc( func.type ); + + if( table == NULL ) + { + if( func.type == WAVEFORM_TABLE ) + return R_LookupTable( func.tableIndex, index ); + return 1.0f; // assume error + } + return FTABLE_EVALUATE( table, index ); +} + /* ============== R_BackendGetNoiseValue @@ -295,11 +300,11 @@ R_BackendGetNoiseValue */ float R_BackendGetNoiseValue( float x, float y, float z, float t ) { - int i; - int ix, iy, iz, it; - float fx, fy, fz, ft; - float front[4], back[4]; - float fvalue, bvalue, value[2], finalvalue; + int i; + int ix, iy, iz, it; + float fx, fy, fz, ft; + float front[4], back[4]; + float fvalue, bvalue, value[2], finalvalue; ix = ( int )floor( x ); fx = x - ix; @@ -326,7 +331,6 @@ float R_BackendGetNoiseValue( float x, float y, float z, float t ) bvalue = NOISE_LERP( NOISE_LERP( back[0], back[1], fx ), NOISE_LERP( back[2], back[3], fx ), fy ); value[i] = NOISE_LERP( fvalue, bvalue, fz ); } - finalvalue = NOISE_LERP( value[0], value[1], ft ); return finalvalue; @@ -339,7 +343,7 @@ R_BackendResetCounters */ void R_BackendResetCounters( void ) { - memset( &r_backacc, 0, sizeof( r_backacc ) ); + Mem_Set( &r_backacc, 0, sizeof( r_backacc )); } /* @@ -546,7 +550,7 @@ R_CleanUpTextureUnits */ static void R_CleanUpTextureUnits( int last ) { - int i; + int i; for( i = glState.activeTMU; i > last - 1; i-- ) { @@ -568,7 +572,6 @@ void R_DeformVertices( void ) uint i, j, k; double args[4], temp; float deflect, *quad[4]; - const float *table; const deform_t *deformv; vec3_t tv, rot_centre; @@ -579,15 +582,12 @@ void R_DeformVertices( void ) { case DEFORM_NONE: break; - case DEFORM_WAVE: - table = R_TableForFunc( deformv->func.type ); - // Deflect vertex along its normal by wave amount if( deformv->func.args[3] == 0 ) { temp = deformv->func.args[2]; - deflect = FTABLE_EVALUATE( table, temp ) * deformv->func.args[1] + deformv->func.args[0]; + deflect = R_TableEvaluate( deformv->func, temp ) * deformv->func.args[1] + deformv->func.args[0]; for( j = 0; j < r_backacc.numVerts; j++ ) VectorMA( inVertsArray[j], deflect, inNormalsArray[j], inVertsArray[j] ); @@ -602,12 +602,11 @@ void R_DeformVertices( void ) for( j = 0; j < r_backacc.numVerts; j++ ) { temp = args[2] + args[3] * ( inVertsArray[j][0] + inVertsArray[j][1] + inVertsArray[j][2] ); - deflect = FTABLE_EVALUATE( table, temp ) * args[1] + args[0]; + deflect = R_TableEvaluate( deformv->func, temp ) * args[1] + args[0]; VectorMA( inVertsArray[j], deflect, inNormalsArray[j], inVertsArray[j] ); } } break; - case DEFORM_NORMAL: // without this * 0.1f deformation looks wrong, although q3a doesn't have it args[0] = deformv->func.args[3] * r_currentShaderTime * 0.1f; @@ -622,16 +621,13 @@ void R_DeformVertices( void ) VectorNormalizeFast( inNormalsArray[j] ); } break; - case DEFORM_MOVE: - table = R_TableForFunc( deformv->func.type ); temp = deformv->func.args[2] + r_currentShaderTime * deformv->func.args[3]; - deflect = FTABLE_EVALUATE( table, temp ) * deformv->func.args[1] + deformv->func.args[0]; + deflect = R_TableEvaluate( deformv->func, temp ) * deformv->func.args[1] + deformv->func.args[0]; for( j = 0; j < r_backacc.numVerts; j++ ) VectorMA( inVertsArray[j], deflect, deformv->args, inVertsArray[j] ); break; - case DEFORM_BULGE: args[0] = deformv->args[0]; args[1] = deformv->args[1]; @@ -644,7 +640,6 @@ void R_DeformVertices( void ) VectorMA( inVertsArray[j], deflect, inNormalsArray[j], inVertsArray[j] ); } break; - case DEFORM_AUTOSPRITE: { vec4_t *v; @@ -709,7 +704,6 @@ void R_DeformVertices( void ) } } break; - case DEFORM_AUTOSPRITE2: if( r_backacc.numElems % 6 ) break; @@ -842,11 +836,9 @@ void R_DeformVertices( void ) } } break; - case DEFORM_PROJECTION_SHADOW: R_DeformVPlanarShadow( r_backacc.numVerts, inVertsArray[0] ); break; - case DEFORM_AUTOPARTICLE: { float scale; @@ -972,7 +964,6 @@ static bool R_VertexTCBase( const ref_stage_t *pass, int unit, mat4x4_t matrix ) pglTexCoordPointer( 2, GL_FLOAT, 0, tr.tcoordBuffer[unit]->pointer ); return true; } - case TCGEN_VECTOR: { GLfloat genVector[2][4]; @@ -1032,7 +1023,6 @@ static bool R_VertexTCBase( const ref_stage_t *pass, int unit, mat4x4_t matrix ) pglTexGenfv( GL_Q, GL_OBJECT_PLANE, genVector[3] ); return false; } - case TCGEN_REFLECTION_CELLSHADE: if( RI.currententity && !( RI.params & RP_SHADOWMAPVIEW ) ) { @@ -1056,7 +1046,6 @@ static bool R_VertexTCBase( const ref_stage_t *pass, int unit, mat4x4_t matrix ) GL_EnableTexGen( GL_R, GL_REFLECTION_MAP_ARB ); GL_EnableTexGen( GL_Q, 0 ); return true; - case TCGEN_FOG: { int fogPtype; @@ -1135,7 +1124,6 @@ static bool R_VertexTCBase( const ref_stage_t *pass, int unit, mat4x4_t matrix ) pglTexCoordPointer( 2, GL_FLOAT, 0, tr.tcoordBuffer[unit]->pointer ); return false; } - case TCGEN_SVECTORS: GL_DisableAllTexGens(); R_UpdateVertexBuffer( tr.tcoordBuffer[unit], sVectorsArray, r_backacc.numVerts * sizeof( vec4_t )); @@ -1159,10 +1147,10 @@ R_ApplyTCMods static void R_ApplyTCMods( const ref_stage_t *pass, mat4x4_t result ) { int i; - const float *table; double t1, t2, sint, cost; mat4x4_t m1, m2; const tcMod_t *tcmod; + waveFunc_t func; for( i = 0, tcmod = pass->tcMods; i < pass->numtcMods; i++, tcmod++ ) { @@ -1181,14 +1169,15 @@ static void R_ApplyTCMods( const ref_stage_t *pass, mat4x4_t result ) Matrix4_Scale2D( result, tcmod->args[0], tcmod->args[1] ); break; case TCMOD_TURB: - t1 = ( 1.0 / 4.0 ); + t1 = ( 1.0f / 4.0f ); t2 = tcmod->args[2] + r_currentShaderTime * tcmod->args[3]; Matrix4_Scale2D( result, 1 + ( tcmod->args[1] * R_FastSin( t2 ) + tcmod->args[0] ) * t1, 1 + ( tcmod->args[1] * R_FastSin( t2 + 0.25 ) + tcmod->args[0] ) * t1 ); break; case TCMOD_STRETCH: - table = R_TableForFunc( tcmod->args[0] ); + func.type = (uint)tcmod->args[0]; + func.tableIndex = (uint)tcmod->args[5]; t2 = tcmod->args[3] + r_currentShaderTime * tcmod->args[4]; - t1 = FTABLE_EVALUATE( table, t2 ) * tcmod->args[2] + tcmod->args[1]; + t1 = R_TableEvaluate( func, t2 ) * tcmod->args[2] + tcmod->args[1]; t1 = t1 ? 1.0f / t1 : 1.0f; t2 = 0.5f - 0.5f * t1; Matrix4_Stretch2D( result, t1, t2 ); @@ -1197,7 +1186,8 @@ static void R_ApplyTCMods( const ref_stage_t *pass, mat4x4_t result ) t1 = tcmod->args[0] * r_currentShaderTime; t2 = tcmod->args[1] * r_currentShaderTime; if( pass->program_type != PROGRAM_TYPE_DISTORTION ) - { // HACK HACK HACK + { + // HACKHACK t1 = t1 - floor( t1 ); t2 = t2 - floor( t2 ); } @@ -1231,6 +1221,196 @@ static _inline texture_t *R_ShaderpassTex( const ref_stage_t *pass, int unit ) return ( pass->textures[0] ? pass->textures[0] : tr.defaultTexture ); } +/* +================= +RB_SetShaderRenderMode + +UNDONE: not all cases are filled +================= +*/ +static void R_ShaderpassRenderMode( ref_stage_t *pass ) +{ + int mod_type = mod_bad; // mod_bad interpretate as orthogonal shader + + if(!(pass->flags & SHADERSTAGE_RENDERMODE)) + return; + + if( RI.currentmodel && !glState.in2DMode ) + mod_type = RI.currentmodel->type; + + switch( tr.iRenderMode ) + { + case kRenderNormal: + switch( mod_type ) + { + case mod_bad: + pass->rgbGen.type = RGBGEN_IDENTITY; + pass->alphaGen.type = ALPHAGEN_IDENTITY; + break; + case mod_world: + case mod_brush: + // bsp surfaces uses lightmaps and ignore color values as well + pass->glState &= ~(GLSTATE_BLENDFUNC|GLSTATE_ALPHAFUNC); + pass->glState |= GLSTATE_DEPTHWRITE; + pass->rgbGen.type = RGBGEN_IDENTITY_LIGHTING; + pass->alphaGen.type = ALPHAGEN_IDENTITY; + break; + case mod_studio: + // UNDONE: wrote R_StudioLighting, change rgbGen to RGBGEN_VERTEX + // UNDONE: setup custom alpha channel for NF_ADDITIVE, change alphaGen to ALPHAGEN_VERTEX + pass->glState &= ~(GLSTATE_BLENDFUNC|GLSTATE_ALPHAFUNC); + pass->rgbGen.type = RGBGEN_LIGHTING_AMBIENT_ONLY; + pass->alphaGen.type = ALPHAGEN_IDENTITY; + break; + case mod_sprite: + pass->glState &= ~(GLSTATE_BLENDFUNC|GLSTATE_ALPHAFUNC); + pass->rgbGen.type = RGBGEN_LIGHTING_AMBIENT_ONLY; + pass->alphaGen.type = ALPHAGEN_IDENTITY; + break; + } + break; + case kRenderTransColor: + switch( mod_type ) + { + case mod_bad: + pass->glState &= ~GLSTATE_ALPHAFUNC; + pass->glState |= (GLSTATE_SRCBLEND_ZERO|GLSTATE_DSTBLEND_SRC_COLOR); + pass->rgbGen.type = RGBGEN_VERTEX; + pass->alphaGen.type = ALPHAGEN_VERTEX; + break; + case mod_world: + pass->glState &= ~(GLSTATE_BLENDFUNC|GLSTATE_ALPHAFUNC); + pass->glState |= GLSTATE_DEPTHWRITE; + pass->rgbGen.type = RGBGEN_IDENTITY_LIGHTING; + pass->alphaGen.type = ALPHAGEN_IDENTITY; + break; + case mod_brush: + case mod_studio: + case mod_sprite: + break; + } + break; + case kRenderTransTexture: + switch( mod_type ) + { + case mod_bad: + pass->glState &= ~GLSTATE_ALPHAFUNC; + pass->glState |= (GLSTATE_SRCBLEND_SRC_ALPHA|GLSTATE_DSTBLEND_ONE_MINUS_SRC_ALPHA); + pass->rgbGen.type = RGBGEN_VERTEX; + pass->alphaGen.type = ALPHAGEN_VERTEX; + break; + case mod_world: + pass->glState &= ~(GLSTATE_BLENDFUNC|GLSTATE_ALPHAFUNC); + pass->glState |= GLSTATE_DEPTHWRITE; + pass->rgbGen.type = RGBGEN_IDENTITY_LIGHTING; + pass->alphaGen.type = ALPHAGEN_IDENTITY; + break; + case mod_brush: + pass->glState &= ~(GLSTATE_DEPTHWRITE|GLSTATE_ALPHAFUNC); + pass->glState |= (GLSTATE_SRCBLEND_SRC_ALPHA|GLSTATE_DSTBLEND_ONE_MINUS_SRC_ALPHA); + pass->rgbGen.type = RGBGEN_IDENTITY_LIGHTING; + pass->alphaGen.type = ALPHAGEN_ENTITY; + break; + case mod_studio: + case mod_sprite: + break; + } + break; + case kRenderGlow: + switch( mod_type ) + { + case mod_bad: + pass->glState &= ~GLSTATE_ALPHAFUNC; + pass->glState |= (GLSTATE_SRCBLEND_SRC_ALPHA|GLSTATE_DSTBLEND_ONE); + pass->rgbGen.type = RGBGEN_VERTEX; + pass->alphaGen.type = ALPHAGEN_VERTEX; + break; + case mod_world: + case mod_brush: + // completely ignore glow mode for world surfaces + pass->glState &= ~(GLSTATE_BLENDFUNC|GLSTATE_ALPHAFUNC); + pass->glState |= GLSTATE_DEPTHWRITE; + pass->rgbGen.type = RGBGEN_IDENTITY_LIGHTING; + pass->alphaGen.type = ALPHAGEN_IDENTITY; + break; + case mod_studio: + case mod_sprite: + pass->glState &= ~(GLSTATE_ALPHAFUNC|GLSTATE_DEPTHWRITE|GLSTATE_DEPTHFUNC_EQ); + pass->glState |= (GLSTATE_SRCBLEND_ONE_MINUS_SRC_ALPHA|GLSTATE_DSTBLEND_ONE); + pass->rgbGen.type = RGBGEN_IDENTITY; // hl1 glow sprites ignores color + pass->alphaGen.type = ALPHAGEN_ENTITY; + break; + } + break; + case kRenderTransAlpha: + switch( mod_type ) + { + case mod_bad: + pass->glState &= ~GLSTATE_BLENDFUNC; + pass->glState |= GLSTATE_AFUNC_GE128; + pass->rgbGen.type = RGBGEN_VERTEX; + pass->alphaGen.type = ALPHAGEN_VERTEX; + break; + case mod_world: + // always ignore transparent surfaces for world + pass->glState &= ~(GLSTATE_BLENDFUNC|GLSTATE_ALPHAFUNC); + pass->glState |= GLSTATE_DEPTHWRITE; + pass->rgbGen.type = RGBGEN_IDENTITY_LIGHTING; + pass->alphaGen.type = ALPHAGEN_IDENTITY; + break; + case mod_brush: + pass->glState &= ~GLSTATE_BLENDFUNC; + pass->glState |= GLSTATE_AFUNC_GE128; + pass->rgbGen.type = RGBGEN_IDENTITY; + pass->alphaGen.type = ALPHAGEN_IDENTITY; + case mod_studio: + // UNDONE: wrote R_StudioLighting, change rgbGen to RGBGEN_VERTEX + // UNDONE: setup custom alpha channel for NF_ADDITIVE, change alphaGen to ALPHAGEN_VERTEX + pass->glState &= ~GLSTATE_BLENDFUNC; + pass->glState |= GLSTATE_AFUNC_GE128; + pass->rgbGen.type = RGBGEN_LIGHTING_AMBIENT_ONLY; + pass->alphaGen.type = ALPHAGEN_ENTITY; + case mod_sprite: + pass->glState &= ~GLSTATE_BLENDFUNC; + pass->glState |= GLSTATE_AFUNC_GE128; + pass->rgbGen.type = RGBGEN_LIGHTING_AMBIENT_ONLY; + pass->alphaGen.type = ALPHAGEN_ENTITY; + break; + } + break; + case kRenderTransAdd: + switch( mod_type ) + { + case mod_bad: + pass->glState &= ~GLSTATE_ALPHAFUNC; + pass->glState |= (GLSTATE_SRCBLEND_SRC_ALPHA|GLSTATE_DSTBLEND_ONE); + pass->rgbGen.type = RGBGEN_VERTEX; + pass->alphaGen.type = ALPHAGEN_VERTEX; + break; + case mod_world: + pass->glState &= ~(GLSTATE_BLENDFUNC|GLSTATE_ALPHAFUNC); + pass->glState |= GLSTATE_DEPTHWRITE; + pass->rgbGen.type = RGBGEN_IDENTITY_LIGHTING; + pass->alphaGen.type = ALPHAGEN_IDENTITY; + break; + case mod_brush: + pass->glState &= ~(GLSTATE_ALPHAFUNC|GLSTATE_DEPTHWRITE); + pass->glState |= (GLSTATE_SRCBLEND_SRC_ALPHA|GLSTATE_DSTBLEND_ONE); + pass->rgbGen.type = RGBGEN_IDENTITY_LIGHTING; + pass->alphaGen.type = ALPHAGEN_ENTITY; + break; + case mod_studio: + case mod_sprite: + pass->glState &= ~(GLSTATE_ALPHAFUNC|GLSTATE_DEPTHWRITE); + pass->glState |= (GLSTATE_SRCBLEND_SRC_ALPHA|GLSTATE_DSTBLEND_ONE); + pass->rgbGen.type = RGBGEN_IDENTITY_LIGHTING; + pass->alphaGen.type = ALPHAGEN_ENTITY; + break; + } + break; + } +} + /* ================ R_BindShaderpass @@ -1238,15 +1418,14 @@ R_BindShaderpass */ static void R_BindShaderpass( const ref_stage_t *pass, texture_t *tex, int unit ) { - mat4x4_t m1, m2, result; - bool identityMatrix; + mat4x4_t m1, m2, result; + bool identityMatrix; - if( !tex ) - tex = R_ShaderpassTex( pass, unit ); + if( !tex ) tex = R_ShaderpassTex( pass, unit ); GL_Bind( unit, tex ); if( unit && !pass->program ) pglEnable( GL_TEXTURE_2D ); - GL_SetTexCoordArrayMode( ( tex->flags & TF_CUBEMAP ? GL_TEXTURE_CUBE_MAP_ARB : GL_TEXTURE_COORD_ARRAY )); + GL_SetTexCoordArrayMode(( tex->flags & TF_CUBEMAP ? GL_TEXTURE_CUBE_MAP_ARB : GL_TEXTURE_COORD_ARRAY )); identityMatrix = R_VertexTCBase( pass, unit, result ); @@ -1267,8 +1446,7 @@ static void R_BindShaderpass( const ref_stage_t *pass, texture_t *tex, int unit if( identityMatrix ) GL_LoadIdentityTexMatrix(); - else - GL_LoadTexMatrix( result ); + else GL_LoadTexMatrix( result ); } /* @@ -1279,9 +1457,9 @@ R_ModifyColor void R_ModifyColor( const ref_stage_t *pass ) { uint i; + float a; int c, bits; double temp; - float *table, a; vec3_t t, v, style; byte *bArray, *inArray, rgba[4] = { 255, 255, 255, 255 }; bool noArray, identityAlpha, entityAlpha; @@ -1297,18 +1475,18 @@ void R_ModifyColor( const ref_stage_t *pass ) if( pass->rgbGen.type == RGBGEN_IDENTITY_LIGHTING ) { entityAlpha = identityAlpha = false; - memset( bArray, r_identityLighting, sizeof( rgba_t ) * r_backacc.numColors ); + Mem_Set( bArray, r_identityLighting, sizeof( rgba_t ) * r_backacc.numColors ); } else if( pass->rgbGen.type == RGBGEN_EXACT_VERTEX ) { entityAlpha = identityAlpha = false; - memcpy( bArray, inArray, sizeof( rgba_t ) * r_backacc.numColors ); + Mem_Copy( bArray, inArray, sizeof( rgba_t ) * r_backacc.numColors ); } else { entityAlpha = false; identityAlpha = true; - memset( bArray, 255, sizeof( rgba_t ) * r_backacc.numColors ); + Mem_Set( bArray, 255, sizeof( rgba_t ) * r_backacc.numColors ); switch( pass->rgbGen.type ) { @@ -1330,9 +1508,8 @@ void R_ModifyColor( const ref_stage_t *pass ) } else { - table = R_TableForFunc( rgbgenfunc->type ); temp = r_currentShaderTime * rgbgenfunc->args[3] + rgbgenfunc->args[2]; - temp = FTABLE_EVALUATE( table, temp ) * rgbgenfunc->args[1] + rgbgenfunc->args[0]; + temp = R_TableEvaluate( *rgbgenfunc, temp ) * rgbgenfunc->args[1] + rgbgenfunc->args[0]; } temp = temp * rgbgenfunc->args[1] + rgbgenfunc->args[0]; @@ -1389,7 +1566,7 @@ void R_ModifyColor( const ref_stage_t *pass ) float *tc; vec3_t temp[MAX_ARRAY_VERTS]; - memset( temp, 0, sizeof( vec3_t ) * r_backacc.numColors ); + Mem_Set( temp, 0, sizeof( vec3_t ) * r_backacc.numColors ); for( j = 0; j < LM_STYLES && r_superLightStyle->vertexStyles[j] != 255; j++ ) { @@ -1504,9 +1681,8 @@ void R_ModifyColor( const ref_stage_t *pass ) } else { - table = R_TableForFunc( alphagenfunc->type ); a = alphagenfunc->args[2] + r_currentShaderTime * alphagenfunc->args[3]; - a = FTABLE_EVALUATE( table, a ); + a = R_TableEvaluate( *alphagenfunc, a ); } a = a * alphagenfunc->args[1] + alphagenfunc->args[0]; @@ -1734,6 +1910,7 @@ void R_RenderMeshGeneric( void ) { const ref_stage_t *pass = r_accumPasses[0]; + R_ShaderpassRenderMode( (ref_stage_t *)pass ); R_BindShaderpass( pass, NULL, 0 ); R_ModifyColor( pass ); diff --git a/render/r_backend.h b/render/r_backend.h index ec5bc3ba..3431ddb7 100644 --- a/render/r_backend.h +++ b/render/r_backend.h @@ -80,6 +80,7 @@ typedef struct { // renderer global variables int registration_sequence; + kRenderMode_t iRenderMode; // vbo stuff int numVertexBufferObjects; diff --git a/render/r_backend.old b/render/r_backend.old deleted file mode 100644 index 3814a09a..00000000 --- a/render/r_backend.old +++ /dev/null @@ -1,2845 +0,0 @@ -/* -Copyright (C) 2002-2007 Victor Luchits - -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. - -*/ - -#include "r_local.h" -#include "mathlib.h" -#include "quatlib.h" - -#define FTABLE_SIZE_POW 10 -#define FTABLE_SIZE ( 1<integer ) - r_identityLighting = (int)( 255.0f / pow( 2, max( 0, floor( r_overbrightbits->value ) ) ) ); - else - r_identityLighting = 255; - - // build lookup tables - for( i = 0; i < FTABLE_SIZE; i++ ) - { - t = (float)i / (float)FTABLE_SIZE; - - r_sintable[i] = sin( t * M_PI2 ); - - if( t < 0.25 ) - r_triangletable[i] = t * 4.0; - else if( t < 0.75 ) - r_triangletable[i] = 2 - 4.0 * t; - else - r_triangletable[i] = ( t - 0.75 ) * 4.0 - 1.0; - - if( t < 0.5 ) - r_squaretable[i] = 1.0f; - else - r_squaretable[i] = -1.0f; - - r_sawtoothtable[i] = t; - r_inversesawtoothtable[i] = 1.0 - t; - } - - for( i = 0; i < 256; i++ ) - r_sintableByte[i] = sin( (float)i / 255.0 * M_PI2 ); - - // init the noise table - srand( 1001 ); - - for( i = 0; i < NOISE_SIZE; i++ ) - { - r_noisetable[i] = (float)( ( ( rand() / (float)RAND_MAX ) * 2.0 - 1.0 ) ); - r_noiseperm[i] = (unsigned char)( rand() / (float)RAND_MAX * 255 ); - } - - // init dynamic lights pass - memset( &r_dlightsPass, 0, sizeof( ref_stage_t ) ); - r_dlightsPass.flags = SHADERSTAGE_DLIGHT; - r_dlightsPass.glState = GLSTATE_DEPTHFUNC_EQ|GLSTATE_SRCBLEND_DST_COLOR|GLSTATE_DSTBLEND_ONE; - - // init fog pass - memset( &r_fogPass, 0, sizeof( ref_stage_t ) ); - r_fogPass.tcgen = TCGEN_FOG; - r_fogPass.rgbGen.type = RGBGEN_FOG; - r_fogPass.alphaGen.type = ALPHAGEN_IDENTITY; - r_fogPass.flags = SHADERSTAGE_NOCOLORARRAY|SHADERSTAGE_BLEND_DECAL; - r_fogPass.glState = GLSTATE_SRCBLEND_SRC_ALPHA|GLSTATE_DSTBLEND_ONE_MINUS_SRC_ALPHA; - - // the very first lightmap pass is reserved for GL_REPLACE or GL_MODULATE - Mem_Set( r_lightmapPasses, 0, sizeof( r_lightmapPasses )); - r_lightmapPasses[0].rgbGen.args = r_lightmapPassesArgs[0]; - - // the rest are GL_ADD - for( i = 1; i < MAX_TEXTURE_UNITS+1; i++ ) - { - r_lightmapPasses[i].flags = SHADERSTAGE_LIGHTMAP|SHADERSTAGE_NOCOLORARRAY|SHADERSTAGE_BLEND_ADD; - r_lightmapPasses[i].glState = GLSTATE_DEPTHFUNC_EQ|GLSTATE_SRCBLEND_ONE|GLSTATE_DSTBLEND_ONE; - r_lightmapPasses[i].tcgen = TCGEN_LIGHTMAP; - r_lightmapPasses[i].alphaGen.type = ALPHAGEN_IDENTITY; - r_lightmapPasses[i].rgbGen.args = r_lightmapPassesArgs[i]; - } - - // init optional GLSL program passes - memset( r_GLSLpasses, 0, sizeof( r_GLSLpasses ) ); - r_GLSLpasses[0].flags = SHADERSTAGE_DLIGHT|SHADERSTAGE_BLEND_ADD; - r_GLSLpasses[0].glState = GLSTATE_DEPTHFUNC_EQ|GLSTATE_SRCBLEND_ONE|GLSTATE_DSTBLEND_ONE; - - r_GLSLpasses[1].flags = SHADERSTAGE_NOCOLORARRAY|SHADERSTAGE_BLEND_MODULATE; - r_GLSLpasses[1].glState = GLSTATE_SRCBLEND_ZERO|GLSTATE_DSTBLEND_SRC_COLOR; - r_GLSLpasses[1].tcgen = TCGEN_BASE; - r_GLSLpasses[1].rgbGen.type = RGBGEN_IDENTITY; - r_GLSLpasses[1].alphaGen.type = ALPHAGEN_IDENTITY; - Mem_Copy( &r_GLSLpasses[2], &r_GLSLpasses[1], sizeof( ref_stage_t ) ); - - r_GLSLpasses[3].flags = SHADERSTAGE_NOCOLORARRAY|SHADERSTAGE_BLEND_MODULATE; - r_GLSLpasses[3].glState = GLSTATE_DEPTHFUNC_EQ /*|GLSTATE_OFFSET_FILL*/|GLSTATE_SRCBLEND_ZERO|GLSTATE_DSTBLEND_SRC_COLOR; - r_GLSLpasses[3].tcgen = TCGEN_PROJECTION_SHADOW; - r_GLSLpasses[3].rgbGen.type = RGBGEN_IDENTITY; - r_GLSLpasses[3].alphaGen.type = ALPHAGEN_IDENTITY; - r_GLSLpasses[3].program = DEFAULT_GLSL_SHADOWMAP_PROGRAM; - r_GLSLpasses[3].program_type = PROGRAM_TYPE_SHADOWMAP; - - Mem_Set( &r_GLSLpassOutline, 0, sizeof( r_GLSLpassOutline ) ); - r_GLSLpassOutline.flags = SHADERSTAGE_NOCOLORARRAY|SHADERSTAGE_BLEND_MODULATE; - r_GLSLpassOutline.glState = GLSTATE_SRCBLEND_ONE|GLSTATE_DSTBLEND_ZERO|GLSTATE_DEPTHWRITE; - r_GLSLpassOutline.rgbGen.type = RGBGEN_OUTLINE; - r_GLSLpassOutline.alphaGen.type = ALPHAGEN_OUTLINE; - r_GLSLpassOutline.tcgen = TCGEN_NONE; - r_GLSLpassOutline.program = DEFAULT_GLSL_OUTLINE_PROGRAM; - r_GLSLpassOutline.program_type = PROGRAM_TYPE_OUTLINE; -} - -/* -============== -R_BackendShutdown -============== -*/ -void R_BackendShutdown( void ) -{ - R_ShutdownVertexBuffers (); -} - -/* -============== -R_FastSin -============== -*/ -float R_FastSin( float t ) -{ - return FTABLE_EVALUATE( r_sintable, t ); -} - -/* -============= -R_LatLongToNorm -============= -*/ -void R_LatLongToNorm( const byte latlong[2], vec3_t out ) -{ - float sin_a, sin_b, cos_a, cos_b; - - cos_a = r_sintableByte[( latlong[0] + 64 ) & 255]; - sin_a = r_sintableByte[latlong[0]]; - cos_b = r_sintableByte[( latlong[1] + 64 ) & 255]; - sin_b = r_sintableByte[latlong[1]]; - - VectorSet( out, cos_b * sin_a, sin_b * sin_a, cos_a ); -} - -/* -============== -R_TableForFunc -============== -*/ -static float *R_TableForFunc( unsigned int func ) -{ - switch( func ) - { - case WAVEFORM_SIN: - return r_sintable; - case WAVEFORM_TRIANGLE: - return r_triangletable; - case WAVEFORM_SQUARE: - return r_squaretable; - case WAVEFORM_SAWTOOTH: - return r_sawtoothtable; - case WAVEFORM_INVERSESAWTOOTH: - return r_inversesawtoothtable; - - case WAVEFORM_NOISE: - return r_sintable; // default to sintable - } - - // assume error - Host_Error( "R_TableForFunc: unknown function\n" ); - - return NULL; -} - -/* -============== -R_BackendGetNoiseValue -============== -*/ -float R_BackendGetNoiseValue( float x, float y, float z, float t ) -{ - int i; - int ix, iy, iz, it; - float fx, fy, fz, ft; - float front[4], back[4]; - float fvalue, bvalue, value[2], finalvalue; - - ix = ( int )floor( x ); - fx = x - ix; - iy = ( int )floor( y ); - fy = y - iy; - iz = ( int )floor( z ); - fz = z - iz; - it = ( int )floor( t ); - ft = t - it; - - for( i = 0; i < 2; i++ ) - { - front[0] = r_noisetable[NOISE_INDEX( ix, iy, iz, it + i )]; - front[1] = r_noisetable[NOISE_INDEX( ix+1, iy, iz, it + i )]; - front[2] = r_noisetable[NOISE_INDEX( ix, iy+1, iz, it + i )]; - front[3] = r_noisetable[NOISE_INDEX( ix+1, iy+1, iz, it + i )]; - - back[0] = r_noisetable[NOISE_INDEX( ix, iy, iz + 1, it + i )]; - back[1] = r_noisetable[NOISE_INDEX( ix+1, iy, iz + 1, it + i )]; - back[2] = r_noisetable[NOISE_INDEX( ix, iy+1, iz + 1, it + i )]; - back[3] = r_noisetable[NOISE_INDEX( ix+1, iy+1, iz + 1, it + i )]; - - fvalue = NOISE_LERP( NOISE_LERP( front[0], front[1], fx ), NOISE_LERP( front[2], front[3], fx ), fy ); - bvalue = NOISE_LERP( NOISE_LERP( back[0], back[1], fx ), NOISE_LERP( back[2], back[3], fx ), fy ); - value[i] = NOISE_LERP( fvalue, bvalue, fz ); - } - - finalvalue = NOISE_LERP( value[0], value[1], ft ); - - return finalvalue; -} - -/* -============== -R_BackendResetCounters -============== -*/ -void R_BackendResetCounters( void ) -{ - memset( &r_backacc, 0, sizeof( r_backacc ) ); -} - -/* -============== -R_BackendStartFrame -============== -*/ -void R_BackendStartFrame( void ) -{ - r_speeds_msg[0] = '\0'; - R_BackendResetCounters(); -} - -/* -============== -R_BackendEndFrame -============== -*/ -void R_BackendEndFrame( void ) -{ - // unlock arrays if any - R_UnlockArrays(); - - // clean up texture units - R_CleanUpTextureUnits( 1 ); - - if( r_speeds->integer && !( RI.refdef.rdflags & RDF_NOWORLDMODEL ) ) - { - switch( r_speeds->integer ) - { - case 1: - default: - com.snprintf( r_speeds_msg, sizeof( r_speeds_msg ), - "%4i wpoly %4i leafs %4i verts %4i tris %4i flushes %3i locks", - c_brush_polys, - c_world_leafs, - r_backacc.c_totalVerts, - r_backacc.c_totalTris, - r_backacc.c_totalFlushes, - r_backacc.c_totalKeptLocks - ); - break; - case 2: - com.snprintf( r_speeds_msg, sizeof( r_speeds_msg ), - "lvs: %5i node: %5i farclip: %6.f", - r_mark_leaves, - r_world_node, - RI.farClip - ); - break; - case 3: - com.snprintf( r_speeds_msg, sizeof( r_speeds_msg ), - "polys\\ents: %5i\\%5i sort\\draw: %5i\\%i", - r_add_polys, r_add_entities, - r_sort_meshes, r_draw_meshes - ); - break; - case 4: - if( r_debug_surface ) - { - com.snprintf( r_speeds_msg, sizeof( r_speeds_msg ), - "%s", r_debug_surface->shader->name ); - - if( r_debug_surface->fog && r_debug_surface->fog->shader - && r_debug_surface->fog->shader != r_debug_surface->shader ) - { - com.strncat( r_speeds_msg, "\n", sizeof( r_speeds_msg ) ); - com.strncat( r_speeds_msg, r_debug_surface->fog->shader->name, sizeof( r_speeds_msg ) ); - } - } - break; - case 5: - com.snprintf( r_speeds_msg, sizeof( r_speeds_msg ), - "%.1f %.1f %.1f (%.1f,%.1f,%.1f)", - RI.refdef.vieworg[0], RI.refdef.vieworg[1], RI.refdef.vieworg[2], - RI.refdef.viewangles[0], RI.refdef.viewangles[1], RI.refdef.viewangles[2] - ); - break; - } - } -} - -/* -============== -R_LockArrays -============== -*/ -void R_LockArrays( int numverts ) -{ - if( r_arraysLocked ) return; - - R_UpdateVertexBuffer( tr.vertexBuffer, vertsArray, numverts * sizeof( vec4_t )); - pglVertexPointer( 3, GL_FLOAT, 16, tr.vertexBuffer->pointer ); - - if( r_features & MF_ENABLENORMALS ) - { - r_normalsEnabled = true; - R_UpdateVertexBuffer( tr.normalBuffer, normalsArray, numverts * sizeof( vec4_t )); - pglEnableClientState( GL_NORMAL_ARRAY ); - pglNormalPointer( GL_FLOAT, 16, tr.normalBuffer->pointer ); - } - - if( GL_Support( R_CUSTOM_VERTEX_ARRAY_EXT )) - pglLockArraysEXT( 0, numverts ); - - r_arraysLocked = true; -} - -/* -============== -R_UnlockArrays -============== -*/ -void R_UnlockArrays( void ) -{ - if( !r_arraysLocked ) - return; - - if(GL_Support( R_CUSTOM_VERTEX_ARRAY_EXT )) - pglUnlockArraysEXT(); - - if( r_normalsEnabled ) - { - r_normalsEnabled = false; - pglDisableClientState( GL_NORMAL_ARRAY ); - } - r_arraysLocked = false; -} - -/* -============== -R_ClearArrays -============== -*/ -void R_ClearArrays( void ) -{ - int i; - - r_backacc.numVerts = 0; - r_backacc.numElems = 0; - r_backacc.numColors = 0; - - vertsArray = inVertsArray; - elemsArray = inElemsArray; - normalsArray = inNormalsArray; - sVectorsArray = inSVectorsArray; - coordsArray = inCoordsArray; - for( i = 0; i < LM_STYLES; i++ ) - lightmapCoordsArray[i] = inLightmapCoordsArray[i]; -} - -/* -============== -R_FlushArrays -============== -*/ -void R_FlushArrays( void ) -{ - if( !r_backacc.numVerts || !r_backacc.numElems ) - return; - - if( r_backacc.numColors == 1 ) - { - pglColor4ubv( colorArray[0] ); - } - else if( r_backacc.numColors > 1 ) - { - pglEnableClientState( GL_COLOR_ARRAY ); - R_UpdateVertexBuffer( tr.colorsBuffer, colorArray, r_backacc.numVerts * sizeof( rgba_t )); - pglColorPointer( 4, GL_UNSIGNED_BYTE, 0, tr.colorsBuffer->pointer ); - } - - if( r_drawelements->integer || glState.in2DMode || RI.refdef.rdflags & RDF_NOWORLDMODEL ) - { - if( GL_Support( R_DRAW_RANGEELEMENTS_EXT )) - pglDrawRangeElementsEXT( GL_TRIANGLES, 0, r_backacc.numVerts, r_backacc.numElems, GL_UNSIGNED_INT, elemsArray ); - else pglDrawElements( GL_TRIANGLES, r_backacc.numElems, GL_UNSIGNED_INT, elemsArray ); - } - - if( r_backacc.numColors > 1 ) - pglDisableClientState( GL_COLOR_ARRAY ); - - r_backacc.c_totalTris += r_backacc.numElems / 3; - r_backacc.c_totalFlushes++; -} - -/* -============== -GL_DisableAllTexGens -============== -*/ -static _inline void GL_DisableAllTexGens( void ) -{ - GL_EnableTexGen( GL_S, 0 ); - GL_EnableTexGen( GL_T, 0 ); - GL_EnableTexGen( GL_R, 0 ); - GL_EnableTexGen( GL_Q, 0 ); -} - -/* -============== -R_CleanUpTextureUnits -============== -*/ -static void R_CleanUpTextureUnits( int last ) -{ - int i; - - for( i = glState.activeTMU; i > last - 1; i-- ) - { - GL_DisableAllTexGens(); - GL_SetTexCoordArrayMode( 0 ); - - pglDisable( GL_TEXTURE_2D ); - GL_SelectTexture( i - 1 ); - } -} - -/* -================ -R_DeformVertices -================ -*/ -void R_DeformVertices( void ) -{ - uint i, j, k; - double args[4], temp; - float deflect, *quad[4]; - const float *table; - const deform_t *deformv; - vec3_t tv, rot_centre; - - deformv = &r_currentShader->deforms[0]; - for( i = 0; i < r_currentShader->numDeforms; i++, deformv++ ) - { - switch( deformv->type ) - { - case DEFORM_NONE: - break; - - case DEFORM_WAVE: - table = R_TableForFunc( deformv->func.type ); - - // Deflect vertex along its normal by wave amount - if( deformv->func.args[3] == 0 ) - { - temp = deformv->func.args[2]; - deflect = FTABLE_EVALUATE( table, temp ) * deformv->func.args[1] + deformv->func.args[0]; - - for( j = 0; j < r_backacc.numVerts; j++ ) - VectorMA( inVertsArray[j], deflect, inNormalsArray[j], inVertsArray[j] ); - } - else - { - args[0] = deformv->func.args[0]; - args[1] = deformv->func.args[1]; - args[2] = deformv->func.args[2] + deformv->func.args[3] * r_currentShaderTime; - args[3] = deformv->args[0]; - - for( j = 0; j < r_backacc.numVerts; j++ ) - { - temp = args[2] + args[3] * ( inVertsArray[j][0] + inVertsArray[j][1] + inVertsArray[j][2] ); - deflect = FTABLE_EVALUATE( table, temp ) * args[1] + args[0]; - VectorMA( inVertsArray[j], deflect, inNormalsArray[j], inVertsArray[j] ); - } - } - break; - - case DEFORM_NORMAL: - // without this * 0.1f deformation looks wrong, although q3a doesn't have it - args[0] = deformv->func.args[3] * r_currentShaderTime * 0.1f; - args[1] = deformv->func.args[1]; - - for( j = 0; j < r_backacc.numVerts; j++ ) - { - VectorScale( inVertsArray[j], 0.98f, tv ); - inNormalsArray[j][0] += args[1] *R_BackendGetNoiseValue( tv[0], tv[1], tv[2], args[0] ); - inNormalsArray[j][1] += args[1] *R_BackendGetNoiseValue( tv[0] + 100, tv[1], tv[2], args[0] ); - inNormalsArray[j][2] += args[1] *R_BackendGetNoiseValue( tv[0] + 200, tv[1], tv[2], args[0] ); - VectorNormalizeFast( inNormalsArray[j] ); - } - break; - - case DEFORM_MOVE: - table = R_TableForFunc( deformv->func.type ); - temp = deformv->func.args[2] + r_currentShaderTime * deformv->func.args[3]; - deflect = FTABLE_EVALUATE( table, temp ) * deformv->func.args[1] + deformv->func.args[0]; - - for( j = 0; j < r_backacc.numVerts; j++ ) - VectorMA( inVertsArray[j], deflect, deformv->args, inVertsArray[j] ); - break; - - case DEFORM_BULGE: - args[0] = deformv->args[0]; - args[1] = deformv->args[1]; - args[2] = r_currentShaderTime * deformv->args[2]; - - for( j = 0; j < r_backacc.numVerts; j++ ) - { - temp = ( coordsArray[j][0] * args[0] + args[2] ) / M_PI2; - deflect = R_FastSin( temp ) * args[1]; - VectorMA( inVertsArray[j], deflect, inNormalsArray[j], inVertsArray[j] ); - } - break; - - case DEFORM_AUTOSPRITE: - { - vec4_t *v; - vec2_t *st; - elem_t *elem; - float radius; - vec3_t point, v_centre, v_right, v_up; - - if( r_backacc.numVerts % 4 || r_backacc.numElems % 6 ) - break; - - if( RI.currententity && (RI.currentmodel != r_worldmodel) ) - { - Matrix_TransformVector( RI.currententity->axis, RI.vright, v_right ); - Matrix_TransformVector( RI.currententity->axis, RI.vup, v_up ); - } - else - { - VectorCopy( RI.vright, v_right ); - VectorCopy( RI.vup, v_up ); - } - - radius = RI.currententity->scale; - if( radius && radius != 1.0f ) - { - radius = 1.0f / radius; - VectorScale( v_right, radius, v_right ); - VectorScale( v_up, radius, v_up ); - } - - for( k = 0, v = inVertsArray, st = coordsArray, elem = elemsArray; k < r_backacc.numVerts; k += 4, v += 4, st += 4, elem += 6 ) - { - for( j = 0; j < 3; j++ ) - v_centre[j] = (v[0][j] + v[1][j] + v[2][j] + v[3][j]) * 0.25; - - VectorSubtract( v[0], v_centre, point ); - radius = VectorLength( point ) * 0.707106f; // 1.0f / sqrt(2) - - // very similar to R_PushSprite - VectorMA( v_centre, -radius, v_up, point ); - VectorMA( point, -radius, v_right, v[0] ); - VectorMA( point, radius, v_right, v[3] ); - - VectorMA( v_centre, radius, v_up, point ); - VectorMA( point, -radius, v_right, v[1] ); - VectorMA( point, radius, v_right, v[2] ); - - // reset texcoords - Vector2Set( st[0], 0, 1 ); - Vector2Set( st[1], 0, 0 ); - Vector2Set( st[2], 1, 0 ); - Vector2Set( st[3], 1, 1 ); - - // trifan elems - elem[0] = k; - elem[1] = k + 2 - 1; - elem[2] = k + 2; - - elem[3] = k; - elem[4] = k + 3 - 1; - elem[5] = k + 3; - } - } - break; - - case DEFORM_AUTOSPRITE2: - if( r_backacc.numElems % 6 ) - break; - - for( k = 0; k < r_backacc.numElems; k += 6 ) - { - int long_axis = 0, short_axis = 0; - vec3_t axis, tmp; - float len[3]; - vec3_t m0[3], m1[3], m2[3], result[3]; - - quad[0] = ( float * )( inVertsArray + elemsArray[k+0] ); - quad[1] = ( float * )( inVertsArray + elemsArray[k+1] ); - quad[2] = ( float * )( inVertsArray + elemsArray[k+2] ); - - for( j = 2; j >= 0; j-- ) - { - quad[3] = ( float * )( inVertsArray + elemsArray[k+3+j] ); - - if( !VectorCompare( quad[3], quad[0] ) && - !VectorCompare( quad[3], quad[1] ) && - !VectorCompare( quad[3], quad[2] ) ) - { - break; - } - } - - // build a matrix were the longest axis of the billboard is the Y-Axis - VectorSubtract( quad[1], quad[0], m0[0] ); - VectorSubtract( quad[2], quad[0], m0[1] ); - VectorSubtract( quad[2], quad[1], m0[2] ); - len[0] = DotProduct( m0[0], m0[0] ); - len[1] = DotProduct( m0[1], m0[1] ); - len[2] = DotProduct( m0[2], m0[2] ); - - if( ( len[2] > len[1] ) && ( len[2] > len[0] ) ) - { - if( len[1] > len[0] ) - { - long_axis = 1; - short_axis = 0; - } - else - { - long_axis = 0; - short_axis = 1; - } - } - else if( ( len[1] > len[2] ) && ( len[1] > len[0] ) ) - { - if( len[2] > len[0] ) - { - long_axis = 2; - short_axis = 0; - } - else - { - long_axis = 0; - short_axis = 2; - } - } - else if( ( len[0] > len[1] ) && ( len[0] > len[2] ) ) - { - if( len[2] > len[1] ) - { - long_axis = 2; - short_axis = 1; - } - else - { - long_axis = 1; - short_axis = 2; - } - } - - if( !len[long_axis] ) - break; - len[long_axis] = Q_RSqrt( len[long_axis] ); - VectorScale( m0[long_axis], len[long_axis], axis ); - - if( DotProduct( m0[long_axis], m0[short_axis] ) ) - { - VectorCopy( axis, m0[1] ); - if( axis[0] || axis[1] ) - VectorVectors( m0[1], m0[0], m0[2] ); - else - VectorVectors( m0[1], m0[2], m0[0] ); - } - else - { - if( !len[short_axis] ) - break; - len[short_axis] = Q_RSqrt( len[short_axis] ); - VectorScale( m0[short_axis], len[short_axis], m0[0] ); - VectorCopy( axis, m0[1] ); - CrossProduct( m0[0], m0[1], m0[2] ); - } - - for( j = 0; j < 3; j++ ) - rot_centre[j] = ( quad[0][j] + quad[1][j] + quad[2][j] + quad[3][j] ) * 0.25; - - if( RI.currententity && ( RI.currentmodel != r_worldmodel ) ) - { - VectorAdd( RI.currententity->origin, rot_centre, tv ); - VectorSubtract( RI.viewOrigin, tv, tmp ); - Matrix_TransformVector( RI.currententity->axis, tmp, tv ); - } - else - { - VectorCopy( rot_centre, tv ); - VectorSubtract( RI.viewOrigin, tv, tv ); - } - - // filter any longest-axis-parts off the camera-direction - deflect = -DotProduct( tv, axis ); - - VectorMA( tv, deflect, axis, m1[2] ); - VectorNormalizeFast( m1[2] ); - VectorCopy( axis, m1[1] ); - CrossProduct( m1[1], m1[2], m1[0] ); - - Matrix_Transpose( m1, m2 ); - Matrix_Multiply( m2, m0, result ); - - for( j = 0; j < 4; j++ ) - { - VectorSubtract( quad[j], rot_centre, tv ); - Matrix_TransformVector( result, tv, quad[j] ); - VectorAdd( rot_centre, quad[j], quad[j] ); - } - } - break; - - case DEFORM_PROJECTION_SHADOW: - R_DeformVPlanarShadow( r_backacc.numVerts, inVertsArray[0] ); - break; - - case DEFORM_AUTOPARTICLE: - { - float scale; - vec3_t m0[3], m1[3], m2[3], result[3]; - - if( r_backacc.numElems % 6 ) - break; - - if( RI.currententity && ( RI.currentmodel != r_worldmodel ) ) - Matrix4_Matrix( RI.modelviewMatrix, m1 ); - else - Matrix4_Matrix( RI.worldviewMatrix, m1 ); - - Matrix_Transpose( m1, m2 ); - - for( k = 0; k < r_backacc.numElems; k += 6 ) - { - quad[0] = ( float * )( inVertsArray + elemsArray[k+0] ); - quad[1] = ( float * )( inVertsArray + elemsArray[k+1] ); - quad[2] = ( float * )( inVertsArray + elemsArray[k+2] ); - - for( j = 2; j >= 0; j-- ) - { - quad[3] = ( float * )( inVertsArray + elemsArray[k+3+j] ); - - if( !VectorCompare( quad[3], quad[0] ) && - !VectorCompare( quad[3], quad[1] ) && - !VectorCompare( quad[3], quad[2] ) ) - { - break; - } - } - - Matrix_FromPoints( quad[0], quad[1], quad[2], m0 ); - Matrix_Multiply( m2, m0, result ); - - // hack a scale up to keep particles from disappearing - scale = ( quad[0][0] - RI.viewOrigin[0] ) * RI.vpn[0] + ( quad[0][1] - RI.viewOrigin[1] ) * RI.vpn[1] + ( quad[0][2] - RI.viewOrigin[2] ) * RI.vpn[2]; - if( scale < 20 ) - scale = 1.5; - else - scale = 1.5 + scale * 0.006f; - - for( j = 0; j < 3; j++ ) - rot_centre[j] = ( quad[0][j] + quad[1][j] + quad[2][j] + quad[3][j] ) * 0.25; - - for( j = 0; j < 4; j++ ) - { - VectorSubtract( quad[j], rot_centre, tv ); - Matrix_TransformVector( result, tv, quad[j] ); - VectorMA( rot_centre, scale, quad[j], quad[j] ); - } - } - } - break; - case DEFORM_OUTLINE: - // Deflect vertex along its normal by outline amount - deflect = RI.currententity->outlineHeight * r_outlines_scale->value; - for( j = 0; j < r_backacc.numVerts; j++ ) - VectorMA( inVertsArray[j], deflect, inNormalsArray[j], inVertsArray[j] ); - break; - default: - break; - } - } -} - -/* -============== -R_VertexTCBase -============== -*/ -static bool R_VertexTCBase( const ref_stage_t *pass, int unit, mat4x4_t matrix ) -{ - unsigned int i; - float *outCoords; - bool identityMatrix = false; - - Matrix4_Identity( matrix ); - - switch( pass->tcgen ) - { - case TCGEN_BASE: - GL_DisableAllTexGens(); - - R_UpdateVertexBuffer( tr.tcoordBuffer[unit], coordsArray, r_backacc.numVerts * sizeof( vec2_t )); - pglTexCoordPointer( 2, GL_FLOAT, 0, coordsArray ); - return true; - case TCGEN_LIGHTMAP: - GL_DisableAllTexGens(); - - R_UpdateVertexBuffer( tr.tcoordBuffer[unit], lightmapCoordsArray[r_lightmapStyleNum[unit]], r_backacc.numVerts * sizeof( vec2_t )); - pglTexCoordPointer( 2, GL_FLOAT, 0, lightmapCoordsArray[r_lightmapStyleNum[unit]] ); - return true; - case TCGEN_ENVIRONMENT: - { - float depth, *n; - vec3_t projection, transform; - - if( glState.in2DMode ) - return true; - - if( !( RI.params & RP_SHADOWMAPVIEW ) ) - { - VectorSubtract( RI.viewOrigin, RI.currententity->origin, projection ); - Matrix_TransformVector( RI.currententity->axis, projection, transform ); - - outCoords = tUnitCoordsArray[unit][0]; - for( i = 0, n = normalsArray[0]; i < r_backacc.numVerts; i++, outCoords += 2, n += 4 ) - { - VectorSubtract( transform, vertsArray[i], projection ); - VectorNormalizeFast( projection ); - - depth = DotProduct( n, projection ); depth += depth; - outCoords[0] = 0.5 + ( n[1] * depth - projection[1] ) * 0.5; - outCoords[1] = 0.5 - ( n[2] * depth - projection[2] ) * 0.5; - } - } - - GL_DisableAllTexGens(); - - R_UpdateVertexBuffer( tr.tcoordBuffer[unit], tUnitCoordsArray, r_backacc.numVerts * sizeof( vec2_t )); - pglTexCoordPointer( 2, GL_FLOAT, 0, tUnitCoordsArray[unit] ); - return true; - } - - case TCGEN_VECTOR: - { - GLfloat genVector[2][4]; - - for( i = 0; i < 3; i++ ) - { - genVector[0][i] = pass->tcgenVec[i]; - genVector[1][i] = pass->tcgenVec[i+4]; - } - genVector[0][3] = genVector[1][3] = 0; - - matrix[12] = pass->tcgenVec[3]; - matrix[13] = pass->tcgenVec[7]; - - GL_SetTexCoordArrayMode( 0 ); - GL_EnableTexGen( GL_S, GL_OBJECT_LINEAR ); - GL_EnableTexGen( GL_T, GL_OBJECT_LINEAR ); - GL_EnableTexGen( GL_R, 0 ); - GL_EnableTexGen( GL_Q, 0 ); - pglTexGenfv( GL_S, GL_OBJECT_PLANE, genVector[0] ); - pglTexGenfv( GL_T, GL_OBJECT_PLANE, genVector[1] ); - return false; - } - case TCGEN_PROJECTION: - { - mat4x4_t m1, m2; - GLfloat genVector[4][4]; - - GL_SetTexCoordArrayMode( 0 ); - - Matrix4_Copy( RI.worldviewProjectionMatrix, matrix ); - - Matrix4_Identity( m1 ); - Matrix4_Scale( m1, 0.5, 0.5, 0.5 ); - Matrix4_Multiply( m1, matrix, m2 ); - - Matrix4_Identity( m1 ); - Matrix4_Translate( m1, 0.5, 0.5, 0.5 ); - Matrix4_Multiply( m1, m2, matrix ); - - for( i = 0; i < 4; i++ ) - { - genVector[0][i] = i == 0 ? 1 : 0; - genVector[1][i] = i == 1 ? 1 : 0; - genVector[2][i] = i == 2 ? 1 : 0; - genVector[3][i] = i == 3 ? 1 : 0; - } - - GL_EnableTexGen( GL_S, GL_OBJECT_LINEAR ); - GL_EnableTexGen( GL_T, GL_OBJECT_LINEAR ); - GL_EnableTexGen( GL_R, GL_OBJECT_LINEAR ); - GL_EnableTexGen( GL_Q, GL_OBJECT_LINEAR ); - - pglTexGenfv( GL_S, GL_OBJECT_PLANE, genVector[0] ); - pglTexGenfv( GL_T, GL_OBJECT_PLANE, genVector[1] ); - pglTexGenfv( GL_R, GL_OBJECT_PLANE, genVector[2] ); - pglTexGenfv( GL_Q, GL_OBJECT_PLANE, genVector[3] ); - return false; - } - - case TCGEN_REFLECTION_CELLSHADE: - if( RI.currententity && !( RI.params & RP_SHADOWMAPVIEW ) ) - { - vec3_t dir; - mat4x4_t m; - - R_LightForOrigin( RI.currententity->lightingOrigin, dir, NULL, NULL, RI.currentmodel->radius * RI.currententity->scale ); - - Matrix4_Identity( m ); - - // rotate direction - Matrix_TransformVector( RI.currententity->axis, dir, &m[0] ); - VectorNormalizeLength( &m[0] ); - - VectorVectors( &m[0], &m[4], &m[8] ); - Matrix4_Transpose( m, matrix ); - } - case TCGEN_REFLECTION: - GL_EnableTexGen( GL_S, GL_REFLECTION_MAP_ARB ); - GL_EnableTexGen( GL_T, GL_REFLECTION_MAP_ARB ); - GL_EnableTexGen( GL_R, GL_REFLECTION_MAP_ARB ); - GL_EnableTexGen( GL_Q, 0 ); - return true; - - case TCGEN_FOG: - { - int fogPtype; - cplane_t *fogPlane; - ref_shader_t *fogShader; - vec3_t viewtofog; - float fogNormal[3], vpnNormal[3]; - float dist, vdist, fogDist, vpnDist; - - fogPlane = r_texFog->visibleplane; - fogShader = r_texFog->shader; - - matrix[0] = matrix[5] = 1.0/(fogShader->fog_dist - fogShader->fog_clearDist); - matrix[13] = 1.5f/(float)FOG_TEXTURE_HEIGHT; - - // distance to fog - dist = RI.fog_dist_to_eye[r_texFog-r_worldbrushmodel->fogs]; - - if( r_currentShader->flags & SHADER_SKYPARMS ) - { - if( dist > 0 ) - VectorMA( RI.viewOrigin, -dist, fogPlane->normal, viewtofog ); - else - VectorCopy( RI.viewOrigin, viewtofog ); - } - else - { - VectorCopy( RI.currententity->origin, viewtofog ); - } - - // some math tricks to take entity's rotation matrix into account - // for fog texture coordinates calculations: - // M is rotation matrix, v is vertex, t is transform vector - // n is plane's normal, d is plane's dist, r is view origin - // (M*v + t)*n - d = (M*n)*v - ((d - t*n)) - // (M*v + t - r)*n = (M*n)*v - ((r - t)*n) - fogNormal[0] = DotProduct( RI.currententity->axis[0], fogPlane->normal ) * RI.currententity->scale; - fogNormal[1] = DotProduct( RI.currententity->axis[1], fogPlane->normal ) * RI.currententity->scale; - fogNormal[2] = DotProduct( RI.currententity->axis[2], fogPlane->normal ) * RI.currententity->scale; - fogPtype = ( fogNormal[0] == 1.0 ? PLANE_X : ( fogNormal[1] == 1.0 ? PLANE_Y : ( fogNormal[2] == 1.0 ? PLANE_Z : PLANE_NONAXIAL ) ) ); - fogDist = ( fogPlane->dist - DotProduct( viewtofog, fogPlane->normal ) ); - - vpnNormal[0] = DotProduct( RI.currententity->axis[0], RI.vpn ) * RI.currententity->scale; - vpnNormal[1] = DotProduct( RI.currententity->axis[1], RI.vpn ) * RI.currententity->scale; - vpnNormal[2] = DotProduct( RI.currententity->axis[2], RI.vpn ) * RI.currententity->scale; - vpnDist = ( ( RI.viewOrigin[0] - viewtofog[0] ) * RI.vpn[0] + ( RI.viewOrigin[1] - viewtofog[1] ) * RI.vpn[1] + ( RI.viewOrigin[2] - viewtofog[2] ) * RI.vpn[2] ) + fogShader->fog_clearDist; - - outCoords = tUnitCoordsArray[unit][0]; - if( dist < 0 ) - { // camera is inside the fog brush - for( i = 0; i < r_backacc.numVerts; i++, outCoords += 2 ) - { - outCoords[0] = DotProduct( vertsArray[i], vpnNormal ) - vpnDist; - if( fogPtype < 3 ) - outCoords[1] = -( vertsArray[i][fogPtype] - fogDist ); - else - outCoords[1] = -( DotProduct( vertsArray[i], fogNormal ) - fogDist ); - } - } - else - { - for( i = 0; i < r_backacc.numVerts; i++, outCoords += 2 ) - { - if( fogPtype < 3 ) - vdist = vertsArray[i][fogPtype] - fogDist; - else - vdist = DotProduct( vertsArray[i], fogNormal ) - fogDist; - outCoords[0] = ( ( vdist < 0 ) ? ( DotProduct( vertsArray[i], vpnNormal ) - vpnDist ) * vdist / ( vdist - dist ) : 0.0f ); - outCoords[1] = -vdist; - } - } - - GL_DisableAllTexGens(); - - R_UpdateVertexBuffer( tr.tcoordBuffer[unit], tUnitCoordsArray, r_backacc.numVerts * sizeof( vec2_t )); - pglTexCoordPointer( 2, GL_FLOAT, 0, tUnitCoordsArray[unit] ); - return false; - } - - case TCGEN_SVECTORS: - GL_DisableAllTexGens(); - R_UpdateVertexBuffer( tr.tcoordBuffer[unit], sVectorsArray, r_backacc.numVerts * sizeof( vec4_t )); - pglTexCoordPointer( 4, GL_FLOAT, 0, sVectorsArray ); - return true; - case TCGEN_PROJECTION_SHADOW: - GL_SetTexCoordArrayMode( 0 ); - GL_DisableAllTexGens(); - Matrix4_Multiply( r_currentCastGroup->worldviewProjectionMatrix, RI.objectMatrix, matrix ); - break; - default: break; - } - return identityMatrix; -} - -/* -================ -R_ApplyTCMods -================ -*/ -static void R_ApplyTCMods( const ref_stage_t *pass, mat4x4_t result ) -{ - int i; - const float *table; - double t1, t2, sint, cost; - mat4x4_t m1, m2; - const tcMod_t *tcmod; - - for( i = 0, tcmod = pass->tcMods; i < pass->numtcMods; i++, tcmod++ ) - { - switch( tcmod->type ) - { - case TCMOD_ROTATE: - cost = tcmod->args[0] * r_currentShaderTime; - sint = R_FastSin( cost ); - cost = R_FastSin( cost + 0.25 ); - m2[0] = cost, m2[1] = sint, m2[12] = 0.5f * ( sint - cost + 1 ); - m2[4] = -sint, m2[5] = cost, m2[13] = -0.5f * ( sint + cost - 1 ); - Matrix4_Copy2D( result, m1 ); - Matrix4_Multiply2D( m2, m1, result ); - break; - case TCMOD_SCALE: - Matrix4_Scale2D( result, tcmod->args[0], tcmod->args[1] ); - break; - case TCMOD_TURB: - t1 = ( 1.0 / 4.0 ); - t2 = tcmod->args[2] + r_currentShaderTime * tcmod->args[3]; - Matrix4_Scale2D( result, 1 + ( tcmod->args[1] * R_FastSin( t2 ) + tcmod->args[0] ) * t1, 1 + ( tcmod->args[1] * R_FastSin( t2 + 0.25 ) + tcmod->args[0] ) * t1 ); - break; - case TCMOD_STRETCH: - table = R_TableForFunc( tcmod->args[0] ); - t2 = tcmod->args[3] + r_currentShaderTime * tcmod->args[4]; - t1 = FTABLE_EVALUATE( table, t2 ) * tcmod->args[2] + tcmod->args[1]; - t1 = t1 ? 1.0f / t1 : 1.0f; - t2 = 0.5f - 0.5f * t1; - Matrix4_Stretch2D( result, t1, t2 ); - break; - case TCMOD_SCROLL: - t1 = tcmod->args[0] * r_currentShaderTime; - t2 = tcmod->args[1] * r_currentShaderTime; - if( pass->program_type != PROGRAM_TYPE_DISTORTION ) - { // HACK HACK HACK - t1 = t1 - floor( t1 ); - t2 = t2 - floor( t2 ); - } - Matrix4_Translate2D( result, t1, t2 ); - break; - case TCMOD_TRANSFORM: - m2[0] = tcmod->args[0], m2[1] = tcmod->args[2], m2[12] = tcmod->args[4], - m2[5] = tcmod->args[1], m2[4] = tcmod->args[3], m2[13] = tcmod->args[5]; - Matrix4_Copy2D( result, m1 ); - Matrix4_Multiply2D( m2, m1, result ); - break; - default: - break; - } - } -} - -/* -============== -R_ShaderpassTex -============== -*/ -static _inline texture_t *R_ShaderpassTex( const ref_stage_t *pass, int unit ) -{ - if( pass->flags & SHADERSTAGE_ANIMFREQUENCY && pass->animFrequency && pass->num_textures ) - return pass->textures[(int)( pass->animFrequency * r_currentShaderTime ) % pass->num_textures]; - if( pass->flags & SHADERSTAGE_LIGHTMAP ) - return tr.lightmapTextures[r_superLightStyle->lightmapNum[r_lightmapStyleNum[unit]]]; - if( pass->flags & SHADERSTAGE_PORTALMAP ) - return tr.portaltexture1; - return ( pass->textures[0] ? pass->textures[0] : tr.defaultTexture ); -} - -/* -================ -R_BindShaderpass -================ -*/ -static void R_BindShaderpass( const ref_stage_t *pass, texture_t *tex, int unit ) -{ - mat4x4_t m1, m2, result; - bool identityMatrix; - - if( !tex ) - tex = R_ShaderpassTex( pass, unit ); - - GL_Bind( unit, tex ); - if( unit && !pass->program ) pglEnable( GL_TEXTURE_2D ); - GL_SetTexCoordArrayMode( ( tex->flags & TF_CUBEMAP ? GL_TEXTURE_CUBE_MAP_ARB : GL_TEXTURE_COORD_ARRAY )); - - identityMatrix = R_VertexTCBase( pass, unit, result ); - - if( pass->numtcMods ) - { - identityMatrix = false; - R_ApplyTCMods( pass, result ); - } - - if( pass->tcgen == TCGEN_REFLECTION || pass->tcgen == TCGEN_REFLECTION_CELLSHADE ) - { - Matrix4_Transpose( RI.modelviewMatrix, m1 ); - Matrix4_Copy( result, m2 ); - Matrix4_Multiply( m2, m1, result ); - GL_LoadTexMatrix( result ); - return; - } - - if( identityMatrix ) - GL_LoadIdentityTexMatrix(); - else - GL_LoadTexMatrix( result ); -} - -/* -================ -R_ModifyColor -================ -*/ -void R_ModifyColor( const ref_stage_t *pass ) -{ - uint i; - int c, bits; - double temp; - float *table, a; - vec3_t t, v, style; - byte *bArray, *inArray, rgba[4] = { 255, 255, 255, 255 }; - bool noArray, identityAlpha, entityAlpha; - const waveFunc_t *rgbgenfunc, *alphagenfunc; - - noArray = ( pass->flags & SHADERSTAGE_NOCOLORARRAY ) && !r_colorFog; - r_backacc.numColors = noArray ? 1 : r_backacc.numVerts; - bits = ( r_overbrightbits->integer > 0 ) && !( r_ignorehwgamma->integer ) ? r_overbrightbits->integer : 0; - - bArray = colorArray[0]; - inArray = inColorsArray[0][0]; - - if( pass->rgbGen.type == RGBGEN_IDENTITY_LIGHTING ) - { - entityAlpha = identityAlpha = false; - memset( bArray, r_identityLighting, sizeof( rgba_t ) * r_backacc.numColors ); - } - else if( pass->rgbGen.type == RGBGEN_EXACT_VERTEX ) - { - entityAlpha = identityAlpha = false; - memcpy( bArray, inArray, sizeof( rgba_t ) * r_backacc.numColors ); - } - else - { - entityAlpha = false; - identityAlpha = true; - memset( bArray, 255, sizeof( rgba_t ) * r_backacc.numColors ); - - switch( pass->rgbGen.type ) - { - case RGBGEN_IDENTITY: - break; - case RGBGEN_CONST: - rgba[0] = R_FloatToByte( pass->rgbGen.args[0] ); - rgba[1] = R_FloatToByte( pass->rgbGen.args[1] ); - rgba[2] = R_FloatToByte( pass->rgbGen.args[2] ); - - for( i = 0, c = *(int *)rgba; i < r_backacc.numColors; i++, bArray += 4 ) - *(int *)bArray = c; - break; - case RGBGEN_WAVE: - rgbgenfunc = pass->rgbGen.func; - if( rgbgenfunc->type == WAVEFORM_NOISE ) - { - temp = R_BackendGetNoiseValue( 0, 0, 0, ( r_currentShaderTime + rgbgenfunc->args[2] ) * rgbgenfunc->args[3] ); - } - else - { - table = R_TableForFunc( rgbgenfunc->type ); - temp = r_currentShaderTime * rgbgenfunc->args[3] + rgbgenfunc->args[2]; - temp = FTABLE_EVALUATE( table, temp ) * rgbgenfunc->args[1] + rgbgenfunc->args[0]; - } - - temp = temp * rgbgenfunc->args[1] + rgbgenfunc->args[0]; - a = pass->rgbGen.args[0] * temp; rgba[0] = a <= 0 ? 0 : R_FloatToByte( a ); - a = pass->rgbGen.args[1] * temp; rgba[1] = a <= 0 ? 0 : R_FloatToByte( a ); - a = pass->rgbGen.args[2] * temp; rgba[2] = a <= 0 ? 0 : R_FloatToByte( a ); - - for( i = 0, c = *(int *)rgba; i < r_backacc.numColors; i++, bArray += 4 ) - *(int *)bArray = c; - break; - case RGBGEN_ENTITY: - entityAlpha = true; - identityAlpha = ( RI.currententity->color[3] == 255 ); - - for( i = 0, c = *(int *)RI.currententity->color; i < r_backacc.numColors; i++, bArray += 4 ) - *(int *)bArray = c; - break; - case RGBGEN_OUTLINE: - identityAlpha = ( RI.currententity->outlineColor[3] == 255 ); - - for( i = 0, c = *(int *)RI.currententity->outlineColor; i < r_backacc.numColors; i++, bArray += 4 ) - *(int *)bArray = c; - break; - case RGBGEN_ONE_MINUS_ENTITY: - rgba[0] = 255 - RI.currententity->color[0]; - rgba[1] = 255 - RI.currententity->color[1]; - rgba[2] = 255 - RI.currententity->color[2]; - - for( i = 0, c = *(int *)rgba; i < r_backacc.numColors; i++, bArray += 4 ) - *(int *)bArray = c; - break; - case RGBGEN_VERTEX: - VectorSet( style, -1, -1, -1 ); - - if( !r_superLightStyle || r_superLightStyle->vertexStyles[1] == 255 ) - { - VectorSet( style, 1, 1, 1 ); - if( r_superLightStyle && r_superLightStyle->vertexStyles[0] != 255 ) - VectorCopy( r_lightStyles[r_superLightStyle->vertexStyles[0]].rgb, style ); - } - - if( style[0] == style[1] && style[1] == style[2] && style[2] == 1 ) - { - for( i = 0; i < r_backacc.numColors; i++, bArray += 4, inArray += 4 ) - { - bArray[0] = inArray[0] >> bits; - bArray[1] = inArray[1] >> bits; - bArray[2] = inArray[2] >> bits; - } - } - else - { - int j; - float *tc; - vec3_t temp[MAX_ARRAY_VERTS]; - - memset( temp, 0, sizeof( vec3_t ) * r_backacc.numColors ); - - for( j = 0; j < LM_STYLES && r_superLightStyle->vertexStyles[j] != 255; j++ ) - { - VectorCopy( r_lightStyles[r_superLightStyle->vertexStyles[j]].rgb, style ); - if( VectorCompare( style, vec3_origin ) ) - continue; - - inArray = inColorsArray[j][0]; - for( i = 0, tc = temp[0]; i < r_backacc.numColors; i++, tc += 3, inArray += 4 ) - { - tc[0] += ( inArray[0] >> bits ) * style[0]; - tc[1] += ( inArray[1] >> bits ) * style[1]; - tc[2] += ( inArray[2] >> bits ) * style[2]; - } - } - - for( i = 0, tc = temp[0]; i < r_backacc.numColors; i++, tc += 3, bArray += 4 ) - { - bArray[0] = bound( 0, tc[0], 255 ); - bArray[1] = bound( 0, tc[1], 255 ); - bArray[2] = bound( 0, tc[2], 255 ); - } - } - break; - case RGBGEN_ONE_MINUS_VERTEX: - for( i = 0; i < r_backacc.numColors; i++, bArray += 4, inArray += 4 ) - { - bArray[0] = 255 - ( inArray[0] >> bits ); - bArray[1] = 255 - ( inArray[1] >> bits ); - bArray[2] = 255 - ( inArray[2] >> bits ); - } - break; - case RGBGEN_LIGHTING_DIFFUSE: - if( RI.currententity ) - R_LightForEntity( RI.currententity, bArray ); - break; - case RGBGEN_LIGHTING_DIFFUSE_ONLY: - if( RI.currententity && !( RI.params & RP_SHADOWMAPVIEW ) ) - { - vec4_t diffuse; - - if( RI.currententity->flags & RF_FULLBRIGHT ) - VectorSet( diffuse, 1, 1, 1 ); - else - R_LightForOrigin( RI.currententity->lightingOrigin, t, NULL, diffuse, RI.currentmodel->radius * RI.currententity->scale ); - - rgba[0] = R_FloatToByte( diffuse[0] ); - rgba[1] = R_FloatToByte( diffuse[1] ); - rgba[2] = R_FloatToByte( diffuse[2] ); - - for( i = 0, c = *(int *)rgba; i < r_backacc.numColors; i++, bArray += 4 ) - *(int *)bArray = c; - } - break; - case RGBGEN_LIGHTING_AMBIENT_ONLY: - if( RI.currententity && !( RI.params & RP_SHADOWMAPVIEW ) ) - { - vec4_t ambient; - - if( RI.currententity->flags & RF_FULLBRIGHT ) - VectorSet( ambient, 1, 1, 1 ); - else - R_LightForOrigin( RI.currententity->lightingOrigin, t, ambient, NULL, RI.currentmodel->radius * RI.currententity->scale ); - - rgba[0] = R_FloatToByte( ambient[0] ); - rgba[1] = R_FloatToByte( ambient[1] ); - rgba[2] = R_FloatToByte( ambient[2] ); - - for( i = 0, c = *(int *)rgba; i < r_backacc.numColors; i++, bArray += 4 ) - *(int *)bArray = c; - } - break; - case RGBGEN_FOG: - for( i = 0, c = *(int *)r_texFog->shader->fog_color; i < r_backacc.numColors; i++, bArray += 4 ) - *(int *)bArray = c; - break; - case RGBGEN_CUSTOM: - c = (int)pass->rgbGen.args[0]; - for( i = 0, c = R_GetCustomColor( c ); i < r_backacc.numColors; i++, bArray += 4 ) - *(int *)bArray = c; - break; - case RGBGEN_ENVIRONMENT: - for( i = 0, c = *(int *)mapConfig.environmentColor; i < r_backacc.numColors; i++, bArray += 4 ) - *(int *)bArray = c; - break; - default: - break; - } - } - - bArray = colorArray[0]; - inArray = inColorsArray[0][0]; - - switch( pass->alphaGen.type ) - { - case ALPHAGEN_IDENTITY: - if( identityAlpha ) - break; - for( i = 0; i < r_backacc.numColors; i++, bArray += 4 ) - bArray[3] = 255; - break; - case ALPHAGEN_CONST: - c = R_FloatToByte( pass->alphaGen.args[0] ); - for( i = 0; i < r_backacc.numColors; i++, bArray += 4 ) - bArray[3] = c; - break; - case ALPHAGEN_WAVE: - alphagenfunc = pass->alphaGen.func; - if( alphagenfunc->type == WAVEFORM_NOISE ) - { - a = R_BackendGetNoiseValue( 0, 0, 0, ( r_currentShaderTime + alphagenfunc->args[2] ) * alphagenfunc->args[3] ); - } - else - { - table = R_TableForFunc( alphagenfunc->type ); - a = alphagenfunc->args[2] + r_currentShaderTime * alphagenfunc->args[3]; - a = FTABLE_EVALUATE( table, a ); - } - - a = a * alphagenfunc->args[1] + alphagenfunc->args[0]; - c = a <= 0 ? 0 : R_FloatToByte( a ); - - for( i = 0; i < r_backacc.numColors; i++, bArray += 4 ) - bArray[3] = c; - break; - case ALPHAGEN_PORTAL: - VectorAdd( vertsArray[0], RI.currententity->origin, v ); - VectorSubtract( RI.viewOrigin, v, t ); - a = VectorLength( t ) * pass->alphaGen.args[0]; - a = bound( 0.0f, a, 1.0f ); - c = R_FloatToByte( a ); - - for( i = 0; i < r_backacc.numColors; i++, bArray += 4 ) - bArray[3] = c; - break; - case ALPHAGEN_VERTEX: - for( i = 0; i < r_backacc.numColors; i++, bArray += 4, inArray += 4 ) - bArray[3] = inArray[3]; - break; - case ALPHAGEN_ONE_MINUS_VERTEX: - for( i = 0; i < r_backacc.numColors; i++, bArray += 4, inArray += 4 ) - bArray[3] = 255 - inArray[3]; - break; - case ALPHAGEN_ENTITY: - if( entityAlpha ) - break; - for( i = 0; i < r_backacc.numColors; i++, bArray += 4 ) - bArray[3] = RI.currententity->color[3]; - break; - case ALPHAGEN_OUTLINE: - for( i = 0; i < r_backacc.numColors; i++, bArray += 4 ) - bArray[3] = RI.currententity->outlineColor[3]; - break; - case ALPHAGEN_SPECULAR: - VectorSubtract( RI.viewOrigin, RI.currententity->origin, t ); - if( !Matrix_Compare( RI.currententity->axis, axis_identity ) ) - Matrix_TransformVector( RI.currententity->axis, t, v ); - else - VectorCopy( t, v ); - - for( i = 0; i < r_backacc.numColors; i++, bArray += 4 ) - { - VectorSubtract( v, vertsArray[i], t ); - c = VectorLength( t ); - a = DotProduct( t, normalsArray[i] ) / max( 0.1, c ); - a = pow( a, pass->alphaGen.args[0] ); - bArray[3] = a <= 0 ? 0 : R_FloatToByte( a ); - } - break; - case ALPHAGEN_DOT: - if( !Matrix_Compare( RI.currententity->axis, axis_identity ) ) - Matrix_TransformVector( RI.currententity->axis, RI.vpn, v ); - else - VectorCopy( RI.vpn, v ); - - for( i = 0; i < r_backacc.numColors; i++, bArray += 4 ) - { - a = DotProduct( v, inNormalsArray[i] ); if( a < 0 ) a = -a; - bArray[3] = R_FloatToByte( bound( pass->alphaGen.args[0], a, pass->alphaGen.args[1] ) ); - } - break; - case ALPHAGEN_ONE_MINUS_DOT: - if( !Matrix_Compare( RI.currententity->axis, axis_identity ) ) - Matrix_TransformVector( RI.currententity->axis, RI.vpn, v ); - else - VectorCopy( RI.vpn, v ); - - for( i = 0; i < r_backacc.numColors; i++, bArray += 4 ) - { - a = DotProduct( v, inNormalsArray[i] ); if( a < 0 ) a = -a;a = 1.0f - a; - bArray[3] = R_FloatToByte( bound( pass->alphaGen.args[0], a, pass->alphaGen.args[1] ) ); - } - default: - break; - } - - if( r_colorFog ) - { - float dist, vdist; - cplane_t *fogPlane; - vec3_t viewtofog; - float fogNormal[3], vpnNormal[3]; - float fogDist, vpnDist, fogShaderDistScale; - int fogptype; - bool alphaFog; - int blendsrc, blenddst; - - blendsrc = pass->glState & GLSTATE_SRCBLEND_MASK; - blenddst = pass->glState & GLSTATE_DSTBLEND_MASK; - if(( blendsrc != GLSTATE_SRCBLEND_SRC_ALPHA && blenddst != GLSTATE_DSTBLEND_SRC_ALPHA ) && ( blendsrc != GLSTATE_SRCBLEND_ONE_MINUS_SRC_ALPHA && blenddst != GLSTATE_DSTBLEND_ONE_MINUS_SRC_ALPHA )) - alphaFog = false; - else alphaFog = true; - - fogPlane = r_colorFog->visibleplane; - fogShaderDistScale = 1.0 / (r_colorFog->shader->fog_dist - r_colorFog->shader->fog_clearDist); - dist = RI.fog_dist_to_eye[r_colorFog-r_worldbrushmodel->fogs]; - - if( r_currentShader->flags & SHADER_SKYPARMS ) - { - if( dist > 0 ) - VectorScale( fogPlane->normal, -dist, viewtofog ); - else - VectorClear( viewtofog ); - } - else - { - VectorCopy( RI.currententity->origin, viewtofog ); - } - - vpnNormal[0] = DotProduct( RI.currententity->axis[0], RI.vpn ) * fogShaderDistScale * RI.currententity->scale; - vpnNormal[1] = DotProduct( RI.currententity->axis[1], RI.vpn ) * fogShaderDistScale * RI.currententity->scale; - vpnNormal[2] = DotProduct( RI.currententity->axis[2], RI.vpn ) * fogShaderDistScale * RI.currententity->scale; - vpnDist = (( ( RI.viewOrigin[0] - viewtofog[0] ) * RI.vpn[0] + ( RI.viewOrigin[1] - viewtofog[1] ) * RI.vpn[1] + ( RI.viewOrigin[2] - viewtofog[2] ) * RI.vpn[2] ) - + r_colorFog->shader->fog_clearDist) * fogShaderDistScale; - - bArray = colorArray[0]; - if( dist < 0 ) - { // camera is inside the fog - for( i = 0; i < r_backacc.numColors; i++, bArray += 4 ) - { - temp = DotProduct( vertsArray[i], vpnNormal ) - vpnDist; - c = ( 1.0f - bound( 0, temp, 1.0f ) ) * 0xFFFF; - - if( alphaFog ) - { - bArray[3] = ( bArray[3] * c ) >> 16; - } - else - { - bArray[0] = ( bArray[0] * c ) >> 16; - bArray[1] = ( bArray[1] * c ) >> 16; - bArray[2] = ( bArray[2] * c ) >> 16; - } - } - } - else - { - fogNormal[0] = DotProduct( RI.currententity->axis[0], fogPlane->normal ) * RI.currententity->scale; - fogNormal[1] = DotProduct( RI.currententity->axis[1], fogPlane->normal ) * RI.currententity->scale; - fogNormal[2] = DotProduct( RI.currententity->axis[2], fogPlane->normal ) * RI.currententity->scale; - fogptype = ( fogNormal[0] == 1.0 ? PLANE_X : ( fogNormal[1] == 1.0 ? PLANE_Y : ( fogNormal[2] == 1.0 ? PLANE_Z : PLANE_NONAXIAL ) ) ); - fogDist = fogPlane->dist - DotProduct( viewtofog, fogPlane->normal ); - - for( i = 0; i < r_backacc.numColors; i++, bArray += 4 ) - { - if( fogptype < 3 ) - vdist = vertsArray[i][fogptype] - fogDist; - else - vdist = DotProduct( vertsArray[i], fogNormal ) - fogDist; - - if( vdist < 0 ) - { - temp = ( DotProduct( vertsArray[i], vpnNormal ) - vpnDist ) * vdist / ( vdist - dist ); - c = ( 1.0f - bound( 0, temp, 1.0f ) ) * 0xFFFF; - - if( alphaFog ) - { - bArray[3] = ( bArray[3] * c ) >> 16; - } - else - { - bArray[0] = ( bArray[0] * c ) >> 16; - bArray[1] = ( bArray[1] * c ) >> 16; - bArray[2] = ( bArray[2] * c ) >> 16; - } - } - } - } - } -} - -/* -================ -R_ShaderpassBlendmode -================ -*/ -static int R_ShaderpassBlendmode( int passFlags ) -{ - if( passFlags & SHADERSTAGE_BLEND_REPLACE ) - return GL_REPLACE; - if( passFlags & SHADERSTAGE_BLEND_MODULATE ) - return GL_MODULATE; - if( passFlags & SHADERSTAGE_BLEND_ADD ) - return GL_ADD; - if( passFlags & SHADERSTAGE_BLEND_DECAL ) - return GL_DECAL; - return 0; -} - -/* -================ -R_SetShaderState -================ -*/ -static void R_SetShaderState( void ) -{ - int state; - - // Face culling - if( !gl_cull->integer || ( r_features & MF_NOCULL )) - GL_Cull( 0 ); - else if( r_currentShader->flags & SHADER_CULL_FRONT ) - GL_Cull( GL_FRONT ); - else if( r_currentShader->flags & SHADER_CULL_BACK ) - GL_Cull( GL_BACK ); - else GL_Cull( 0 ); - - state = 0; - if( r_currentShader->flags & SHADER_POLYGONOFFSET || RI.params & RP_SHADOWMAPVIEW ) - state |= GLSTATE_OFFSET_FILL; - if( r_currentShader->type == SHADER_FLARE ) - state |= GLSTATE_NO_DEPTH_TEST; - r_currentShaderState = state; -} - -/* -================ -R_RenderMeshGeneric -================ -*/ -void R_RenderMeshGeneric( void ) -{ - const ref_stage_t *pass = r_accumPasses[0]; - - R_BindShaderpass( pass, NULL, 0 ); - R_ModifyColor( pass ); - - if( pass->flags & SHADERSTAGE_BLEND_REPLACE ) - GL_TexEnv( GL_REPLACE ); - else - GL_TexEnv( GL_MODULATE ); - GL_SetState( r_currentShaderState | ( pass->glState & r_currentShaderPassMask )); - - R_FlushArrays(); -} - -/* -================ -R_RenderMeshMultitextured -================ -*/ -void R_RenderMeshMultitextured( void ) -{ - int i; - const ref_stage_t *pass = r_accumPasses[0]; - - R_BindShaderpass( pass, NULL, 0 ); - R_ModifyColor( pass ); - - GL_TexEnv( GL_MODULATE ); - GL_SetState( r_currentShaderState | ( pass->glState & r_currentShaderPassMask ) | GLSTATE_BLEND_MTEX ); - - for( i = 1; i < r_numAccumPasses; i++ ) - { - pass = r_accumPasses[i]; - R_BindShaderpass( pass, NULL, i ); - GL_TexEnv( R_ShaderpassBlendmode( pass->flags ) ); - } - - R_FlushArrays(); -} - -/* -================ -R_RenderMeshCombined -================ -*/ -void R_RenderMeshCombined( void ) -{ - int i; - const ref_stage_t *pass = r_accumPasses[0]; - - R_BindShaderpass( pass, NULL, 0 ); - R_ModifyColor( pass ); - - GL_TexEnv( GL_MODULATE ); - GL_SetState( r_currentShaderState | ( pass->glState & r_currentShaderPassMask ) | GLSTATE_BLEND_MTEX ); - - for( i = 1; i < r_numAccumPasses; i++ ) - { - pass = r_accumPasses[i]; - R_BindShaderpass( pass, NULL, i ); - - if( pass->flags & ( SHADERSTAGE_BLEND_REPLACE|SHADERSTAGE_BLEND_MODULATE )) - { - GL_TexEnv( GL_MODULATE ); - } - else if( pass->flags & SHADERSTAGE_BLEND_ADD ) - { - // these modes are best set with TexEnv, Combine4 would need much more setup - GL_TexEnv( GL_ADD ); - } - else if( pass->flags & SHADERSTAGE_BLEND_DECAL ) - { - // mimics Alpha-Blending in upper texture stage, but instead of multiplying the alpha-channel, they're added - // this way it can be possible to use GL_DECAL in both texture-units, while still looking good - // normal mutlitexturing would multiply the alpha-channel which looks ugly - GL_TexEnv( GL_COMBINE_ARB ); - pglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB ); - pglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_ADD ); - - pglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE ); - pglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR ); - pglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE ); - pglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA ); - - pglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB ); - pglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR ); - pglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PREVIOUS_ARB ); - pglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA ); - - pglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE ); - pglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA ); - } - else - { - Com_Assert( 1 ); - } - } - - R_FlushArrays(); -} - -/* -================ -R_RenderMeshGLSL_Material -================ -*/ -static void R_RenderMeshGLSL_Material( void ) -{ - int i, tcgen; - int state; - bool breakIntoPasses = false; - int program, object; - int programFeatures = 0; - texture_t *base, *normalmap, *glossmap, *decalmap; - mat4x4_t unused; - vec3_t lightDir = { 0.0f, 0.0f, 0.0f }; - vec4_t ambient = { 0.0f, 0.0f, 0.0f, 0.0f }, diffuse = { 0.0f, 0.0f, 0.0f, 0.0f }; - float offsetmappingScale; - superLightStyle_t *lightStyle; - ref_stage_t *pass = r_accumPasses[0]; - - // handy pointers - base = pass->textures[0]; - normalmap = pass->textures[1]; - glossmap = pass->textures[2]; - decalmap = pass->textures[3]; - - Com_Assert( normalmap == NULL ); - - if( normalmap->samples == 4 ) - offsetmappingScale = r_offsetmapping_scale->value * r_currentShader->offsetmapping_scale; - else // no alpha in normalmap, don't bother with offset mapping - offsetmappingScale = 0; - - if( GL_Support( R_GLSL_BRANCHING )) - programFeatures |= PROGRAM_APPLY_BRANCHING; - if( GL_Support( R_GLSL_NO_HALF_TYPES )) - programFeatures |= PROGRAM_APPLY_NO_HALF_TYPES; - if( RI.params & RP_CLIPPLANE ) - programFeatures |= PROGRAM_APPLY_CLIPPING; - - if( r_currentMeshBuffer->infokey > 0 ) - { - // world surface - int srcAlpha = (pass->flags & SHADERSTAGE_BLEND_DECAL); - - // CHECKTHIS: this is right ? - srcAlpha |= (pass->glState & (GLSTATE_ALPHAFUNC|GLSTATE_SRCBLEND_SRC_ALPHA|GLSTATE_SRCBLEND_ONE_MINUS_SRC_ALPHA|GLSTATE_DSTBLEND_SRC_ALPHA|GLSTATE_DSTBLEND_ONE_MINUS_SRC_ALPHA)); - - if( !( r_offsetmapping->integer & 1 ) ) - offsetmappingScale = 0; - - if( r_lightmap->integer || ( r_currentDlightBits && !pass->textures[5] ) ) - { - if( !srcAlpha ) - base = tr.whiteTexture; // white - else - programFeatures |= PROGRAM_APPLY_BASETEX_ALPHA_ONLY; - } - - // we use multipass for dynamic lights, so bind the white texture - // instead of base in GLSL program and add another modulative pass (diffusemap) - if( !r_lightmap->integer && ( r_currentDlightBits && !pass->textures[5] ) ) - { - breakIntoPasses = true; - r_GLSLpasses[1] = *pass; - r_GLSLpasses[1].flags = ( pass->flags & SHADERSTAGE_NOCOLORARRAY )|SHADERSTAGE_BLEND_MODULATE; - r_GLSLpasses[1].glState = GLSTATE_SRCBLEND_ZERO|GLSTATE_DSTBLEND_SRC_COLOR|((pass->glState & GLSTATE_ALPHAFUNC) ? GLSTATE_DEPTHFUNC_EQ : 0); - - // decal - if( decalmap ) - { - r_GLSLpasses[1].rgbGen.type = RGBGEN_IDENTITY; - r_GLSLpasses[1].alphaGen.type = ALPHAGEN_IDENTITY; - - r_GLSLpasses[2] = *pass; - r_GLSLpasses[2].flags = ( pass->flags & SHADERSTAGE_NOCOLORARRAY )|SHADERSTAGE_BLEND_DECAL; - r_GLSLpasses[2].glState = GLSTATE_SRCBLEND_SRC_ALPHA|GLSTATE_DSTBLEND_ONE_MINUS_SRC_ALPHA|((pass->glState & GLSTATE_ALPHAFUNC) ? GLSTATE_DEPTHFUNC_EQ : 0); - r_GLSLpasses[2].textures[0] = decalmap; - } - - if( offsetmappingScale <= 0 ) - { - r_GLSLpasses[1].program = r_GLSLpasses[2].program = NULL; - r_GLSLpasses[1].program_type = r_GLSLpasses[2].program_type = PROGRAM_TYPE_NONE; - } - else - { - r_GLSLpasses[1].textures[2] = r_GLSLpasses[2].textures[2] = NULL; // no specular - r_GLSLpasses[1].textures[3] = r_GLSLpasses[2].textures[3] = NULL; // no decal - r_GLSLpasses[1].textures[6] = r_GLSLpasses[6].textures[2] = ((texture_t *)1); // HACKHACK no ambient - } - } - } - else if( ( r_currentMeshBuffer->sortkey & 3 ) == MB_POLY ) - { // polys - if( !( r_offsetmapping->integer & 2 ) ) - offsetmappingScale = 0; - - R_BuildTangentVectors( r_backacc.numVerts, vertsArray, normalsArray, coordsArray, r_backacc.numElems/3, elemsArray, inSVectorsArray ); - } - else - { // models - if( !( r_offsetmapping->integer & 4 ) ) - offsetmappingScale = 0; - } - - tcgen = pass->tcgen; // store the original tcgen - - pass->tcgen = TCGEN_BASE; - R_BindShaderpass( pass, base, 0 ); - if( !breakIntoPasses ) - { - // calculate the fragment color - R_ModifyColor( pass ); - } - else - { // rgbgen identity (255,255,255,255) - r_backacc.numColors = 1; - colorArray[0][0] = colorArray[0][1] = colorArray[0][2] = colorArray[0][3] = 255; - } - - // set shaderpass state (blending, depthwrite, etc) - state = r_currentShaderState | ( pass->glState & r_currentShaderPassMask ) | GLSTATE_BLEND_MTEX; - GL_SetState( state ); - - // don't waste time on processing GLSL programs with zero colormask - if( RI.params & RP_SHADOWMAPVIEW ) - { - pass->tcgen = tcgen; // restore original tcgen - R_FlushArrays(); - return; - } - - // we only send S-vectors to GPU and recalc T-vectors as cross product - // in vertex shader - pass->tcgen = TCGEN_SVECTORS; - GL_Bind( 1, normalmap ); // normalmap - GL_SetTexCoordArrayMode( GL_TEXTURE_COORD_ARRAY ); - R_VertexTCBase( pass, 1, unused ); - - if( glossmap && r_lighting_glossintensity->value ) - { - programFeatures |= PROGRAM_APPLY_SPECULAR; - GL_Bind( 2, glossmap ); // gloss - GL_SetTexCoordArrayMode( 0 ); - } - - if( decalmap && !breakIntoPasses ) - { - programFeatures |= PROGRAM_APPLY_DECAL; - GL_Bind( 3, decalmap ); // decal - GL_SetTexCoordArrayMode( 0 ); - } - - if( offsetmappingScale > 0 ) - programFeatures |= r_offsetmapping_reliefmapping->integer ? PROGRAM_APPLY_RELIEFMAPPING : PROGRAM_APPLY_OFFSETMAPPING; - - if( r_currentMeshBuffer->infokey > 0 ) - { // world surface - lightStyle = r_superLightStyle; - - // bind lightmap textures and set program's features for lightstyles - if( r_superLightStyle && r_superLightStyle->lightmapNum[0] >= 0 ) - { - pass->tcgen = TCGEN_LIGHTMAP; - - for( i = 0; i < LM_STYLES && r_superLightStyle->lightmapStyles[i] != 255; i++ ) - { - programFeatures |= ( PROGRAM_APPLY_LIGHTSTYLE0 << i ); - - r_lightmapStyleNum[i+4] = i; - GL_Bind( i+4, tr.lightmapTextures[r_superLightStyle->lightmapNum[i]] ); // lightmap - GL_SetTexCoordArrayMode( GL_TEXTURE_COORD_ARRAY ); - R_VertexTCBase( pass, i+4, unused ); - } - - if( i == 1 ) - { - vec_t *rgb = r_lightStyles[r_superLightStyle->lightmapStyles[0]].rgb; - - // PROGRAM_APPLY_FB_LIGHTMAP indicates that there's no need to renormalize - // the lighting vector for specular (saves 3 adds, 3 muls and 1 normalize per pixel) - if( rgb[0] == 1 && rgb[1] == 1 && rgb[2] == 1 ) - programFeatures |= PROGRAM_APPLY_FB_LIGHTMAP; - } - } - - if( !pass->textures[6] && !VectorCompare( mapConfig.ambient, vec3_origin ) ) - { - VectorCopy( mapConfig.ambient, ambient ); - programFeatures |= PROGRAM_APPLY_AMBIENT_COMPENSATION; - } - } - else - { - vec3_t temp; - - lightStyle = NULL; - programFeatures |= PROGRAM_APPLY_DIRECTIONAL_LIGHT; - - if( ( r_currentMeshBuffer->sortkey & 3 ) == MB_POLY ) - { - VectorCopy( r_polys[-r_currentMeshBuffer->infokey-1].normal, lightDir ); - Vector4Set( ambient, 0, 0, 0, 0 ); - Vector4Set( diffuse, 1, 1, 1, 1 ); - } - else if( RI.currententity ) - { - if( RI.currententity->flags & RF_FULLBRIGHT ) - { - Vector4Set( ambient, 1, 1, 1, 1 ); - Vector4Set( diffuse, 1, 1, 1, 1 ); - } - else - { - // get weighted incoming direction of world and dynamic lights - R_LightForOrigin( RI.currententity->lightingOrigin, temp, ambient, diffuse, - RI.currententity->model ? RI.currententity->model->radius * RI.currententity->scale : 0 ); - - if( RI.currententity->flags & EF_MINLIGHT ) - { - if( ambient[0] <= 0.1f || ambient[1] <= 0.1f || ambient[2] <= 0.1f ) - VectorSet( ambient, 0.1f, 0.1f, 0.1f ); - } - - // rotate direction - Matrix_TransformVector( RI.currententity->axis, temp, lightDir ); - } - } - } - - pass->tcgen = tcgen; // restore original tcgen - - program = R_RegisterGLSLProgram( pass->program, NULL, programFeatures ); - object = R_GetProgramObject( program ); - if( object ) - { - pglUseProgramObjectARB( object ); - - // update uniforms - R_UpdateProgramUniforms( program, RI.viewOrigin, vec3_origin, lightDir, ambient, diffuse, lightStyle, - true, 0, 0, 0, offsetmappingScale ); - - R_FlushArrays(); - - pglUseProgramObjectARB( 0 ); - } - - if( breakIntoPasses ) - { - unsigned int oDB = r_currentDlightBits; // HACK HACK HACK - superLightStyle_t *oSL = r_superLightStyle; - - R_AccumulatePass( &r_GLSLpasses[0] ); // dynamic lighting pass - - if( offsetmappingScale ) - { - r_superLightStyle = NULL; - r_currentDlightBits = 0; - } - - R_AccumulatePass( &r_GLSLpasses[1] ); // modulate (diffusemap) - - if( decalmap ) - R_AccumulatePass( &r_GLSLpasses[2] ); // alpha-blended decal texture - - if( offsetmappingScale ) - { - r_superLightStyle = oSL; - r_currentDlightBits = oDB; - } - } -} - -/* -================ -R_RenderMeshGLSL_Distortion -================ -*/ -static void R_RenderMeshGLSL_Distortion( void ) -{ - int state, tcgen; - int program, object; - int programFeatures = 0; - mat4x4_t unused; - ref_stage_t *pass = r_accumPasses[0]; - texture_t *portaltexture1, *portaltexture2; - bool frontPlane; - - if( !( RI.params & ( RP_PORTALCAPTURED|RP_PORTALCAPTURED2 ))) - return; - - if( GL_Support( R_GLSL_BRANCHING )) - programFeatures |= PROGRAM_APPLY_BRANCHING; - if( GL_Support( R_GLSL_NO_HALF_TYPES )) - programFeatures |= PROGRAM_APPLY_NO_HALF_TYPES; - if( RI.params & RP_CLIPPLANE ) - programFeatures |= PROGRAM_APPLY_CLIPPING; - - portaltexture1 = ( RI.params & RP_PORTALCAPTURED ) ? tr.portaltexture1 : tr.blackTexture; - portaltexture2 = ( RI.params & RP_PORTALCAPTURED2 ) ? tr.portaltexture2 : tr.blackTexture; - - frontPlane = (PlaneDiff( RI.viewOrigin, &RI.portalPlane ) > 0 ? true : false); - - tcgen = pass->tcgen; // store the original tcgen - - R_BindShaderpass( pass, pass->textures[0], 0 ); // dudvmap - - // calculate the fragment color - R_ModifyColor( pass ); - - if( frontPlane ) - { - if( pass->alphaGen.type != ALPHAGEN_IDENTITY ) - programFeatures |= PROGRAM_APPLY_DISTORTION_ALPHA; - } - - // set shaderpass state (blending, depthwrite, etc) - state = r_currentShaderState | ( pass->glState & r_currentShaderPassMask ) | GLSTATE_BLEND_MTEX; - GL_SetState( state ); - - if( pass->textures[1] /* && ( RI.params & RP_PORTALCAPTURED )*/ ) - { - // eyeDot - programFeatures |= PROGRAM_APPLY_EYEDOT; - - pass->tcgen = TCGEN_SVECTORS; - GL_Bind( 1, pass->textures[1] ); // normalmap - GL_SetTexCoordArrayMode( GL_TEXTURE_COORD_ARRAY ); - R_VertexTCBase( pass, 1, unused ); - } - - GL_Bind( 2, portaltexture1 ); // reflection - GL_Bind( 3, portaltexture2 ); // refraction - - pass->tcgen = tcgen; // restore original tcgen - - // update uniforms - program = R_RegisterGLSLProgram( pass->program, NULL, programFeatures ); - object = R_GetProgramObject( program ); - if( object ) - { - pglUseProgramObjectARB( object ); - - R_UpdateProgramUniforms( program, RI.viewOrigin, vec3_origin, vec3_origin, NULL, NULL, NULL, - frontPlane, tr.portaltexture1->width, tr.portaltexture1->height, 0, 0 ); - - R_FlushArrays(); - - pglUseProgramObjectARB( 0 ); - } -} - -/* -================ -R_RenderMeshGLSL_Shadowmap -================ -*/ -static void R_RenderMeshGLSL_Shadowmap( void ) -{ - int i; - int state; - int program, object; - int programFeatures = GL_Support( R_GLSL_BRANCHING ) ? PROGRAM_APPLY_BRANCHING : 0; - ref_stage_t *pass = r_accumPasses[0]; - - if( r_shadows_pcf->integer == 2 ) - programFeatures |= PROGRAM_APPLY_PCF2x2; - else if( r_shadows_pcf->integer == 3 ) - programFeatures |= PROGRAM_APPLY_PCF3x3; - - // update uniforms - program = R_RegisterGLSLProgram( pass->program, NULL, programFeatures ); - object = R_GetProgramObject( program ); - if( !object ) - return; - - for( i = 0, r_currentCastGroup = r_shadowGroups; i < r_numShadowGroups; i++, r_currentCastGroup++ ) - { - if( !( r_currentShadowBits & r_currentCastGroup->bit ) ) - continue; - - R_BindShaderpass( pass, r_currentCastGroup->depthTexture, 0 ); - - pglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB ); - pglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL ); - - // calculate the fragment color - R_ModifyColor( pass ); - - // set shaderpass state (blending, depthwrite, etc) - state = r_currentShaderState | ( pass->glState & r_currentShaderPassMask ) | GLSTATE_BLEND_MTEX; - GL_SetState( state ); - - pglUseProgramObjectARB( object ); - - R_UpdateProgramUniforms( program, RI.viewOrigin, vec3_origin, vec3_origin, NULL, NULL, NULL, true, - r_currentCastGroup->depthTexture->width, r_currentCastGroup->depthTexture->height, - r_currentCastGroup->projDist, 0 ); - - R_FlushArrays(); - - pglUseProgramObjectARB( 0 ); - - pglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE ); - } -} - -/* -================ -R_RenderMeshGLSL_Outline -================ -*/ -static void R_RenderMeshGLSL_Outline( void ) -{ - int faceCull; - int state; - int program, object; - int programFeatures = GL_Support( R_GLSL_BRANCHING ) ? PROGRAM_APPLY_BRANCHING : 0; - ref_stage_t *pass = r_accumPasses[0]; - - if( RI.params & RP_CLIPPLANE ) - programFeatures |= PROGRAM_APPLY_CLIPPING; - - // update uniforms - program = R_RegisterGLSLProgram( pass->program, NULL, programFeatures ); - object = R_GetProgramObject( program ); - if( !object ) - return; - - faceCull = glState.faceCull; - GL_Cull( GL_BACK ); - - GL_SelectTexture( 0 ); - GL_SetTexCoordArrayMode( 0 ); - - // calculate the fragment color - R_ModifyColor( pass ); - - // set shaderpass state (blending, depthwrite, etc) - state = r_currentShaderState | ( pass->glState & r_currentShaderPassMask ) | GLSTATE_BLEND_MTEX; - GL_SetState( state ); - - pglUseProgramObjectARB( object ); - - R_UpdateProgramUniforms( program, RI.viewOrigin, vec3_origin, vec3_origin, NULL, NULL, NULL, true, - 0, 0, RI.currententity->outlineHeight * r_outlines_scale->value, 0 ); - - R_FlushArrays(); - - pglUseProgramObjectARB( 0 ); - - GL_Cull( faceCull ); -} - -/* -================ -R_RenderMeshGLSLProgrammed -================ -*/ -static void R_RenderMeshGLSLProgrammed( void ) -{ - const ref_stage_t *pass = ( ref_stage_t * )r_accumPasses[0]; - - switch( pass->program_type ) - { - case PROGRAM_TYPE_MATERIAL: - R_RenderMeshGLSL_Material(); - break; - case PROGRAM_TYPE_DISTORTION: - R_RenderMeshGLSL_Distortion(); - break; - case PROGRAM_TYPE_SHADOWMAP: - R_RenderMeshGLSL_Shadowmap(); - break; - case PROGRAM_TYPE_OUTLINE: - R_RenderMeshGLSL_Outline (); - break; - default: - MsgDev( D_WARN, "Unknown GLSL program type %i\n", pass->program_type ); - break; - } -} - -/* -================ -R_RenderAccumulatedPasses -================ -*/ -static void R_RenderAccumulatedPasses( void ) -{ - const ref_stage_t *pass = r_accumPasses[0]; - - R_CleanUpTextureUnits( r_numAccumPasses ); - - if( pass->program ) - { - r_numAccumPasses = 0; - R_RenderMeshGLSLProgrammed(); - return; - } - if( pass->flags & SHADERSTAGE_DLIGHT ) - { - r_numAccumPasses = 0; - R_AddDynamicLights( r_currentDlightBits, r_currentShaderState | ( pass->glState & r_currentShaderPassMask )); - return; - } - if( pass->flags & SHADERSTAGE_STENCILSHADOW ) - { - r_numAccumPasses = 0; - R_PlanarShadowPass( r_currentShaderState | ( pass->glState & r_currentShaderPassMask )); - return; - } - - if( r_numAccumPasses == 1 ) - R_RenderMeshGeneric(); - else if( GL_Support( R_COMBINE_EXT )) - R_RenderMeshCombined(); - else - R_RenderMeshMultitextured(); - - r_numAccumPasses = 0; -} - -/* -================ -R_AccumulatePass -================ -*/ -static void R_AccumulatePass( ref_stage_t *pass ) -{ - bool accumulate, renderNow; - const ref_stage_t *prevPass; - - // for depth texture we render light's view to, ignore passes that do not write into depth buffer - if( ( RI.params & RP_SHADOWMAPVIEW ) && !( pass->glState & GLSTATE_DEPTHWRITE )) - return; - - // see if there are any free texture units - renderNow = ( pass->flags & ( SHADERSTAGE_DLIGHT|SHADERSTAGE_STENCILSHADOW ) ) || pass->program; - accumulate = ( r_numAccumPasses < glConfig.max_texture_units ) && !renderNow; - - if( accumulate ) - { - if( !r_numAccumPasses ) - { - r_accumPasses[r_numAccumPasses++] = pass; - return; - } - - // ok, we've got several passes, diff against the previous - prevPass = r_accumPasses[r_numAccumPasses-1]; - - // see if depthfuncs and colors are good - if( - (( prevPass->glState ^ pass->glState ) & GLSTATE_DEPTHFUNC_EQ ) || - ( pass->glState & GLSTATE_ALPHAFUNC ) || - ( pass->rgbGen.type != RGBGEN_IDENTITY ) || - ( pass->alphaGen.type != ALPHAGEN_IDENTITY ) || - ( ( prevPass->glState & GLSTATE_ALPHAFUNC ) && !( pass->glState & GLSTATE_DEPTHFUNC_EQ )) - ) - accumulate = false; - - // see if blendmodes are good - if( accumulate ) - { - int mode, prevMode; - - mode = R_ShaderpassBlendmode( pass->flags ); - if( mode ) - { - prevMode = R_ShaderpassBlendmode( prevPass->flags ); - - if( GL_Support( R_COMBINE_EXT )) - { - if( prevMode == GL_REPLACE ) - accumulate = ( mode == GL_ADD ) ? GL_Support( R_TEXTURE_ENV_ADD_EXT ) : true; - else if( prevMode == GL_ADD ) - accumulate = ( mode == GL_ADD ) && GL_Support( R_TEXTURE_ENV_ADD_EXT ); - else if( prevMode == GL_MODULATE ) - accumulate = ( mode == GL_MODULATE || mode == GL_REPLACE ); - else - accumulate = false; - } - else /* if( GL_Support( R_ARB_MULTITEXTURE ))*/ - { - if( prevMode == GL_REPLACE ) - accumulate = ( mode == GL_ADD ) ? GL_Support( R_TEXTURE_ENV_ADD_EXT ) : ( mode != GL_DECAL ); - else if( prevMode == GL_ADD ) - accumulate = ( mode == GL_ADD ) && GL_Support( R_TEXTURE_ENV_ADD_EXT ); - else if( prevMode == GL_MODULATE ) - accumulate = ( mode == GL_MODULATE || mode == GL_REPLACE ); - else - accumulate = false; - } - } - else - { - accumulate = false; - } - } - } - - // no, failed to accumulate - if( !accumulate ) - { - if( r_numAccumPasses ) - R_RenderAccumulatedPasses(); - } - - r_accumPasses[r_numAccumPasses++] = pass; - if( renderNow ) - R_RenderAccumulatedPasses(); -} - -/* -================ -R_SetupLightmapMode -================ -*/ -void R_SetupLightmapMode( void ) -{ - r_lightmapPasses[0].tcgen = TCGEN_LIGHTMAP; - r_lightmapPasses[0].rgbGen.type = RGBGEN_IDENTITY; - r_lightmapPasses[0].alphaGen.type = ALPHAGEN_IDENTITY; - r_lightmapPasses[0].flags &= ~SHADERSTAGE_BLENDMODE; - r_lightmapPasses[0].glState &= ~( GLSTATE_ALPHAFUNC|GLSTATE_SRCBLEND_MASK|GLSTATE_DSTBLEND_MASK|GLSTATE_DEPTHFUNC_EQ ); - r_lightmapPasses[0].flags |= SHADERSTAGE_LIGHTMAP|SHADERSTAGE_NOCOLORARRAY|SHADERSTAGE_BLEND_MODULATE; -// r_lightmapPasses[0].glState |= GLSTATE_SRCBLEND_ONE|GLSTATE_DSTBLEND_ZERO; - if( r_lightmap->integer ) r_lightmapPasses[0].glState |= GLSTATE_DEPTHWRITE; -} - -/* -================ -R_RenderMeshBuffer -================ -*/ -void R_RenderMeshBuffer( const meshbuffer_t *mb ) -{ - int i; - msurface_t *surf; - ref_stage_t *pass; - mfog_t *fog; - - if( !r_backacc.numVerts || !r_backacc.numElems ) - { - R_ClearArrays(); - return; - } - - surf = mb->infokey > 0 ? &r_worldbrushmodel->surfaces[mb->infokey-1] : NULL; - if( surf ) - r_superLightStyle = &r_superLightStyles[surf->superLightStyle]; - else - r_superLightStyle = NULL; - r_currentMeshBuffer = mb; - - MB_NUM2SHADER( mb->shaderkey, r_currentShader ); - - if( glState.in2DMode ) - { - r_currentShaderTime = Sys_DoubleTime(); - } - else - { - r_currentShaderTime = (double)RI.refdef.time; - if( RI.currententity ) - { - r_currentShaderTime -= (double)RI.currententity->shaderTime; - if( r_currentShaderTime < 0 ) r_currentShaderTime = 0; - } - } - - if( !r_triangleOutlines ) - R_SetShaderState(); - - if( r_currentShader->numDeforms ) - R_DeformVertices(); - - if( r_features & MF_KEEPLOCK ) - r_backacc.c_totalKeptLocks++; - else - R_UnlockArrays(); - - if( r_triangleOutlines ) - { - R_LockArrays( r_backacc.numVerts ); - - if( RI.params & RP_TRISOUTLINES ) - R_DrawTriangles(); - if( RI.params & RP_SHOWNORMALS ) - R_DrawNormals(); - - R_ClearArrays(); - return; - } - - // extract the fog volume number from sortkey - if( !r_worldmodel ) - fog = NULL; - else - MB_NUM2FOG( mb->sortkey, fog ); - if( fog && !fog->shader ) - fog = NULL; - - // can we fog the geometry with alpha texture? - r_texFog = ( fog && ( ( r_currentShader->sort <= SORT_ALPHATEST && - ( r_currentShader->flags & (SHADER_DEPTHWRITE|SHADER_SKYPARMS))) || r_currentShader->fog_dist ) ) ? fog : NULL; - - // check if the fog volume is present but we can't use alpha texture - r_colorFog = ( fog && !r_texFog ) ? fog : NULL; - - if( r_currentShader->type == SHADER_FLARE ) - r_currentDlightBits = 0; - else - r_currentDlightBits = surf ? mb->dlightbits : 0; - - r_currentShadowBits = mb->shadowbits & RI.shadowBits; - - R_LockArrays( r_backacc.numVerts ); - - // accumulate passes for dynamic merging - for( i = 0, pass = r_currentShader->stages; i < r_currentShader->num_stages; i++, pass++ ) - { - if( !pass->program ) - { - if( pass->flags & SHADERSTAGE_LIGHTMAP ) - { - int j, k, l, u; - - // no valid lightmaps, goodbye - if( !r_superLightStyle || r_superLightStyle->lightmapNum[0] < 0 || r_superLightStyle->lightmapStyles[0] == 255 ) - continue; - - // try to apply lightstyles - if(( !( pass->glState & (GLSTATE_SRCBLEND_MASK|GLSTATE_DSTBLEND_MASK)) || ( pass->flags & SHADERSTAGE_BLEND_MODULATE )) && ( pass->rgbGen.type == RGBGEN_IDENTITY ) && ( pass->alphaGen.type == ALPHAGEN_IDENTITY )) - { - vec3_t colorSum, color; - - // the first pass is always GL_MODULATE or GL_REPLACE - // other passes are GL_ADD - r_lightmapPasses[0] = *pass; - - for( j = 0, l = 0, u = 0; j < LM_STYLES && r_superLightStyle->lightmapStyles[j] != 255; j++ ) - { - VectorCopy( r_lightStyles[r_superLightStyle->lightmapStyles[j]].rgb, colorSum ); - VectorClear( color ); - - for( ; ; l++ ) - { - for( k = 0; k < 3; k++ ) - { - colorSum[k] -= color[k]; - color[k] = bound( 0, colorSum[k], 1 ); - } - - if( l ) - { - if( !color[0] && !color[1] && !color[2] ) - break; - if( l == MAX_TEXTURE_UNITS+1 ) - r_lightmapPasses[0] = r_lightmapPasses[1]; - u = l % ( MAX_TEXTURE_UNITS+1 ); - } - - if( VectorCompare( color, colorWhite ) ) - { - r_lightmapPasses[u].rgbGen.type = RGBGEN_IDENTITY; - } - else - { - if( !l ) - { - r_lightmapPasses[0].flags &= ~SHADERSTAGE_BLENDMODE; - r_lightmapPasses[0].flags |= SHADERSTAGE_BLEND_MODULATE; - } - r_lightmapPasses[u].rgbGen.type = RGBGEN_CONST; - VectorCopy( color, r_lightmapPasses[u].rgbGen.args ); - } - - if( r_lightmap->integer && !l ) - R_SetupLightmapMode(); - R_AccumulatePass( &r_lightmapPasses[u] ); - r_lightmapStyleNum[r_numAccumPasses - 1] = j; - } - } - } - else - { - if( r_lightmap->integer ) - { - R_SetupLightmapMode(); - pass = r_lightmapPasses; - } - R_AccumulatePass( pass ); - r_lightmapStyleNum[r_numAccumPasses - 1] = 0; - } - continue; - } - else if( r_lightmap->integer && ( r_currentShader->flags & SHADER_HASLIGHTMAP )) - continue; - if(( pass->flags & SHADERSTAGE_PORTALMAP ) && !( RI.params & RP_PORTALCAPTURED )) - continue; - if(( pass->flags & SHADERSTAGE_DETAIL ) && !r_detailtextures->integer ) - continue; - if(( pass->flags & SHADERSTAGE_DLIGHT ) && !r_currentDlightBits ) - continue; - } - - R_AccumulatePass( pass ); - } - - // accumulate dynamic lights pass and fog pass if any - if( r_currentDlightBits && !( r_currentShader->flags & SHADER_NO_MODULATIVE_DLIGHTS )) - { - if( !r_lightmap->integer || !( r_currentShader->flags & SHADER_HASLIGHTMAP )) - R_AccumulatePass( &r_dlightsPass ); - } - - if( r_currentShadowBits && ( r_currentShader->sort >= SORT_OPAQUE ) && ( r_currentShader->sort <= SORT_ALPHATEST )) - R_AccumulatePass( &r_GLSLpasses[3] ); - - if( GL_Support( R_SHADER_GLSL100_EXT ) && RI.currententity && RI.currententity->outlineHeight && r_outlines_scale->value > 0 - && ( r_currentShader->sort == SORT_OPAQUE ) && ( r_currentShader->flags & SHADER_CULL_FRONT ) ) - R_AccumulatePass( &r_GLSLpassOutline ); - - if( r_texFog && r_texFog->shader ) - { - r_fogPass.textures[0] = tr.fogTexture; - if( !r_currentShader->num_stages || r_currentShader->fog_dist || ( r_currentShader->flags & SHADER_SKYPARMS ) ) - r_fogPass.glState &= ~GLSTATE_DEPTHFUNC_EQ; - else r_fogPass.glState |= GLSTATE_DEPTHFUNC_EQ; - R_AccumulatePass( &r_fogPass ); - } - - // flush any remaining passes - if( r_numAccumPasses ) - R_RenderAccumulatedPasses(); - - R_ClearArrays(); - - pglMatrixMode( GL_MODELVIEW ); -} - -/* -================ -R_BackendCleanUpTextureUnits -================ -*/ -void R_BackendCleanUpTextureUnits( void ) -{ - R_CleanUpTextureUnits( 1 ); - - GL_LoadIdentityTexMatrix(); - pglMatrixMode( GL_MODELVIEW ); - - GL_DisableAllTexGens(); - GL_SetTexCoordArrayMode( 0 ); -} - -/* -================ -R_BackendSetPassMask -================ -*/ -void R_BackendSetPassMask( int mask ) -{ - r_currentShaderPassMask = mask; -} - -/* -================ -R_BackendResetPassMask -================ -*/ -void R_BackendResetPassMask( void ) -{ - r_currentShaderPassMask = GLSTATE_MASK; -} - -/* -================ -R_BackendBeginTriangleOutlines -================ -*/ -void R_BackendBeginTriangleOutlines( void ) -{ - r_triangleOutlines = true; - pglColor4fv( colorWhite ); - - GL_Cull( 0 ); - GL_SetState( GLSTATE_NO_DEPTH_TEST ); - pglDisable( GL_TEXTURE_2D ); - pglPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); -} - -/* -================ -R_BackendEndTriangleOutlines -================ -*/ -void R_BackendEndTriangleOutlines( void ) -{ - r_triangleOutlines = false; - pglColor4fv( colorWhite ); - GL_SetState( 0 ); - pglEnable( GL_TEXTURE_2D ); - pglPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); -} - -/* -================ -R_SetColorForOutlines -================ -*/ -static _inline void R_SetColorForOutlines( void ) -{ - int type = r_currentMeshBuffer->sortkey & 3; - - switch( type ) - { - case MB_MODEL: - if( r_currentMeshBuffer->infokey < 0 ) - pglColor4fv( colorRed ); - else - pglColor4fv( colorWhite ); - break; - case MB_SPRITE: - pglColor4fv( colorBlue ); - break; - case MB_POLY: - pglColor4fv( colorGreen ); - break; - } -} - -/* -================ -R_DrawTriangles -================ -*/ -static void R_DrawTriangles( void ) -{ - if( r_showtris->integer == 2 ) - R_SetColorForOutlines(); - - if( GL_Support( R_DRAW_RANGEELEMENTS_EXT )) - pglDrawRangeElementsEXT( GL_TRIANGLES, 0, r_backacc.numVerts, r_backacc.numElems, GL_UNSIGNED_INT, elemsArray ); - else pglDrawElements( GL_TRIANGLES, r_backacc.numElems, GL_UNSIGNED_INT, elemsArray ); -} - -/* -================ -R_DrawNormals -================ -*/ -static void R_DrawNormals( void ) -{ - unsigned int i; - - if( r_shownormals->integer == 2 ) - R_SetColorForOutlines(); - - pglBegin( GL_LINES ); - for( i = 0; i < r_backacc.numVerts; i++ ) - { - pglVertex3fv( vertsArray[i] ); - pglVertex3f( vertsArray[i][0] + normalsArray[i][0], vertsArray[i][1] + normalsArray[i][1], vertsArray[i][2] + normalsArray[i][2] ); - } - pglEnd(); -} - -static void R_DrawLine( int color, int numpoints, const float *points, const int *elements ) -{ - int i = numpoints - 1; - vec3_t p0, p1; - - VectorSet( p0, points[i*3+0], points[i*3+1], points[i*3+2] ); - if( r_physbdebug->integer == 1 ) ConvertPositionToGame( p0 ); - - for( i = 0; i < numpoints; i++ ) - { - VectorSet( p1, points[i*3+0], points[i*3+1], points[i*3+2] ); - if( r_physbdebug->integer == 1 ) ConvertPositionToGame( p1 ); - - pglColor4fv( UnpackRGBA( color )); - pglVertex3fv( p0 ); - pglVertex3fv( p1 ); - - VectorCopy( p1, p0 ); - } -} - -/* -================ -R_DrawPhysDebug -================ -*/ -void R_DrawPhysDebug( void ) -{ - if( r_physbdebug->integer ) - { - // physic debug - pglLoadMatrixf( RI.worldviewMatrix ); - pglBegin( GL_LINES ); - ri.ShowCollision( R_DrawLine ); - pglEnd(); - } -} \ No newline at end of file diff --git a/render/r_draw.c b/render/r_draw.c index c4570753..34f58c2c 100644 --- a/render/r_draw.c +++ b/render/r_draw.c @@ -56,6 +56,7 @@ void R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, f } } + tr.iRenderMode = glState.draw_rendermode; pic_mbuffer.infokey -= 4; pic_mbuffer.shaderkey = shader->sortkey; diff --git a/render/r_local.h b/render/r_local.h index 8f3819ec..b5bb63cc 100644 --- a/render/r_local.h +++ b/render/r_local.h @@ -759,6 +759,7 @@ enum // #define SHADERPASS_DSTBLEND_MASK (((GLSTATE_DSTBLEND_DST_ALPHA)<<1)-GLSTATE_DSTBLEND_ZERO) #define GLSTATE_DSTBLEND_MASK 0xF0 +#define GLSTATE_BLENDFUNC ( GLSTATE_SRCBLEND_MASK|GLSTATE_DSTBLEND_MASK ) #define GLSTATE_ALPHAFUNC ( GLSTATE_AFUNC_GT0|GLSTATE_AFUNC_LT128|GLSTATE_AFUNC_GE128 ) typedef struct diff --git a/render/r_shader.c b/render/r_shader.c index d0d62bab..b887fb32 100644 --- a/render/r_shader.c +++ b/render/r_shader.c @@ -92,8 +92,8 @@ static void R_LoadTable( const char *name, tableFlags_t flags, size_t size, floa Host_Error( "R_LoadTable: MAX_TABLES limit exceeds\n" ); // fill it in - r_tables[r_numTables++] = table = Mem_Alloc( r_shaderpool, sizeof( table_t )); - com.strncpy( table->name, name, sizeof( table->name )); + table = r_tables[r_numTables++] = Mem_Alloc( r_shaderpool, sizeof( table_t )); + table->name = Shader_CopyString( name ); table->index = r_numTables - 1; table->flags = flags; table->size = size; @@ -274,7 +274,7 @@ static bool R_ParseTable( script_t *script, tableFlags_t flags ) R_LookupTable ================= */ -static float R_LookupTable( int tableIndex, float index ) +float R_LookupTable( int tableIndex, float index ) { table_t *table; float frac, value; @@ -308,6 +308,27 @@ static float R_LookupTable( int tableIndex, float index ) return value; } +/* +================= +R_GetTableByHandle +================= +*/ +float *R_GetTableByHandle( int tableIndex ) +{ + table_t *table; + + if( tableIndex < 0 || tableIndex >= r_numTables ) + { + MsgDev( D_ERROR, "R_GetTableByHandle: out of range\n" ); + return NULL; + } + table = r_tables[tableIndex]; + + if( !table ) return NULL; + return table->values; +} + + /* ======================================================================= @@ -637,10 +658,13 @@ static bool Shader_ParseSkySides( script_t *script, ref_shader_t *shader, ref_sh static bool Shader_ParseFunc( script_t *script, waveFunc_t *func, ref_shader_t *shader ) { token_t tok; + table_t *tb; if( !Com_ReadToken( script, false, &tok )) return false; + func->tableIndex = -1; + if( !com.stricmp( tok.string, "0" )) func->type = WAVEFORM_SIN; else if( !com.stricmp( tok.string, "sin" )) func->type = WAVEFORM_SIN; else if( !com.stricmp( tok.string, "triangle" )) func->type = WAVEFORM_TRIANGLE; @@ -649,9 +673,18 @@ static bool Shader_ParseFunc( script_t *script, waveFunc_t *func, ref_shader_t * else if( !com.stricmp( tok.string, "inverseSawtooth" )) func->type = WAVEFORM_INVERSESAWTOOTH; else if( !com.stricmp( tok.string, "noise" )) func->type = WAVEFORM_NOISE; else - { - MsgDev( D_WARN, "unknown waveform '%s' in shader '%s', defaulting to sin\n", tok.string, shader->name ); - func->type = WAVEFORM_SIN; + { // check for custom table + tb = R_FindTable( tok.string ); + if( tb ) + { + func->type = WAVEFORM_TABLE; + func->tableIndex = tb->index; + } + else + { + MsgDev( D_WARN, "unknown waveform '%s' in shader '%s', defaulting to sin\n", tok.string, shader->name ); + func->type = WAVEFORM_SIN; + } } if( !Shader_ParseVector( script, func->args, 4 )) @@ -2065,6 +2098,7 @@ static bool Shaderpass_TcMod( ref_shader_t *shader, ref_stage_t *pass, script_t } tcMod->args[0] = func.type; + tcMod->args[5] = func.tableIndex; for( i = 1; i < 5; i++ ) tcMod->args[i] = func.args[i-1]; tcMod->type = TCMOD_STRETCH; @@ -2352,7 +2386,10 @@ void R_ShaderList_f( void ) Msg( "?? %i", shader->type ); break; } - Msg( " %s\n", shader->name ); + Msg( " %s", shader->name ); + if( shader->flags & SHADER_DEFAULTED ) + Msg( " DEFAULTED\n" ); + else Msg( "\n" ); shaderCount++; } @@ -3504,6 +3541,7 @@ static ref_shader_t *Shader_CreateDefault( ref_shader_t *shader, int type, int a // calculate sortkey shader->sortkey = Shader_Sortkey( shader, shader->sort ); + shader->flags |= SHADER_DEFAULTED; // add to hash table hashKey = Com_HashKey( shortname, SHADERS_HASH_SIZE ); diff --git a/render/r_shader.h b/render/r_shader.h index 71ddad74..d9d71fad 100644 --- a/render/r_shader.h +++ b/render/r_shader.h @@ -70,6 +70,7 @@ typedef enum SHADER_PORTAL_CAPTURE1 = BIT(15), SHADER_PORTAL_CAPTURE2 = BIT(16), SHADER_RENDERMODE = BIT(17), + SHADER_DEFAULTED = BIT(18), SHADER_PORTAL_CAPTURE = (SHADER_PORTAL_CAPTURE1|SHADER_PORTAL_CAPTURE1), SHADER_CULL = (SHADER_CULL_FRONT|SHADER_CULL_BACK) } shaderFlags_t; @@ -121,7 +122,8 @@ typedef enum WAVEFORM_SAWTOOTH, WAVEFORM_INVERSESAWTOOTH, WAVEFORM_NOISE, - WAVEFORM_CONSTANT + WAVEFORM_CONSTANT, + WAVEFORM_TABLE // custom table } waveForm_t; // RGB colors generation @@ -237,6 +239,7 @@ typedef struct table_s typedef struct { waveForm_t type; // SHADER_FUNC enum + uint tableIndex; // valid only for WAVEFORM_TABLE float args[4]; // offset, amplitude, phase_offset, rate } waveFunc_t; @@ -333,6 +336,8 @@ ref_shader_t *R_LoadShader( const char *name, int type, bool forceDefault, int a // misc utilities void R_ShaderFreeUnused( void ); +float R_LookupTable( int tableIndex, float index ); +float *R_GetTableByHandle( int tableIndex ); void Shader_TouchImages( ref_shader_t *shader, bool free_unused ); void R_ShaderSetSpriteTexture( texture_t *mipTex ); void R_ShaderSetRenderMode( kRenderMode_t mode ); diff --git a/render/r_skm.c b/render/r_skm.c deleted file mode 100644 index 0cb023a1..00000000 --- a/render/r_skm.c +++ /dev/null @@ -1,1430 +0,0 @@ -/* -Copyright (C) 2002-2007 Victor Luchits - -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. - -*/ - -// r_skm.c: skeletal animation model format - -#include "r_local.h" -#include "mathlib.h" -#include "quatlib.h" -#include "byteorder.h" - -static mesh_t skm_mesh; - -static vec3_t skm_mins; -static vec3_t skm_maxs; -static float skm_radius; -char *COM_ParseExt( const char **data_p, bool nl ); - -/* -============================================================================== - -SKM MODELS - -============================================================================== -*/ - -/* -================= -Mod_LoadSkeletalPose -================= -*/ -void Mod_LoadSkeletalPose( char *name, ref_model_t *mod, void *buffer ) -{ - unsigned int i, j, k; - mskmodel_t *poutmodel; - dskpheader_t *pinmodel; - dskpbone_t *pinbone; - mskbone_t *poutbone; - dskpframe_t *pinframe; - mskframe_t *poutframe; - dskpbonepose_t *pinbonepose; - bonepose_t *poutbonepose; - byte *membuffer; - size_t memBufferSize; - - if( LittleLong(*(uint *)buffer) != SKMHEADER ) - Host_Error( "uknown fileid for %s\n", name ); - - pinmodel = ( dskpheader_t * )buffer; - poutmodel = ( mskmodel_t * )mod->extradata; - - if( LittleLong( pinmodel->type ) != SKM_MODELTYPE ) - Host_Error( "%s has wrong type number (%i should be %i)\n", - name, LittleLong( pinmodel->type ), SKM_MODELTYPE ); - if( LittleLong( pinmodel->filesize ) > SKM_MAX_FILESIZE ) - Host_Error( "%s has has wrong filesize (%i should be less than %i)\n", - name, LittleLong( pinmodel->filesize ), SKM_MAX_FILESIZE ); - if( LittleLong( pinmodel->num_bones ) != poutmodel->numbones ) - Host_Error( "%s has has wrong number of bones (%i should be less than %i)\n", - name, LittleLong( pinmodel->num_bones ), poutmodel->numbones ); - - poutmodel->numframes = LittleLong( pinmodel->num_frames ); - if( poutmodel->numframes <= 0 ) - Host_Error( "%s has no frames\n", name ); - else if( poutmodel->numframes > SKM_MAX_FRAMES ) - Host_Error( "%s has too many frames\n", name ); - - memBufferSize = 0; - memBufferSize += sizeof( mskbone_t ) * poutmodel->numbones; - memBufferSize += sizeof( mskframe_t ) * poutmodel->numframes; - memBufferSize += sizeof( bonepose_t ) * poutmodel->numbones * poutmodel->numframes; - membuffer = Mod_Malloc( mod, memBufferSize ); - - pinbone = ( dskpbone_t * )( ( byte * )pinmodel + LittleLong( pinmodel->ofs_bones ) ); - poutbone = poutmodel->bones = ( mskbone_t * )membuffer; membuffer += sizeof( mskbone_t ) * poutmodel->numbones; - - for( i = 0; i < poutmodel->numbones; i++, pinbone++, poutbone++ ) - { - com.strncpy( poutbone->name, pinbone->name, SKM_MAX_NAME ); - poutbone->flags = LittleLong( pinbone->flags ); - poutbone->parent = LittleLong( pinbone->parent ); - } - - pinframe = ( dskpframe_t * )( ( byte * )pinmodel + LittleLong( pinmodel->ofs_frames ) ); - poutframe = poutmodel->frames = ( mskframe_t * )membuffer; membuffer += sizeof( mskframe_t ) * poutmodel->numframes; - - for( i = 0; i < poutmodel->numframes; i++, pinframe++, poutframe++ ) - { - pinbonepose = ( dskpbonepose_t * )( ( byte * )pinmodel + LittleLong( pinframe->ofs_bonepositions ) ); - poutbonepose = poutframe->boneposes = ( bonepose_t * )membuffer; membuffer += sizeof( bonepose_t ) * poutmodel->numbones; - - ClearBounds( poutframe->mins, poutframe->maxs ); - - for( j = 0; j < poutmodel->numbones; j++, pinbonepose++, poutbonepose++ ) - { - for( k = 0; k < 4; k++ ) - poutbonepose->quat[k] = LittleFloat( pinbonepose->quat[k] ); - for( k = 0; k < 3; k++ ) - poutbonepose->origin[k] = LittleFloat( pinbonepose->origin[k] ); - } - } -} - -/* -================= -Mod_LoadSkeletalModel -================= -*/ -void Mod_LoadSkeletalModel( ref_model_t *mod, ref_model_t *parent, const void *buffer ) -{ - unsigned int i, j, k, l, m; - vec_t *v, *n; - dskmheader_t *pinmodel; - mskmodel_t *poutmodel; - dskmmesh_t *pinmesh; - mskmesh_t *poutmesh; - dskmvertex_t *pinskmvert; - dskmbonevert_t *pinbonevert; - dskmcoord_t *pinstcoord; - vec2_t *poutstcoord; - elem_t *pintris, *pouttris; - unsigned int *pinreferences, *poutreferences; - bonepose_t *bp, *basepose, *poutbonepose; - mskframe_t *pframe; - vec3_t ebbox = { 0, 0, 0 }; - size_t alignment = 16; - byte *buf; - - pinmodel = ( dskmheader_t * )buffer; - - if( LittleLong( pinmodel->type ) != SKM_MODELTYPE ) - Host_Error( "%s has wrong type number (%i should be %i)\n", - mod->name, LittleLong( pinmodel->type ), SKM_MODELTYPE ); - if( LittleLong( pinmodel->filesize ) > SKM_MAX_FILESIZE ) - Host_Error( "%s has has wrong filesize (%i should be less than %i)\n", - mod->name, LittleLong( pinmodel->filesize ), SKM_MAX_FILESIZE ); - - poutmodel = mod->extradata = Mod_Malloc( mod, sizeof( mskmodel_t ) ); - poutmodel->nummeshes = LittleLong( pinmodel->num_meshes ); - if( poutmodel->nummeshes <= 0 ) - Host_Error( "%s has no meshes\n", mod->name ); - else if( poutmodel->nummeshes > SKM_MAX_MESHES ) - Host_Error( "%s has too many meshes\n", mod->name ); - - poutmodel->numbones = LittleLong( pinmodel->num_bones ); - if( poutmodel->numbones <= 0 ) - Host_Error( "%s has no bones\n", mod->name ); - else if( poutmodel->numbones > SKM_MAX_BONES ) - Host_Error( "%s has too many bones\n", mod->name ); - - // if we have a parent model then we are a LOD file and should use parent model's pose data - if( parent ) - { - mskmodel_t *parentskm = ( mskmodel_t * )parent->extradata; - - if( !parentskm ) - Host_Error( "%s is not a LOD model for %s\n", - mod->name, parent->name ); - - if( poutmodel->numbones != parentskm->numbones ) - Host_Error( "%s has has wrong number of bones (%i should be less than %i)\n", - mod->name, poutmodel->numbones, parentskm->numbones ); - - poutmodel->bones = parentskm->bones; - poutmodel->frames = parentskm->frames; - poutmodel->numframes = parentskm->numframes; - } - else - { // load a config file - string temp; - string poseName, configName; - - com.strcpy( temp, mod->name ); - FS_StripExtension( temp ); - com.snprintf( configName, sizeof( configName ), "%s.cfg", temp ); - - memset( poseName, 0, sizeof( poseName ) ); - - buf = FS_LoadFile( configName, NULL ); - if( !buf ) - { - com.snprintf( poseName, sizeof( poseName ), "%s.skp", temp ); - } - else - { - char *ptr, *token; - - ptr = ( char * )buf; - while( ptr ) - { - token = COM_ParseExt( &ptr, true ); - if( !token[0] ) - break; - - if( !com.stricmp( token, "import" ) ) - { - token = COM_ParseExt( &ptr, false ); - com.strcpy( temp, token ); - FS_StripExtension( temp ); - com.snprintf( poseName, sizeof( poseName ), "%s.skp", temp ); - break; - } - } - - Mem_Free( buf ); - } - - buf = FS_LoadFile( poseName, NULL ); - if( !buf ) - Host_Error( "Could not find pose file for %s\n", mod->name ); - - Mod_LoadSkeletalPose( poseName, mod, buf ); - - Mem_Free( buf ); - } - - // clear model's bounding box - mod->radius = 0; - ClearBounds( mod->mins, mod->maxs ); - - // reconstruct frame 0 bone poses and inverse bone poses - basepose = Mod_Malloc( mod, sizeof( *basepose ) * poutmodel->numbones ); - poutmodel->invbaseposes = Mod_Malloc( mod, sizeof( *poutmodel->invbaseposes ) * poutmodel->numbones ); - - for( i = 0, bp = basepose; i < poutmodel->numbones; i++, bp++ ) - { - int parent = poutmodel->bones[i].parent; - bonepose_t *obp = &poutmodel->frames[0].boneposes[i], *ibp = &poutmodel->invbaseposes[i]; - - if( parent >= 0 ) - Quat_ConcatTransforms( basepose[parent].quat, basepose[parent].origin, - obp->quat, obp->origin, bp->quat, bp->origin ); - else - *bp = *obp; - - // reconstruct invserse bone pose - Quat_Conjugate( bp->quat, ibp->quat ); - Quat_TransformVector( ibp->quat, bp->origin, ibp->origin ); - VectorNegate( ibp->origin, ibp->origin ); - } - - pinmesh = ( dskmmesh_t * )( ( byte * )pinmodel + LittleLong( pinmodel->ofs_meshes ) ); - poutmesh = poutmodel->meshes = Mod_Malloc( mod, sizeof( mskmesh_t ) * poutmodel->nummeshes ); - - for( i = 0; i < poutmodel->nummeshes; i++, pinmesh++, poutmesh++ ) - { - float *influences; - unsigned int size, *bones; - - poutmesh->numverts = LittleLong( pinmesh->num_verts ); - if( poutmesh->numverts <= 0 ) - Host_Error("mesh %i in model %s has no vertexes\n", i, mod->name ); - else if( poutmesh->numverts > SKM_MAX_VERTS ) - Host_Error("mesh %i in model %s has too many vertexes", i, mod->name ); - - poutmesh->numtris = LittleLong( pinmesh->num_tris ); - if( poutmesh->numtris <= 0 ) - Host_Error("mesh %i in model %s has no indices\n", i, mod->name ); - else if( poutmesh->numtris > SKM_MAX_TRIS ) - Host_Error("mesh %i in model %s has too many indices\n", i, mod->name ); - - poutmesh->numreferences = LittleLong( pinmesh->num_references ); - if( poutmesh->numreferences <= 0 ) - Host_Error("mesh %i in model %s has no bone references\n", i, mod->name ); - else if( poutmesh->numreferences > SKM_MAX_BONES ) - Host_Error("mesh %i in model %s has too many bone references\n", i, mod->name ); - - com.strncpy( poutmesh->name, pinmesh->meshname, sizeof( poutmesh->name ) ); - Mod_StripLODSuffix( poutmesh->name ); - - FS_StripExtension( pinmesh->shadername ); - poutmesh->skin.shader = R_LoadShader( pinmesh->shadername, SHADER_ALIAS, false, 0, SHADER_INVALID ); - R_DeformvBBoxForShader( poutmesh->skin.shader, ebbox ); - - pinreferences = ( elem_t *)( ( byte * )pinmodel + LittleLong( pinmesh->ofs_references ) ); - poutreferences = poutmesh->references = Mod_Malloc( mod, sizeof( unsigned int ) * poutmesh->numreferences ); - for( j = 0; j < poutmesh->numreferences; j++, pinreferences++, poutreferences++ ) - *poutreferences = LittleLong( *pinreferences ); - - pinskmvert = ( dskmvertex_t * )( ( byte * )pinmodel + LittleLong( pinmesh->ofs_verts ) ); - - poutmesh->influences = ( float * )Mod_Malloc( mod, ( sizeof( *poutmesh->influences ) + sizeof( *poutmesh->bones ) ) * SKM_MAX_WEIGHTS * poutmesh->numverts ); - poutmesh->bones = ( unsigned int * )( ( byte * )poutmesh->influences + sizeof( *poutmesh->influences ) * SKM_MAX_WEIGHTS * poutmesh->numverts ); - - size = sizeof( vec4_t ) + sizeof( vec4_t ); // xyz and normals - if( GL_Support( R_SHADER_GLSL100_EXT )) - size += sizeof( vec4_t ); // s-vectors - - size *= ( poutmesh->numverts+1 ); // pad by one additional vertex for prefetching - - // align poutmesh->xyzArray on a 16-byte boundary (we leak 16 bytes at most though) - buf = ( byte * )( Mod_Malloc( mod, size+alignment ) ); - poutmesh->xyzArray = ( vec4_t * )( buf+alignment-( (size_t)buf % alignment ) ); - poutmesh->normalsArray = ( vec4_t * )( ( byte * )poutmesh->xyzArray + sizeof( vec4_t ) * ( poutmesh->numverts+1 ) ); - - v = ( vec_t * )poutmesh->xyzArray[0]; - n = ( vec_t * )poutmesh->normalsArray[0]; - influences = poutmesh->influences; - bones = poutmesh->bones; - pframe = &poutmodel->frames[0]; - for( j = 0; j < poutmesh->numverts; j++, v += 4, n += 4, influences += SKM_MAX_WEIGHTS, bones += SKM_MAX_WEIGHTS ) - { - float sum, influence; - unsigned int bonenum, numweights; - vec3_t origin, normal, t, matrix[3]; - - pinbonevert = ( dskmbonevert_t * )( ( byte * )pinskmvert + sizeof( pinskmvert->numweights ) ); - numweights = LittleLong( pinskmvert->numweights ); - - for( l = 0; l < numweights; l++, pinbonevert++ ) - { - bonenum = LittleLong( pinbonevert->bonenum ); - influence = LittleFloat( pinbonevert->influence ); - poutbonepose = basepose + bonenum; - for( k = 0; k < 3; k++ ) - { - origin[k] = LittleFloat( pinbonevert->origin[k] ); - normal[k] = LittleFloat( pinbonevert->normal[k] ); - } - - // rebuild the base pose - Quat_Matrix( poutbonepose->quat, matrix ); - - Matrix_TransformVector( matrix, origin, t ); - VectorAdd( v, t, v ); - VectorMA( v, influence, poutbonepose->origin, v ); - v[3] = 1; - - Matrix_TransformVector( matrix, normal, t ); - VectorAdd( n, t, n ); - n[3] = 0; - - if( !l ) - { // store the first influence - bones[0] = bonenum; - influences[0] = influence; - } - else - { // store the new influence if needed - for( k = 0; k < SKM_MAX_WEIGHTS; k++ ) - { - if( influence > influences[k] ) - { - // pop the most weak influences out of the array, - // shifting the rest of them to the beginning - for( m = SKM_MAX_WEIGHTS-1; m > k; m-- ) - { - bones[m] = bones[m-1]; - influences[m] = influences[m-1]; - } - - // store the new influence - bones[k] = bonenum; - influences[k] = influence; - break; - } - } - } - } - - // normalize influences if needed - for( l = 0, sum = 0; l < SKM_MAX_WEIGHTS && influences[l]; l++ ) - sum += influences[l]; - if( sum > 1.0f - 1.0/256.0f ) - { - for( l = 0, sum = 1.0f / sum; l < SKM_MAX_WEIGHTS && influences[l]; l++ ) - influences[l] *= sum; - } - - for( l = 0; l < SKM_MAX_WEIGHTS; l++ ) - { - if( influences[l] == 1.0f ) - { - Com_Assert( l > SKM_MAX_WEIGHTS-1 ); - influences[l] = 1; - influences[l+1] = 0; - break; - } - } - - // test vertex against the bounding box - AddPointToBounds( v, pframe->mins, pframe->maxs ); - - pinskmvert = ( dskmvertex_t * )( ( byte * )pinbonevert ); - } - - pinstcoord = ( dskmcoord_t * )( ( byte * )pinmodel + LittleLong( pinmesh->ofs_texcoords ) ); - poutstcoord = poutmesh->stArray = Mod_Malloc( mod, poutmesh->numverts * sizeof( vec2_t ) ); - for( j = 0; j < poutmesh->numverts; j++, pinstcoord++ ) - { - poutstcoord[j][0] = LittleFloat( pinstcoord->st[0] ); - poutstcoord[j][1] = LittleFloat( pinstcoord->st[1] ); - } - - pintris = ( elem_t * )( ( byte * )pinmodel + LittleLong( pinmesh->ofs_indices ) ); - pouttris = poutmesh->elems = Mod_Malloc( mod, sizeof( elem_t ) * poutmesh->numtris * 3 ); - for( j = 0; j < poutmesh->numtris; j++, pintris += 3, pouttris += 3 ) - { - pouttris[0] = (elem_t)LittleLong( pintris[0] ); - pouttris[1] = (elem_t)LittleLong( pintris[1] ); - pouttris[2] = (elem_t)LittleLong( pintris[2] ); - } - - // - // build S and T vectors - // - if( GL_Support( R_SHADER_GLSL100_EXT )) - { - poutmesh->sVectorsArray = ( vec4_t * )( ( byte * )poutmesh->normalsArray + sizeof( vec4_t ) * ( poutmesh->numverts+1 ) ); - R_BuildTangentVectors( poutmesh->numverts, poutmesh->xyzArray, poutmesh->normalsArray, poutmesh->stArray, - poutmesh->numtris, poutmesh->elems, poutmesh->sVectorsArray ); - } - } - -#if 0 - // enable this to speed up loading - for( j = 0; j < 3; j++ ) - { - mod->mins[j] -= 48; - mod->maxs[j] += 48; - } -#else - // so much work just to calc the model's bounds, doh - for( j = 1; j < poutmodel->numframes; j++ ) - { - pframe = &poutmodel->frames[j]; - - for( i = 0, bp = basepose; i < poutmodel->numbones; i++, bp++ ) - { - int parent = poutmodel->bones[i].parent; - bonepose_t *obp = &pframe->boneposes[i]; - - if( parent >= 0 ) - Quat_ConcatTransforms( basepose[parent].quat, basepose[parent].origin, - obp->quat, obp->origin, bp->quat, bp->origin ); - else - *bp = *obp; - } - - pinmesh = ( dskmmesh_t * )( ( byte * )pinmodel + LittleLong( pinmodel->ofs_meshes ) ); - for( i = 0, poutmesh = poutmodel->meshes; i < poutmodel->nummeshes; i++, pinmesh++, poutmesh++ ) - { - pinskmvert = ( dskmvertex_t * )( ( byte * )pinmodel + LittleLong( pinmesh->ofs_verts ) ); - - for( k = 0; k < poutmesh->numverts; k++ ) - { - float influence; - unsigned int numweights, bonenum; - vec3_t v; - - pinbonevert = ( dskmbonevert_t * )( ( byte * )pinskmvert + sizeof( pinskmvert->numweights ) ); - numweights = LittleLong( pinskmvert->numweights ); - - VectorClear( v ); - for( l = 0; l < numweights; l++, pinbonevert++ ) - { - vec3_t origin, t; - - bonenum = LittleLong( pinbonevert->bonenum ); - influence = LittleFloat( pinbonevert->influence ); - poutbonepose = basepose + bonenum; - for( m = 0; m < 3; m++ ) - origin[m] = LittleFloat( pinbonevert->origin[m] ); - - // transform vertex - Quat_TransformVector( poutbonepose->quat, origin, t ); - VectorAdd( v, t, v ); - VectorMA( v, influence, poutbonepose->origin, v ); - } - - // test vertex against the bounding box - AddPointToBounds( v, pframe->mins, pframe->maxs ); - - pinskmvert = ( dskmvertex_t * )( ( byte * )pinbonevert ); - } - } - - } -#endif - - ClearBounds( mod->mins, mod->maxs ); - for( j = 0, pframe = poutmodel->frames; j < poutmodel->numframes; j++, pframe++ ) - { - VectorSubtract( pframe->mins, ebbox, pframe->mins ); - VectorAdd( pframe->maxs, ebbox, pframe->maxs ); - pframe->radius = RadiusFromBounds( pframe->mins, pframe->maxs ); - AddPointToBounds( pframe->mins, mod->mins, mod->maxs ); - AddPointToBounds( pframe->maxs, mod->mins, mod->maxs ); - } - mod->radius = RadiusFromBounds( mod->mins, mod->maxs ); - - Mem_Free( basepose ); - mod->type = mod_studio; - mod->touchFrame = tr.registration_sequence; // register model -} - -/* -================ -R_SkeletalGetNumBones -================ -*/ -int R_SkeletalGetNumBones( const ref_model_t *mod, int *numFrames ) -{ - mskmodel_t *skmodel; - - if( !mod || mod->type != mod_studio ) - return 0; - - skmodel = ( mskmodel_t * )mod->extradata; - if( numFrames ) - *numFrames = skmodel->numframes; - return skmodel->numbones; -} - -/* -================ -R_SkeletalGetBoneInfo -================ -*/ -int R_SkeletalGetBoneInfo( const ref_model_t *mod, int bonenum, char *name, size_t name_size, int *flags ) -{ - const mskbone_t *bone; - const mskmodel_t *skmodel; - - if( !mod || mod->type != mod_studio ) - return 0; - - skmodel = ( mskmodel_t * )mod->extradata; - if( (unsigned int)bonenum >= (int)skmodel->numbones ) - Host_Error("R_SkeletalGetBone: bad bone number" ); - - bone = &skmodel->bones[bonenum]; - if( name && name_size ) - com.strncpy( name, bone->name, name_size ); - if( flags ) - *flags = bone->flags; - return bone->parent; -} - -/* -================ -R_SkeletalGetBonePose -================ -*/ -void R_SkeletalGetBonePose( const ref_model_t *mod, int bonenum, int frame, bonepose_t *bonepose ) -{ - const mskmodel_t *skmodel; - - if( !mod || mod->type != mod_studio ) - return; - - skmodel = ( mskmodel_t * )mod->extradata; - if( bonenum < 0 || bonenum >= (int)skmodel->numbones ) - Host_Error("R_SkeletalGetBonePose: bad bone number\n" ); - if( frame < 0 || frame >= (int)skmodel->numframes ) - Host_Error("R_SkeletalGetBonePose: bad frame number\n" ); - - if( bonepose ) - *bonepose = skmodel->frames[frame].boneposes[bonenum]; -} - -/* -================ -R_SkeletalModelLOD -================ -*/ -static ref_model_t *R_SkeletalModelLOD( ref_entity_t *e ) -{ - int lod; - float dist; - - if( !e->model->numlods || ( e->flags & RF_FORCENOLOD ) ) - return e->model; - - dist = DistanceFast( e->origin, RI.viewOrigin ); - dist *= RI.lod_dist_scale_for_fov; - - lod = (int)( dist / e->model->radius ); - if( r_lodscale->integer ) - lod /= r_lodscale->integer; - lod += r_lodbias->integer; - - if( lod < 1 ) - return e->model; - return e->model->lods[min( lod, e->model->numlods )-1]; -} - -/* -================ -R_SkeletalModelLerpBBox -================ -*/ -static void R_SkeletalModelLerpBBox( ref_entity_t *e, ref_model_t *mod ) -{ - int i; - mskframe_t *pframe, *poldframe; - float *thismins, *oldmins, *thismaxs, *oldmaxs; - mskmodel_t *skmodel = ( mskmodel_t * )mod->extradata; - - if( !skmodel->nummeshes ) - { - skm_radius = 0; - ClearBounds( skm_mins, skm_maxs ); - return; - } - - if( ( e->frame >= (int)skmodel->numframes ) || ( e->frame < 0 ) ) - { - MsgDev( D_ERROR, "R_SkeletalModelBBox %s: no such frame %d\n", mod->name, e->frame ); - e->frame = 0; - } - if( ( e->oldframe >= (int)skmodel->numframes ) || ( e->oldframe < 0 ) ) - { - MsgDev( D_ERROR, "R_SkeletalModelBBox %s: no such oldframe %d\n", mod->name, e->oldframe ); - e->oldframe = 0; - } - - pframe = skmodel->frames + e->frame; - poldframe = skmodel->frames + e->oldframe; - - // compute axially aligned mins and maxs - if( pframe == poldframe ) - { - VectorCopy( pframe->mins, skm_mins ); - VectorCopy( pframe->maxs, skm_maxs ); - skm_radius = pframe->radius; - } - else - { - thismins = pframe->mins; - thismaxs = pframe->maxs; - - oldmins = poldframe->mins; - oldmaxs = poldframe->maxs; - - for( i = 0; i < 3; i++ ) - { - skm_mins[i] = min( thismins[i], oldmins[i] ); - skm_maxs[i] = max( thismaxs[i], oldmaxs[i] ); - } - skm_radius = RadiusFromBounds( thismins, thismaxs ); - } - - if( e->scale != 1.0f ) - { - VectorScale( skm_mins, e->scale, skm_mins ); - VectorScale( skm_maxs, e->scale, skm_maxs ); - skm_radius *= e->scale; - } -} - -//======================================================================= - -/* -================ -R_SkeletalTransformVerts -================ -*/ -static void R_SkeletalTransformVerts( int numverts, const unsigned int *bones, const float *influences, mat4x4_t *relbonepose, const vec_t *v, vec_t *ov ) -{ - int j; - float i; - const float *pose; - - for( ; numverts; numverts--, v += 4, ov += 4, bones += SKM_MAX_WEIGHTS, influences += SKM_MAX_WEIGHTS ) - { - i = *influences; - pose = relbonepose[*bones]; - - if( i == 1 ) - { // most common case - ov[0] = v[0] * pose[0] + v[1] * pose[4] + v[2] * pose[8] + pose[12]; - ov[1] = v[0] * pose[1] + v[1] * pose[5] + v[2] * pose[9] + pose[13]; - ov[2] = v[0] * pose[2] + v[1] * pose[6] + v[2] * pose[10] + pose[14]; - } - else - { - ov[0] = i * ( v[0] * pose[0] + v[1] * pose[4] + v[2] * pose[8] + pose[12] ); - ov[1] = i * ( v[0] * pose[1] + v[1] * pose[5] + v[2] * pose[9] + pose[13] ); - ov[2] = i * ( v[0] * pose[2] + v[1] * pose[6] + v[2] * pose[10] + pose[14] ); - - for( j = 1; j < SKM_MAX_WEIGHTS && influences[j]; j++ ) - { - i = influences[j]; - pose = relbonepose[bones[j]]; - - ov[0] += i * ( v[0] * pose[0] + v[1] * pose[4] + v[2] * pose[8] + pose[12] ); - ov[1] += i * ( v[0] * pose[1] + v[1] * pose[5] + v[2] * pose[9] + pose[13] ); - ov[2] += i * ( v[0] * pose[2] + v[1] * pose[6] + v[2] * pose[10] + pose[14] ); - } - } - } -} - -/* -================ -R_SkeletalTransformNormals -================ -*/ -static void R_SkeletalTransformNormals( int numverts, const unsigned int *bones, const float *influences, mat4x4_t *relbonepose, const vec_t *v, vec_t *ov ) -{ - int j; - float i; - const float *pose; - - for( ; numverts; numverts--, v += 4, ov += 4, bones += SKM_MAX_WEIGHTS, influences += SKM_MAX_WEIGHTS ) - { - i = *influences; - pose = relbonepose[*bones]; - - if( i == 1 ) - { // most common case - ov[0] = v[0] * pose[0] + v[1] * pose[4] + v[2] * pose[8]; - ov[1] = v[0] * pose[1] + v[1] * pose[5] + v[2] * pose[9]; - ov[2] = v[0] * pose[2] + v[1] * pose[6] + v[2] * pose[10]; - ov[3] = v[3]; - } - else - { - ov[0] = i * ( v[0] * pose[0] + v[1] * pose[4] + v[2] * pose[8] ); - ov[1] = i * ( v[0] * pose[1] + v[1] * pose[5] + v[2] * pose[9] ); - ov[2] = i * ( v[0] * pose[2] + v[1] * pose[6] + v[2] * pose[10] ); - ov[3] = v[3]; - - for( j = 1; j < SKM_MAX_WEIGHTS && influences[j]; j++ ) - { - i = influences[j]; - pose = relbonepose[bones[j]]; - - ov[0] += i * ( v[0] * pose[0] + v[1] * pose[4] + v[2] * pose[8] ); - ov[1] += i * ( v[0] * pose[1] + v[1] * pose[5] + v[2] * pose[9] ); - ov[2] += i * ( v[0] * pose[2] + v[1] * pose[6] + v[2] * pose[10] ); - } - } - } -} - -#if defined ( id386 ) && !defined ( __MACOSX__ ) - -#if defined ( __GNUC__ ) - -#define R_SkeletalTransformVerts_SSE R_SkeletalTransformVerts -#define R_SkeletalTransformNormals_SSE R_SkeletalTransformNormals - -#elif defined ( _WIN32 ) && ( _MSC_VER >= 1400 ) -#pragma optimize( "", off ) - -/* -================ -R_SkeletalTransformVerts_SSE -================ -*/ -static void R_SkeletalTransformVerts_SSE( int numverts, const unsigned int *bones, const float *influences, mat4x4_t *relbonepose, const vec_t *v, vec_t *ov ) -{ - __asm { - mov eax, numverts; - test eax, eax; - jz done; - - imul eax, 0x10; - mov numverts, eax; - xor eax, eax; - - mov ebx, v; - mov edi, ov; - mov ecx, relbonepose; - -sl1: - movaps xmm0, ds : dword ptr[ebx+eax]; - movaps xmm1, ds : dword ptr[ebx+eax]; - movaps xmm2, ds : dword ptr[ebx+eax]; - // prefetchnta [ebx+eax+0x10]; - - // loop init - xor edx, edx; - - //i = influence[0]; - mov esi, influences; - cmp ds : dword ptr[esi], 0x3F800000; // IEEE-format representation of 1.0f - - movss xmm7, ds : dword ptr[esi]; // xmm7 contains influence - shufps xmm7, xmm7, 0x00; - - shufps xmm0, xmm0, 0x00; - shufps xmm1, xmm1, 0x55; - shufps xmm2, xmm2, 0xAA; - - mov esi, bones; - mov esi, ds : dword ptr[esi]; - lea esi,[esi *8]; - lea esi,[esi *8+ecx]; - - jne slowCase; - - // fastCase: - // copying pose[0], pose[1], pose[2], pose[3] into xmm3 - movaps xmm3, ds : dword ptr[esi+0x00]; - // copying pose[4], pose[5], pose[6], pose[7] into xmm4 - movaps xmm4, ds : dword ptr[esi+0x10]; - // copying pose[8], pose[9], pose[10], pose[11] into xmm5 - movaps xmm5, ds : dword ptr[esi+0x20]; - // copying pose[12], pose[13], pose[14], pose[15] into xmm5 - movaps xmm6, ds : dword ptr[esi+0x30]; - - mulps xmm3, xmm0; // xmm3 * v[0] - mulps xmm4, xmm1; // xmm4 * v[1] - mulps xmm5, xmm2; // xmm5 * v[2] - - // adding each column vector into xmm6 - addps xmm6, xmm3; - addps xmm6, xmm4; - addps xmm6, xmm5; - jmp endOfLoop; - - // loop start -slowCase: - xorps xmm6, xmm6; - -continueSlowLoop: - // copying pose[0], pose[1], pose[2], pose[3] into xmm4 - movaps xmm3, ds : dword ptr[esi+0x00]; - // copying pose[4], pose[5], pose[6], pose[7] into xmm5 - movaps xmm4, ds : dword ptr[esi+0x10]; - // copying pose[8], pose[9], pose[10], pose[11] into xmm4 - movaps xmm5, ds : dword ptr[esi+0x20]; - - mulps xmm3, xmm0; // xmm3 * v[0] - mulps xmm4, xmm1; // xmm4 * v[1] - mulps xmm5, xmm2; // xmm5 * v[2] - - // adding each column vector into xmm5 - addps xmm5, ds : dword ptr[esi+0x30]; // adding pose[12], pose[13], pose[14], pose[15] into xmm5 - - mulps xmm3, xmm7; // i * v[0] * pos - mulps xmm4, xmm7; // i * v[1] * pos - mulps xmm5, xmm7; // i * v[2] * pos - - addps xmm6, xmm3; - addps xmm6, xmm4; - addps xmm6, xmm5; // adding the result to ov vector - - inc edx; - cmp edx, SKM_MAX_WEIGHTS; - - // loop condition - je endOfLoop; - - mov esi, influences; - cmp ds : dword ptr[esi+edx*0x04], 0; - je endOfLoop; - - //i = influence[j]; - movss xmm7, ds : dword ptr[esi+edx*0x04]; // xmm6 contains i - shufps xmm7, xmm7, 0x00; - - mov esi, bones; - mov esi, ds : dword ptr[esi+edx*0x04]; - lea esi,[esi *8]; - lea esi,[esi *8+ecx]; - - jmp continueSlowLoop; - -endOfLoop: - movaps ds : dword ptr[edi+eax], xmm6; - - add bones, SKM_MAX_WEIGHTS *0x04; - add influences, SKM_MAX_WEIGHTS *0x04; - - add eax, 0x10; - cmp eax, numverts; - - jl sl1; -done: - ; - } -} - -/* -================ -R_SkeletalTransformNormals_SSE -================ -*/ -static void R_SkeletalTransformNormals_SSE( int numverts, const unsigned int *bones, const float *influences, mat4x4_t *relbonepose, const vec_t *v, vec_t *ov ) -{ - __asm { - mov eax, numverts; - test eax, eax; - jz done; - - imul eax, 0x10; - mov numverts, eax; - xor eax, eax; - - mov ebx, v; - mov edi, ov; - mov ecx, relbonepose; - -sl1: - movaps xmm0, ds : dword ptr[ebx+eax]; - movaps xmm1, ds : dword ptr[ebx+eax]; - movaps xmm2, ds : dword ptr[ebx+eax]; - // prefetchnta [ebx+eax+0x10]; - - // loop init - xor edx, edx; - - //i = influence[0]; - mov esi, influences; - cmp ds : dword ptr[esi], 0x3F800000; // IEEE-format representation of 1.0f - - movss xmm7, ds : dword ptr[esi]; // xmm7 contains influence - shufps xmm7, xmm7, 0x00; - - shufps xmm0, xmm0, 0x00; - shufps xmm1, xmm1, 0x55; - shufps xmm2, xmm2, 0xAA; - - mov esi, bones; - mov esi, ds : dword ptr[esi]; - lea esi,[esi *8]; - lea esi,[esi *8+ecx]; - - jne slowCase; - - // fastCase: - xorps xmm6, xmm6; - - // copying pose[0], pose[1], pose[2], pose[3] into xmm3 - movaps xmm3, ds : dword ptr[esi+0x00]; - // copying pose[4], pose[5], pose[6], pose[7] into xmm4 - movaps xmm4, ds : dword ptr[esi+0x10]; - // copying pose[8], pose[9], pose[10], pose[11] into xmm5 - movaps xmm5, ds : dword ptr[esi+0x20]; - - mulps xmm3, xmm0; // xmm3 * v[0] - mulps xmm4, xmm1; // xmm4 * v[1] - mulps xmm5, xmm2; // xmm5 * v[2] - - // adding each column vector into xmm6 - addps xmm6, xmm3; - addps xmm6, xmm4; - addps xmm6, xmm5; - jmp endOfLoop; - - // loop start -slowCase: - xorps xmm6, xmm6; - -continueSlowLoop: - // copying pose[0], pose[1], pose[2], pose[3] into xmm4 - movaps xmm3, ds : dword ptr[esi+0x00]; - // copying pose[4], pose[5], pose[6], pose[7] into xmm5 - movaps xmm4, ds : dword ptr[esi+0x10]; - // copying pose[8], pose[9], pose[10], pose[11] into xmm4 - movaps xmm5, ds : dword ptr[esi+0x20]; - - mulps xmm3, xmm0; // xmm3 * v[0] - mulps xmm4, xmm1; // xmm4 * v[1] - mulps xmm5, xmm2; // xmm5 * v[2] - - mulps xmm3, xmm7; // i * v[0] * pos - mulps xmm4, xmm7; // i * v[1] * pos - mulps xmm5, xmm7; // i * v[2] * pos - - addps xmm6, xmm3; - addps xmm6, xmm4; - addps xmm6, xmm5; // adding the result to ov vector - - inc edx; - cmp edx, SKM_MAX_WEIGHTS; - - // loop condition - je endOfLoop; - - mov esi, influences; - cmp ds : dword ptr[esi+edx*0x04], 0; - je endOfLoop; - - //i = influence[j]; - movss xmm7, ds : dword ptr[esi+edx*0x04]; // xmm6 contains i - shufps xmm7, xmm7, 0x00; - - mov esi, bones; - mov esi, ds : dword ptr[esi+edx*0x04]; - lea esi,[esi *8]; - lea esi,[esi *8+ecx]; - - jmp continueSlowLoop; - -endOfLoop: - movaps ds : dword ptr[edi+eax], xmm6; - - add bones, SKM_MAX_WEIGHTS *0x04; - add influences, SKM_MAX_WEIGHTS *0x04; - - add eax, 0x10; - cmp eax, numverts; - - jl sl1; -done: - ; - } -} - -#pragma optimize( "", on ) -#else -#define R_SkeletalTransformVerts_SSE R_SkeletalTransformVerts -#define R_SkeletalTransformNormals_SSE R_SkeletalTransformNormals -#endif -#else -#define R_SkeletalTransformVerts_SSE R_SkeletalTransformVerts -#define R_SkeletalTransformNormals_SSE R_SkeletalTransformNormals -#endif - -//======================================================================= - -static ALIGN( 16 ) mat4x4_t relbonepose[SKM_MAX_BONES]; - -/* -================ -R_DrawBonesFrameLerp -================ -*/ -static void R_DrawBonesFrameLerp( const meshbuffer_t *mb, float backlerp ) -{ - unsigned int i, j, meshnum; - int features; - float frontlerp = 1.0 - backlerp, *pose; - mskmesh_t *mesh; - bonepose_t *bonepose, *oldbonepose, tempbonepose[SKM_MAX_BONES], *lerpedbonepose; - bonepose_t *bp, *oldbp, *out, tp; - ref_entity_t *e = RI.currententity; - ref_model_t *mod = Mod_ForHandle( mb->LODModelHandle ); - mskmodel_t *skmodel = ( mskmodel_t * )mod->extradata; - ref_shader_t *shader; - mskbone_t *bone; - vec4_t *xyzArray, *normalsArray, *sVectorsArray; - - meshnum = -( mb->infokey + 1 ); - if( meshnum >= skmodel->nummeshes ) - return; - mesh = skmodel->meshes + meshnum; - - xyzArray = inVertsArray; - normalsArray = inNormalsArray; - sVectorsArray = inSVectorsArray; - - MB_NUM2SHADER( mb->shaderkey, shader ); - - features = MF_NONBATCHED | shader->features; - if( RI.params & RP_SHADOWMAPVIEW ) - { - features &= ~( MF_COLORS|MF_SVECTORS|MF_ENABLENORMALS ); - if( !( shader->features & MF_DEFORMVS ) ) - features &= ~MF_NORMALS; - } - else - { - if( ( features & MF_SVECTORS ) || r_shownormals->integer ) - features |= MF_NORMALS; - if( e->outlineHeight ) - features |= MF_NORMALS|(GL_Support( R_SHADER_GLSL100_EXT ) ? MF_ENABLENORMALS : 0); - } - - // not sure if it's really needed - if( e->boneposes == skmodel->frames[0].boneposes ) - { - e->boneposes = NULL; - e->frame = e->oldframe = 0; - } - - // choose boneposes for lerping - if( e->boneposes ) - { - bp = e->boneposes; - if( e->oldboneposes ) - oldbp = e->oldboneposes; - else - oldbp = bp; - } - else - { - if( ( e->frame >= (int)skmodel->numframes ) || ( e->frame < 0 ) ) - { - MsgDev( D_ERROR, "R_DrawBonesFrameLerp %s: no such frame %d\n", mod->name, e->frame ); - e->frame = 0; - } - if( ( e->oldframe >= (int)skmodel->numframes ) || ( e->oldframe < 0 ) ) - { - MsgDev( D_ERROR, "R_DrawBonesFrameLerp %s: no such oldframe %d\n", mod->name, e->oldframe ); - e->oldframe = 0; - } - - bp = skmodel->frames[e->frame].boneposes; - oldbp = skmodel->frames[e->oldframe].boneposes; - } - - lerpedbonepose = tempbonepose; - if( bp == oldbp || frontlerp == 1 ) - { - if( e->boneposes ) - { // assume that parent transforms have already been applied - lerpedbonepose = bp; - } - else - { // transform - if( !e->frame ) - { // fastpath: render frame 0 as is - xyzArray = mesh->xyzArray; - normalsArray = mesh->normalsArray; - sVectorsArray = mesh->sVectorsArray; - - goto pushmesh; - } - - for( i = 0; i < mesh->numreferences; i++ ) - { - j = mesh->references[i]; - out = lerpedbonepose + j; - bonepose = bp + j; - bone = skmodel->bones + j; - - if( bone->parent >= 0 ) - { - Quat_ConcatTransforms( lerpedbonepose[bone->parent].quat, lerpedbonepose[bone->parent].origin, - bonepose->quat, bonepose->origin, out->quat, out->origin ); - } - else - { - Quat_Copy( bonepose->quat, out->quat ); - VectorCopy( bonepose->origin, out->origin ); - } - } - } - } - else - { - if( e->boneposes ) - { // lerp, assume that parent transforms have already been applied - for( i = 0, out = lerpedbonepose, bonepose = bp, oldbonepose = oldbp, bone = skmodel->bones; i < skmodel->numbones; i++, out++, bonepose++, oldbonepose++, bone++ ) - { - Quat_Lerp( oldbonepose->quat, bonepose->quat, frontlerp, out->quat ); - out->origin[0] = oldbonepose->origin[0] + ( bonepose->origin[0] - oldbonepose->origin[0] ) * frontlerp; - out->origin[1] = oldbonepose->origin[1] + ( bonepose->origin[1] - oldbonepose->origin[1] ) * frontlerp; - out->origin[2] = oldbonepose->origin[2] + ( bonepose->origin[2] - oldbonepose->origin[2] ) * frontlerp; - } - } - else - { // lerp and transform - for( i = 0; i < mesh->numreferences; i++ ) - { - j = mesh->references[i]; - out = lerpedbonepose + j; - bonepose = bp + j; - oldbonepose = oldbp + j; - bone = skmodel->bones + j; - - Quat_Lerp( oldbonepose->quat, bonepose->quat, frontlerp, tp.quat ); - tp.origin[0] = oldbonepose->origin[0] + ( bonepose->origin[0] - oldbonepose->origin[0] ) * frontlerp; - tp.origin[1] = oldbonepose->origin[1] + ( bonepose->origin[1] - oldbonepose->origin[1] ) * frontlerp; - tp.origin[2] = oldbonepose->origin[2] + ( bonepose->origin[2] - oldbonepose->origin[2] ) * frontlerp; - - if( bone->parent >= 0 ) - { - Quat_ConcatTransforms( tempbonepose[bone->parent].quat, tempbonepose[bone->parent].origin, - tp.quat, tp.origin, out->quat, out->origin ); - } - else - { - Quat_Copy( tp.quat, out->quat ); - VectorCopy( tp.origin, out->origin ); - } - } - } - } - - for( i = 0; i < mesh->numreferences; i++ ) - { - j = mesh->references[i]; - pose = relbonepose[j]; - - Quat_ConcatTransforms( lerpedbonepose[j].quat, lerpedbonepose[j].origin, - skmodel->invbaseposes[j].quat, skmodel->invbaseposes[j].origin, tp.quat, &pose[12] ); - pose[15] = 1.0f; - - // make origin the forth column instead of row so that - // things can be optimized more easily - Matrix_FromQuaternion( tp.quat, pose ); - } - - if( 0 ) - { - R_SkeletalTransformVerts_SSE( mesh->numverts, mesh->bones, mesh->influences, relbonepose, - ( vec_t * )mesh->xyzArray[0], ( vec_t * )inVertsArray ); - - if( features & MF_NORMALS ) - R_SkeletalTransformNormals_SSE( mesh->numverts, mesh->bones, mesh->influences, relbonepose, - ( vec_t * )mesh->normalsArray[0], ( vec_t * )inNormalsArray ); - - if( features & MF_SVECTORS ) - R_SkeletalTransformNormals_SSE( mesh->numverts, mesh->bones, mesh->influences, relbonepose, - ( vec_t * )mesh->sVectorsArray[0], ( vec_t * )inSVectorsArray ); - } - else - { - R_SkeletalTransformVerts( mesh->numverts, mesh->bones, mesh->influences, relbonepose, - ( vec_t * )mesh->xyzArray[0], ( vec_t * )inVertsArray ); - - if( features & MF_NORMALS ) - R_SkeletalTransformNormals( mesh->numverts, mesh->bones, mesh->influences, relbonepose, - ( vec_t * )mesh->normalsArray[0], ( vec_t * )inNormalsArray ); - - if( features & MF_SVECTORS ) - R_SkeletalTransformNormals( mesh->numverts, mesh->bones, mesh->influences, relbonepose, - ( vec_t * )mesh->sVectorsArray[0], ( vec_t * )inSVectorsArray ); - } - -pushmesh: - skm_mesh.elems = mesh->elems; - skm_mesh.numElems = mesh->numtris * 3; - skm_mesh.numVertexes = mesh->numverts; - skm_mesh.xyzArray = xyzArray; - skm_mesh.stArray = mesh->stArray; - skm_mesh.normalsArray = normalsArray; - skm_mesh.sVectorsArray = sVectorsArray; - - R_RotateForEntity( e ); - - R_PushMesh( &skm_mesh, features ); - R_RenderMeshBuffer( mb ); -} - -/* -================= -R_DrawSkeletalModel -================= -*/ -void R_DrawSkeletalModel( const meshbuffer_t *mb ) -{ - ref_entity_t *e = RI.currententity; - - if( OCCLUSION_QUERIES_ENABLED( RI ) && OCCLUSION_TEST_ENTITY( e ) ) - { - ref_shader_t *shader; - - MB_NUM2SHADER( mb->shaderkey, shader ); - if( !R_GetOcclusionQueryResultBool( shader->type == SHADER_PLANAR_SHADOW ? OQ_PLANARSHADOW : OQ_ENTITY, - e - r_entities, true ) ) - return; - } - - // hack the depth range to prevent view model from poking into walls - if( e->flags & RF_WEAPONMODEL ) - pglDepthRange( gldepthmin, gldepthmin + 0.3 * ( gldepthmax - gldepthmin ) ); - - // backface culling for left-handed weapons - if( e->flags & RF_CULLHACK ) - GL_FrontFace( !glState.frontFace ); - - if( !r_lerpmodels->integer ) - e->backlerp = 0; - - R_DrawBonesFrameLerp( mb, e->backlerp ); - - if( e->flags & RF_WEAPONMODEL ) - pglDepthRange( gldepthmin, gldepthmax ); - - if( e->flags & RF_CULLHACK ) - GL_FrontFace( !glState.frontFace ); -} - -/* -================= -R_SkeletalModelBBox -================= -*/ -float R_SkeletalModelBBox( ref_entity_t *e, vec3_t mins, vec3_t maxs ) -{ - ref_model_t *mod; - - mod = R_SkeletalModelLOD( e ); - if( !mod ) - return 0; - - R_SkeletalModelLerpBBox( e, mod ); - - VectorCopy( skm_mins, mins ); - VectorCopy( skm_maxs, maxs ); - return skm_radius; -} - -/* -================= -R_CullSkeletalModel -================= -*/ -bool R_CullSkeletalModel( ref_entity_t *e ) -{ - int i, clipped; - bool frustum, query; - unsigned int modhandle; - ref_model_t *mod; - ref_shader_t *shader; - mskmesh_t *mesh; - mskmodel_t *skmodel; - meshbuffer_t *mb; - - mod = R_SkeletalModelLOD( e ); - if( !( skmodel = ( ( mskmodel_t * )mod->extradata ) ) || !skmodel->nummeshes ) - return true; - - R_SkeletalModelLerpBBox( e, mod ); - modhandle = Mod_Handle( mod ); - - clipped = R_CullModel( e, skm_mins, skm_maxs, skm_radius ); - frustum = clipped & 1; - if( clipped & 2 ) - return true; - - query = OCCLUSION_QUERIES_ENABLED( RI ) && OCCLUSION_TEST_ENTITY( e ) ? true : false; - if( !frustum && query ) - { - R_IssueOcclusionQuery( R_GetOcclusionQueryNum( OQ_ENTITY, e - r_entities ), e, skm_mins, skm_maxs ); - } - - if( RI.refdef.rdflags & RDF_NOWORLDMODEL - || ( r_shadows->integer != SHADOW_PLANAR && !( r_shadows->integer == SHADOW_MAPPING && ( e->flags & RF_PLANARSHADOW ) ) ) - || R_CullPlanarShadow( e, skm_mins, skm_maxs, query ) ) - return frustum; // entity is not in PVS or shadow is culled away by frustum culling - - for( i = 0, mesh = skmodel->meshes; i < (int)skmodel->nummeshes; i++, mesh++ ) - { - shader = NULL; - if( e->customSkin ) - shader = R_FindShaderForSkinFile( e->customSkin, mesh->name ); - else if( e->customShader ) - shader = e->customShader; - else if( mesh->skin.shader ) - shader = mesh->skin.shader; - - if( shader && ( shader->sort <= SORT_ALPHATEST ) ) - { - mb = R_AddMeshToList( MB_MODEL, NULL, R_PlanarShadowShader(), -( i+1 ) ); - if( mb ) - mb->LODModelHandle = modhandle; - } - } - - return frustum; -} - -/* -================= -R_AddSkeletalModelToList -================= -*/ -void R_AddSkeletalModelToList( ref_entity_t *e ) -{ - int i; - unsigned int modhandle, entnum = e - r_entities; - mfog_t *fog = NULL; - ref_model_t *mod; - ref_shader_t *shader; - mskmesh_t *mesh; - mskmodel_t *skmodel; - - mod = R_SkeletalModelLOD( e ); - skmodel = ( mskmodel_t * )mod->extradata; - modhandle = Mod_Handle( mod ); - - if( RI.params & RP_SHADOWMAPVIEW ) - { - if( r_entShadowBits[entnum] & RI.shadowGroup->bit ) - { - if( !r_shadows_self_shadow->integer ) - r_entShadowBits[entnum] &= ~RI.shadowGroup->bit; - if( e->flags & RF_WEAPONMODEL ) - return; - } - else - { - R_SkeletalModelLerpBBox( e, mod ); - if( !R_CullModel( e, skm_mins, skm_maxs, skm_radius ) ) - r_entShadowBits[entnum] |= RI.shadowGroup->bit; - return; // mark as shadowed, proceed with caster otherwise - } - } - else - { - fog = R_FogForSphere( e->origin, skm_radius ); -#if 0 - if( !( e->flags & RF_WEAPONMODEL ) && fog ) - { - R_SkeletalModelLerpBBox( e, mod ); - if( R_CompletelyFogged( fog, e->origin, skm_radius ) ) - return; - } -#endif - } - - for( i = 0, mesh = skmodel->meshes; i < (int)skmodel->nummeshes; i++, mesh++ ) - { - shader = NULL; - if( e->customSkin ) - shader = R_FindShaderForSkinFile( e->customSkin, mesh->name ); - else if( e->customShader ) - shader = e->customShader; - else - shader = mesh->skin.shader; - - if( shader ) - R_AddModelMeshToList( modhandle, fog, shader, i ); - } -} diff --git a/render/render.plg b/render/render.plg index 66e34829..ed77a3cd 100644 --- a/render/render.plg +++ b/render/render.plg @@ -6,13 +6,13 @@ --------------------Configuration: render - Win32 Debug--------------------

Command Lines

-Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSPD5.tmp" with contents +Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP47C.tmp" with contents [ /nologo /MDd /W3 /Gm /Gi /GX /ZI /Od /I "../public" /I "../common" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"..\temp\render\!debug/" /Fo"..\temp\render\!debug/" /Fd"..\temp\render\!debug/" /FD /c -"D:\Xash3D\src_main\render\r_image.c" +"D:\Xash3D\src_main\render\r_backend.c" ] -Creating command line "cl.exe @C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSPD5.tmp" -Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSPD6.tmp" with contents +Creating command line "cl.exe @C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP47C.tmp" +Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP47D.tmp" with contents [ msvcrtd.lib user32.lib gdi32.lib /nologo /subsystem:windows /dll /incremental:yes /pdb:"..\temp\render\!debug/render.pdb" /debug /machine:I386 /nodefaultlib:"msvcrt.lib" /out:"..\temp\render\!debug/render.dll" /implib:"..\temp\render\!debug/render.lib" /pdbtype:sept "\Xash3D\src_main\temp\render\!debug\cin.obj" @@ -38,16 +38,17 @@ msvcrtd.lib user32.lib gdi32.lib /nologo /subsystem:windows /dll /incremental:ye "\Xash3D\src_main\temp\render\!debug\r_sky.obj" "\Xash3D\src_main\temp\render\!debug\r_surf.obj" ] -Creating command line "link.exe @C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSPD6.tmp" -Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSPD7.bat" with contents +Creating command line "link.exe @C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP47D.tmp" +Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP47E.bat" with contents [ @echo off copy \Xash3D\src_main\temp\render\!debug\render.dll "D:\Xash3D\bin\render.dll" ] -Creating command line "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSPD7.bat" +Creating command line "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP47E.bat" Compiling... -r_image.c +r_backend.c Linking... + Creating library ..\temp\render\!debug/render.lib and object ..\temp\render\!debug/render.exp

Output Window

Performing Custom Build Step on \Xash3D\src_main\temp\render\!debug\render.dll Скопировано файлов: 1. diff --git a/render/warpsin.h b/render/warpsin.h new file mode 100644 index 00000000..e140acf9 --- /dev/null +++ b/render/warpsin.h @@ -0,0 +1,53 @@ +/* +Copyright (C) 1997-2001 Id Software, Inc. + +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. + +*/ + + +0.000000, 0.098165, 0.196270, 0.294259, 0.392069, 0.489643, 0.586920, 0.683850, +0.780360, 0.876405, 0.971920, 1.066850, 1.161140, 1.254725, 1.347560, 1.439580, +1.530735, 1.620965, 1.710220, 1.798445, 1.885585, 1.971595, 2.056410, 2.139990, +2.222280, 2.303235, 2.382795, 2.460925, 2.537575, 2.612690, 2.686235, 2.758160, +2.828425, 2.896990, 2.963805, 3.028835, 3.092040, 3.153385, 3.212830, 3.270340, +3.325880, 3.379415, 3.430915, 3.480350, 3.527685, 3.572895, 3.615955, 3.656840, +3.695520, 3.731970, 3.766175, 3.798115, 3.827760, 3.855105, 3.880125, 3.902810, +3.923140, 3.941110, 3.956705, 3.969920, 3.980740, 3.989160, 3.995180, 3.998795, +4.000000, 3.998795, 3.995180, 3.989160, 3.980740, 3.969920, 3.956705, 3.941110, +3.923140, 3.902810, 3.880125, 3.855105, 3.827760, 3.798115, 3.766175, 3.731970, +3.695520, 3.656840, 3.615955, 3.572895, 3.527685, 3.480350, 3.430915, 3.379415, +3.325880, 3.270340, 3.212830, 3.153385, 3.092040, 3.028835, 2.963805, 2.896990, +2.828425, 2.758160, 2.686235, 2.612690, 2.537575, 2.460925, 2.382795, 2.303235, +2.222280, 2.139990, 2.056410, 1.971595, 1.885585, 1.798445, 1.710220, 1.620965, +1.530735, 1.439580, 1.347560, 1.254725, 1.161140, 1.066850, 0.971920, 0.876405, +0.780360, 0.683850, 0.586920, 0.489643, 0.392069, 0.294259, 0.196270, 0.098165, +0.000000, -0.098165, -0.196270, -0.294259, -0.392069, -0.489643, -0.586920, -0.683850, +-0.780360, -0.876405, -0.971920, -1.066850, -1.161140, -1.254725, -1.347560, -1.439580, +-1.530735, -1.620965, -1.710220, -1.798445, -1.885585, -1.971595, -2.056410, -2.139990, +-2.222280, -2.303235, -2.382795, -2.460925, -2.537575, -2.612690, -2.686235, -2.758160, +-2.828425, -2.896990, -2.963805, -3.028835, -3.092040, -3.153385, -3.212830, -3.270340, +-3.325880, -3.379415, -3.430915, -3.480350, -3.527685, -3.572895, -3.615955, -3.656840, +-3.695520, -3.731970, -3.766175, -3.798115, -3.827760, -3.855105, -3.880125, -3.902810, +-3.923140, -3.941110, -3.956705, -3.969920, -3.980740, -3.989160, -3.995180, -3.998795, +-4.000000, -3.998795, -3.995180, -3.989160, -3.980740, -3.969920, -3.956705, -3.941110, +-3.923140, -3.902810, -3.880125, -3.855105, -3.827760, -3.798115, -3.766175, -3.731970, +-3.695520, -3.656840, -3.615955, -3.572895, -3.527685, -3.480350, -3.430915, -3.379415, +-3.325880, -3.270340, -3.212830, -3.153385, -3.092040, -3.028835, -2.963805, -2.896990, +-2.828425, -2.758160, -2.686235, -2.612690, -2.537575, -2.460925, -2.382795, -2.303235, +-2.222280, -2.139990, -2.056410, -1.971595, -1.885585, -1.798445, -1.710220, -1.620965, +-1.530735, -1.439580, -1.347560, -1.254725, -1.161140, -1.066850, -0.971920, -0.876405, +-0.780360, -0.683850, -0.586920, -0.489643, -0.392069, -0.294259, -0.196270, -0.098165, diff --git a/server/server.plg b/server/server.plg deleted file mode 100644 index 2aaf2920..00000000 --- a/server/server.plg +++ /dev/null @@ -1,100 +0,0 @@ - - -
-

Build Log

-

---------------------Configuration: server - Win32 Debug-------------------- -

-

Command Lines

-Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSPBB.tmp" with contents -[ -/nologo /MDd /W3 /Gm /Gi /GX /ZI /Od /I "./" /I "ents" /I "game" /I "global" /I "monsters" /I "../common" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"..\temp\server\!debug/" /Fo"..\temp\server\!debug/" /Fd"..\temp\server\!debug/" /FD /c -"D:\Xash3D\src_main\server\global\client.cpp" -] -Creating command line "cl.exe @C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSPBB.tmp" -Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSPBC.tmp" with contents -[ -msvcrtd.lib /nologo /subsystem:windows /dll /incremental:yes /pdb:"..\temp\server\!debug/server.pdb" /debug /machine:I386 /nodefaultlib:"libc.lib" /def:".\server.def" /out:"..\temp\server\!debug/server.dll" /implib:"..\temp\server\!debug/server.lib" /pdbtype:sept -"\Xash3D\src_main\temp\server\!debug\ai_sound.obj" -"\Xash3D\src_main\temp\server\!debug\animating.obj" -"\Xash3D\src_main\temp\server\!debug\animation.obj" -"\Xash3D\src_main\temp\server\!debug\apache.obj" -"\Xash3D\src_main\temp\server\!debug\barnacle.obj" -"\Xash3D\src_main\temp\server\!debug\barney.obj" -"\Xash3D\src_main\temp\server\!debug\basebrush.obj" -"\Xash3D\src_main\temp\server\!debug\baseentity.obj" -"\Xash3D\src_main\temp\server\!debug\basefunc.obj" -"\Xash3D\src_main\temp\server\!debug\basefx.obj" -"\Xash3D\src_main\temp\server\!debug\baseinfo.obj" -"\Xash3D\src_main\temp\server\!debug\baseitem.obj" -"\Xash3D\src_main\temp\server\!debug\baselogic.obj" -"\Xash3D\src_main\temp\server\!debug\basemonster.obj" -"\Xash3D\src_main\temp\server\!debug\basemover.obj" -"\Xash3D\src_main\temp\server\!debug\baseother.obj" -"\Xash3D\src_main\temp\server\!debug\basepath.obj" -"\Xash3D\src_main\temp\server\!debug\basephys.obj" -"\Xash3D\src_main\temp\server\!debug\baserockets.obj" -"\Xash3D\src_main\temp\server\!debug\basetank.obj" -"\Xash3D\src_main\temp\server\!debug\basetrigger.obj" -"\Xash3D\src_main\temp\server\!debug\baseutil.obj" -"\Xash3D\src_main\temp\server\!debug\baseweapon.obj" -"\Xash3D\src_main\temp\server\!debug\baseworld.obj" -"\Xash3D\src_main\temp\server\!debug\client.obj" -"\Xash3D\src_main\temp\server\!debug\combat.obj" -"\Xash3D\src_main\temp\server\!debug\decals.obj" -"\Xash3D\src_main\temp\server\!debug\defaultai.obj" -"\Xash3D\src_main\temp\server\!debug\dll_int.obj" -"\Xash3D\src_main\temp\server\!debug\flyingmonster.obj" -"\Xash3D\src_main\temp\server\!debug\game.obj" -"\Xash3D\src_main\temp\server\!debug\gamerules.obj" -"\Xash3D\src_main\temp\server\!debug\generic.obj" -"\Xash3D\src_main\temp\server\!debug\globals.obj" -"\Xash3D\src_main\temp\server\!debug\gman.obj" -"\Xash3D\src_main\temp\server\!debug\hassassin.obj" -"\Xash3D\src_main\temp\server\!debug\headcrab.obj" -"\Xash3D\src_main\temp\server\!debug\hgrunt.obj" -"\Xash3D\src_main\temp\server\!debug\leech.obj" -"\Xash3D\src_main\temp\server\!debug\legacy.obj" -"\Xash3D\src_main\temp\server\!debug\lights.obj" -"\Xash3D\src_main\temp\server\!debug\multiplay_gamerules.obj" -"\Xash3D\src_main\temp\server\!debug\nodes.obj" -"\Xash3D\src_main\temp\server\!debug\osprey.obj" -"\Xash3D\src_main\temp\server\!debug\parent.obj" -"\Xash3D\src_main\temp\server\!debug\player.obj" -"\Xash3D\src_main\temp\server\!debug\rat.obj" -"\Xash3D\src_main\temp\server\!debug\roach.obj" -"\Xash3D\src_main\temp\server\!debug\saverestore.obj" -"\Xash3D\src_main\temp\server\!debug\scientist.obj" -"\Xash3D\src_main\temp\server\!debug\scripted.obj" -"\Xash3D\src_main\temp\server\!debug\sfx.obj" -"\Xash3D\src_main\temp\server\!debug\singleplay_gamerules.obj" -"\Xash3D\src_main\temp\server\!debug\sound.obj" -"\Xash3D\src_main\temp\server\!debug\squadmonster.obj" -"\Xash3D\src_main\temp\server\!debug\talkmonster.obj" -"\Xash3D\src_main\temp\server\!debug\teamplay_gamerules.obj" -"\Xash3D\src_main\temp\server\!debug\turret.obj" -"\Xash3D\src_main\temp\server\!debug\utils.obj" -"\Xash3D\src_main\temp\server\!debug\weapon_generic.obj" -"\Xash3D\src_main\temp\server\!debug\zombie.obj" -] -Creating command line "link.exe @C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSPBC.tmp" -Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSPBD.bat" with contents -[ -@echo off -copy \Xash3D\src_main\temp\server\!debug\server.dll "D:\Xash3D\bin\server.dll" -] -Creating command line "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSPBD.bat" -Compiling... -client.cpp -Linking... -

Output Window

-Performing Custom Build Step on \Xash3D\src_main\temp\server\!debug\server.dll -Скопировано файлов: 1. - - - -

Results

-server.dll - 0 error(s), 0 warning(s) -
- - diff --git a/todo.log b/todo.log index 0a122e8d..9529e899 100644 --- a/todo.log +++ b/todo.log @@ -111,9 +111,10 @@ Beta 13.12.08 80. implement $rgb, $alpha OK 89. get rid of R_Upload32 OK 90. get rid of Com_ParseExt OK -91. Xash backend extensions +91. implement rendermodes 92. implement VBO OK 93. implement sky rotate 94. make default sky shader, R_SetupSky -95. support for custom tables (external) -96. implement sprite format +95. support for custom tables (external) OK +96. implement sprite format +97. fix fog color on q3tourney5