diff --git a/code/client/cl_main.c b/code/client/cl_main.c index c03ba61e..143e1201 100644 --- a/code/client/cl_main.c +++ b/code/client/cl_main.c @@ -2429,6 +2429,9 @@ void CL_InitServerInfo( serverInfo_t *server, netadr_t *address ) { server->game[0] = '\0'; server->gameType = 0; server->netType = 0; + server->punkbuster = 0; + server->g_humanplayers = 0; + server->g_needpass = 0; } #define MAX_SERVERSPERPACKET 256 @@ -2937,13 +2940,13 @@ void CL_Frame ( int msec ) { if ( CL_VideoRecording( ) && cl_aviFrameRate->integer && msec) { // save the current screen if ( clc.state == CA_ACTIVE || cl_forceavidemo->integer) { + float fps = MIN(cl_aviFrameRate->value * com_timescale->value, 1000.0f); + float frameDuration = MAX(1000.0f / fps, 1.0f) + clc.aviVideoFrameRemainder; + CL_TakeVideoFrame( ); - // fixed time for next frame' - msec = (int)ceil( (1000.0f / cl_aviFrameRate->value) * com_timescale->value ); - if (msec == 0) { - msec = 1; - } + msec = (int)frameDuration; + clc.aviVideoFrameRemainder = frameDuration - msec; } } @@ -3836,21 +3839,8 @@ void CL_ServerInfoPacket( netadr_t from, msg_t *msg ) { // add this to the list cls.numlocalservers = i+1; - cls.localServers[i].adr = from; - cls.localServers[i].clients = 0; - cls.localServers[i].hostName[0] = '\0'; - cls.localServers[i].mapName[0] = '\0'; - cls.localServers[i].maxClients = 0; - cls.localServers[i].maxPing = 0; - cls.localServers[i].minPing = 0; - cls.localServers[i].ping = -1; - cls.localServers[i].game[0] = '\0'; - cls.localServers[i].gameType = 0; - cls.localServers[i].netType = from.type; - cls.localServers[i].punkbuster = 0; - cls.localServers[i].g_humanplayers = 0; - cls.localServers[i].g_needpass = 0; - + CL_InitServerInfo( &cls.localServers[i], &from ); + Q_strncpyz( info, MSG_ReadString( msg ), MAX_INFO_STRING ); if (strlen(info)) { if (info[strlen(info)-1] != '\n') { diff --git a/code/client/client.h b/code/client/client.h index a6155555..a9b3e51e 100644 --- a/code/client/client.h +++ b/code/client/client.h @@ -233,6 +233,9 @@ typedef struct { int timeDemoMaxDuration; // maximum frame duration unsigned char timeDemoDurations[ MAX_TIMEDEMO_DURATIONS ]; // log of frame durations + float aviVideoFrameRemainder; + float aviSoundFrameRemainder; + #ifdef USE_VOIP qboolean voipEnabled; qboolean speexInitialized; diff --git a/code/client/snd_dma.c b/code/client/snd_dma.c index d4ba8906..1e78f350 100644 --- a/code/client/snd_dma.c +++ b/code/client/snd_dma.c @@ -271,6 +271,11 @@ static sfx_t *S_FindName( const char *name ) { return NULL; } + if (name[0] == '*') { + Com_Printf( S_COLOR_YELLOW "WARNING: Tried to load player sound directly: %s\n", name ); + return NULL; + } + hash = S_HashSFXName(name); sfx = sfxHash[hash]; @@ -1237,7 +1242,13 @@ void S_GetSoundtime(void) if( CL_VideoRecording( ) ) { - s_soundtime += (int)ceil( dma.speed / cl_aviFrameRate->value ); + float fps = MIN(cl_aviFrameRate->value, 1000.0f); + float frameDuration = MAX(dma.speed / fps, 1.0f) + clc.aviSoundFrameRemainder; + + int msec = (int)frameDuration; + s_soundtime += msec; + clc.aviSoundFrameRemainder = frameDuration - msec; + return; } diff --git a/code/client/snd_mem.c b/code/client/snd_mem.c index d42084b7..1031f34c 100644 --- a/code/client/snd_mem.c +++ b/code/client/snd_mem.c @@ -208,11 +208,6 @@ qboolean S_LoadSound( sfx_t *sfx ) snd_info_t info; // int size; - // player specific sounds are never directly loaded - if ( sfx->soundName[0] == '*') { - return qfalse; - } - // load it in data = S_CodecLoad(sfx->soundName, &info); if(!data) diff --git a/code/client/snd_openal.c b/code/client/snd_openal.c index 83eb541e..649c748e 100644 --- a/code/client/snd_openal.c +++ b/code/client/snd_openal.c @@ -208,6 +208,11 @@ static sfxHandle_t S_AL_BufferFind(const char *filename) return 0; } + if ( filename[0] == '*' ) { + Com_Printf( S_COLOR_YELLOW "WARNING: Tried to load player sound directly: %s\n", filename ); + return 0; + } + for(i = 0; i < numSfx; i++) { if(!Q_stricmp(knownSfx[i].filename, filename)) @@ -325,10 +330,6 @@ static void S_AL_BufferLoad(sfxHandle_t sfx, qboolean cache) if(curSfx->filename[0] == '\0') return; - // Player SFX - if(curSfx->filename[0] == '*') - return; - // Already done? if((curSfx->inMemory) || (curSfx->isDefault) || (!cache && curSfx->isDefaultChecked)) return; diff --git a/code/renderergl1/tr_init.c b/code/renderergl1/tr_init.c index 14d7fbaa..98cbfc65 100644 --- a/code/renderergl1/tr_init.c +++ b/code/renderergl1/tr_init.c @@ -874,16 +874,6 @@ void GL_SetDefaultState( void ) qglEnable( GL_SCISSOR_TEST ); qglDisable( GL_CULL_FACE ); qglDisable( GL_BLEND ); - - qglColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE ); - qglClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); - qglClearDepth( 1.0 ); - - qglDrawBuffer( GL_FRONT ); - qglClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_ACCUM_BUFFER_BIT|GL_STENCIL_BUFFER_BIT ); - - qglDrawBuffer( GL_BACK ); - qglClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_ACCUM_BUFFER_BIT|GL_STENCIL_BUFFER_BIT ); } /* diff --git a/code/renderergl1/tr_local.h b/code/renderergl1/tr_local.h index 9e8770a6..3f5a975a 100644 --- a/code/renderergl1/tr_local.h +++ b/code/renderergl1/tr_local.h @@ -41,10 +41,6 @@ typedef unsigned int glIndex_t; #define SHADERNUM_BITS 14 #define MAX_SHADERS (1<ofs_vertexarrays, header->num_vertexarrays, @@ -264,11 +274,20 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na } break; case IQM_BLENDINDEXES: + if( (vertexarray->format != IQM_INT && + vertexarray->format != IQM_UBYTE) || + vertexarray->size != 4 ) { + return qfalse; + } + blendIndexesType = vertexarray->format; + break; case IQM_BLENDWEIGHTS: - if( vertexarray->format != IQM_UBYTE || + if( (vertexarray->format != IQM_FLOAT && + vertexarray->format != IQM_UBYTE) || vertexarray->size != 4 ) { return qfalse; } + blendWeightsType = vertexarray->format; break; case IQM_COLOR: if( vertexarray->format != IQM_UBYTE || @@ -343,7 +362,9 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na } } - if( header->num_poses != header->num_joints ) { + if( header->num_poses != header->num_joints && header->num_poses != 0 ) { + ri.Printf(PRINT_WARNING, "R_LoadIQM: %s has %d poses and %d joints, must have the same number or 0 poses\n", + mod_name, header->num_poses, header->num_joints ); return qfalse; } @@ -379,7 +400,10 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na joint_names += strlen( (char *)header + header->ofs_text + joint->name ) + 1; } + } + if ( header->num_poses ) + { // check and swap poses if( IQM_CheckRange( header, header->ofs_poses, header->num_poses, sizeof(iqmPose_t) ) ) { @@ -438,7 +462,7 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na size = sizeof(iqmData_t); size += header->num_meshes * sizeof( srfIQModel_t ); size += header->num_joints * 12 * sizeof( float ); // joint mats - size += header->num_joints * header->num_frames * 12 * sizeof( float ); // pose mats + size += header->num_poses * header->num_frames * 12 * sizeof( float ); // pose mats if(header->ofs_bounds) size += header->num_frames * 6 * sizeof(float); // model bounds size += header->num_vertexes * 3 * sizeof(float); // positions @@ -446,12 +470,18 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na size += header->num_vertexes * 3 * sizeof(float); // normals size += header->num_vertexes * 4 * sizeof(float); // tangents size += header->num_vertexes * 4 * sizeof(byte); // blendIndexes - size += header->num_vertexes * 4 * sizeof(byte); // blendWeights size += header->num_vertexes * 4 * sizeof(byte); // colors size += header->num_joints * sizeof(int); // parents size += header->num_triangles * 3 * sizeof(int); // triangles size += joint_names; // joint names + // blendWeights + if (blendWeightsType == IQM_FLOAT) { + size += header->num_vertexes * 4 * sizeof(float); + } else { + size += header->num_vertexes * 4 * sizeof(byte); + } + mod->type = MOD_IQM; iqmData = (iqmData_t *)ri.Hunk_Alloc( size, h_low ); mod->modelData = iqmData; @@ -462,28 +492,40 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na iqmData->num_frames = header->num_frames; iqmData->num_surfaces = header->num_meshes; iqmData->num_joints = header->num_joints; + iqmData->num_poses = header->num_poses; + iqmData->blendWeightsType = blendWeightsType; iqmData->surfaces = (srfIQModel_t *)(iqmData + 1); iqmData->jointMats = (float *) (iqmData->surfaces + iqmData->num_surfaces); iqmData->poseMats = iqmData->jointMats + 12 * header->num_joints; if(header->ofs_bounds) { - iqmData->bounds = iqmData->poseMats + 12 * header->num_joints * header->num_frames; + iqmData->bounds = iqmData->poseMats + 12 * header->num_poses * header->num_frames; iqmData->positions = iqmData->bounds + 6 * header->num_frames; } else - iqmData->positions = iqmData->poseMats + 12 * header->num_joints * header->num_frames; + iqmData->positions = iqmData->poseMats + 12 * header->num_poses * header->num_frames; iqmData->texcoords = iqmData->positions + 3 * header->num_vertexes; iqmData->normals = iqmData->texcoords + 2 * header->num_vertexes; iqmData->tangents = iqmData->normals + 3 * header->num_vertexes; iqmData->blendIndexes = (byte *)(iqmData->tangents + 4 * header->num_vertexes); - iqmData->blendWeights = iqmData->blendIndexes + 4 * header->num_vertexes; - iqmData->colors = iqmData->blendWeights + 4 * header->num_vertexes; + + if(blendWeightsType == IQM_FLOAT) { + iqmData->blendWeights.f = (float *)(iqmData->blendIndexes + 4 * header->num_vertexes); + iqmData->colors = (byte *)(iqmData->blendWeights.f + 4 * header->num_vertexes); + } else { + iqmData->blendWeights.b = iqmData->blendIndexes + 4 * header->num_vertexes; + iqmData->colors = iqmData->blendWeights.b + 4 * header->num_vertexes; + } + iqmData->jointParents = (int *)(iqmData->colors + 4 * header->num_vertexes); iqmData->triangles = iqmData->jointParents + header->num_joints; iqmData->names = (char *)(iqmData->triangles + 3 * header->num_triangles); if ( header->num_joints == 0 ) - iqmData->jointMats = iqmData->poseMats = NULL; + iqmData->jointMats = NULL; + + if ( header->num_poses == 0 ) + iqmData->poseMats = NULL; // calculate joint matrices and their inverses // joint inverses are needed only until the pose matrices are calculated @@ -620,14 +662,27 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na n * sizeof(float) ); break; case IQM_BLENDINDEXES: - Com_Memcpy( iqmData->blendIndexes, - (byte *)header + vertexarray->offset, - n * sizeof(byte) ); + if( blendIndexesType == IQM_INT ) { + int *data = (int*)((byte*)header + vertexarray->offset); + for ( j = 0; j < n; j++ ) { + iqmData->blendIndexes[j] = (byte)data[j]; + } + } else { + Com_Memcpy( iqmData->blendIndexes, + (byte *)header + vertexarray->offset, + n * sizeof(byte) ); + } break; case IQM_BLENDWEIGHTS: - Com_Memcpy( iqmData->blendWeights, - (byte *)header + vertexarray->offset, - n * sizeof(byte) ); + if( blendWeightsType == IQM_FLOAT ) { + Com_Memcpy( iqmData->blendWeights.f, + (byte *)header + vertexarray->offset, + n * sizeof(float) ); + } else { + Com_Memcpy( iqmData->blendWeights.b, + (byte *)header + vertexarray->offset, + n * sizeof(byte) ); + } break; case IQM_COLOR: Com_Memcpy( iqmData->colors, @@ -892,9 +947,21 @@ static void ComputePoseMats( iqmData_t *data, int frame, int oldframe, int *joint = data->jointParents; int i; - if ( oldframe == frame ) { - mat1 = data->poseMats + 12 * data->num_joints * frame; + if ( data->num_poses == 0 ) { for( i = 0; i < data->num_joints; i++, joint++ ) { + if( *joint >= 0 ) { + Matrix34Multiply( mat + 12 * *joint, + identityMatrix, mat + 12*i ); + } else { + Com_Memcpy( mat + 12*i, identityMatrix, 12 * sizeof(float) ); + } + } + return; + } + + if ( oldframe == frame ) { + mat1 = data->poseMats + 12 * data->num_poses * frame; + for( i = 0; i < data->num_poses; i++, joint++ ) { if( *joint >= 0 ) { Matrix34Multiply( mat + 12 * *joint, mat1 + 12*i, mat + 12*i ); @@ -903,10 +970,10 @@ static void ComputePoseMats( iqmData_t *data, int frame, int oldframe, } } } else { - mat1 = data->poseMats + 12 * data->num_joints * frame; - mat2 = data->poseMats + 12 * data->num_joints * oldframe; + mat1 = data->poseMats + 12 * data->num_poses * frame; + mat2 = data->poseMats + 12 * data->num_poses * oldframe; - for( i = 0; i < data->num_joints; i++, joint++ ) { + for( i = 0; i < data->num_poses; i++, joint++ ) { if( *joint >= 0 ) { float tmpMat[12]; InterpolateMatrix( mat1 + 12*i, mat2 + 12*i, @@ -974,7 +1041,7 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) { outColor = &tess.vertexColors[tess.numVertexes]; // compute interpolated joint matrices - if ( data->num_joints > 0 ) { + if ( data->num_poses > 0 ) { ComputePoseMats( data, frame, oldframe, backlerp, jointMats ); } @@ -985,28 +1052,31 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) { float vtxMat[12]; float nrmMat[9]; int vtx = i + surf->first_vertex; + float blendWeights[4]; + int numWeights; - if ( data->num_joints == 0 || data->blendWeights[4*vtx] <= 0 ) { + for ( numWeights = 0; numWeights < 4; numWeights++ ) { + if ( data->blendWeightsType == IQM_FLOAT ) + blendWeights[numWeights] = data->blendWeights.f[4*vtx + numWeights]; + else + blendWeights[numWeights] = (float)data->blendWeights.b[4*vtx + numWeights] / 255.0f; + + if ( blendWeights[numWeights] <= 0 ) + break; + } + + if ( data->num_poses == 0 || numWeights == 0 ) { // no blend joint, use identity matrix. - for( j = 0; j < 3; j++ ) { - for( k = 0; k < 4; k++ ) - vtxMat[4*j+k] = ( k == j ) ? 1 : 0; - } + Com_Memcpy( vtxMat, identityMatrix, 12 * sizeof (float) ); } else { // compute the vertex matrix by blending the up to // four blend weights - for( k = 0; k < 12; k++ ) - vtxMat[k] = data->blendWeights[4*vtx] - * jointMats[12*data->blendIndexes[4*vtx] + k]; - for( j = 1; j < 4; j++ ) { - if( data->blendWeights[4*vtx + j] <= 0 ) - break; - for( k = 0; k < 12; k++ ) - vtxMat[k] += data->blendWeights[4*vtx + j] - * jointMats[12*data->blendIndexes[4*vtx + j] + k]; + Com_Memset( vtxMat, 0, 12 * sizeof (float) ); + for( j = 0; j < numWeights; j++ ) { + for( k = 0; k < 12; k++ ) { + vtxMat[k] += blendWeights[j] * jointMats[12*data->blendIndexes[4*vtx + j] + k]; + } } - for( k = 0; k < 12; k++ ) - vtxMat[k] *= 1.0f / 255.0f; } // compute the normal matrix as transpose of the adjoint diff --git a/code/renderergl1/tr_shade.c b/code/renderergl1/tr_shade.c index 04cef08b..08648b2e 100644 --- a/code/renderergl1/tr_shade.c +++ b/code/renderergl1/tr_shade.c @@ -1145,12 +1145,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) // // set state // - if ( pStage->bundle[0].vertexLightmap && ( (r_vertexLight->integer && !r_uiFullScreen->integer) || glConfig.hardwareType == GLHW_PERMEDIA2 ) && r_lightmap->integer ) - { - GL_Bind( tr.whiteImage ); - } - else - R_BindAnimatedImage( &pStage->bundle[0] ); + R_BindAnimatedImage( &pStage->bundle[0] ); GL_State( pStage->stateBits ); @@ -1160,7 +1155,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) R_DrawElements( input->numIndexes, input->indexes ); } // allow skipping out to show just lightmaps during development - if ( r_lightmap->integer && ( pStage->bundle[0].isLightmap || pStage->bundle[1].isLightmap || pStage->bundle[0].vertexLightmap ) ) + if ( r_lightmap->integer && ( pStage->bundle[0].isLightmap || pStage->bundle[1].isLightmap ) ) { break; } diff --git a/code/renderergl2/glsl/fogpass_vp.glsl b/code/renderergl2/glsl/fogpass_vp.glsl index f18bc707..ce0e015b 100644 --- a/code/renderergl2/glsl/fogpass_vp.glsl +++ b/code/renderergl2/glsl/fogpass_vp.glsl @@ -85,15 +85,12 @@ float CalcFog(vec4 position) float s = dot(position, u_FogDistance) * 8.0; float t = dot(position, u_FogDepth); - if (t < 1.0) - { - t = step(step(0.0, -u_FogEyeT), t); - } - else - { - t /= t - min(u_FogEyeT, 0.0); - } - + float eyeOutside = step(0.0, -u_FogEyeT); + float fogged = step(eyeOutside, t); + + t = max(t, 1e-6); + t *= fogged / (t - u_FogEyeT * eyeOutside); + return s * t; } diff --git a/code/renderergl2/glsl/generic_vp.glsl b/code/renderergl2/glsl/generic_vp.glsl index 67360b1b..94e3c83e 100644 --- a/code/renderergl2/glsl/generic_vp.glsl +++ b/code/renderergl2/glsl/generic_vp.glsl @@ -17,7 +17,7 @@ uniform vec4 u_DiffuseTexMatrix; uniform vec4 u_DiffuseTexOffTurb; #if defined(USE_TCGEN) || defined(USE_RGBAGEN) -uniform vec3 u_ViewOrigin; +uniform vec3 u_LocalViewOrigin; #endif #if defined(USE_TCGEN) @@ -48,7 +48,7 @@ uniform int u_ColorGen; uniform int u_AlphaGen; uniform vec3 u_AmbientLight; uniform vec3 u_DirectedLight; -uniform vec4 u_LightOrigin; +uniform vec3 u_ModelLightDir; uniform float u_PortalRange; #endif @@ -93,7 +93,7 @@ vec3 DeformPosition(const vec3 pos, const vec3 normal, const vec2 st) } else if (u_DeformGen == DGEN_WAVE_TRIANGLE) { - func = abs(fract(value + 0.75) - 0.5) * 4.0 - 1.0; + func = 1.0 - abs(4.0 * fract(value + 0.25) - 2.0); } else if (u_DeformGen == DGEN_WAVE_SAWTOOTH) { @@ -123,7 +123,7 @@ vec2 GenTexCoords(int TCGen, vec3 position, vec3 normal, vec3 TCGenVector0, vec3 } else if (TCGen == TCGEN_ENVIRONMENT_MAPPED) { - vec3 viewer = normalize(u_ViewOrigin - position); + vec3 viewer = normalize(u_LocalViewOrigin - position); tex = -reflect(viewer, normal).yz * vec2(0.5, -0.5) + 0.5; } else if (TCGen == TCGEN_VECTOR) @@ -158,30 +158,25 @@ vec4 CalcColor(vec3 position, vec3 normal) if (u_ColorGen == CGEN_LIGHTING_DIFFUSE) { - float incoming = clamp(dot(normal, u_LightOrigin.xyz), 0.0, 1.0); + float incoming = clamp(dot(normal, u_ModelLightDir), 0.0, 1.0); color.rgb = clamp(u_DirectedLight * incoming + u_AmbientLight, 0.0, 1.0); } - vec3 toView = u_ViewOrigin - position; - vec3 viewer = normalize(u_ViewOrigin - position); + vec3 viewer = u_LocalViewOrigin - position; if (u_AlphaGen == AGEN_LIGHTING_SPECULAR) { - vec3 lightDir = normalize(vec3(-960.0, -1980.0, 96.0) - position.xyz); - vec3 halfangle = normalize(lightDir + viewer); + vec3 lightDir = normalize(vec3(-960.0, 1980.0, 96.0) - position.xyz); + vec3 reflected = -reflect(lightDir, normal); - color.a = pow(max(dot(normal, halfangle), 0.0), 8.0); + color.a = clamp(dot(reflected, normalize(viewer)), 0.0, 1.0); + color.a *= color.a; + color.a *= color.a; } else if (u_AlphaGen == AGEN_PORTAL) { - float alpha = length(toView) / u_PortalRange; - - color.a = clamp(alpha, 0.0, 1.0); - } - else if (u_AlphaGen == AGEN_FRESNEL) - { - color.a = 0.10 + 0.90 * pow(1.0 - dot(normal, viewer), 5); + color.a = clamp(length(viewer) / u_PortalRange, 0.0, 1.0); } return color; @@ -194,14 +189,11 @@ float CalcFog(vec4 position) float s = dot(position, u_FogDistance) * 8.0; float t = dot(position, u_FogDepth); - if (t < 1.0) - { - t = step(step(0.0, -u_FogEyeT), t); - } - else - { - t /= t - min(u_FogEyeT, 0.0); - } + float eyeOutside = step(0.0, -u_FogEyeT); + float fogged = step(eyeOutside, t); + + t = max(t, 1e-6); + t *= fogged / (t - u_FogEyeT * eyeOutside); return s * t; } diff --git a/code/renderergl2/glsl/lightall_fp.glsl b/code/renderergl2/glsl/lightall_fp.glsl index 6aec2b4a..f223bb0c 100644 --- a/code/renderergl2/glsl/lightall_fp.glsl +++ b/code/renderergl2/glsl/lightall_fp.glsl @@ -24,45 +24,40 @@ uniform sampler2D u_ShadowMap; uniform samplerCube u_CubeMap; #endif -#if defined(USE_LIGHT_VECTOR) +#if defined(USE_LIGHT_VECTOR) && !defined(USE_FAST_LIGHT) uniform vec3 u_DirectedLight; uniform vec3 u_AmbientLight; -uniform float u_LightRadius; #endif #if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP) uniform vec3 u_PrimaryLightColor; uniform vec3 u_PrimaryLightAmbient; -uniform float u_PrimaryLightRadius; #endif -#if defined(USE_LIGHT) +#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) uniform vec2 u_MaterialInfo; #endif -varying vec2 var_DiffuseTex; -#if defined(USE_LIGHTMAP) -varying vec2 var_LightTex; -#endif +varying vec4 var_TexCoords; + varying vec4 var_Color; #if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP) -varying vec3 var_ViewDir; -varying vec3 var_Normal; -varying vec3 var_Tangent; -varying vec3 var_Bitangent; +varying vec4 var_Normal; +varying vec4 var_Tangent; +varying vec4 var_Bitangent; #endif #if defined(USE_LIGHT_VERTEX) && !defined(USE_FAST_LIGHT) -varying vec3 var_lightColor; +varying vec3 var_LightColor; #endif -#if defined(USE_LIGHT) && !defined(USE_DELUXEMAP) +#if defined(USE_LIGHT) && !defined(USE_DELUXEMAP) && !defined(USE_FAST_LIGHT) varying vec4 var_LightDir; #endif #if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP) -varying vec3 var_PrimaryLightDir; +varying vec4 var_PrimaryLightDir; #endif @@ -181,17 +176,21 @@ float CalcBlinn(float NH, float shininess) #endif } -float CalcGGX(float NH, float shininess) +float CalcGGX(float NH, float gloss) { - // from http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes.pdf - float m_sq = 2.0 / shininess; - float d = ((NH * NH) * (m_sq - 1.0) + 1.0); - return m_sq / (d * d); + // from http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf + float a_sq = exp2(gloss * -13.0 + 1.0); + float d = ((NH * NH) * (a_sq - 1.0) + 1.0); + return a_sq / (d * d); } float CalcFresnel(float EH) { #if 1 + // From http://blog.selfshadow.com/publications/s2013-shading-course/lazarov/s2013_pbs_black_ops_2_notes.pdf + // not accurate, but fast + return exp2(-10.0 * EH); +#elif 0 // From http://seblagarde.wordpress.com/2012/06/03/spherical-gaussien-approximation-for-blinn-phong-phong-and-fresnel/ return exp2((-5.55473 * EH - 6.98316) * EH); #elif 0 @@ -201,42 +200,48 @@ float CalcFresnel(float EH) return blend; #else - return pow(1.0 - NH, 5.0); + return pow(1.0 - EH, 5.0); #endif } -float CalcVisibility(float NH, float NL, float NE, float EH, float shininess) +float CalcVisibility(float NH, float NL, float NE, float EH, float gloss) { -#if 0 - float geo = 2.0 * NH * min(NE, NL); - geo /= max(EH, geo); - - return geo; -#else - // Modified from http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes.pdf - // NL, NE in numerator factored out from cook-torrance +#if 1 + // From http://blog.selfshadow.com/publications/s2013-shading-course/lazarov/s2013_pbs_black_ops_2_notes.pdf + float k = min(1.0, gloss + 0.545); + return 1.0 / (k * EH * EH + (1.0 - k)); +#elif 0 + float roughness = exp2(gloss * -6.5); + #if defined(USE_GGX) - float roughness = sqrt(2.0 / (shininess + 2.0)); - float k = (roughness + 1.0); + // From http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf + float k = roughness + 1.0; k *= k * 0.125; #else - float k = 2.0 / sqrt(3.1415926535 * (shininess + 2.0)); + float k = roughness; #endif + // Modified from http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf + // NL, NE in numerator factored out from cook-torrance float k2 = 1.0 - k; float invGeo1 = NL * k2 + k; float invGeo2 = NE * k2 + k; return 1.0 / (invGeo1 * invGeo2); - #endif +#else + float geo = 2.0 * NH * min(NE, NL); + geo /= max(EH, geo); + + return geo; +#endif } -vec3 CalcSpecular(vec3 specular, float NH, float NL, float NE, float EH, float shininess) +vec3 CalcSpecular(vec3 specular, float NH, float NL, float NE, float EH, float gloss, float shininess) { float blinn = CalcBlinn(NH, shininess); vec3 fSpecular = mix(specular, vec3(1.0), CalcFresnel(EH)); - float vis = CalcVisibility(NH, NL, NE, EH, shininess); + float vis = CalcVisibility(NH, NL, NE, EH, gloss); #if defined(USE_BLINN) // Normalized Blinn-Phong @@ -261,60 +266,66 @@ vec3 CalcSpecular(vec3 specular, float NH, float NL, float NE, float EH, float s return vec3(0.0); } + +float CalcLightAttenuation(vec3 dir, float sqrRadius) +{ + // point light at >0 radius, directional otherwise + float point = float(sqrRadius > 0.0); + + // inverse square light + float attenuation = sqrRadius / dot(dir, dir); + + // zero light at radius, approximating q3 style + // also don't attenuate directional light + attenuation = (0.5 * attenuation - 1.5) * point + 1.0; + + // clamp attenuation + #if defined(NO_LIGHT_CLAMP) + attenuation = max(attenuation, 0.0); + #else + attenuation = clamp(attenuation, 0.0, 1.0); + #endif + + return attenuation; +} + + void main() { vec3 L, N, E, H; float NL, NH, NE, EH; #if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP) - mat3 tangentToWorld = mat3(var_Tangent, var_Bitangent, var_Normal); + mat3 tangentToWorld = mat3(var_Tangent.xyz, var_Bitangent.xyz, var_Normal.xyz); #endif #if defined(USE_DELUXEMAP) - L = (2.0 * texture2D(u_DeluxeMap, var_LightTex).xyz - vec3(1.0)); + L = (2.0 * texture2D(u_DeluxeMap, var_TexCoords.zw).xyz - vec3(1.0)); #if defined(USE_TANGENT_SPACE_LIGHT) - L = L * tangentToWorld; + L = L * tangentToWorld; #endif #elif defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) L = var_LightDir.xyz; #endif #if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP) - E = normalize(var_ViewDir); + E = normalize(vec3(var_Normal.w, var_Tangent.w, var_Bitangent.w)); #endif #if defined(USE_LIGHTMAP) - vec4 lightSample = texture2D(u_LightMap, var_LightTex).rgba; + vec4 lightSample = texture2D(u_LightMap, var_TexCoords.zw).rgba; #if defined(RGBM_LIGHTMAP) lightSample.rgb *= 32.0 * lightSample.a; #endif vec3 lightColor = lightSample.rgb; #elif defined(USE_LIGHT_VECTOR) && !defined(USE_FAST_LIGHT) - // inverse square light - float attenuation = u_LightRadius * u_LightRadius / dot(L, L); - - // zero light at radius, approximating q3 style - attenuation = 0.5 * attenuation - 0.5; - //attenuation = 0.0697168 * attenuation; - //attenuation *= step(0.294117, attenuation); - - // clamp attenuation - #if defined(NO_LIGHT_CLAMP) - attenuation *= step(0.0, attenuation); - #else - attenuation = clamp(attenuation, 0.0, 1.0); - #endif - - // don't attenuate directional light - attenuation = (attenuation - 1.0) * var_LightDir.w + 1.0; - - vec3 lightColor = u_DirectedLight * attenuation; + vec3 lightColor = u_DirectedLight * CalcLightAttenuation(L, var_LightDir.w); vec3 ambientColor = u_AmbientLight; #elif defined(USE_LIGHT_VERTEX) && !defined(USE_FAST_LIGHT) - vec3 lightColor = var_lightColor; + vec3 lightColor = var_LightColor; #endif - - vec2 texCoords = var_DiffuseTex; + + vec2 texCoords = var_TexCoords.xy; #if defined(USE_PARALLAXMAP) #if defined(USE_TANGENT_SPACE_LIGHT) @@ -329,13 +340,12 @@ void main() #endif vec4 diffuse = texture2D(u_DiffuseMap, texCoords); +#if defined(USE_GAMMA2_TEXTURES) + diffuse.rgb *= diffuse.rgb; +#endif + #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) - - #if defined(USE_LINEAR_LIGHT) - diffuse.rgb *= diffuse.rgb; - #endif - #if defined(USE_NORMALMAP) #if defined(SWIZZLE_NORMALMAP) N.xy = 2.0 * texture2D(u_NormalMap, texCoords).ag - vec2(1.0); @@ -349,7 +359,7 @@ void main() #elif defined(USE_TANGENT_SPACE_LIGHT) N = vec3(0.0, 0.0, 1.0); #else - N = normalize(var_Normal); + N = normalize(var_Normal.xyz); #endif L = normalize(L); @@ -362,7 +372,7 @@ void main() #if defined(USE_TANGENT_SPACE_LIGHT) shadowValue *= step(0.0, var_PrimaryLightDir.z); #else - shadowValue *= step(0.0, dot(var_Normal, var_PrimaryLightDir)); + shadowValue *= step(0.0, dot(var_Normal.xyz, var_PrimaryLightDir.xyz)); #endif #if defined(SHADOWMAP_MODULATE) @@ -371,7 +381,7 @@ void main() #if 0 // Only shadow when the world light is parallel to the primary light - shadowValue = 1.0 + (shadowValue - 1.0) * clamp(dot(L, var_PrimaryLightDir), 0.0, 1.0); + shadowValue = 1.0 + (shadowValue - 1.0) * clamp(dot(L, var_PrimaryLightDir.xyz), 0.0, 1.0); #endif lightColor = mix(shadowColor, lightColor, shadowValue); #endif @@ -383,7 +393,7 @@ void main() #if defined(USE_TANGENT_SPACE_LIGHT) float surfNL = L.z; #else - float surfNL = clamp(dot(var_Normal, L), 0.0, 1.0); + float surfNL = clamp(dot(var_Normal.xyz, L), 0.0, 1.0); #endif // Scale the incoming light to compensate for the baked-in light angle @@ -402,9 +412,9 @@ void main() #if defined(USE_SPECULARMAP) vec4 specular = texture2D(u_SpecularMap, texCoords); - #if defined(USE_LINEAR_LIGHT) + #if defined(USE_GAMMA2_TEXTURES) specular.rgb *= specular.rgb; - #endif + #endif #else vec4 specular = vec4(1.0); #endif @@ -413,7 +423,6 @@ void main() float gloss = specular.a; float shininess = exp2(gloss * 13.0); - float localOcclusion = clamp((diffuse.r + diffuse.g + diffuse.b) * 16.0f, 0.0, 1.0); #if defined(SPECULAR_IS_METALLIC) // diffuse is actually base color, and red of specular is metallicness @@ -430,10 +439,12 @@ void main() reflectance = CalcDiffuse(diffuse.rgb, N, L, E, NE, NL, shininess); #if defined(r_deluxeSpecular) || defined(USE_LIGHT_VECTOR) + float adjGloss = gloss; float adjShininess = shininess; #if !defined(USE_LIGHT_VECTOR) - adjShininess = exp2(gloss * r_deluxeSpecular * 13.0); + adjGloss *= r_deluxeSpecular; + adjShininess = exp2(adjGloss * 13.0); #endif H = normalize(L + E); @@ -442,9 +453,9 @@ void main() NH = clamp(dot(N, H), 0.0, 1.0); #if !defined(USE_LIGHT_VECTOR) - reflectance += CalcSpecular(specular.rgb, NH, NL, NE, EH, adjShininess) * r_deluxeSpecular * localOcclusion; + reflectance += CalcSpecular(specular.rgb, NH, NL, NE, EH, adjGloss, adjShininess) * r_deluxeSpecular; #else - reflectance += CalcSpecular(specular.rgb, NH, NL, NE, EH, adjShininess) * localOcclusion; + reflectance += CalcSpecular(specular.rgb, NH, NL, NE, EH, adjGloss, adjShininess); #endif #endif @@ -461,24 +472,20 @@ void main() vec3 cubeLightColor = textureCubeLod(u_CubeMap, R, 7.0 - gloss * 7.0).rgb; - #if defined(USE_LINEAR_LIGHT) - cubeLightColor *= cubeLightColor; - #endif - #if defined(USE_LIGHTMAP) cubeLightColor *= lightSample.rgb; #elif defined (USE_LIGHT_VERTEX) - cubeLightColor *= var_lightColor; + cubeLightColor *= var_LightColor; #else cubeLightColor *= lightColor * NL + ambientColor; #endif //gl_FragColor.rgb += diffuse.rgb * textureCubeLod(u_CubeMap, N, 7.0).rgb; - gl_FragColor.rgb += cubeLightColor * reflectance * localOcclusion; + gl_FragColor.rgb += cubeLightColor * reflectance; #endif #if defined(USE_PRIMARY_LIGHT) - L = normalize(var_PrimaryLightDir); + L = var_PrimaryLightDir.xyz; //normalize(var_PrimaryLightDir.xyz); NL = clamp(dot(N, L), 0.0, 1.0); H = normalize(L + E); @@ -486,17 +493,15 @@ void main() NH = clamp(dot(N, H), 0.0, 1.0); reflectance = CalcDiffuse(diffuse.rgb, N, L, E, NE, NL, shininess); - reflectance += CalcSpecular(specular.rgb, NH, NL, NE, EH, shininess); + reflectance += CalcSpecular(specular.rgb, NH, NL, NE, EH, gloss, shininess); + lightColor = u_PrimaryLightColor; // * CalcLightAttenuation(L, u_PrimaryLightDir.w); + #if defined(USE_SHADOWMAP) - reflectance *= shadowValue; + lightColor *= shadowValue; #endif - gl_FragColor.rgb += u_PrimaryLightColor * reflectance * NL; - #endif - - #if defined(USE_LINEAR_LIGHT) - gl_FragColor.rgb = sqrt(gl_FragColor.rgb); + gl_FragColor.rgb += lightColor * reflectance * NL; #endif gl_FragColor.a = diffuse.a; diff --git a/code/renderergl2/glsl/lightall_vp.glsl b/code/renderergl2/glsl/lightall_vp.glsl index d2bfb395..ce83d10a 100644 --- a/code/renderergl2/glsl/lightall_vp.glsl +++ b/code/renderergl2/glsl/lightall_vp.glsl @@ -22,6 +22,7 @@ attribute vec3 attr_LightDirection; #if defined(USE_TCGEN) || defined(USE_NORMALMAP) || defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) uniform vec3 u_ViewOrigin; +uniform vec3 u_LocalViewOrigin; #endif #if defined(USE_TCGEN) @@ -49,37 +50,30 @@ uniform float u_VertexLerp; #if defined(USE_LIGHT_VECTOR) uniform vec4 u_LightOrigin; - #if defined(USE_FAST_LIGHT) -uniform vec3 u_DirectedLight; -uniform vec3 u_AmbientLight; uniform float u_LightRadius; +uniform vec3 u_DirectedLight; + #if defined(USE_FAST_LIGHT) +uniform vec3 u_AmbientLight; #endif #endif #if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP) uniform vec4 u_PrimaryLightOrigin; +uniform float u_PrimaryLightRadius; #endif -varying vec2 var_DiffuseTex; - -#if defined(USE_LIGHTMAP) -varying vec2 var_LightTex; -#endif - -#if defined(USE_NORMALMAP) || (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) -varying vec3 var_ViewDir; -#endif +varying vec4 var_TexCoords; varying vec4 var_Color; #if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP) -varying vec3 var_Normal; -varying vec3 var_Tangent; -varying vec3 var_Bitangent; +varying vec4 var_Normal; +varying vec4 var_Tangent; +varying vec4 var_Bitangent; #endif #if defined(USE_LIGHT_VERTEX) && !defined(USE_FAST_LIGHT) -varying vec3 var_lightColor; +varying vec3 var_LightColor; #endif #if defined(USE_LIGHT) && !defined(USE_DELUXEMAP) && !defined(USE_FAST_LIGHT) @@ -87,7 +81,7 @@ varying vec4 var_LightDir; #endif #if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP) -varying vec3 var_PrimaryLightDir; +varying vec4 var_PrimaryLightDir; #endif #if defined(USE_TCGEN) @@ -101,7 +95,7 @@ vec2 GenTexCoords(int TCGen, vec3 position, vec3 normal, vec3 TCGenVector0, vec3 } else if (TCGen == TCGEN_ENVIRONMENT_MAPPED) { - vec3 viewer = normalize(u_ViewOrigin - position); + vec3 viewer = normalize(u_LocalViewOrigin - position); tex = -reflect(viewer, normal).yz * vec2(0.5, -0.5) + 0.5; } else if (TCGen == TCGEN_VECTOR) @@ -120,7 +114,7 @@ vec2 ModTexCoords(vec2 st, vec3 position, vec4 texMatrix, vec4 offTurb) float phase = offTurb.w; vec2 st2 = vec2(dot(st, texMatrix.xz), dot(st, texMatrix.yw)) + offTurb.xy; - vec3 offsetPos = position * 0.0009765625; + vec3 offsetPos = position / 1024.0; offsetPos.x += offsetPos.z; vec2 texOffset = sin((offsetPos.xy + vec2(phase)) * 2.0 * M_PI); @@ -130,6 +124,29 @@ vec2 ModTexCoords(vec2 st, vec3 position, vec4 texMatrix, vec4 offTurb) #endif +float CalcLightAttenuation(vec3 dir, float sqrRadius) +{ + // point light at >0 radius, directional otherwise + float point = float(sqrRadius > 0.0); + + // inverse square light + float attenuation = sqrRadius / dot(dir, dir); + + // zero light at radius, approximating q3 style + // also don't attenuate directional light + attenuation = (0.5 * attenuation - 1.5) * point + 1.0; + + // clamp attenuation + #if defined(NO_LIGHT_CLAMP) + attenuation = max(attenuation, 0.0); + #else + attenuation = clamp(attenuation, 0.0, 1.0); + #endif + + return attenuation; +} + + void main() { #if defined(USE_VERTEX_ANIMATION) @@ -151,9 +168,9 @@ void main() #endif #if defined(USE_TCMOD) - var_DiffuseTex = ModTexCoords(texCoords, position, u_DiffuseTexMatrix, u_DiffuseTexOffTurb); + var_TexCoords.xy = ModTexCoords(texCoords, position, u_DiffuseTexMatrix, u_DiffuseTexOffTurb); #else - var_DiffuseTex = texCoords; + var_TexCoords.xy = texCoords; #endif gl_Position = u_ModelViewProjectionMatrix * vec4(position, 1.0); @@ -167,84 +184,67 @@ void main() #if defined(USE_LIGHT_VECTOR) vec3 L = u_LightOrigin.xyz - (position * u_LightOrigin.w); -#elif defined(USE_LIGHT) && !defined(USE_LIGHT_VECTOR) +#elif defined(USE_LIGHT) && !defined(USE_DELUXEMAP) vec3 L = attr_LightDirection; #if defined(USE_MODELMATRIX) - L = (u_ModelMatrix * vec4(L, 0.0)).xyz; + L = (u_ModelMatrix * vec4(L, 0.0)).xyz; #endif #endif #if defined(USE_LIGHTMAP) - var_LightTex = attr_TexCoord1.st; + var_TexCoords.zw = attr_TexCoord1.st; #endif -#if defined(USE_LIGHT_VERTEX) && !defined(USE_FAST_LIGHT) - var_lightColor = u_VertColor.rgb * attr_Color.rgb; - var_Color.rgb = vec3(1.0); - var_Color.a = u_VertColor.a * attr_Color.a + u_BaseColor.a; -#else var_Color = u_VertColor * attr_Color + u_BaseColor; +#if defined(USE_LIGHT_VERTEX) && !defined(USE_FAST_LIGHT) + var_LightColor = var_Color.rgb; + var_Color.rgb = vec3(1.0); #endif #if defined(USE_LIGHT_VECTOR) && defined(USE_FAST_LIGHT) - // inverse square light - float attenuation = u_LightRadius * u_LightRadius / dot(L, L); - - // zero light at radius, approximating q3 style - attenuation = 0.5 * attenuation - 0.5; - //attenuation = 0.0697168 * attenuation; - //attenuation *= step(0.294117, attenuation); - - // clamp attenuation - #if defined(NO_LIGHT_CLAMP) - attenuation *= step(0.0, attenuation); - #else - attenuation = clamp(attenuation, 0.0, 1.0); - #endif - - // don't attenuate directional light - attenuation = (attenuation - 1.0) * u_LightOrigin.w + 1.0; - + float attenuation = CalcLightAttenuation(L, u_LightRadius * u_LightRadius); float NL = clamp(dot(normal, normalize(L)), 0.0, 1.0); var_Color.rgb *= u_DirectedLight * attenuation * NL + u_AmbientLight; #endif -#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP) - var_Normal = normal; - var_Tangent = tangent; - var_Bitangent = bitangent; -#endif - #if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP) - var_PrimaryLightDir = (u_PrimaryLightOrigin.xyz - (position * u_PrimaryLightOrigin.w)); + var_PrimaryLightDir.xyz = u_PrimaryLightOrigin.xyz - (position * u_PrimaryLightOrigin.w); + var_PrimaryLightDir.w = u_PrimaryLightRadius * u_PrimaryLightRadius; #endif #if defined(USE_LIGHT) && !defined(USE_DELUXEMAP) && !defined(USE_FAST_LIGHT) #if defined(USE_LIGHT_VECTOR) - var_LightDir = vec4(L, u_LightOrigin.w); + var_LightDir = vec4(L, u_LightRadius * u_LightRadius); #else var_LightDir = vec4(L, 0.0); #endif #endif -#if defined(USE_NORMALMAP) || (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) - var_ViewDir = (u_ViewOrigin - position); +#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP) + vec3 viewDir = u_ViewOrigin - position; #endif #if defined(USE_TANGENT_SPACE_LIGHT) mat3 tangentToWorld = mat3(tangent, bitangent, normal); #if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP) - var_PrimaryLightDir = var_PrimaryLightDir * tangentToWorld; + var_PrimaryLightDir.xyz = var_PrimaryLightDir.xyz * tangentToWorld; #endif #if defined(USE_LIGHT) && !defined(USE_DELUXEMAP) && !defined(USE_FAST_LIGHT) var_LightDir.xyz = var_LightDir.xyz * tangentToWorld; #endif - #if defined(USE_NORMALMAP) || (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) - var_ViewDir = var_ViewDir * tangentToWorld; + #if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP) + viewDir = viewDir * tangentToWorld; #endif #endif + +#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP) + // store view direction in tangent space to save on varyings + var_Normal = vec4(normal, viewDir.x); + var_Tangent = vec4(tangent, viewDir.y); + var_Bitangent = vec4(bitangent, viewDir.z); +#endif } diff --git a/code/renderergl2/tr_bsp.c b/code/renderergl2/tr_bsp.c index 64d54805..275fdf83 100644 --- a/code/renderergl2/tr_bsp.c +++ b/code/renderergl2/tr_bsp.c @@ -271,7 +271,7 @@ static void R_LoadLightmaps( lump_t *l, lump_t *surfs ) { if (r_hdr->integer) { - if (glRefConfig.textureFloat && glRefConfig.halfFloatPixel) + if (glRefConfig.textureFloat && glRefConfig.halfFloatPixel && r_floatLightmap->integer) textureInternalFormat = GL_RGBA16F_ARB; else textureInternalFormat = GL_RGBA8; @@ -410,7 +410,7 @@ static void R_LoadLightmaps( lump_t *l, lump_t *surfs ) { VectorScale(color, lightScale, color); - if (glRefConfig.textureFloat && glRefConfig.halfFloatPixel) + if (glRefConfig.textureFloat && glRefConfig.halfFloatPixel && r_floatLightmap->integer) ColorToRGBA16F(color, (unsigned short *)(&image[j*8])); else ColorToRGBM(color, &image[j*4]); @@ -652,7 +652,7 @@ ParseFace */ static void ParseFace( dsurface_t *ds, drawVert_t *verts, float *hdrVertColors, msurface_t *surf, int *indexes ) { int i, j; - srfSurfaceFace_t *cv; + srfBspSurface_t *cv; srfTriangle_t *tri; int numVerts, numTriangles, badTriangles; int realLightmapNum; @@ -767,12 +767,12 @@ static void ParseFace( dsurface_t *ds, drawVert_t *verts, float *hdrVertColors, // take the plane information from the lightmap vector for ( i = 0 ; i < 3 ; i++ ) { - cv->plane.normal[i] = LittleFloat( ds->lightmapVecs[2][i] ); + cv->cullPlane.normal[i] = LittleFloat( ds->lightmapVecs[2][i] ); } - cv->plane.dist = DotProduct( cv->verts[0].xyz, cv->plane.normal ); - SetPlaneSignbits( &cv->plane ); - cv->plane.type = PlaneTypeForNormal( cv->plane.normal ); - surf->cullinfo.plane = cv->plane; + cv->cullPlane.dist = DotProduct( cv->verts[0].xyz, cv->cullPlane.normal ); + SetPlaneSignbits( &cv->cullPlane ); + cv->cullPlane.type = PlaneTypeForNormal( cv->cullPlane.normal ); + surf->cullinfo.plane = cv->cullPlane; surf->data = (surfaceType_t *)cv; @@ -800,7 +800,7 @@ ParseMesh =============== */ static void ParseMesh ( dsurface_t *ds, drawVert_t *verts, float *hdrVertColors, msurface_t *surf ) { - srfGridMesh_t *grid; + srfBspSurface_t *grid; int i, j; int width, height, numPoints; srfVert_t points[MAX_PATCH_SIZE*MAX_PATCH_SIZE]; @@ -903,7 +903,7 @@ ParseTriSurf =============== */ static void ParseTriSurf( dsurface_t *ds, drawVert_t *verts, float *hdrVertColors, msurface_t *surf, int *indexes ) { - srfTriangles_t *cv; + srfBspSurface_t *cv; srfTriangle_t *tri; int i, j; int numVerts, numTriangles, badTriangles; @@ -1065,7 +1065,7 @@ R_MergedWidthPoints returns true if there are grid points merged on a width edge ================= */ -int R_MergedWidthPoints(srfGridMesh_t *grid, int offset) { +int R_MergedWidthPoints(srfBspSurface_t *grid, int offset) { int i, j; for (i = 1; i < grid->width-1; i++) { @@ -1086,7 +1086,7 @@ R_MergedHeightPoints returns true if there are grid points merged on a height edge ================= */ -int R_MergedHeightPoints(srfGridMesh_t *grid, int offset) { +int R_MergedHeightPoints(srfBspSurface_t *grid, int offset) { int i, j; for (i = 1; i < grid->height-1; i++) { @@ -1109,13 +1109,13 @@ NOTE: never sync LoD through grid edges with merged points! FIXME: write generalized version that also avoids cracks between a patch and one that meets half way? ================= */ -void R_FixSharedVertexLodError_r( int start, srfGridMesh_t *grid1 ) { +void R_FixSharedVertexLodError_r( int start, srfBspSurface_t *grid1 ) { int j, k, l, m, n, offset1, offset2, touch; - srfGridMesh_t *grid2; + srfBspSurface_t *grid2; for ( j = start; j < s_worldData.numsurfaces; j++ ) { // - grid2 = (srfGridMesh_t *) s_worldData.surfaces[j].data; + grid2 = (srfBspSurface_t *) s_worldData.surfaces[j].data; // if this surface is not a grid if ( grid2->surfaceType != SF_GRID ) continue; // if the LOD errors are already fixed for this patch @@ -1223,11 +1223,11 @@ If this is not the case this function will still do its job but won't fix the hi */ void R_FixSharedVertexLodError( void ) { int i; - srfGridMesh_t *grid1; + srfBspSurface_t *grid1; for ( i = 0; i < s_worldData.numsurfaces; i++ ) { // - grid1 = (srfGridMesh_t *) s_worldData.surfaces[i].data; + grid1 = (srfBspSurface_t *) s_worldData.surfaces[i].data; // if this surface is not a grid if ( grid1->surfaceType != SF_GRID ) continue; @@ -1249,11 +1249,11 @@ R_StitchPatches */ int R_StitchPatches( int grid1num, int grid2num ) { float *v1, *v2; - srfGridMesh_t *grid1, *grid2; + srfBspSurface_t *grid1, *grid2; int k, l, m, n, offset1, offset2, row, column; - grid1 = (srfGridMesh_t *) s_worldData.surfaces[grid1num].data; - grid2 = (srfGridMesh_t *) s_worldData.surfaces[grid2num].data; + grid1 = (srfBspSurface_t *) s_worldData.surfaces[grid1num].data; + grid2 = (srfBspSurface_t *) s_worldData.surfaces[grid2num].data; for (n = 0; n < 2; n++) { // if (n) offset1 = (grid1->height-1) * grid1->width; @@ -1664,13 +1664,13 @@ might still appear at that side. */ int R_TryStitchingPatch( int grid1num ) { int j, numstitches; - srfGridMesh_t *grid1, *grid2; + srfBspSurface_t *grid1, *grid2; numstitches = 0; - grid1 = (srfGridMesh_t *) s_worldData.surfaces[grid1num].data; + grid1 = (srfBspSurface_t *) s_worldData.surfaces[grid1num].data; for ( j = 0; j < s_worldData.numsurfaces; j++ ) { // - grid2 = (srfGridMesh_t *) s_worldData.surfaces[j].data; + grid2 = (srfBspSurface_t *) s_worldData.surfaces[j].data; // if this surface is not a grid if ( grid2->surfaceType != SF_GRID ) continue; // grids in the same LOD group should have the exact same lod radius @@ -1695,7 +1695,7 @@ R_StitchAllPatches */ void R_StitchAllPatches( void ) { int i, stitched, numstitches; - srfGridMesh_t *grid1; + srfBspSurface_t *grid1; numstitches = 0; do @@ -1703,7 +1703,7 @@ void R_StitchAllPatches( void ) { stitched = qfalse; for ( i = 0; i < s_worldData.numsurfaces; i++ ) { // - grid1 = (srfGridMesh_t *) s_worldData.surfaces[i].data; + grid1 = (srfBspSurface_t *) s_worldData.surfaces[i].data; // if this surface is not a grid if ( grid1->surfaceType != SF_GRID ) continue; @@ -1728,11 +1728,11 @@ R_MovePatchSurfacesToHunk */ void R_MovePatchSurfacesToHunk(void) { int i, size; - srfGridMesh_t *grid, *hunkgrid; + srfBspSurface_t *grid, *hunkgrid; for ( i = 0; i < s_worldData.numsurfaces; i++ ) { // - grid = (srfGridMesh_t *) s_worldData.surfaces[i].data; + grid = (srfBspSurface_t *) s_worldData.surfaces[i].data; // if this surface is not a grid if ( grid->surfaceType != SF_GRID ) continue; @@ -1831,10 +1831,10 @@ static void CopyVert(const srfVert_t * in, srfVert_t * out) /* =============== -R_CreateWorldVBO +R_CreateWorldVBOs =============== */ -static void R_CreateWorldVBO(void) +static void R_CreateWorldVBOs(void) { int i, j, k; @@ -1844,73 +1844,32 @@ static void R_CreateWorldVBO(void) int numTriangles; srfTriangle_t *triangles; - int numSurfaces; - msurface_t *surface; + int numSortedSurfaces, numSurfaces; + msurface_t *surface, **firstSurf, **lastSurf, **currSurf; msurface_t **surfacesSorted; + VBO_t *vbo; + IBO_t *ibo; + int startTime, endTime; startTime = ri.Milliseconds(); - numVerts = 0; - numTriangles = 0; - numSurfaces = 0; - for(k = 0, surface = &s_worldData.surfaces[0]; k < s_worldData.numsurfaces /* s_worldData.numWorldSurfaces */; k++, surface++) + // count surfaces + numSortedSurfaces = 0; + for(surface = &s_worldData.surfaces[0]; surface < &s_worldData.surfaces[s_worldData.numsurfaces]; surface++) { - if(*surface->data == SF_FACE) + if(*surface->data == SF_FACE || *surface->data == SF_GRID || *surface->data == SF_TRIANGLES) { - srfSurfaceFace_t *face = (srfSurfaceFace_t *) surface->data; - - if(face->numVerts) - numVerts += face->numVerts; - - if(face->numTriangles) - numTriangles += face->numTriangles; - - numSurfaces++; - } - else if(*surface->data == SF_GRID) - { - srfGridMesh_t *grid = (srfGridMesh_t *) surface->data; - - if(grid->numVerts) - numVerts += grid->numVerts; - - if(grid->numTriangles) - numTriangles += grid->numTriangles; - - numSurfaces++; - } - else if(*surface->data == SF_TRIANGLES) - { - srfTriangles_t *tri = (srfTriangles_t *) surface->data; - - if(tri->numVerts) - numVerts += tri->numVerts; - - if(tri->numTriangles) - numTriangles += tri->numTriangles; - - numSurfaces++; + numSortedSurfaces++; } } - if(!numVerts || !numTriangles) - return; - - ri.Printf(PRINT_ALL, "...calculating world VBO ( %i verts %i tris )\n", numVerts, numTriangles); - - // create arrays - - verts = ri.Hunk_AllocateTempMemory(numVerts * sizeof(srfVert_t)); - - triangles = ri.Hunk_AllocateTempMemory(numTriangles * sizeof(srfTriangle_t)); - // presort surfaces - surfacesSorted = ri.Malloc(numSurfaces * sizeof(*surfacesSorted)); + surfacesSorted = ri.Malloc(numSortedSurfaces * sizeof(*surfacesSorted)); j = 0; - for(k = 0, surface = &s_worldData.surfaces[0]; k < s_worldData.numsurfaces; k++, surface++) + for(surface = &s_worldData.surfaces[0]; surface < &s_worldData.surfaces[s_worldData.numsurfaces]; surface++) { if(*surface->data == SF_FACE || *surface->data == SF_GRID || *surface->data == SF_TRIANGLES) { @@ -1918,211 +1877,169 @@ static void R_CreateWorldVBO(void) } } - qsort(surfacesSorted, numSurfaces, sizeof(*surfacesSorted), BSPSurfaceCompare); + qsort(surfacesSorted, numSortedSurfaces, sizeof(*surfacesSorted), BSPSurfaceCompare); - // set up triangle indices - numVerts = 0; - numTriangles = 0; - for(k = 0, surface = surfacesSorted[k]; k < numSurfaces; k++, surface = surfacesSorted[k]) + k = 0; + for(firstSurf = lastSurf = surfacesSorted; firstSurf < &surfacesSorted[numSortedSurfaces]; firstSurf = lastSurf) { - if(*surface->data == SF_FACE) + while(lastSurf < &surfacesSorted[numSortedSurfaces] && (*lastSurf)->shader->sortedIndex == (*firstSurf)->shader->sortedIndex) + lastSurf++; + + numVerts = 0; + numTriangles = 0; + numSurfaces = 0; + for (currSurf = firstSurf; currSurf < lastSurf; currSurf++) { - srfSurfaceFace_t *srf = (srfSurfaceFace_t *) surface->data; + srfBspSurface_t *bspSurf = (srfBspSurface_t *) (*currSurf)->data; - srf->firstIndex = numTriangles * 3; - - if(srf->numTriangles) + switch (bspSurf->surfaceType) { - srfTriangle_t *tri; + case SF_FACE: + case SF_GRID: + case SF_TRIANGLES: + if(bspSurf->numVerts) + numVerts += bspSurf->numVerts; - srf->minIndex = numVerts + srf->triangles->indexes[0]; - srf->maxIndex = numVerts + srf->triangles->indexes[0]; + if(bspSurf->numTriangles) + numTriangles += bspSurf->numTriangles; - for(i = 0, tri = srf->triangles; i < srf->numTriangles; i++, tri++) - { - for(j = 0; j < 3; j++) + numSurfaces++; + break; + + default: + break; + } + } + + if(!numVerts || !numTriangles) + continue; + + ri.Printf(PRINT_ALL, "...calculating world VBO %d ( %i verts %i tris )\n", k, numVerts, numTriangles); + + // create arrays + verts = ri.Hunk_AllocateTempMemory(numVerts * sizeof(srfVert_t)); + triangles = ri.Hunk_AllocateTempMemory(numTriangles * sizeof(srfTriangle_t)); + + // set up triangle indices + numVerts = 0; + numTriangles = 0; + for (currSurf = firstSurf; currSurf < lastSurf; currSurf++) + { + srfBspSurface_t *bspSurf = (srfBspSurface_t *) (*currSurf)->data; + + switch (bspSurf->surfaceType) + { + case SF_FACE: + case SF_GRID: + case SF_TRIANGLES: + bspSurf->firstIndex = numTriangles * 3; + + if(bspSurf->numTriangles) { - triangles[numTriangles + i].indexes[j] = numVerts + tri->indexes[j]; - srf->minIndex = MIN(srf->minIndex, numVerts + tri->indexes[j]); - srf->maxIndex = MAX(srf->maxIndex, numVerts + tri->indexes[j]); + srfTriangle_t *tri; + + bspSurf->minIndex = numVerts + bspSurf->triangles->indexes[0]; + bspSurf->maxIndex = numVerts + bspSurf->triangles->indexes[0]; + + for(i = 0, tri = bspSurf->triangles; i < bspSurf->numTriangles; i++, tri++) + { + for(j = 0; j < 3; j++) + { + triangles[numTriangles + i].indexes[j] = numVerts + tri->indexes[j]; + bspSurf->minIndex = MIN(bspSurf->minIndex, numVerts + tri->indexes[j]); + bspSurf->maxIndex = MAX(bspSurf->maxIndex, numVerts + tri->indexes[j]); + } + } + + numTriangles += bspSurf->numTriangles; } - } - numTriangles += srf->numTriangles; + if(bspSurf->numVerts) + numVerts += bspSurf->numVerts; + + break; + + default: + break; } - - if(srf->numVerts) - numVerts += srf->numVerts; } - else if(*surface->data == SF_GRID) + + // build vertices + numVerts = 0; + for (currSurf = firstSurf; currSurf < lastSurf; currSurf++) { - srfGridMesh_t *srf = (srfGridMesh_t *) surface->data; + srfBspSurface_t *bspSurf = (srfBspSurface_t *) (*currSurf)->data; - srf->firstIndex = numTriangles * 3; - - if(srf->numTriangles) + switch (bspSurf->surfaceType) { - srfTriangle_t *tri; + case SF_FACE: + case SF_GRID: + case SF_TRIANGLES: + bspSurf->firstVert = numVerts; - srf->minIndex = numVerts + srf->triangles->indexes[0]; - srf->maxIndex = numVerts + srf->triangles->indexes[0]; - - for(i = 0, tri = srf->triangles; i < srf->numTriangles; i++, tri++) - { - for(j = 0; j < 3; j++) + if(bspSurf->numVerts) { - triangles[numTriangles + i].indexes[j] = numVerts + tri->indexes[j]; - srf->minIndex = MIN(srf->minIndex, numVerts + tri->indexes[j]); - srf->maxIndex = MAX(srf->maxIndex, numVerts + tri->indexes[j]); + for(i = 0; i < bspSurf->numVerts; i++) + { + CopyVert(&bspSurf->verts[i], &verts[numVerts + i]); + } + + numVerts += bspSurf->numVerts; } - } - numTriangles += srf->numTriangles; - } + break; - if(srf->numVerts) - numVerts += srf->numVerts; - } - else if(*surface->data == SF_TRIANGLES) - { - srfTriangles_t *srf = (srfTriangles_t *) surface->data; - - srf->firstIndex = numTriangles * 3; - - if(srf->numTriangles) - { - srfTriangle_t *tri; - - srf->minIndex = numVerts + srf->triangles->indexes[0]; - srf->maxIndex = numVerts + srf->triangles->indexes[0]; - - for(i = 0, tri = srf->triangles; i < srf->numTriangles; i++, tri++) - { - for(j = 0; j < 3; j++) - { - triangles[numTriangles + i].indexes[j] = numVerts + tri->indexes[j]; - srf->minIndex = MIN(srf->minIndex, numVerts + tri->indexes[j]); - srf->maxIndex = MAX(srf->maxIndex, numVerts + tri->indexes[j]); - } - } - - numTriangles += srf->numTriangles; - } - - if(srf->numVerts) - numVerts += srf->numVerts; - } - } - - // build vertices - numVerts = 0; - for(k = 0, surface = surfacesSorted[k]; k < numSurfaces; k++, surface = surfacesSorted[k]) - { - if(*surface->data == SF_FACE) - { - srfSurfaceFace_t *srf = (srfSurfaceFace_t *) surface->data; - - srf->firstVert = numVerts; - - if(srf->numVerts) - { - for(i = 0; i < srf->numVerts; i++) - { - CopyVert(&srf->verts[i], &verts[numVerts + i]); - } - - numVerts += srf->numVerts; + default: + break; } } - else if(*surface->data == SF_GRID) - { - srfGridMesh_t *srf = (srfGridMesh_t *) surface->data; - - srf->firstVert = numVerts; - - if(srf->numVerts) - { - for(i = 0; i < srf->numVerts; i++) - { - CopyVert(&srf->verts[i], &verts[numVerts + i]); - } - - numVerts += srf->numVerts; - } - } - else if(*surface->data == SF_TRIANGLES) - { - srfTriangles_t *srf = (srfTriangles_t *) surface->data; - - srf->firstVert = numVerts; - - if(srf->numVerts) - { - for(i = 0; i < srf->numVerts; i++) - { - CopyVert(&srf->verts[i], &verts[numVerts + i]); - } - - numVerts += srf->numVerts; - } - } - } #ifdef USE_VERT_TANGENT_SPACE - s_worldData.vbo = R_CreateVBO2(va("staticBspModel0_VBO %i", 0), numVerts, verts, - ATTR_POSITION | ATTR_TEXCOORD | ATTR_LIGHTCOORD | ATTR_TANGENT | ATTR_BITANGENT | - ATTR_NORMAL | ATTR_COLOR | ATTR_LIGHTDIRECTION, VBO_USAGE_STATIC); + vbo = R_CreateVBO2(va("staticBspModel0_VBO %i", k), numVerts, verts, + ATTR_POSITION | ATTR_TEXCOORD | ATTR_LIGHTCOORD | ATTR_TANGENT | ATTR_BITANGENT | + ATTR_NORMAL | ATTR_COLOR | ATTR_LIGHTDIRECTION, VBO_USAGE_STATIC); #else - s_worldData.vbo = R_CreateVBO2(va("staticBspModel0_VBO %i", 0), numVerts, verts, - ATTR_POSITION | ATTR_TEXCOORD | ATTR_LIGHTCOORD | - ATTR_NORMAL | ATTR_COLOR | ATTR_LIGHTDIRECTION, VBO_USAGE_STATIC); + vbo = R_CreateVBO2(va("staticBspModel0_VBO %i", k), numVerts, verts, + ATTR_POSITION | ATTR_TEXCOORD | ATTR_LIGHTCOORD | + ATTR_NORMAL | ATTR_COLOR | ATTR_LIGHTDIRECTION, VBO_USAGE_STATIC); #endif - s_worldData.ibo = R_CreateIBO2(va("staticBspModel0_IBO %i", 0), numTriangles, triangles, VBO_USAGE_STATIC); + ibo = R_CreateIBO2(va("staticBspModel0_IBO %i", k), numTriangles, triangles, VBO_USAGE_STATIC); - endTime = ri.Milliseconds(); - ri.Printf(PRINT_ALL, "world VBO calculation time = %5.2f seconds\n", (endTime - startTime) / 1000.0); - - // point triangle surfaces to world VBO - for(k = 0, surface = surfacesSorted[k]; k < numSurfaces; k++, surface = surfacesSorted[k]) - { - if(*surface->data == SF_FACE) + // point triangle surfaces to VBO + for (currSurf = firstSurf; currSurf < lastSurf; currSurf++) { - srfSurfaceFace_t *srf = (srfSurfaceFace_t *) surface->data; + srfBspSurface_t *bspSurf = (srfBspSurface_t *) (*currSurf)->data; - if( srf->numVerts && srf->numTriangles) + switch (bspSurf->surfaceType) { - srf->vbo = s_worldData.vbo; - srf->ibo = s_worldData.ibo; + case SF_FACE: + case SF_GRID: + case SF_TRIANGLES: + if( bspSurf->numVerts && bspSurf->numTriangles) + { + bspSurf->vbo = vbo; + bspSurf->ibo = ibo; + } + + break; + + default: + break; } } - else if(*surface->data == SF_GRID) - { - srfGridMesh_t *srf = (srfGridMesh_t *) surface->data; - if( srf->numVerts && srf->numTriangles) - { - srf->vbo = s_worldData.vbo; - srf->ibo = s_worldData.ibo; - } - } - else if(*surface->data == SF_TRIANGLES) - { - srfTriangles_t *srf = (srfTriangles_t *) surface->data; + ri.Hunk_FreeTempMemory(triangles); + ri.Hunk_FreeTempMemory(verts); + + k++; - if( srf->numVerts && srf->numTriangles) - { - srf->vbo = s_worldData.vbo; - srf->ibo = s_worldData.ibo; - } - } } - ri.Free(surfacesSorted); - ri.Hunk_FreeTempMemory(triangles); - ri.Hunk_FreeTempMemory(verts); + endTime = ri.Milliseconds(); + ri.Printf(PRINT_ALL, "world VBOs calculation time = %5.2f seconds\n", (endTime - startTime) / 1000.0); } /* @@ -2196,10 +2113,10 @@ static void R_LoadSurfaces( lump_t *surfs, lump_t *verts, lump_t *indexLump ) { // FIXME: do this break; case MST_TRIANGLE_SOUP: - out->data = ri.Hunk_Alloc( sizeof(srfTriangles_t), h_low); + out->data = ri.Hunk_Alloc( sizeof(srfBspSurface_t), h_low); break; case MST_PLANAR: - out->data = ri.Hunk_Alloc( sizeof(srfSurfaceFace_t), h_low); + out->data = ri.Hunk_Alloc( sizeof(srfBspSurface_t), h_low); break; case MST_FLARE: out->data = ri.Hunk_Alloc( sizeof(srfFlare_t), h_low); @@ -2216,13 +2133,13 @@ static void R_LoadSurfaces( lump_t *surfs, lump_t *verts, lump_t *indexLump ) { case MST_PATCH: ParseMesh ( in, dv, hdrVertColors, out ); { - srfGridMesh_t *surface = (srfGridMesh_t *)out->data; + srfBspSurface_t *surface = (srfBspSurface_t *)out->data; out->cullinfo.type = CULLINFO_BOX | CULLINFO_SPHERE; - VectorCopy(surface->meshBounds[0], out->cullinfo.bounds[0]); - VectorCopy(surface->meshBounds[1], out->cullinfo.bounds[1]); - VectorCopy(surface->localOrigin, out->cullinfo.localOrigin); - out->cullinfo.radius = surface->meshRadius; + VectorCopy(surface->cullBounds[0], out->cullinfo.bounds[0]); + VectorCopy(surface->cullBounds[1], out->cullinfo.bounds[1]); + VectorCopy(surface->cullOrigin, out->cullinfo.localOrigin); + out->cullinfo.radius = surface->cullRadius; } numMeshes++; break; @@ -3006,6 +2923,7 @@ void R_MergeLeafSurfaces(void) int mergedSurfIndex; int numMergedSurfaces; int numUnmergedSurfaces; + VBO_t *vbo; IBO_t *ibo; msurface_t *mergedSurf; @@ -3025,14 +2943,6 @@ void R_MergeLeafSurfaces(void) s_worldData.surfacesViewCount[i] = -1; } - // create ibo - ibo = tr.ibos[tr.numIBOs++] = ri.Hunk_Alloc(sizeof(*ibo), h_low); - memset(ibo, 0, sizeof(*ibo)); - Q_strncpyz(ibo->name, "staticWorldMesh_IBO_mergedSurfs", sizeof(ibo->name)); - - // allocate more than we need - iboIndexes = outIboIndexes = ri.Malloc(s_worldData.ibo->indexesSize); - // mark matching surfaces for (i = 0; i < s_worldData.numnodes - s_worldData.numDecisionNodes; i++) { @@ -3166,6 +3076,9 @@ void R_MergeLeafSurfaces(void) s_worldData.viewSurfaces[i] = s_worldData.marksurfaces[i]; } + // need to be synched here + R_IssuePendingRenderCommands(); + // actually merge surfaces numIboIndexes = 0; mergedSurfIndex = 0; @@ -3181,13 +3094,27 @@ void R_MergeLeafSurfaces(void) int numVerts; int firstIndex; - srfVBOMesh_t *vboSurf; + srfBspSurface_t *vboSurf; if (s_worldData.surfacesViewCount[i] != i) continue; - + surf1 = s_worldData.surfaces + i; + // retrieve vbo + switch(*surf1->data) + { + case SF_FACE: + case SF_GRID: + case SF_TRIANGLES: + vbo = ((srfBspSurface_t *)(surf1->data))->vbo; + break; + + default: + vbo = NULL; + break; + } + // count verts, indexes, and surfaces numSurfsToMerge = 0; numTriangles = 0; @@ -3195,42 +3122,21 @@ void R_MergeLeafSurfaces(void) for (j = 0; j < numWorldSurfaces; j++) { msurface_t *surf2; + srfBspSurface_t *bspSurf; if (s_worldData.surfacesViewCount[j] != i) continue; surf2 = s_worldData.surfaces + j; - switch(*surf2->data) + bspSurf = (srfBspSurface_t *) surf2->data; + switch(bspSurf->surfaceType) { case SF_FACE: - { - srfSurfaceFace_t *face; - - face = (srfSurfaceFace_t *) surf2->data; - numTriangles += face->numTriangles; - numVerts += face->numVerts; - } - break; - case SF_GRID: - { - srfGridMesh_t *grid; - - grid = (srfGridMesh_t *) surf2->data; - numTriangles += grid->numTriangles; - numVerts += grid->numVerts; - } - break; - case SF_TRIANGLES: - { - srfTriangles_t *tris; - - tris = (srfTriangles_t *) surf2->data; - numTriangles += tris->numTriangles; - numVerts += tris->numVerts; - } + numTriangles += bspSurf->numTriangles; + numVerts += bspSurf->numVerts; break; default: @@ -3245,12 +3151,22 @@ void R_MergeLeafSurfaces(void) continue; } + // create ibo + ibo = tr.ibos[tr.numIBOs] = ri.Hunk_Alloc(sizeof(*ibo), h_low); + memset(ibo, 0, sizeof(*ibo)); + Q_strncpyz(ibo->name, va("staticWorldMesh_IBO_mergedSurfs%i", tr.numIBOs++), sizeof(ibo->name)); + numIboIndexes = 0; + + // allocate indexes + iboIndexes = outIboIndexes = ri.Malloc(numTriangles * 3 * sizeof(*outIboIndexes)); + // Merge surfaces (indexes) and calculate bounds ClearBounds(bounds[0], bounds[1]); firstIndex = numIboIndexes; for (j = 0; j < numWorldSurfaces; j++) { msurface_t *surf2; + srfBspSurface_t *bspSurf; if (s_worldData.surfacesViewCount[j] != i) continue; @@ -3260,53 +3176,18 @@ void R_MergeLeafSurfaces(void) AddPointToBounds(surf2->cullinfo.bounds[0], bounds[0], bounds[1]); AddPointToBounds(surf2->cullinfo.bounds[1], bounds[0], bounds[1]); - switch(*surf2->data) + bspSurf = (srfBspSurface_t *) surf2->data; + switch(bspSurf->surfaceType) { case SF_FACE: - { - srfSurfaceFace_t *face; - - face = (srfSurfaceFace_t *) surf2->data; - - for (k = 0; k < face->numTriangles; k++) - { - *outIboIndexes++ = face->triangles[k].indexes[0] + face->firstVert; - *outIboIndexes++ = face->triangles[k].indexes[1] + face->firstVert; - *outIboIndexes++ = face->triangles[k].indexes[2] + face->firstVert; - numIboIndexes += 3; - } - } - break; - case SF_GRID: - { - srfGridMesh_t *grid; - - grid = (srfGridMesh_t *) surf2->data; - - for (k = 0; k < grid->numTriangles; k++) - { - *outIboIndexes++ = grid->triangles[k].indexes[0] + grid->firstVert; - *outIboIndexes++ = grid->triangles[k].indexes[1] + grid->firstVert; - *outIboIndexes++ = grid->triangles[k].indexes[2] + grid->firstVert; - numIboIndexes += 3; - } - } - break; - case SF_TRIANGLES: + for (k = 0; k < bspSurf->numTriangles; k++) { - srfTriangles_t *tris; - - tris = (srfTriangles_t *) surf2->data; - - for (k = 0; k < tris->numTriangles; k++) - { - *outIboIndexes++ = tris->triangles[k].indexes[0] + tris->firstVert; - *outIboIndexes++ = tris->triangles[k].indexes[1] + tris->firstVert; - *outIboIndexes++ = tris->triangles[k].indexes[2] + tris->firstVert; - numIboIndexes += 3; - } + *outIboIndexes++ = bspSurf->triangles[k].indexes[0] + bspSurf->firstVert; + *outIboIndexes++ = bspSurf->triangles[k].indexes[1] + bspSurf->firstVert; + *outIboIndexes++ = bspSurf->triangles[k].indexes[2] + bspSurf->firstVert; + numIboIndexes += 3; } break; @@ -3320,10 +3201,10 @@ void R_MergeLeafSurfaces(void) memset(vboSurf, 0, sizeof(*vboSurf)); vboSurf->surfaceType = SF_VBO_MESH; - vboSurf->vbo = s_worldData.vbo; + vboSurf->vbo = vbo; vboSurf->ibo = ibo; - vboSurf->numIndexes = numTriangles * 3; + vboSurf->numTriangles = numTriangles; vboSurf->numVerts = numVerts; vboSurf->firstIndex = firstIndex; @@ -3336,12 +3217,8 @@ void R_MergeLeafSurfaces(void) vboSurf->maxIndex = MAX(vboSurf->maxIndex, *(iboIndexes + firstIndex + j)); } - vboSurf->shader = surf1->shader; - vboSurf->fogIndex = surf1->fogIndex; - vboSurf->cubemapIndex = surf1->cubemapIndex; - - VectorCopy(bounds[0], vboSurf->bounds[0]); - VectorCopy(bounds[1], vboSurf->bounds[1]); + VectorCopy(bounds[0], vboSurf->cullBounds[0]); + VectorCopy(bounds[1], vboSurf->cullBounds[1]); VectorCopy(bounds[0], mergedSurf->cullinfo.bounds[0]); VectorCopy(bounds[1], mergedSurf->cullinfo.bounds[1]); @@ -3352,6 +3229,17 @@ void R_MergeLeafSurfaces(void) mergedSurf->cubemapIndex = surf1->cubemapIndex; mergedSurf->shader = surf1->shader; + // finish up the ibo + qglGenBuffersARB(1, &ibo->indexesVBO); + + R_BindIBO(ibo); + qglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, numIboIndexes * sizeof(*iboIndexes), iboIndexes, GL_STATIC_DRAW_ARB); + R_BindNullIBO(); + + GL_CheckErrors(); + + ri.Free(iboIndexes); + // redirect view surfaces to this surf for (j = 0; j < numWorldSurfaces; j++) { @@ -3372,21 +3260,6 @@ void R_MergeLeafSurfaces(void) mergedSurf++; } - // finish up the ibo - R_IssuePendingRenderCommands(); - - qglGenBuffersARB(1, &ibo->indexesVBO); - - R_BindIBO(ibo); - - qglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, numIboIndexes * sizeof(*iboIndexes), iboIndexes, GL_STATIC_DRAW_ARB); - - R_BindNullIBO(); - - GL_CheckErrors(); - - ri.Free(iboIndexes); - endTime = ri.Milliseconds(); ri.Printf(PRINT_ALL, "Processed %d surfaces into %d merged, %d unmerged in %5.2f seconds\n", @@ -3407,41 +3280,20 @@ void R_CalcVertexLightDirs( void ) for(k = 0, surface = &s_worldData.surfaces[0]; k < s_worldData.numsurfaces /* s_worldData.numWorldSurfaces */; k++, surface++) { - if(*surface->data == SF_FACE) - { - srfSurfaceFace_t *srf = (srfSurfaceFace_t *) surface->data; + srfBspSurface_t *bspSurf = (srfBspSurface_t *) surface->data; - if(srf->numVerts) - { - for(i = 0; i < srf->numVerts; i++) - { - R_LightDirForPoint( srf->verts[i].xyz, srf->verts[i].lightdir, srf->verts[i].normal, &s_worldData ); - } - } - } - else if(*surface->data == SF_GRID) + switch(bspSurf->surfaceType) { - srfGridMesh_t *srf = (srfGridMesh_t *) surface->data; + case SF_FACE: + case SF_GRID: + case SF_TRIANGLES: + for(i = 0; i < bspSurf->numVerts; i++) + R_LightDirForPoint( bspSurf->verts[i].xyz, bspSurf->verts[i].lightdir, bspSurf->verts[i].normal, &s_worldData ); - if(srf->numVerts) - { - for(i = 0; i < srf->numVerts; i++) - { - R_LightDirForPoint( srf->verts[i].xyz, srf->verts[i].lightdir, srf->verts[i].normal, &s_worldData ); - } - } - } - else if(*surface->data == SF_TRIANGLES) - { - srfTriangles_t *srf = (srfTriangles_t *) surface->data; + break; - if(srf->numVerts) - { - for(i = 0; i < srf->numVerts; i++) - { - R_LightDirForPoint( srf->verts[i].xyz, srf->verts[i].lightdir, srf->verts[i].normal, &s_worldData ); - } - } + default: + break; } } } @@ -3743,7 +3595,7 @@ void RE_LoadWorldMap( const char *name ) { } // create static VBOS from the world - R_CreateWorldVBO(); + R_CreateWorldVBOs(); if (r_mergeLeafSurfaces->integer) { R_MergeLeafSurfaces(); diff --git a/code/renderergl2/tr_curve.c b/code/renderergl2/tr_curve.c index 3d439257..e9414159 100644 --- a/code/renderergl2/tr_curve.c +++ b/code/renderergl2/tr_curve.c @@ -25,14 +25,14 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA /* This file does all of the processing necessary to turn a raw grid of points -read from the map file into a srfGridMesh_t ready for rendering. +read from the map file into a srfBspSurface_t ready for rendering. The level of detail solution is direction independent, based only on subdivided distance from the true curve. Only a single entry point: -srfGridMesh_t *R_SubdividePatchToGrid( int width, int height, +srfBspSurface_t *R_SubdividePatchToGrid( int width, int height, srfVert_t points[MAX_PATCH_SIZE*MAX_PATCH_SIZE] ) { */ @@ -329,8 +329,6 @@ static int MakeMeshTriangles(int width, int height, srfVert_t ctrl[MAX_GRID_SIZE } } - R_CalcSurfaceTriangleNeighbors(numTriangles, triangles); - // FIXME: use more elegant way for(i = 0; i < width; i++) { @@ -341,8 +339,6 @@ static int MakeMeshTriangles(int width, int height, srfVert_t ctrl[MAX_GRID_SIZE } } - R_CalcSurfaceTrianglePlanes(numTriangles, triangles, ctrl2); - return numTriangles; } @@ -420,13 +416,13 @@ static void PutPointsOnCurve( srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE], R_CreateSurfaceGridMesh ================= */ -srfGridMesh_t *R_CreateSurfaceGridMesh(int width, int height, +srfBspSurface_t *R_CreateSurfaceGridMesh(int width, int height, srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE], float errorTable[2][MAX_GRID_SIZE], int numTriangles, srfTriangle_t triangles[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2]) { int i, j, size; srfVert_t *vert; vec3_t tmpVec; - srfGridMesh_t *grid; + srfBspSurface_t *grid; // copy the results out to a grid size = (width * height - 1) * sizeof( srfVert_t ) + sizeof( *grid ); @@ -468,23 +464,23 @@ srfGridMesh_t *R_CreateSurfaceGridMesh(int width, int height, grid->width = width; grid->height = height; grid->surfaceType = SF_GRID; - ClearBounds( grid->meshBounds[0], grid->meshBounds[1] ); + ClearBounds( grid->cullBounds[0], grid->cullBounds[1] ); for ( i = 0 ; i < width ; i++ ) { for ( j = 0 ; j < height ; j++ ) { vert = &grid->verts[j*width+i]; *vert = ctrl[j][i]; - AddPointToBounds( vert->xyz, grid->meshBounds[0], grid->meshBounds[1] ); + AddPointToBounds( vert->xyz, grid->cullBounds[0], grid->cullBounds[1] ); } } // compute local origin and bounds - VectorAdd( grid->meshBounds[0], grid->meshBounds[1], grid->localOrigin ); - VectorScale( grid->localOrigin, 0.5f, grid->localOrigin ); - VectorSubtract( grid->meshBounds[0], grid->localOrigin, tmpVec ); - grid->meshRadius = VectorLength( tmpVec ); + VectorAdd( grid->cullBounds[0], grid->cullBounds[1], grid->cullOrigin ); + VectorScale( grid->cullOrigin, 0.5f, grid->cullOrigin ); + VectorSubtract( grid->cullBounds[0], grid->cullOrigin, tmpVec ); + grid->cullRadius = VectorLength( tmpVec ); - VectorCopy( grid->localOrigin, grid->lodOrigin ); - grid->lodRadius = grid->meshRadius; + VectorCopy( grid->cullOrigin, grid->lodOrigin ); + grid->lodRadius = grid->cullRadius; // return grid; } @@ -494,7 +490,7 @@ srfGridMesh_t *R_CreateSurfaceGridMesh(int width, int height, R_FreeSurfaceGridMesh ================= */ -void R_FreeSurfaceGridMesh( srfGridMesh_t *grid ) { +void R_FreeSurfaceGridMesh( srfBspSurface_t *grid ) { ri.Free(grid->widthLodError); ri.Free(grid->heightLodError); ri.Free(grid->triangles); @@ -507,7 +503,7 @@ void R_FreeSurfaceGridMesh( srfGridMesh_t *grid ) { R_SubdividePatchToGrid ================= */ -srfGridMesh_t *R_SubdividePatchToGrid( int width, int height, +srfBspSurface_t *R_SubdividePatchToGrid( int width, int height, srfVert_t points[MAX_PATCH_SIZE*MAX_PATCH_SIZE] ) { int i, j, k, l; srfVert_t_cleared( prev ); @@ -690,7 +686,7 @@ srfGridMesh_t *R_SubdividePatchToGrid( int width, int height, R_GridInsertColumn =============== */ -srfGridMesh_t *R_GridInsertColumn( srfGridMesh_t *grid, int column, int row, vec3_t point, float loderror ) { +srfBspSurface_t *R_GridInsertColumn( srfBspSurface_t *grid, int column, int row, vec3_t point, float loderror ) { int i, j; int width, height, oldwidth; srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE]; @@ -750,7 +746,7 @@ srfGridMesh_t *R_GridInsertColumn( srfGridMesh_t *grid, int column, int row, vec R_GridInsertRow =============== */ -srfGridMesh_t *R_GridInsertRow( srfGridMesh_t *grid, int row, int column, vec3_t point, float loderror ) { +srfBspSurface_t *R_GridInsertRow( srfBspSurface_t *grid, int row, int column, vec3_t point, float loderror ) { int i, j; int width, height, oldheight; srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE]; diff --git a/code/renderergl2/tr_extensions.c b/code/renderergl2/tr_extensions.c index 41cd9164..5cd5c2a5 100644 --- a/code/renderergl2/tr_extensions.c +++ b/code/renderergl2/tr_extensions.c @@ -701,8 +701,10 @@ void GLimp_InitExtraExtensions() glRefConfig.seamlessCubeMap = qfalse; if( GLimp_HaveExtension( extension ) ) { - glRefConfig.seamlessCubeMap = qtrue; - ri.Printf(PRINT_ALL, result[1], extension); + if (r_arb_seamless_cube_map->integer) + glRefConfig.seamlessCubeMap = qtrue; + + ri.Printf(PRINT_ALL, result[glRefConfig.seamlessCubeMap], extension); } else { diff --git a/code/renderergl2/tr_glsl.c b/code/renderergl2/tr_glsl.c index a2707cd0..8203e68b 100644 --- a/code/renderergl2/tr_glsl.c +++ b/code/renderergl2/tr_glsl.c @@ -106,6 +106,7 @@ static uniformInfo_t uniformsInfo[] = { "u_LightUp", GLSL_VEC3 }, { "u_LightRight", GLSL_VEC3 }, { "u_LightOrigin", GLSL_VEC4 }, + { "u_ModelLightDir", GLSL_VEC3 }, { "u_LightRadius", GLSL_FLOAT }, { "u_AmbientLight", GLSL_VEC3 }, { "u_DirectedLight", GLSL_VEC3 }, @@ -124,11 +125,12 @@ static uniformInfo_t uniformsInfo[] = { "u_VertexLerp" , GLSL_FLOAT }, { "u_MaterialInfo", GLSL_VEC2 }, - { "u_ViewInfo", GLSL_VEC4 }, - { "u_ViewOrigin", GLSL_VEC3 }, - { "u_ViewForward", GLSL_VEC3 }, - { "u_ViewLeft", GLSL_VEC3 }, - { "u_ViewUp", GLSL_VEC3 }, + { "u_ViewInfo", GLSL_VEC4 }, + { "u_ViewOrigin", GLSL_VEC3 }, + { "u_LocalViewOrigin", GLSL_VEC3 }, + { "u_ViewForward", GLSL_VEC3 }, + { "u_ViewLeft", GLSL_VEC3 }, + { "u_ViewUp", GLSL_VEC3 }, { "u_InvTexRes", GLSL_VEC2 }, { "u_AutoExposureMinMax", GLSL_VEC2 }, @@ -294,11 +296,9 @@ static void GLSL_GetShaderHeader( GLenum shaderType, const GLcharARB *extra, cha "#define alphaGen_t\n" "#define AGEN_LIGHTING_SPECULAR %i\n" "#define AGEN_PORTAL %i\n" - "#define AGEN_FRESNEL %i\n" "#endif\n", AGEN_LIGHTING_SPECULAR, - AGEN_PORTAL, - AGEN_FRESNEL)); + AGEN_PORTAL)); Q_strcat(dest, size, va("#ifndef texenv_t\n" @@ -907,7 +907,7 @@ void GLSL_InitGPUShaders(void) if (i & GENERICDEF_USE_LIGHTMAP) Q_strcat(extradefines, 1024, "#define USE_LIGHTMAP\n"); - if (r_hdr->integer && !(glRefConfig.textureFloat && glRefConfig.halfFloatPixel)) + if (r_hdr->integer && !(glRefConfig.textureFloat && glRefConfig.halfFloatPixel && r_floatLightmap->integer)) Q_strcat(extradefines, 1024, "#define RGBM_LIGHTMAP\n"); if (!GLSL_InitGPUShader(&tr.genericShader[i], "generic", attribs, qtrue, extradefines, qtrue, fallbackShader_generic_vp, fallbackShader_generic_fp)) @@ -1036,7 +1036,7 @@ void GLSL_InitGPUShaders(void) Q_strcat(extradefines, 1024, "#define SWIZZLE_NORMALMAP\n"); } - if (r_hdr->integer && !(glRefConfig.textureFloat && glRefConfig.halfFloatPixel)) + if (r_hdr->integer && !(glRefConfig.textureFloat && glRefConfig.halfFloatPixel && r_floatLightmap->integer)) Q_strcat(extradefines, 1024, "#define RGBM_LIGHTMAP\n"); if (i & LIGHTDEF_LIGHTTYPE_MASK) @@ -1696,7 +1696,7 @@ void GLSL_VertexAttribPointers(uint32_t attribBits) // position/normal/tangent/bitangent are always set in case of animation oldFrame = glState.vertexAttribsOldFrame; newFrame = glState.vertexAttribsNewFrame; - animated = (oldFrame != newFrame) && (glState.vertexAttribsInterpolation > 0.0f); + animated = glState.vertexAnimation; if((attribBits & ATTR_POSITION) && (!(glState.vertexAttribPointersSet & ATTR_POSITION) || animated)) { @@ -1829,7 +1829,6 @@ shaderProgram_t *GLSL_GetGenericShaderProgram(int stage) { case AGEN_LIGHTING_SPECULAR: case AGEN_PORTAL: - case AGEN_FRESNEL: shaderAttribs |= GENERICDEF_USE_RGBAGEN; break; default: @@ -1846,7 +1845,7 @@ shaderProgram_t *GLSL_GetGenericShaderProgram(int stage) shaderAttribs |= GENERICDEF_USE_DEFORM_VERTEXES; } - if (glState.vertexAttribsInterpolation > 0.0f && backEnd.currentEntity && backEnd.currentEntity != &tr.worldEntity) + if (glState.vertexAnimation) { shaderAttribs |= GENERICDEF_USE_VERTEX_ANIMATION; } diff --git a/code/renderergl2/tr_image.c b/code/renderergl2/tr_image.c index a80c975b..09031dc0 100644 --- a/code/renderergl2/tr_image.c +++ b/code/renderergl2/tr_image.c @@ -2303,6 +2303,9 @@ image_t *R_CreateImage( const char *name, byte *pic, int width, int height, imgT qglTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); qglTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); + if (image->flags & IMGFLAG_MIPMAP) + qglGenerateMipmapEXT(GL_TEXTURE_CUBE_MAP); + image->uploadWidth = width; image->uploadHeight = height; } diff --git a/code/renderergl2/tr_init.c b/code/renderergl2/tr_init.c index 3705f1a5..dc67e3ee 100644 --- a/code/renderergl2/tr_init.c +++ b/code/renderergl2/tr_init.c @@ -102,6 +102,7 @@ cvar_t *r_ext_framebuffer_object; cvar_t *r_ext_texture_float; cvar_t *r_arb_half_float_pixel; cvar_t *r_ext_framebuffer_multisample; +cvar_t *r_arb_seamless_cube_map; cvar_t *r_mergeMultidraws; cvar_t *r_mergeLeafSurfaces; @@ -111,6 +112,7 @@ cvar_t *r_cameraExposure; cvar_t *r_softOverbright; cvar_t *r_hdr; +cvar_t *r_floatLightmap; cvar_t *r_postProcess; cvar_t *r_toneMap; @@ -952,16 +954,6 @@ void GL_SetDefaultState( void ) qglDisable( GL_CULL_FACE ); qglDisable( GL_BLEND ); - qglColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE ); - qglClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); - qglClearDepth( 1.0 ); - - qglDrawBuffer( GL_FRONT ); - qglClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_ACCUM_BUFFER_BIT|GL_STENCIL_BUFFER_BIT ); - - qglDrawBuffer( GL_BACK ); - qglClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_ACCUM_BUFFER_BIT|GL_STENCIL_BUFFER_BIT ); - if (glRefConfig.seamlessCubeMap) qglEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); } @@ -1135,6 +1127,7 @@ void R_Register( void ) r_ext_texture_float = ri.Cvar_Get( "r_ext_texture_float", "1", CVAR_ARCHIVE | CVAR_LATCH); r_arb_half_float_pixel = ri.Cvar_Get( "r_arb_half_float_pixel", "1", CVAR_ARCHIVE | CVAR_LATCH); r_ext_framebuffer_multisample = ri.Cvar_Get( "r_ext_framebuffer_multisample", "0", CVAR_ARCHIVE | CVAR_LATCH); + r_arb_seamless_cube_map = ri.Cvar_Get( "r_arb_seamless_cube_map", "0", CVAR_ARCHIVE | CVAR_LATCH); r_ext_texture_filter_anisotropic = ri.Cvar_Get( "r_ext_texture_filter_anisotropic", "0", CVAR_ARCHIVE | CVAR_LATCH ); @@ -1170,6 +1163,7 @@ void R_Register( void ) r_softOverbright = ri.Cvar_Get( "r_softOverbright", "1", CVAR_ARCHIVE | CVAR_LATCH ); r_hdr = ri.Cvar_Get( "r_hdr", "1", CVAR_ARCHIVE | CVAR_LATCH ); + r_floatLightmap = ri.Cvar_Get( "r_floatLightmap", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_postProcess = ri.Cvar_Get( "r_postProcess", "1", CVAR_ARCHIVE ); r_toneMap = ri.Cvar_Get( "r_toneMap", "1", CVAR_ARCHIVE | CVAR_LATCH ); diff --git a/code/renderergl2/tr_light.c b/code/renderergl2/tr_light.c index ee7dad92..3d1d1f24 100644 --- a/code/renderergl2/tr_light.c +++ b/code/renderergl2/tr_light.c @@ -94,12 +94,17 @@ void R_DlightBmodel( bmodel_t *bmodel ) { for ( i = 0 ; i < bmodel->numSurfaces ; i++ ) { surf = tr.world->surfaces + bmodel->firstSurface + i; - if ( *surf->data == SF_FACE ) { - ((srfSurfaceFace_t *)surf->data)->dlightBits = mask; - } else if ( *surf->data == SF_GRID ) { - ((srfGridMesh_t *)surf->data)->dlightBits = mask; - } else if ( *surf->data == SF_TRIANGLES ) { - ((srfTriangles_t *)surf->data)->dlightBits = mask; + switch(*surf->data) + { + case SF_FACE: + case SF_GRID: + case SF_TRIANGLES: + case SF_VBO_MESH: + ((srfBspSurface_t *)surf->data)->dlightBits = mask; + break; + + default: + break; } } } @@ -403,8 +408,11 @@ void R_SetupEntityLighting( const trRefdef_t *refdef, trRefEntity_t *ent ) { ((byte *)&ent->ambientLightInt)[3] = 0xff; // transform the direction to local space - // no need to do this if using lightentity glsl shader VectorNormalize( lightDir ); + ent->modelLightDir[0] = DotProduct( lightDir, ent->e.axis[0] ); + ent->modelLightDir[1] = DotProduct( lightDir, ent->e.axis[1] ); + ent->modelLightDir[2] = DotProduct( lightDir, ent->e.axis[2] ); + VectorCopy(lightDir, ent->lightDir); } diff --git a/code/renderergl2/tr_local.h b/code/renderergl2/tr_local.h index b2930aa3..8debab33 100644 --- a/code/renderergl2/tr_local.h +++ b/code/renderergl2/tr_local.h @@ -47,10 +47,6 @@ typedef unsigned int glIndex_t; #define SHADERNUM_BITS 14 #define MAX_SHADERS (1<indexes[0] == start && tri->indexes[1] == end) || - (tri->indexes[1] == start && tri->indexes[2] == end) || (tri->indexes[2] == start && tri->indexes[0] == end)) - { - if(i != ignore) - { - match = i; - } - - count++; - } - else if((tri->indexes[1] == start && tri->indexes[0] == end) || - (tri->indexes[2] == start && tri->indexes[1] == end) || (tri->indexes[0] == start && tri->indexes[2] == end)) - { - count++; - } - } - - // detect edges shared by three triangles and make them seams - if(count > 2) - { - match = -1; - } - - return match; -} - - -/* -================= -R_CalcSurfaceTriangleNeighbors - -Recoded from Q2E -================= -*/ -void R_CalcSurfaceTriangleNeighbors(int numTriangles, srfTriangle_t * triangles) -{ - int i; - srfTriangle_t *tri; - - for(i = 0, tri = triangles; i < numTriangles; i++, tri++) - { - tri->neighbors[0] = R_FindSurfaceTriangleWithEdge(numTriangles, triangles, tri->indexes[1], tri->indexes[0], i); - tri->neighbors[1] = R_FindSurfaceTriangleWithEdge(numTriangles, triangles, tri->indexes[2], tri->indexes[1], i); - tri->neighbors[2] = R_FindSurfaceTriangleWithEdge(numTriangles, triangles, tri->indexes[0], tri->indexes[2], i); - } -} - -/* -================= -R_CalcSurfaceTrianglePlanes -================= -*/ -void R_CalcSurfaceTrianglePlanes(int numTriangles, srfTriangle_t * triangles, srfVert_t * verts) -{ - int i; - srfTriangle_t *tri; - - for(i = 0, tri = triangles; i < numTriangles; i++, tri++) - { - float *v1, *v2, *v3; - vec3_t d1, d2; - - v1 = verts[tri->indexes[0]].xyz; - v2 = verts[tri->indexes[1]].xyz; - v3 = verts[tri->indexes[2]].xyz; - - VectorSubtract(v2, v1, d1); - VectorSubtract(v3, v1, d2); - - CrossProduct(d2, d1, tri->plane); - tri->plane[3] = DotProduct(tri->plane, v1); - } -} - - /* ================= R_CullLocalBox @@ -1365,7 +1272,7 @@ R_PlaneForSurface ============= */ void R_PlaneForSurface (surfaceType_t *surfType, cplane_t *plane) { - srfTriangles_t *tri; + srfBspSurface_t *tri; srfPoly_t *poly; srfVert_t *v1, *v2, *v3; vec4_t plane4; @@ -1377,10 +1284,10 @@ void R_PlaneForSurface (surfaceType_t *surfType, cplane_t *plane) { } switch (*surfType) { case SF_FACE: - *plane = ((srfSurfaceFace_t *)surfType)->plane; + *plane = ((srfBspSurface_t *)surfType)->cullPlane; return; case SF_TRIANGLES: - tri = (srfTriangles_t *)surfType; + tri = (srfBspSurface_t *)surfType; v1 = tri->verts + tri->triangles[0].indexes[0]; v2 = tri->verts + tri->triangles[0].indexes[1]; v3 = tri->verts + tri->triangles[0].indexes[2]; diff --git a/code/renderergl2/tr_marks.c b/code/renderergl2/tr_marks.c index 4d070565..dc625102 100644 --- a/code/renderergl2/tr_marks.c +++ b/code/renderergl2/tr_marks.c @@ -268,7 +268,7 @@ int R_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projectio vec3_t clipPoints[2][MAX_VERTS_ON_POLY]; int numClipPoints; float *v; - srfGridMesh_t *cv; + srfBspSurface_t *cv; srfTriangle_t *tri; srfVert_t *dv; vec3_t normal; @@ -327,7 +327,7 @@ int R_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projectio if (*surfaces[i] == SF_GRID) { - cv = (srfGridMesh_t *) surfaces[i]; + cv = (srfBspSurface_t *) surfaces[i]; for ( m = 0 ; m < cv->height - 1 ; m++ ) { for ( n = 0 ; n < cv->width - 1 ; n++ ) { // We triangulate the grid and chop all triangles within @@ -407,10 +407,10 @@ int R_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projectio } else if (*surfaces[i] == SF_FACE) { - srfSurfaceFace_t *surf = ( srfSurfaceFace_t * ) surfaces[i]; + srfBspSurface_t *surf = ( srfBspSurface_t * ) surfaces[i]; // check the normal of this face - if (DotProduct(surf->plane.normal, projectionDir) > -0.5) { + if (DotProduct(surf->cullPlane.normal, projectionDir) > -0.5) { continue; } @@ -419,7 +419,7 @@ int R_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projectio for(j = 0; j < 3; j++) { v = surf->verts[tri->indexes[j]].xyz; - VectorMA(v, MARKER_OFFSET, surf->plane.normal, clipPoints[0][j]); + VectorMA(v, MARKER_OFFSET, surf->cullPlane.normal, clipPoints[0][j]); } // add the fragments of this face @@ -435,7 +435,7 @@ int R_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projectio } else if(*surfaces[i] == SF_TRIANGLES && r_marksOnTriangleMeshes->integer) { - srfTriangles_t *surf = (srfTriangles_t *) surfaces[i]; + srfBspSurface_t *surf = (srfBspSurface_t *) surfaces[i]; for(k = 0, tri = surf->triangles; k < surf->numTriangles; k++, tri++) { diff --git a/code/renderergl2/tr_model.c b/code/renderergl2/tr_model.c index 8feeab0e..6d9cd9e4 100644 --- a/code/renderergl2/tr_model.c +++ b/code/renderergl2/tr_model.c @@ -562,8 +562,6 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize, tri->indexes[2] = LittleLong(md3Tri->indexes[2]); } - R_CalcSurfaceTriangleNeighbors(surf->numTriangles, surf->triangles); - // swap all the XyzNormals surf->numVerts = md3Surf->numVerts; surf->verts = v = ri.Hunk_Alloc(sizeof(*v) * (md3Surf->numVerts * md3Surf->numFrames), h_low); diff --git a/code/renderergl2/tr_model_iqm.c b/code/renderergl2/tr_model_iqm.c index 44c98ee0..44c4a956 100644 --- a/code/renderergl2/tr_model_iqm.c +++ b/code/renderergl2/tr_model_iqm.c @@ -25,6 +25,13 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #define LL(x) x=LittleLong(x) +// 3x4 identity matrix +static float identityMatrix[12] = { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0 +}; + static qboolean IQM_CheckRange( iqmHeader_t *header, int offset, int count,int size ) { // return true if the range specified by offset, count and size @@ -143,6 +150,7 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na iqmData_t *iqmData; srfIQModel_t *surface; char meshName[MAX_QPATH]; + byte blendIndexesType, blendWeightsType; if( filesize < sizeof(iqmHeader_t) ) { return qfalse; @@ -198,6 +206,8 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na return qfalse; } + blendIndexesType = blendWeightsType = IQM_UBYTE; + // check and swap vertex arrays if( IQM_CheckRange( header, header->ofs_vertexarrays, header->num_vertexarrays, @@ -264,11 +274,20 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na } break; case IQM_BLENDINDEXES: + if( (vertexarray->format != IQM_INT && + vertexarray->format != IQM_UBYTE) || + vertexarray->size != 4 ) { + return qfalse; + } + blendIndexesType = vertexarray->format; + break; case IQM_BLENDWEIGHTS: - if( vertexarray->format != IQM_UBYTE || + if( (vertexarray->format != IQM_FLOAT && + vertexarray->format != IQM_UBYTE) || vertexarray->size != 4 ) { return qfalse; } + blendWeightsType = vertexarray->format; break; case IQM_COLOR: if( vertexarray->format != IQM_UBYTE || @@ -343,7 +362,9 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na } } - if( header->num_poses != header->num_joints ) { + if( header->num_poses != header->num_joints && header->num_poses != 0 ) { + ri.Printf(PRINT_WARNING, "R_LoadIQM: %s has %d poses and %d joints, must have the same number or 0 poses\n", + mod_name, header->num_poses, header->num_joints ); return qfalse; } @@ -379,7 +400,10 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na joint_names += strlen( (char *)header + header->ofs_text + joint->name ) + 1; } + } + if ( header->num_poses ) + { // check and swap poses if( IQM_CheckRange( header, header->ofs_poses, header->num_poses, sizeof(iqmPose_t) ) ) { @@ -438,7 +462,7 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na size = sizeof(iqmData_t); size += header->num_meshes * sizeof( srfIQModel_t ); size += header->num_joints * 12 * sizeof( float ); // joint mats - size += header->num_joints * header->num_frames * 12 * sizeof( float ); // pose mats + size += header->num_poses * header->num_frames * 12 * sizeof( float ); // pose mats if(header->ofs_bounds) size += header->num_frames * 6 * sizeof(float); // model bounds size += header->num_vertexes * 3 * sizeof(float); // positions @@ -446,12 +470,18 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na size += header->num_vertexes * 3 * sizeof(float); // normals size += header->num_vertexes * 4 * sizeof(float); // tangents size += header->num_vertexes * 4 * sizeof(byte); // blendIndexes - size += header->num_vertexes * 4 * sizeof(byte); // blendWeights size += header->num_vertexes * 4 * sizeof(byte); // colors size += header->num_joints * sizeof(int); // parents size += header->num_triangles * 3 * sizeof(int); // triangles size += joint_names; // joint names + // blendWeights + if (blendWeightsType == IQM_FLOAT) { + size += header->num_vertexes * 4 * sizeof(float); + } else { + size += header->num_vertexes * 4 * sizeof(byte); + } + mod->type = MOD_IQM; iqmData = (iqmData_t *)ri.Hunk_Alloc( size, h_low ); mod->modelData = iqmData; @@ -462,28 +492,40 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na iqmData->num_frames = header->num_frames; iqmData->num_surfaces = header->num_meshes; iqmData->num_joints = header->num_joints; + iqmData->num_poses = header->num_poses; + iqmData->blendWeightsType = blendWeightsType; iqmData->surfaces = (srfIQModel_t *)(iqmData + 1); iqmData->jointMats = (float *) (iqmData->surfaces + iqmData->num_surfaces); iqmData->poseMats = iqmData->jointMats + 12 * header->num_joints; if(header->ofs_bounds) { - iqmData->bounds = iqmData->poseMats + 12 * header->num_joints * header->num_frames; + iqmData->bounds = iqmData->poseMats + 12 * header->num_poses * header->num_frames; iqmData->positions = iqmData->bounds + 6 * header->num_frames; } else - iqmData->positions = iqmData->poseMats + 12 * header->num_joints * header->num_frames; + iqmData->positions = iqmData->poseMats + 12 * header->num_poses * header->num_frames; iqmData->texcoords = iqmData->positions + 3 * header->num_vertexes; iqmData->normals = iqmData->texcoords + 2 * header->num_vertexes; iqmData->tangents = iqmData->normals + 3 * header->num_vertexes; iqmData->blendIndexes = (byte *)(iqmData->tangents + 4 * header->num_vertexes); - iqmData->blendWeights = iqmData->blendIndexes + 4 * header->num_vertexes; - iqmData->colors = iqmData->blendWeights + 4 * header->num_vertexes; + + if(blendWeightsType == IQM_FLOAT) { + iqmData->blendWeights.f = (float *)(iqmData->blendIndexes + 4 * header->num_vertexes); + iqmData->colors = (byte *)(iqmData->blendWeights.f + 4 * header->num_vertexes); + } else { + iqmData->blendWeights.b = iqmData->blendIndexes + 4 * header->num_vertexes; + iqmData->colors = iqmData->blendWeights.b + 4 * header->num_vertexes; + } + iqmData->jointParents = (int *)(iqmData->colors + 4 * header->num_vertexes); iqmData->triangles = iqmData->jointParents + header->num_joints; iqmData->names = (char *)(iqmData->triangles + 3 * header->num_triangles); if ( header->num_joints == 0 ) - iqmData->jointMats = iqmData->poseMats = NULL; + iqmData->jointMats = NULL; + + if ( header->num_poses == 0 ) + iqmData->poseMats = NULL; // calculate joint matrices and their inverses // joint inverses are needed only until the pose matrices are calculated @@ -620,14 +662,27 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na n * sizeof(float) ); break; case IQM_BLENDINDEXES: - Com_Memcpy( iqmData->blendIndexes, - (byte *)header + vertexarray->offset, - n * sizeof(byte) ); + if( blendIndexesType == IQM_INT ) { + int *data = (int*)((byte*)header + vertexarray->offset); + for ( j = 0; j < n; j++ ) { + iqmData->blendIndexes[j] = (byte)data[j]; + } + } else { + Com_Memcpy( iqmData->blendIndexes, + (byte *)header + vertexarray->offset, + n * sizeof(byte) ); + } break; case IQM_BLENDWEIGHTS: - Com_Memcpy( iqmData->blendWeights, - (byte *)header + vertexarray->offset, - n * sizeof(byte) ); + if( blendWeightsType == IQM_FLOAT ) { + Com_Memcpy( iqmData->blendWeights.f, + (byte *)header + vertexarray->offset, + n * sizeof(float) ); + } else { + Com_Memcpy( iqmData->blendWeights.b, + (byte *)header + vertexarray->offset, + n * sizeof(byte) ); + } break; case IQM_COLOR: Com_Memcpy( iqmData->colors, @@ -895,9 +950,21 @@ static void ComputePoseMats( iqmData_t *data, int frame, int oldframe, int *joint = data->jointParents; int i; - if ( oldframe == frame ) { - mat1 = data->poseMats + 12 * data->num_joints * frame; + if ( data->num_poses == 0 ) { for( i = 0; i < data->num_joints; i++, joint++ ) { + if( *joint >= 0 ) { + Matrix34Multiply( mat + 12 * *joint, + identityMatrix, mat + 12*i ); + } else { + Com_Memcpy( mat + 12*i, identityMatrix, 12 * sizeof(float) ); + } + } + return; + } + + if ( oldframe == frame ) { + mat1 = data->poseMats + 12 * data->num_poses * frame; + for( i = 0; i < data->num_poses; i++, joint++ ) { if( *joint >= 0 ) { Matrix34Multiply( mat + 12 * *joint, mat1 + 12*i, mat + 12*i ); @@ -906,10 +973,10 @@ static void ComputePoseMats( iqmData_t *data, int frame, int oldframe, } } } else { - mat1 = data->poseMats + 12 * data->num_joints * frame; - mat2 = data->poseMats + 12 * data->num_joints * oldframe; + mat1 = data->poseMats + 12 * data->num_poses * frame; + mat2 = data->poseMats + 12 * data->num_poses * oldframe; - for( i = 0; i < data->num_joints; i++, joint++ ) { + for( i = 0; i < data->num_poses; i++, joint++ ) { if( *joint >= 0 ) { float tmpMat[12]; InterpolateMatrix( mat1 + 12*i, mat2 + 12*i, @@ -977,7 +1044,7 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) { outColor = &tess.vertexColors[tess.numVertexes]; // compute interpolated joint matrices - if ( data->num_joints > 0 ) { + if ( data->num_poses > 0 ) { ComputePoseMats( data, frame, oldframe, backlerp, jointMats ); } @@ -988,28 +1055,31 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) { float vtxMat[12]; float nrmMat[9]; int vtx = i + surf->first_vertex; + float blendWeights[4]; + int numWeights; - if ( data->num_joints == 0 || data->blendWeights[4*vtx] <= 0 ) { + for ( numWeights = 0; numWeights < 4; numWeights++ ) { + if ( data->blendWeightsType == IQM_FLOAT ) + blendWeights[numWeights] = data->blendWeights.f[4*vtx + numWeights]; + else + blendWeights[numWeights] = (float)data->blendWeights.b[4*vtx + numWeights] / 255.0f; + + if ( blendWeights[numWeights] <= 0 ) + break; + } + + if ( data->num_poses == 0 || numWeights == 0 ) { // no blend joint, use identity matrix. - for( j = 0; j < 3; j++ ) { - for( k = 0; k < 4; k++ ) - vtxMat[4*j+k] = ( k == j ) ? 1 : 0; - } + Com_Memcpy( vtxMat, identityMatrix, 12 * sizeof (float) ); } else { // compute the vertex matrix by blending the up to // four blend weights - for( k = 0; k < 12; k++ ) - vtxMat[k] = data->blendWeights[4*vtx] - * jointMats[12*data->blendIndexes[4*vtx] + k]; - for( j = 1; j < 4; j++ ) { - if( data->blendWeights[4*vtx + j] <= 0 ) - break; - for( k = 0; k < 12; k++ ) - vtxMat[k] += data->blendWeights[4*vtx + j] - * jointMats[12*data->blendIndexes[4*vtx + j] + k]; + Com_Memset( vtxMat, 0, 12 * sizeof (float) ); + for( j = 0; j < numWeights; j++ ) { + for( k = 0; k < 12; k++ ) { + vtxMat[k] += blendWeights[j] * jointMats[12*data->blendIndexes[4*vtx + j] + k]; + } } - for( k = 0; k < 12; k++ ) - vtxMat[k] *= 1.0f / 255.0f; } // compute the normal matrix as transpose of the adjoint diff --git a/code/renderergl2/tr_shade.c b/code/renderergl2/tr_shade.c index c704310b..74b8fe1f 100644 --- a/code/renderergl2/tr_shade.c +++ b/code/renderergl2/tr_shade.c @@ -221,14 +221,22 @@ extern float EvalWaveForm( const waveForm_t *wf ); extern float EvalWaveFormClamped( const waveForm_t *wf ); -static void ComputeTexMatrix( shaderStage_t *pStage, int bundleNum, float *outmatrix) +static void ComputeTexMods( shaderStage_t *pStage, int bundleNum, float *outMatrix, float *outOffTurb) { int tm; - float matrix[16], currentmatrix[16]; + float matrix[6], currentmatrix[6]; textureBundle_t *bundle = &pStage->bundle[bundleNum]; - Matrix16Identity(outmatrix); - Matrix16Identity(currentmatrix); + matrix[0] = 1.0f; matrix[2] = 0.0f; matrix[4] = 0.0f; + matrix[1] = 0.0f; matrix[3] = 1.0f; matrix[5] = 0.0f; + + currentmatrix[0] = 1.0f; currentmatrix[2] = 0.0f; currentmatrix[4] = 0.0f; + currentmatrix[1] = 0.0f; currentmatrix[3] = 1.0f; currentmatrix[5] = 0.0f; + + outMatrix[0] = 1.0f; outMatrix[2] = 0.0f; + outMatrix[1] = 0.0f; outMatrix[3] = 1.0f; + + outOffTurb[0] = 0.0f; outOffTurb[1] = 0.0f; outOffTurb[2] = 0.0f; outOffTurb[3] = 0.0f; for ( tm = 0; tm < bundle->numTexMods ; tm++ ) { switch ( bundle->texMods[tm].type ) @@ -239,59 +247,73 @@ static void ComputeTexMatrix( shaderStage_t *pStage, int bundleNum, float *outma break; case TMOD_TURBULENT: - RB_CalcTurbulentTexMatrix( &bundle->texMods[tm].wave, - matrix ); - outmatrix[12] = matrix[12]; - outmatrix[13] = matrix[13]; - Matrix16Copy(outmatrix, currentmatrix); + RB_CalcTurbulentFactors(&bundle->texMods[tm].wave, &outOffTurb[2], &outOffTurb[3]); break; case TMOD_ENTITY_TRANSLATE: - RB_CalcScrollTexMatrix( backEnd.currentEntity->e.shaderTexCoord, - matrix ); - Matrix16Multiply(matrix, currentmatrix, outmatrix); - Matrix16Copy(outmatrix, currentmatrix); + RB_CalcScrollTexMatrix( backEnd.currentEntity->e.shaderTexCoord, matrix ); break; case TMOD_SCROLL: RB_CalcScrollTexMatrix( bundle->texMods[tm].scroll, matrix ); - Matrix16Multiply(matrix, currentmatrix, outmatrix); - Matrix16Copy(outmatrix, currentmatrix); break; case TMOD_SCALE: RB_CalcScaleTexMatrix( bundle->texMods[tm].scale, matrix ); - Matrix16Multiply(matrix, currentmatrix, outmatrix); - Matrix16Copy(outmatrix, currentmatrix); break; case TMOD_STRETCH: RB_CalcStretchTexMatrix( &bundle->texMods[tm].wave, matrix ); - Matrix16Multiply(matrix, currentmatrix, outmatrix); - Matrix16Copy(outmatrix, currentmatrix); break; case TMOD_TRANSFORM: RB_CalcTransformTexMatrix( &bundle->texMods[tm], matrix ); - Matrix16Multiply(matrix, currentmatrix, outmatrix); - Matrix16Copy(outmatrix, currentmatrix); break; case TMOD_ROTATE: RB_CalcRotateTexMatrix( bundle->texMods[tm].rotateSpeed, matrix ); - Matrix16Multiply(matrix, currentmatrix, outmatrix); - Matrix16Copy(outmatrix, currentmatrix); break; default: ri.Error( ERR_DROP, "ERROR: unknown texmod '%d' in shader '%s'", bundle->texMods[tm].type, tess.shader->name ); break; } + + switch ( bundle->texMods[tm].type ) + { + case TMOD_NONE: + case TMOD_TURBULENT: + default: + break; + + case TMOD_ENTITY_TRANSLATE: + case TMOD_SCROLL: + case TMOD_SCALE: + case TMOD_STRETCH: + case TMOD_TRANSFORM: + case TMOD_ROTATE: + outMatrix[0] = matrix[0] * currentmatrix[0] + matrix[2] * currentmatrix[1]; + outMatrix[1] = matrix[1] * currentmatrix[0] + matrix[3] * currentmatrix[1]; + + outMatrix[2] = matrix[0] * currentmatrix[2] + matrix[2] * currentmatrix[3]; + outMatrix[3] = matrix[1] * currentmatrix[2] + matrix[3] * currentmatrix[3]; + + outOffTurb[0] = matrix[0] * currentmatrix[4] + matrix[2] * currentmatrix[5] + matrix[4]; + outOffTurb[1] = matrix[1] * currentmatrix[4] + matrix[3] * currentmatrix[5] + matrix[5]; + + currentmatrix[0] = outMatrix[0]; + currentmatrix[1] = outMatrix[1]; + currentmatrix[2] = outMatrix[2]; + currentmatrix[3] = outMatrix[3]; + currentmatrix[4] = outOffTurb[0]; + currentmatrix[5] = outOffTurb[1]; + break; + } } } @@ -423,44 +445,27 @@ static void ProjectDlightTexture( void ) { static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t vertColor ) { + baseColor[0] = + baseColor[1] = + baseColor[2] = + baseColor[3] = 1.0f; + + vertColor[0] = + vertColor[1] = + vertColor[2] = + vertColor[3] = 0.0f; + // // rgbGen // switch ( pStage->rgbGen ) { - case CGEN_IDENTITY: - baseColor[0] = - baseColor[1] = - baseColor[2] = - baseColor[3] = 1.0f; - - vertColor[0] = - vertColor[1] = - vertColor[2] = - vertColor[3] = 0.0f; - break; case CGEN_IDENTITY_LIGHTING: baseColor[0] = baseColor[1] = baseColor[2] = tr.identityLight; - baseColor[3] = 1.0f; - - vertColor[0] = - vertColor[1] = - vertColor[2] = - vertColor[3] = 0.0f; break; case CGEN_EXACT_VERTEX: - baseColor[0] = - baseColor[1] = - baseColor[2] = - baseColor[3] = 0.0f; - - vertColor[0] = - vertColor[1] = - vertColor[2] = - vertColor[3] = 1.0f; - break; case CGEN_EXACT_VERTEX_LIT: baseColor[0] = baseColor[1] = @@ -477,11 +482,6 @@ static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t baseColor[1] = pStage->constantColor[1] / 255.0f; baseColor[2] = pStage->constantColor[2] / 255.0f; baseColor[3] = pStage->constantColor[3] / 255.0f; - - vertColor[0] = - vertColor[1] = - vertColor[2] = - vertColor[3] = 0.0f; break; case CGEN_VERTEX: baseColor[0] = @@ -509,12 +509,10 @@ static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t baseColor[0] = baseColor[1] = baseColor[2] = tr.identityLight; - baseColor[3] = 1.0f; vertColor[0] = vertColor[1] = vertColor[2] = -tr.identityLight; - vertColor[3] = 0.0f; break; case CGEN_FOG: { @@ -527,22 +525,11 @@ static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t baseColor[2] = ((unsigned char *)(&fog->colorInt))[2] / 255.0f; baseColor[3] = ((unsigned char *)(&fog->colorInt))[3] / 255.0f; } - - vertColor[0] = - vertColor[1] = - vertColor[2] = - vertColor[3] = 0.0f; break; case CGEN_WAVEFORM: baseColor[0] = baseColor[1] = baseColor[2] = RB_CalcWaveColorSingle( &pStage->rgbWave ); - baseColor[3] = 1.0f; - - vertColor[0] = - vertColor[1] = - vertColor[2] = - vertColor[3] = 0.0f; break; case CGEN_ENTITY: if (backEnd.currentEntity) @@ -552,11 +539,6 @@ static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t baseColor[2] = ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[2] / 255.0f; baseColor[3] = ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[3] / 255.0f; } - - vertColor[0] = - vertColor[1] = - vertColor[2] = - vertColor[3] = 0.0f; break; case CGEN_ONE_MINUS_ENTITY: if (backEnd.currentEntity) @@ -566,23 +548,10 @@ static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t baseColor[2] = 1.0f - ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[2] / 255.0f; baseColor[3] = 1.0f - ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[3] / 255.0f; } - - vertColor[0] = - vertColor[1] = - vertColor[2] = - vertColor[3] = 0.0f; break; + case CGEN_IDENTITY: case CGEN_LIGHTING_DIFFUSE: case CGEN_BAD: - baseColor[0] = - baseColor[1] = - baseColor[2] = - baseColor[3] = 1.0f; - - vertColor[0] = - vertColor[1] = - vertColor[2] = - vertColor[3] = 0.0f; break; } @@ -593,10 +562,6 @@ static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t { case AGEN_SKIP: break; - case AGEN_IDENTITY: - baseColor[3] = 1.0f; - vertColor[3] = 0.0f; - break; case AGEN_CONST: baseColor[3] = pStage->constantColor[3] / 255.0f; vertColor[3] = 0.0f; @@ -627,9 +592,9 @@ static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t baseColor[3] = 1.0f; vertColor[3] = -1.0f; break; + case AGEN_IDENTITY: case AGEN_LIGHTING_SPECULAR: case AGEN_PORTAL: - case AGEN_FRESNEL: // Done entirely in vertex program baseColor[3] = 1.0f; vertColor[3] = 0.0f; @@ -749,7 +714,8 @@ static void ForwardDlight( void ) { dlight_t *dl; shaderProgram_t *sp; vec4_t vector; - matrix_t matrix; + vec4_t texMatrix; + vec4_t texOffTurb; if ( !( tess.dlightBits & ( 1 << l ) ) ) { continue; // this surface definately doesn't have any of this light @@ -776,6 +742,7 @@ static void ForwardDlight( void ) { GLSL_SetUniformMatrix16(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection); GLSL_SetUniformVec3(sp, UNIFORM_VIEWORIGIN, backEnd.viewParms.or.origin); + GLSL_SetUniformVec3(sp, UNIFORM_LOCALVIEWORIGIN, backEnd.or.viewOrigin); GLSL_SetUniformFloat(sp, UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation); @@ -851,13 +818,9 @@ static void ForwardDlight( void ) { GL_SelectTexture(0); } - ComputeTexMatrix( pStage, TB_DIFFUSEMAP, matrix ); - - VectorSet4(vector, matrix[0], matrix[1], matrix[4], matrix[5]); - GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, vector); - - VectorSet4(vector, matrix[8], matrix[9], matrix[12], matrix[13]); - GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, vector); + ComputeTexMods( pStage, TB_DIFFUSEMAP, texMatrix, texOffTurb ); + GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, texMatrix); + GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, texOffTurb); GLSL_SetUniformInt(sp, UNIFORM_TCGEN0, pStage->bundle[0].tcGen); @@ -982,7 +945,7 @@ static void RB_FogPass( void ) { if (deformGen != DGEN_NONE) index |= FOGDEF_USE_DEFORM_VERTEXES; - if (glState.vertexAttribsInterpolation) + if (glState.vertexAnimation) index |= FOGDEF_USE_VERTEX_ANIMATION; sp = &tr.fogShader[index]; @@ -1039,7 +1002,7 @@ static unsigned int RB_CalcShaderVertexAttribs( shaderCommands_t *input ) { unsigned int vertexAttribs = input->shader->vertexAttribs; - if(glState.vertexAttribsInterpolation > 0.0f) + if(glState.vertexAnimation) { vertexAttribs |= ATTR_POSITION2; if (vertexAttribs & ATTR_NORMAL) @@ -1058,7 +1021,6 @@ static unsigned int RB_CalcShaderVertexAttribs( shaderCommands_t *input ) static void RB_IterateStagesGeneric( shaderCommands_t *input ) { int stage; - matrix_t matrix; vec4_t fogDistanceVector, fogDepthVector = {0, 0, 0, 0}; float eyeT = 0; @@ -1074,6 +1036,8 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) { shaderStage_t *pStage = input->xstages[stage]; shaderProgram_t *sp; + vec4_t texMatrix; + vec4_t texOffTurb; if ( !pStage ) { @@ -1082,7 +1046,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) if (backEnd.depthFill) { - if (pStage->glslShaderGroup) + if (pStage->glslShaderGroup == tr.lightallShader) { int index = 0; @@ -1107,7 +1071,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) shaderAttribs |= GENERICDEF_USE_DEFORM_VERTEXES; } - if (glState.vertexAttribsInterpolation > 0.0f && backEnd.currentEntity && backEnd.currentEntity != &tr.worldEntity) + if (glState.vertexAnimation) { shaderAttribs |= GENERICDEF_USE_VERTEX_ANIMATION; } @@ -1120,7 +1084,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) sp = &tr.genericShader[shaderAttribs]; } } - else if (pStage->glslShaderGroup) + else if (pStage->glslShaderGroup == tr.lightallShader) { int index = pStage->glslShaderIndex; @@ -1146,10 +1110,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) sp = &pStage->glslShaderGroup[index]; - if (pStage->glslShaderGroup == tr.lightallShader) - { - backEnd.pc.c_lightallDraws++; - } + backEnd.pc.c_lightallDraws++; } else { @@ -1162,6 +1123,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) GLSL_SetUniformMatrix16(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection); GLSL_SetUniformVec3(sp, UNIFORM_VIEWORIGIN, backEnd.viewParms.or.origin); + GLSL_SetUniformVec3(sp, UNIFORM_LOCALVIEWORIGIN, backEnd.or.viewOrigin); GLSL_SetUniformFloat(sp, UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation); @@ -1210,8 +1172,9 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) VectorCopy(backEnd.currentEntity->lightDir, vec); vec[3] = 0.0f; GLSL_SetUniformVec4(sp, UNIFORM_LIGHTORIGIN, vec); + GLSL_SetUniformVec3(sp, UNIFORM_MODELLIGHTDIR, backEnd.currentEntity->modelLightDir); - GLSL_SetUniformFloat(sp, UNIFORM_LIGHTRADIUS, 999999.0f); + GLSL_SetUniformFloat(sp, UNIFORM_LIGHTRADIUS, 0.0f); } if (pStage->alphaGen == AGEN_PORTAL) @@ -1231,16 +1194,9 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) GLSL_SetUniformVec4(sp, UNIFORM_FOGCOLORMASK, fogColorMask); } - ComputeTexMatrix( pStage, TB_DIFFUSEMAP, matrix ); - - { - vec4_t vector; - VectorSet4(vector, matrix[0], matrix[1], matrix[4], matrix[5]); - GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, vector); - - VectorSet4(vector, matrix[8], matrix[9], matrix[12], matrix[13]); - GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, vector); - } + ComputeTexMods( pStage, TB_DIFFUSEMAP, texMatrix, texOffTurb ); + GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, texMatrix); + GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, texOffTurb); GLSL_SetUniformInt(sp, UNIFORM_TCGEN0, pStage->bundle[0].tcGen); if (pStage->bundle[0].tcGen == TCGEN_VECTOR) @@ -1269,7 +1225,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) else if ( pStage->bundle[TB_COLORMAP].image[0] != 0 ) R_BindAnimatedImageToTMU( &pStage->bundle[TB_COLORMAP], TB_COLORMAP ); } - else if ( pStage->glslShaderGroup ) + else if ( pStage->glslShaderGroup == tr.lightallShader ) { int i; @@ -1285,13 +1241,27 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) { for (i = 0; i < NUM_TEXTURE_BUNDLES; i++) { - if (i == TB_LIGHTMAP) + if (pStage->bundle[i].image[0]) { - R_BindAnimatedImageToTMU( &pStage->bundle[i], i); - } - else if (pStage->bundle[i].image[0]) - { - GL_BindToTMU( tr.whiteImage, i); + switch(i) + { + case TB_LIGHTMAP: + R_BindAnimatedImageToTMU( &pStage->bundle[TB_LIGHTMAP], i); + break; + + case TB_DIFFUSEMAP: + case TB_SPECULARMAP: + case TB_SHADOWMAP: + case TB_CUBEMAP: + default: + GL_BindToTMU( tr.whiteImage, i); + break; + + case TB_NORMALMAP: + case TB_DELUXEMAP: + GL_BindToTMU( tr.greyImage, i); + break; + } } } } @@ -1299,15 +1269,30 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) { for (i = 0; i < NUM_TEXTURE_BUNDLES; i++) { - if (i == TB_LIGHTMAP) + if (pStage->bundle[i].image[0]) { - R_BindAnimatedImageToTMU( &pStage->bundle[TB_DELUXEMAP], i); - } - else if (pStage->bundle[i].image[0]) - { - GL_BindToTMU( tr.whiteImage, i); + switch(i) + { + case TB_LIGHTMAP: + R_BindAnimatedImageToTMU( &pStage->bundle[TB_DELUXEMAP], i); + break; + + case TB_DIFFUSEMAP: + case TB_SPECULARMAP: + case TB_SHADOWMAP: + case TB_CUBEMAP: + default: + GL_BindToTMU( tr.whiteImage, i); + break; + + case TB_NORMALMAP: + case TB_DELUXEMAP: + GL_BindToTMU( tr.greyImage, i); + break; + } } } + } else { @@ -1340,12 +1325,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) // // set state // - if ( pStage->bundle[0].vertexLightmap && ( (r_vertexLight->integer && !r_uiFullScreen->integer) || glConfig.hardwareType == GLHW_PERMEDIA2 ) && r_lightmap->integer ) - { - GL_BindToTMU( tr.whiteImage, 0 ); - } - else - R_BindAnimatedImageToTMU( &pStage->bundle[0], 0 ); + R_BindAnimatedImageToTMU( &pStage->bundle[0], 0 ); GLSL_SetUniformInt(sp, UNIFORM_TEXTURE1ENV, 0); } @@ -1369,7 +1349,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) } // allow skipping out to show just lightmaps during development - if ( r_lightmap->integer && ( pStage->bundle[0].isLightmap || pStage->bundle[1].isLightmap || pStage->bundle[0].vertexLightmap ) ) + if ( r_lightmap->integer && ( pStage->bundle[0].isLightmap || pStage->bundle[1].isLightmap ) ) { break; } diff --git a/code/renderergl2/tr_shade_calc.c b/code/renderergl2/tr_shade_calc.c index a5c4e9ab..faab03e5 100644 --- a/code/renderergl2/tr_shade_calc.c +++ b/code/renderergl2/tr_shade_calc.c @@ -84,42 +84,16 @@ static float EvalWaveFormClamped( const waveForm_t *wf ) } /* -** RB_CalcStretchTexCoords +** RB_CalcStretchTexMatrix */ -void RB_CalcStretchTexCoords( const waveForm_t *wf, float *st ) -{ - float p; - texModInfo_t tmi; - - p = 1.0f / EvalWaveForm( wf ); - - tmi.matrix[0][0] = p; - tmi.matrix[1][0] = 0; - tmi.translate[0] = 0.5f - 0.5f * p; - - tmi.matrix[0][1] = 0; - tmi.matrix[1][1] = p; - tmi.translate[1] = 0.5f - 0.5f * p; - - RB_CalcTransformTexCoords( &tmi, st ); -} - void RB_CalcStretchTexMatrix( const waveForm_t *wf, float *matrix ) { float p; - texModInfo_t tmi; p = 1.0f / EvalWaveForm( wf ); - tmi.matrix[0][0] = p; - tmi.matrix[1][0] = 0; - tmi.translate[0] = 0.5f - 0.5f * p; - - tmi.matrix[0][1] = 0; - tmi.matrix[1][1] = p; - tmi.translate[1] = 0.5f - 0.5f * p; - - RB_CalcTransformTexMatrix( &tmi, matrix ); + matrix[0] = p; matrix[2] = 0; matrix[4] = 0.5f - 0.5f * p; + matrix[1] = 0; matrix[3] = p; matrix[5] = 0.5f - 0.5f * p; } /* @@ -618,88 +592,6 @@ COLORS */ -/* -** RB_CalcColorFromEntity -*/ -void RB_CalcColorFromEntity( unsigned char *dstColors ) -{ - int i; - int *pColors = ( int * ) dstColors; - int c; - - if ( !backEnd.currentEntity ) - return; - - c = * ( int * ) backEnd.currentEntity->e.shaderRGBA; - - for ( i = 0; i < tess.numVertexes; i++, pColors++ ) - { - *pColors = c; - } -} - -/* -** RB_CalcColorFromOneMinusEntity -*/ -void RB_CalcColorFromOneMinusEntity( unsigned char *dstColors ) -{ - int i; - int *pColors = ( int * ) dstColors; - unsigned char invModulate[4]; - int c; - - if ( !backEnd.currentEntity ) - return; - - invModulate[0] = 255 - backEnd.currentEntity->e.shaderRGBA[0]; - invModulate[1] = 255 - backEnd.currentEntity->e.shaderRGBA[1]; - invModulate[2] = 255 - backEnd.currentEntity->e.shaderRGBA[2]; - invModulate[3] = 255 - backEnd.currentEntity->e.shaderRGBA[3]; // this trashes alpha, but the AGEN block fixes it - - c = * ( int * ) invModulate; - - for ( i = 0; i < tess.numVertexes; i++, pColors++ ) - { - *pColors = c; - } -} - -/* -** RB_CalcAlphaFromEntity -*/ -void RB_CalcAlphaFromEntity( unsigned char *dstColors ) -{ - int i; - - if ( !backEnd.currentEntity ) - return; - - dstColors += 3; - - for ( i = 0; i < tess.numVertexes; i++, dstColors += 4 ) - { - *dstColors = backEnd.currentEntity->e.shaderRGBA[3]; - } -} - -/* -** RB_CalcAlphaFromOneMinusEntity -*/ -void RB_CalcAlphaFromOneMinusEntity( unsigned char *dstColors ) -{ - int i; - - if ( !backEnd.currentEntity ) - return; - - dstColors += 3; - - for ( i = 0; i < tess.numVertexes; i++, dstColors += 4 ) - { - *dstColors = 0xff - backEnd.currentEntity->e.shaderRGBA[3]; - } -} - /* ** RB_CalcWaveColorSingle */ @@ -723,29 +615,6 @@ float RB_CalcWaveColorSingle( const waveForm_t *wf ) return glow; } -/* -** RB_CalcWaveColor -*/ -void RB_CalcWaveColor( const waveForm_t *wf, unsigned char *dstColors ) -{ - int i; - int v; - float glow; - int *colors = ( int * ) dstColors; - byte color[4]; - - glow = RB_CalcWaveColorSingle( wf ); - - v = ri.ftol(255 * glow); - color[0] = color[1] = color[2] = v; - color[3] = 255; - v = *(int *)color; - - for ( i = 0; i < tess.numVertexes; i++, colors++ ) { - *colors = v; - } -} - /* ** RB_CalcWaveAlphaSingle */ @@ -754,25 +623,6 @@ float RB_CalcWaveAlphaSingle( const waveForm_t *wf ) return EvalWaveFormClamped( wf ); } -/* -** RB_CalcWaveAlpha -*/ -void RB_CalcWaveAlpha( const waveForm_t *wf, unsigned char *dstColors ) -{ - int i; - int v; - float glow; - - glow = EvalWaveFormClamped( wf ); - - v = 255 * glow; - - for ( i = 0; i < tess.numVertexes; i++, dstColors += 4 ) - { - dstColors[3] = v; - } -} - /* ** RB_CalcModulateColorsByFog */ @@ -793,45 +643,6 @@ void RB_CalcModulateColorsByFog( unsigned char *colors ) { } } -/* -** RB_CalcModulateAlphasByFog -*/ -void RB_CalcModulateAlphasByFog( unsigned char *colors ) { - int i; - float texCoords[SHADER_MAX_VERTEXES][2]; - - // calculate texcoords so we can derive density - // this is not wasted, because it would only have - // been previously called if the surface was opaque - RB_CalcFogTexCoords( texCoords[0] ); - - for ( i = 0; i < tess.numVertexes; i++, colors += 4 ) { - float f = 1.0 - R_FogFactor( texCoords[i][0], texCoords[i][1] ); - colors[3] *= f; - } -} - -/* -** RB_CalcModulateRGBAsByFog -*/ -void RB_CalcModulateRGBAsByFog( unsigned char *colors ) { - int i; - float texCoords[SHADER_MAX_VERTEXES][2]; - - // calculate texcoords so we can derive density - // this is not wasted, because it would only have - // been previously called if the surface was opaque - RB_CalcFogTexCoords( texCoords[0] ); - - for ( i = 0; i < tess.numVertexes; i++, colors += 4 ) { - float f = 1.0 - R_FogFactor( texCoords[i][0], texCoords[i][1] ); - colors[0] *= f; - colors[1] *= f; - colors[2] *= f; - colors[3] *= f; - } -} - /* ==================================================================== @@ -928,118 +739,27 @@ void RB_CalcFogTexCoords( float *st ) { } } - - /* -** RB_CalcEnvironmentTexCoords +** RB_CalcTurbulentFactors */ -void RB_CalcEnvironmentTexCoords( float *st ) +void RB_CalcTurbulentFactors( const waveForm_t *wf, float *amplitude, float *now ) { - int i; - float *v, *normal; - vec3_t viewer, reflected; - float d; - - v = tess.xyz[0]; - normal = tess.normal[0]; - - for (i = 0 ; i < tess.numVertexes ; i++, v += 4, normal += 4, st += 2 ) - { - VectorSubtract (backEnd.or.viewOrigin, v, viewer); - VectorNormalizeFast (viewer); - - d = DotProduct (normal, viewer); - - reflected[0] = normal[0]*2*d - viewer[0]; - reflected[1] = normal[1]*2*d - viewer[1]; - reflected[2] = normal[2]*2*d - viewer[2]; - - st[0] = 0.5 + reflected[1] * 0.5; - st[1] = 0.5 - reflected[2] * 0.5; - } + *now = wf->phase + tess.shaderTime * wf->frequency; + *amplitude = wf->amplitude; } /* -** RB_CalcTurbulentTexCoords +** RB_CalcScaleTexMatrix */ -void RB_CalcTurbulentTexCoords( const waveForm_t *wf, float *st ) -{ - int i; - float now; - - now = ( wf->phase + tess.shaderTime * wf->frequency ); - - for ( i = 0; i < tess.numVertexes; i++, st += 2 ) - { - float s = st[0]; - float t = st[1]; - - st[0] = s + tr.sinTable[ ( ( int ) ( ( ( tess.xyz[i][0] + tess.xyz[i][2] )* 1.0/128 * 0.125 + now ) * FUNCTABLE_SIZE ) ) & ( FUNCTABLE_MASK ) ] * wf->amplitude; - st[1] = t + tr.sinTable[ ( ( int ) ( ( tess.xyz[i][1] * 1.0/128 * 0.125 + now ) * FUNCTABLE_SIZE ) ) & ( FUNCTABLE_MASK ) ] * wf->amplitude; - } -} - -void RB_CalcTurbulentTexMatrix( const waveForm_t *wf, matrix_t matrix ) -{ - float now; - - now = ( wf->phase + tess.shaderTime * wf->frequency ); - - // bit of a hack here, hide amplitude and now in the matrix - // the vertex program will extract them and perform a turbulent pass last if it's nonzero - - matrix[ 0] = 1.0f; matrix[ 4] = 0.0f; matrix[ 8] = 0.0f; matrix[12] = wf->amplitude; - matrix[ 1] = 0.0f; matrix[ 5] = 1.0f; matrix[ 9] = 0.0f; matrix[13] = now; - matrix[ 2] = 0.0f; matrix[ 6] = 0.0f; matrix[10] = 1.0f; matrix[14] = 0.0f; - matrix[ 3] = 0.0f; matrix[ 7] = 0.0f; matrix[11] = 0.0f; matrix[15] = 1.0f; -} - -/* -** RB_CalcScaleTexCoords -*/ -void RB_CalcScaleTexCoords( const float scale[2], float *st ) -{ - int i; - - for ( i = 0; i < tess.numVertexes; i++, st += 2 ) - { - st[0] *= scale[0]; - st[1] *= scale[1]; - } -} - void RB_CalcScaleTexMatrix( const float scale[2], float *matrix ) { - matrix[ 0] = scale[0]; matrix[ 4] = 0.0f; matrix[ 8] = 0.0f; matrix[12] = 0.0f; - matrix[ 1] = 0.0f; matrix[ 5] = scale[1]; matrix[ 9] = 0.0f; matrix[13] = 0.0f; - matrix[ 2] = 0.0f; matrix[ 6] = 0.0f; matrix[10] = 1.0f; matrix[14] = 0.0f; - matrix[ 3] = 0.0f; matrix[ 7] = 0.0f; matrix[11] = 0.0f; matrix[15] = 1.0f; + matrix[0] = scale[0]; matrix[2] = 0.0f; matrix[4] = 0.0f; + matrix[1] = 0.0f; matrix[3] = scale[1]; matrix[5] = 0.0f; } /* -** RB_CalcScrollTexCoords +** RB_CalcScrollTexMatrix */ -void RB_CalcScrollTexCoords( const float scrollSpeed[2], float *st ) -{ - int i; - float timeScale = tess.shaderTime; - float adjustedScrollS, adjustedScrollT; - - adjustedScrollS = scrollSpeed[0] * timeScale; - adjustedScrollT = scrollSpeed[1] * timeScale; - - // clamp so coordinates don't continuously get larger, causing problems - // with hardware limits - adjustedScrollS = adjustedScrollS - floor( adjustedScrollS ); - adjustedScrollT = adjustedScrollT - floor( adjustedScrollT ); - - for ( i = 0; i < tess.numVertexes; i++, st += 2 ) - { - st[0] += adjustedScrollS; - st[1] += adjustedScrollT; - } -} - void RB_CalcScrollTexMatrix( const float scrollSpeed[2], float *matrix ) { float timeScale = tess.shaderTime; @@ -1053,73 +773,28 @@ void RB_CalcScrollTexMatrix( const float scrollSpeed[2], float *matrix ) adjustedScrollS = adjustedScrollS - floor( adjustedScrollS ); adjustedScrollT = adjustedScrollT - floor( adjustedScrollT ); - - matrix[ 0] = 1.0f; matrix[ 4] = 0.0f; matrix[ 8] = adjustedScrollS; matrix[12] = 0.0f; - matrix[ 1] = 0.0f; matrix[ 5] = 1.0f; matrix[ 9] = adjustedScrollT; matrix[13] = 0.0f; - matrix[ 2] = 0.0f; matrix[ 6] = 0.0f; matrix[10] = 1.0f; matrix[14] = 0.0f; - matrix[ 3] = 0.0f; matrix[ 7] = 0.0f; matrix[11] = 0.0f; matrix[15] = 1.0f; + matrix[0] = 1.0f; matrix[2] = 0.0f; matrix[4] = adjustedScrollS; + matrix[1] = 0.0f; matrix[3] = 1.0f; matrix[5] = adjustedScrollT; } /* -** RB_CalcTransformTexCoords +** RB_CalcTransformTexMatrix */ -void RB_CalcTransformTexCoords( const texModInfo_t *tmi, float *st ) -{ - int i; - - for ( i = 0; i < tess.numVertexes; i++, st += 2 ) - { - float s = st[0]; - float t = st[1]; - - st[0] = s * tmi->matrix[0][0] + t * tmi->matrix[1][0] + tmi->translate[0]; - st[1] = s * tmi->matrix[0][1] + t * tmi->matrix[1][1] + tmi->translate[1]; - } -} - void RB_CalcTransformTexMatrix( const texModInfo_t *tmi, float *matrix ) { - matrix[ 0] = tmi->matrix[0][0]; matrix[ 4] = tmi->matrix[1][0]; matrix[ 8] = tmi->translate[0]; matrix[12] = 0.0f; - matrix[ 1] = tmi->matrix[0][1]; matrix[ 5] = tmi->matrix[1][1]; matrix[ 9] = tmi->translate[1]; matrix[13] = 0.0f; - matrix[ 2] = 0.0f; matrix[ 6] = 0.0f; matrix[10] = 1.0f; matrix[14] = 0.0f; - matrix[ 3] = 0.0f; matrix[ 7] = 0.0f; matrix[11] = 0.0f; matrix[15] = 1.0f; + matrix[0] = tmi->matrix[0][0]; matrix[2] = tmi->matrix[1][0]; matrix[4] = tmi->translate[0]; + matrix[1] = tmi->matrix[0][1]; matrix[3] = tmi->matrix[1][1]; matrix[5] = tmi->translate[1]; } /* -** RB_CalcRotateTexCoords +** RB_CalcRotateTexMatrix */ -void RB_CalcRotateTexCoords( float degsPerSecond, float *st ) -{ - float timeScale = tess.shaderTime; - float degs; - int index; - float sinValue, cosValue; - texModInfo_t tmi; - - degs = -degsPerSecond * timeScale; - index = degs * ( FUNCTABLE_SIZE / 360.0f ); - - sinValue = tr.sinTable[ index & FUNCTABLE_MASK ]; - cosValue = tr.sinTable[ ( index + FUNCTABLE_SIZE / 4 ) & FUNCTABLE_MASK ]; - - tmi.matrix[0][0] = cosValue; - tmi.matrix[1][0] = -sinValue; - tmi.translate[0] = 0.5 - 0.5 * cosValue + 0.5 * sinValue; - - tmi.matrix[0][1] = sinValue; - tmi.matrix[1][1] = cosValue; - tmi.translate[1] = 0.5 - 0.5 * sinValue - 0.5 * cosValue; - - RB_CalcTransformTexCoords( &tmi, st ); -} - void RB_CalcRotateTexMatrix( float degsPerSecond, float *matrix ) { float timeScale = tess.shaderTime; float degs; int index; float sinValue, cosValue; - texModInfo_t tmi; degs = -degsPerSecond * timeScale; index = degs * ( FUNCTABLE_SIZE / 360.0f ); @@ -1127,213 +802,6 @@ void RB_CalcRotateTexMatrix( float degsPerSecond, float *matrix ) sinValue = tr.sinTable[ index & FUNCTABLE_MASK ]; cosValue = tr.sinTable[ ( index + FUNCTABLE_SIZE / 4 ) & FUNCTABLE_MASK ]; - tmi.matrix[0][0] = cosValue; - tmi.matrix[1][0] = -sinValue; - tmi.translate[0] = 0.5 - 0.5 * cosValue + 0.5 * sinValue; - - tmi.matrix[0][1] = sinValue; - tmi.matrix[1][1] = cosValue; - tmi.translate[1] = 0.5 - 0.5 * sinValue - 0.5 * cosValue; - - RB_CalcTransformTexMatrix( &tmi, matrix ); + matrix[0] = cosValue; matrix[2] = -sinValue; matrix[4] = 0.5 - 0.5 * cosValue + 0.5 * sinValue; + matrix[1] = sinValue; matrix[3] = cosValue; matrix[5] = 0.5 - 0.5 * sinValue - 0.5 * cosValue; } -/* -** RB_CalcSpecularAlpha -** -** Calculates specular coefficient and places it in the alpha channel -*/ -vec3_t lightOrigin = { -960, 1980, 96 }; // FIXME: track dynamically - -void RB_CalcSpecularAlpha( unsigned char *alphas ) { - int i; - float *v, *normal; - vec3_t viewer, reflected; - float l, d; - int b; - vec3_t lightDir; - int numVertexes; - - v = tess.xyz[0]; - normal = tess.normal[0]; - - alphas += 3; - - numVertexes = tess.numVertexes; - for (i = 0 ; i < numVertexes ; i++, v += 4, normal += 4, alphas += 4) { - float ilength; - - VectorSubtract( lightOrigin, v, lightDir ); -// ilength = Q_rsqrt( DotProduct( lightDir, lightDir ) ); - VectorNormalizeFast( lightDir ); - - // calculate the specular color - d = DotProduct (normal, lightDir); -// d *= ilength; - - // we don't optimize for the d < 0 case since this tends to - // cause visual artifacts such as faceted "snapping" - reflected[0] = normal[0]*2*d - lightDir[0]; - reflected[1] = normal[1]*2*d - lightDir[1]; - reflected[2] = normal[2]*2*d - lightDir[2]; - - VectorSubtract (backEnd.or.viewOrigin, v, viewer); - ilength = Q_rsqrt( DotProduct( viewer, viewer ) ); - l = DotProduct (reflected, viewer); - l *= ilength; - - if (l < 0) { - b = 0; - } else { - l = l*l; - l = l*l; - b = l * 255; - if (b > 255) { - b = 255; - } - } - - *alphas = b; - } -} - -/* -** RB_CalcDiffuseColor -** -** The basic vertex lighting calc -*/ -#if idppc_altivec -static void RB_CalcDiffuseColor_altivec( unsigned char *colors ) -{ - int i; - float *v, *normal; - trRefEntity_t *ent; - int ambientLightInt; - vec3_t lightDir; - int numVertexes; - vector unsigned char vSel = VECCONST_UINT8(0x00, 0x00, 0x00, 0xff, - 0x00, 0x00, 0x00, 0xff, - 0x00, 0x00, 0x00, 0xff, - 0x00, 0x00, 0x00, 0xff); - vector float ambientLightVec; - vector float directedLightVec; - vector float lightDirVec; - vector float normalVec0, normalVec1; - vector float incomingVec0, incomingVec1, incomingVec2; - vector float zero, jVec; - vector signed int jVecInt; - vector signed short jVecShort; - vector unsigned char jVecChar, normalPerm; - ent = backEnd.currentEntity; - ambientLightInt = ent->ambientLightInt; - // A lot of this could be simplified if we made sure - // entities light info was 16-byte aligned. - jVecChar = vec_lvsl(0, ent->ambientLight); - ambientLightVec = vec_ld(0, (vector float *)ent->ambientLight); - jVec = vec_ld(11, (vector float *)ent->ambientLight); - ambientLightVec = vec_perm(ambientLightVec,jVec,jVecChar); - - jVecChar = vec_lvsl(0, ent->directedLight); - directedLightVec = vec_ld(0,(vector float *)ent->directedLight); - jVec = vec_ld(11,(vector float *)ent->directedLight); - directedLightVec = vec_perm(directedLightVec,jVec,jVecChar); - - jVecChar = vec_lvsl(0, ent->lightDir); - lightDirVec = vec_ld(0,(vector float *)ent->lightDir); - jVec = vec_ld(11,(vector float *)ent->lightDir); - lightDirVec = vec_perm(lightDirVec,jVec,jVecChar); - - zero = (vector float)vec_splat_s8(0); - VectorCopy( ent->lightDir, lightDir ); - - v = tess.xyz[0]; - normal = tess.normal[0]; - - normalPerm = vec_lvsl(0,normal); - numVertexes = tess.numVertexes; - for (i = 0 ; i < numVertexes ; i++, v += 4, normal += 4) { - normalVec0 = vec_ld(0,(vector float *)normal); - normalVec1 = vec_ld(11,(vector float *)normal); - normalVec0 = vec_perm(normalVec0,normalVec1,normalPerm); - incomingVec0 = vec_madd(normalVec0, lightDirVec, zero); - incomingVec1 = vec_sld(incomingVec0,incomingVec0,4); - incomingVec2 = vec_add(incomingVec0,incomingVec1); - incomingVec1 = vec_sld(incomingVec1,incomingVec1,4); - incomingVec2 = vec_add(incomingVec2,incomingVec1); - incomingVec0 = vec_splat(incomingVec2,0); - incomingVec0 = vec_max(incomingVec0,zero); - normalPerm = vec_lvsl(12,normal); - jVec = vec_madd(incomingVec0, directedLightVec, ambientLightVec); - jVecInt = vec_cts(jVec,0); // RGBx - jVecShort = vec_pack(jVecInt,jVecInt); // RGBxRGBx - jVecChar = vec_packsu(jVecShort,jVecShort); // RGBxRGBxRGBxRGBx - jVecChar = vec_sel(jVecChar,vSel,vSel); // RGBARGBARGBARGBA replace alpha with 255 - vec_ste((vector unsigned int)jVecChar,0,(unsigned int *)&colors[i*4]); // store color - } -} -#endif - -static void RB_CalcDiffuseColor_scalar( unsigned char *colors ) -{ - int i, j; - float *v, *normal; - float incoming; - trRefEntity_t *ent; - int ambientLightInt; - vec3_t ambientLight; - vec3_t lightDir; - vec3_t directedLight; - int numVertexes; - ent = backEnd.currentEntity; - ambientLightInt = ent->ambientLightInt; - VectorCopy( ent->ambientLight, ambientLight ); - VectorCopy( ent->directedLight, directedLight ); - VectorCopy( ent->lightDir, lightDir ); - - v = tess.xyz[0]; - normal = tess.normal[0]; - - numVertexes = tess.numVertexes; - for (i = 0 ; i < numVertexes ; i++, v += 4, normal += 4) { - incoming = DotProduct (normal, lightDir); - if ( incoming <= 0 ) { - *(int *)&colors[i*4] = ambientLightInt; - continue; - } - j = ri.ftol(ambientLight[0] + incoming * directedLight[0]); - if ( j > 255 ) { - j = 255; - } - colors[i*4+0] = j; - - j = ri.ftol(ambientLight[1] + incoming * directedLight[1]); - if ( j > 255 ) { - j = 255; - } - colors[i*4+1] = j; - - j = ri.ftol(ambientLight[2] + incoming * directedLight[2]); - if ( j > 255 ) { - j = 255; - } - colors[i*4+2] = j; - - colors[i*4+3] = 255; - } -} - -void RB_CalcDiffuseColor( unsigned char *colors ) -{ -#if idppc_altivec - if (com_altivec->integer) { - // must be in a seperate function or G3 systems will crash. - RB_CalcDiffuseColor_altivec( colors ); - return; - } -#endif - RB_CalcDiffuseColor_scalar( colors ); -} - - - - - diff --git a/code/renderergl2/tr_shader.c b/code/renderergl2/tr_shader.c index c246127d..7ff74feb 100644 --- a/code/renderergl2/tr_shader.c +++ b/code/renderergl2/tr_shader.c @@ -1109,10 +1109,6 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) shader.portalRange = atof( token ); } } - else if ( !Q_stricmp( token, "fresnel" ) ) - { - stage->alphaGen = AGEN_FRESNEL; - } else { ri.Printf( PRINT_WARNING, "WARNING: unknown alphaGen parameter '%s' in shader '%s'\n", token, shader.name ); @@ -2011,7 +2007,6 @@ static void ComputeVertexAttribs(void) switch(pStage->alphaGen) { case AGEN_LIGHTING_SPECULAR: - case AGEN_FRESNEL: shader.vertexAttribs |= ATTR_NORMAL; break; @@ -2247,15 +2242,6 @@ static void CollapseStagesToLightall(shaderStage_t *diffuse, defs |= LIGHTDEF_USE_PARALLAXMAP; } } - - if (!diffuse->bundle[TB_NORMALMAP].image[0]) - { - // use 0x80 image, shader will interpret as (0,0,1) - diffuse->bundle[TB_NORMALMAP] = diffuse->bundle[0]; - diffuse->bundle[TB_NORMALMAP].numImageAnimations = 0; - diffuse->bundle[TB_NORMALMAP].image[0] = tr.greyImage; - //ri.Printf(PRINT_ALL, ", normalmap %s", diffuse->bundle[TB_NORMALMAP].image[0]->imgName); - } } if (r_specularMapping->integer) @@ -2267,18 +2253,6 @@ static void CollapseStagesToLightall(shaderStage_t *diffuse, diffuse->materialInfo[0] = specular->materialInfo[0]; diffuse->materialInfo[1] = specular->materialInfo[1]; } - else if (lightmap || useLightVector || useLightVertex) - { - // use a white image, materialinfo will do the rest - diffuse->bundle[TB_SPECULARMAP] = diffuse->bundle[0]; - diffuse->bundle[TB_SPECULARMAP].numImageAnimations = 0; - diffuse->bundle[TB_SPECULARMAP].image[0] = tr.whiteImage; - if (!diffuse->materialInfo[0]) - diffuse->materialInfo[0] = r_baseSpecular->value; - if (!diffuse->materialInfo[1]) - diffuse->materialInfo[1] = r_baseGloss->value; - //ri.Printf(PRINT_ALL, ", specularmap %s", diffuse->bundle[TB_SPECULARMAP].image[0]->imgName); - } } if (tcgen || diffuse->bundle[0].numTexMods) @@ -2308,7 +2282,7 @@ static qboolean CollapseStagesToGLSL(void) { // if 2+ stages and first stage is lightmap, switch them // this makes it easier for the later bits to process - if (stages[0].active && stages[0].bundle[0].isLightmap && stages[1].active) + if (stages[0].active && stages[0].bundle[0].tcGen == TCGEN_LIGHTMAP && stages[1].active) { int blendBits = stages[1].stateBits & ( GLS_DSTBLEND_BITS | GLS_SRCBLEND_BITS ); @@ -2345,7 +2319,7 @@ static qboolean CollapseStagesToGLSL(void) break; } - if (pStage->bundle[0].isLightmap) + if (pStage->bundle[0].tcGen == TCGEN_LIGHTMAP) { int blendBits = pStage->stateBits & ( GLS_DSTBLEND_BITS | GLS_SRCBLEND_BITS ); @@ -2362,6 +2336,7 @@ static qboolean CollapseStagesToGLSL(void) case TCGEN_TEXTURE: case TCGEN_LIGHTMAP: case TCGEN_ENVIRONMENT_MAPPED: + case TCGEN_VECTOR: break; default: skip = qtrue; @@ -2372,7 +2347,6 @@ static qboolean CollapseStagesToGLSL(void) { case AGEN_LIGHTING_SPECULAR: case AGEN_PORTAL: - case AGEN_FRESNEL: skip = qtrue; break; default: @@ -2397,7 +2371,7 @@ static qboolean CollapseStagesToGLSL(void) continue; // skip lightmaps - if (pStage->bundle[0].isLightmap) + if (pStage->bundle[0].tcGen == TCGEN_LIGHTMAP) continue; diffuse = pStage; @@ -2439,7 +2413,7 @@ static qboolean CollapseStagesToGLSL(void) break; case ST_COLORMAP: - if (pStage2->bundle[0].isLightmap) + if (pStage2->bundle[0].tcGen == TCGEN_LIGHTMAP) { lightmap = pStage2; } @@ -2481,7 +2455,7 @@ static qboolean CollapseStagesToGLSL(void) if (!pStage->active) continue; - if (pStage->bundle[0].isLightmap) + if (pStage->bundle[0].tcGen == TCGEN_LIGHTMAP) { pStage->active = qfalse; } @@ -2547,7 +2521,7 @@ static qboolean CollapseStagesToGLSL(void) if (pStage->adjustColorsForFog) continue; - if (pStage->bundle[TB_DIFFUSEMAP].isLightmap) + if (pStage->bundle[TB_DIFFUSEMAP].tcGen == TCGEN_LIGHTMAP) { pStage->glslShaderGroup = tr.lightallShader; pStage->glslShaderIndex = LIGHTDEF_USE_LIGHTMAP; @@ -2556,6 +2530,7 @@ static qboolean CollapseStagesToGLSL(void) pStage->bundle[TB_LIGHTMAP] = pStage->bundle[TB_DIFFUSEMAP]; pStage->bundle[TB_DIFFUSEMAP].image[0] = tr.whiteImage; pStage->bundle[TB_DIFFUSEMAP].isLightmap = qfalse; + pStage->bundle[TB_DIFFUSEMAP].tcGen = TCGEN_TEXTURE; } } } @@ -2577,11 +2552,14 @@ static qboolean CollapseStagesToGLSL(void) { pStage->glslShaderGroup = tr.lightallShader; pStage->glslShaderIndex = LIGHTDEF_USE_LIGHT_VECTOR; + + if (pStage->bundle[0].tcGen != TCGEN_TEXTURE || pStage->bundle[0].numTexMods != 0) + pStage->glslShaderIndex |= LIGHTDEF_USE_TCGEN_AND_TCMOD; } } } - // convert any remaining lightingdiffuse stages to a lighting pass + // insert default normal and specular textures if necessary for (i = 0; i < MAX_SHADER_STAGES; i++) { shaderStage_t *pStage = &stages[i]; @@ -2589,14 +2567,27 @@ static qboolean CollapseStagesToGLSL(void) if (!pStage->active) continue; - if (pStage->rgbGen == CGEN_LIGHTING_DIFFUSE) + if (pStage->glslShaderGroup != tr.lightallShader) + continue; + + if ((pStage->glslShaderIndex & LIGHTDEF_LIGHTTYPE_MASK) == 0) + continue; + + if (!pStage->bundle[TB_NORMALMAP].image[0] && r_normalMapping->integer) { - pStage->glslShaderGroup = tr.lightallShader; - pStage->glslShaderIndex = LIGHTDEF_USE_LIGHT_VECTOR; + pStage->bundle[TB_NORMALMAP].image[0] = tr.greyImage; + } + + if (!pStage->bundle[TB_SPECULARMAP].image[0] && r_specularMapping->integer) + { + pStage->bundle[TB_SPECULARMAP].image[0] = tr.whiteImage; + if (!pStage->materialInfo[0]) + pStage->materialInfo[0] = r_baseSpecular->value; + if (!pStage->materialInfo[1]) + pStage->materialInfo[1] = r_baseGloss->value; } } - return numStages; } diff --git a/code/renderergl2/tr_surface.c b/code/renderergl2/tr_surface.c index 06072a82..5102e1d1 100644 --- a/code/renderergl2/tr_surface.c +++ b/code/renderergl2/tr_surface.c @@ -522,7 +522,7 @@ static qboolean RB_SurfaceVbo(VBO_t *vbo, IBO_t *ibo, int numVerts, int numIndex RB_SurfaceTriangles ============= */ -static void RB_SurfaceTriangles( srfTriangles_t *srf ) { +static void RB_SurfaceTriangles( srfBspSurface_t *srf ) { if( RB_SurfaceVbo (srf->vbo, srf->ibo, srf->numVerts, srf->numTriangles * 3, srf->firstIndex, srf->minIndex, srf->maxIndex, srf->dlightBits, srf->pshadowBits, qtrue ) ) { @@ -1247,7 +1247,7 @@ static void RB_SurfaceMesh(mdvSurface_t *surface) { RB_SurfaceFace ============== */ -static void RB_SurfaceFace( srfSurfaceFace_t *srf ) { +static void RB_SurfaceFace( srfBspSurface_t *srf ) { if( RB_SurfaceVbo (srf->vbo, srf->ibo, srf->numVerts, srf->numTriangles * 3, srf->firstIndex, srf->minIndex, srf->maxIndex, srf->dlightBits, srf->pshadowBits, qtrue ) ) { @@ -1296,7 +1296,7 @@ RB_SurfaceGrid Just copy the grid of points and triangulate ============= */ -static void RB_SurfaceGrid( srfGridMesh_t *srf ) { +static void RB_SurfaceGrid( srfBspSurface_t *srf ) { int i, j; float *xyz; float *texCoords, *lightCoords; @@ -1574,9 +1574,9 @@ static void RB_SurfaceFlare(srfFlare_t *surf) RB_AddFlare(surf, tess.fogNum, surf->origin, surf->color, surf->normal); } -static void RB_SurfaceVBOMesh(srfVBOMesh_t * srf) +static void RB_SurfaceVBOMesh(srfBspSurface_t * srf) { - RB_SurfaceVbo (srf->vbo, srf->ibo, srf->numVerts, srf->numIndexes, srf->firstIndex, + RB_SurfaceVbo (srf->vbo, srf->ibo, srf->numVerts, srf->numTriangles * 3, srf->firstIndex, srf->minIndex, srf->maxIndex, srf->dlightBits, srf->pshadowBits, qfalse ); } @@ -1621,11 +1621,12 @@ void RB_SurfaceVBOMDVMesh(srfVBOMDVMesh_t * surface) glState.vertexAttribsOldFrame = refEnt->oldframe; glState.vertexAttribsNewFrame = refEnt->frame; + glState.vertexAnimation = qtrue; RB_EndSurface(); // So we don't lerp surfaces that shouldn't be lerped - glState.vertexAttribsInterpolation = 0; + glState.vertexAnimation = qfalse; } static void RB_SurfaceDisplayList( srfDisplayList_t *surf ) { diff --git a/code/renderergl2/tr_vbo.c b/code/renderergl2/tr_vbo.c index e9f2598b..11eb3ceb 100644 --- a/code/renderergl2/tr_vbo.c +++ b/code/renderergl2/tr_vbo.c @@ -608,6 +608,7 @@ void R_BindVBO(VBO_t * vbo) glState.vertexAttribsInterpolation = 0; glState.vertexAttribsOldFrame = 0; glState.vertexAttribsNewFrame = 0; + glState.vertexAnimation = qfalse; qglBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo->vertexesVBO); @@ -856,6 +857,9 @@ void RB_UpdateVBOs(unsigned int attribBits) { R_BindVBO(tess.vbo); + // orphan old buffer so we don't stall on it + qglBufferDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->vertexesSize, NULL, GL_DYNAMIC_DRAW_ARB); + if(attribBits & ATTR_BITS) { if(attribBits & ATTR_POSITION) @@ -923,6 +927,9 @@ void RB_UpdateVBOs(unsigned int attribBits) { R_BindIBO(tess.ibo); + // orphan old buffer so we don't stall on it + qglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, tess.ibo->indexesSize, NULL, GL_DYNAMIC_DRAW_ARB); + qglBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, tess.numIndexes * sizeof(tess.indexes[0]), tess.indexes); } } diff --git a/code/renderergl2/tr_world.c b/code/renderergl2/tr_world.c index 0ee4ad28..dba15c45 100644 --- a/code/renderergl2/tr_world.c +++ b/code/renderergl2/tr_world.c @@ -208,16 +208,18 @@ static int R_DlightSurface( msurface_t *surf, int dlightBits ) { } } - if ( *surf->data == SF_FACE ) { - ((srfSurfaceFace_t *)surf->data)->dlightBits = dlightBits; - } else if ( *surf->data == SF_GRID ) { - ((srfGridMesh_t *)surf->data)->dlightBits = dlightBits; - } else if ( *surf->data == SF_TRIANGLES ) { - ((srfTriangles_t *)surf->data)->dlightBits = dlightBits; - } else if ( *surf->data == SF_VBO_MESH ) { - ((srfVBOMesh_t *)surf->data)->dlightBits = dlightBits; - } else { - dlightBits = 0; + switch(*surf->data) + { + case SF_FACE: + case SF_GRID: + case SF_TRIANGLES: + case SF_VBO_MESH: + ((srfBspSurface_t *)surf->data)->dlightBits = dlightBits; + break; + + default: + dlightBits = 0; + break; } if ( dlightBits ) { @@ -292,16 +294,18 @@ static int R_PshadowSurface( msurface_t *surf, int pshadowBits ) { } } - if ( *surf->data == SF_FACE ) { - ((srfSurfaceFace_t *)surf->data)->pshadowBits = pshadowBits; - } else if ( *surf->data == SF_GRID ) { - ((srfGridMesh_t *)surf->data)->pshadowBits = pshadowBits; - } else if ( *surf->data == SF_TRIANGLES ) { - ((srfTriangles_t *)surf->data)->pshadowBits = pshadowBits; - } else if ( *surf->data == SF_VBO_MESH ) { - ((srfVBOMesh_t *)surf->data)->pshadowBits = pshadowBits; - } else { - pshadowBits = 0; + switch(*surf->data) + { + case SF_FACE: + case SF_GRID: + case SF_TRIANGLES: + case SF_VBO_MESH: + ((srfBspSurface_t *)surf->data)->pshadowBits = pshadowBits; + break; + + default: + pshadowBits = 0; + break; } if ( pshadowBits ) { diff --git a/code/ui/ui_main.c b/code/ui/ui_main.c index 21423cd2..6cdaa12c 100644 --- a/code/ui/ui_main.c +++ b/code/ui/ui_main.c @@ -849,7 +849,7 @@ void UI_ParseMenu(const char *menuFile) { int handle; pc_token_t token; - Com_Printf("Parsing menu file:%s\n", menuFile); + Com_Printf("Parsing menu file: %s\n", menuFile); handle = trap_PC_LoadSource(menuFile); if (!handle) {