From 08fcecc829b5820543d80dcde37ecb33f451b101 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Mon, 14 Oct 2013 01:55:54 -0700 Subject: [PATCH] OpenGL2: Clean up texmod calculations, and improve vertex animation handling. --- code/renderergl2/tr_glsl.c | 4 +- code/renderergl2/tr_local.h | 3 +- code/renderergl2/tr_shade.c | 107 +++--- code/renderergl2/tr_shade_calc.c | 570 ++----------------------------- code/renderergl2/tr_shader.c | 2 + code/renderergl2/tr_surface.c | 3 +- code/renderergl2/tr_vbo.c | 7 + 7 files changed, 92 insertions(+), 604 deletions(-) diff --git a/code/renderergl2/tr_glsl.c b/code/renderergl2/tr_glsl.c index dd6211be..8203e68b 100644 --- a/code/renderergl2/tr_glsl.c +++ b/code/renderergl2/tr_glsl.c @@ -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)) { @@ -1845,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_local.h b/code/renderergl2/tr_local.h index c19a1e1b..82fbb004 100644 --- a/code/renderergl2/tr_local.h +++ b/code/renderergl2/tr_local.h @@ -1566,6 +1566,7 @@ typedef struct { uint32_t vertexAttribsNewFrame; uint32_t vertexAttribsOldFrame; float vertexAttribsInterpolation; + qboolean vertexAnimation; shaderProgram_t *currentProgram; FBO_t *currentFBO; VBO_t *currentVBO; @@ -2514,7 +2515,7 @@ void RB_CalcTransformTexCoords( const texModInfo_t *tmi, float *dstTexCoords ); void RB_CalcScaleTexMatrix( const float scale[2], float *matrix ); void RB_CalcScrollTexMatrix( const float scrollSpeed[2], float *matrix ); void RB_CalcRotateTexMatrix( float degsPerSecond, float *matrix ); -void RB_CalcTurbulentTexMatrix( const waveForm_t *wf, matrix_t matrix ); +void RB_CalcTurbulentFactors( const waveForm_t *wf, float *amplitude, float *now ); void RB_CalcTransformTexMatrix( const texModInfo_t *tmi, float *matrix ); void RB_CalcStretchTexMatrix( const waveForm_t *wf, float *matrix ); diff --git a/code/renderergl2/tr_shade.c b/code/renderergl2/tr_shade.c index c80f7679..6ccbacf1 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; + } } } @@ -692,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 @@ -795,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); @@ -926,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]; @@ -983,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) @@ -1002,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; @@ -1018,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 ) { @@ -1051,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; } @@ -1174,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) @@ -1228,8 +1241,6 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) { for (i = 0; i < NUM_TEXTURE_BUNDLES; i++) { - image_t *img; - if (pStage->bundle[i].image[0]) { switch(i) @@ -1258,8 +1269,6 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) { for (i = 0; i < NUM_TEXTURE_BUNDLES; i++) { - image_t *img; - if (pStage->bundle[i].image[0]) { switch(i) 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 42f235cb..7ff74feb 100644 --- a/code/renderergl2/tr_shader.c +++ b/code/renderergl2/tr_shader.c @@ -2336,6 +2336,7 @@ static qboolean CollapseStagesToGLSL(void) case TCGEN_TEXTURE: case TCGEN_LIGHTMAP: case TCGEN_ENVIRONMENT_MAPPED: + case TCGEN_VECTOR: break; default: skip = qtrue; @@ -2529,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; } } } diff --git a/code/renderergl2/tr_surface.c b/code/renderergl2/tr_surface.c index 06072a82..9f83c7ba 100644 --- a/code/renderergl2/tr_surface.c +++ b/code/renderergl2/tr_surface.c @@ -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); } }