removed dead code

This commit is contained in:
myT 2023-09-10 22:13:14 +02:00
parent 29939c951c
commit 6fdf62d710
9 changed files with 3 additions and 905 deletions

View file

@ -25,585 +25,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
backEndData_t* backEndData;
backEndState_t backEnd;
// @TODO: remove all this
#if 0
static int64_t startTime;
static void RB_Set2D()
{
backEnd.projection2D = qtrue;
backEnd.pc = backEnd.pc2D;
// set time for 2D shaders
backEnd.refdef.time = ri.Milliseconds();
backEnd.refdef.floatTime = (double)backEnd.refdef.time / 1000.0;
//@TODO: gal.Begin2D();
}
static const void* RB_SetColor( const void* data )
{
const uiSetColorCommand_t* cmd = (const uiSetColorCommand_t*)data;
backEnd.color2D[0] = (byte)(cmd->color[0] * 255);
backEnd.color2D[1] = (byte)(cmd->color[1] * 255);
backEnd.color2D[2] = (byte)(cmd->color[2] * 255);
backEnd.color2D[3] = (byte)(cmd->color[3] * 255);
return (const void*)(cmd + 1);
}
static const void* RB_StretchPic( const void* data )
{
const uiDrawQuadCommand_t* cmd = (const uiDrawQuadCommand_t*)data;
if ( !backEnd.projection2D )
RB_Set2D();
const shader_t* shader = cmd->shader;
if ( shader != tess.shader ) {
if ( tess.numIndexes ) {
RB_EndSurface();
}
backEnd.currentEntity = &backEnd.entity2D;
RB_BeginSurface( shader, 0 );
tess.greyscale = 0.0f;
}
RB_CHECKOVERFLOW( 4, 6 );
int numVerts = tess.numVertexes;
int numIndexes = tess.numIndexes;
tess.numVertexes += 4;
tess.numIndexes += 6;
tess.indexes[ numIndexes ] = numVerts + 3;
tess.indexes[ numIndexes + 1 ] = numVerts + 0;
tess.indexes[ numIndexes + 2 ] = numVerts + 2;
tess.indexes[ numIndexes + 3 ] = numVerts + 2;
tess.indexes[ numIndexes + 4 ] = numVerts + 0;
tess.indexes[ numIndexes + 5 ] = numVerts + 1;
*(int *)tess.vertexColors[ numVerts ] =
*(int *)tess.vertexColors[ numVerts + 1 ] =
*(int *)tess.vertexColors[ numVerts + 2 ] =
*(int *)tess.vertexColors[ numVerts + 3 ] = *(int *)backEnd.color2D;
tess.xyz[ numVerts ][0] = cmd->x;
tess.xyz[ numVerts ][1] = cmd->y;
tess.xyz[ numVerts ][2] = 0;
tess.texCoords[ numVerts ][0] = cmd->s1;
tess.texCoords[ numVerts ][1] = cmd->t1;
tess.xyz[ numVerts + 1 ][0] = cmd->x + cmd->w;
tess.xyz[ numVerts + 1 ][1] = cmd->y;
tess.xyz[ numVerts + 1 ][2] = 0;
tess.texCoords[ numVerts + 1 ][0] = cmd->s2;
tess.texCoords[ numVerts + 1 ][1] = cmd->t1;
tess.xyz[ numVerts + 2 ][0] = cmd->x + cmd->w;
tess.xyz[ numVerts + 2 ][1] = cmd->y + cmd->h;
tess.xyz[ numVerts + 2 ][2] = 0;
tess.texCoords[ numVerts + 2 ][0] = cmd->s2;
tess.texCoords[ numVerts + 2 ][1] = cmd->t2;
tess.xyz[ numVerts + 3 ][0] = cmd->x;
tess.xyz[ numVerts + 3 ][1] = cmd->y + cmd->h;
tess.xyz[ numVerts + 3 ][2] = 0;
tess.texCoords[ numVerts + 3 ][0] = cmd->s1;
tess.texCoords[ numVerts + 3 ][1] = cmd->t2;
return (const void*)(cmd + 1);
}
static const void* RB_Triangle( const void* data )
{
const uiDrawTriangleCommand_t* cmd = (const uiDrawTriangleCommand_t*)data;
if ( !backEnd.projection2D )
RB_Set2D();
const shader_t* shader = cmd->shader;
if ( shader != tess.shader ) {
if ( tess.numIndexes ) {
RB_EndSurface();
}
backEnd.currentEntity = &backEnd.entity2D;
RB_BeginSurface( shader, 0 );
tess.greyscale = 0.0f;
}
RB_CHECKOVERFLOW( 3, 3 );
int numVerts = tess.numVertexes;
int numIndexes = tess.numIndexes;
tess.numVertexes += 3;
tess.numIndexes += 3;
tess.indexes[ numIndexes + 0 ] = numVerts + 0;
tess.indexes[ numIndexes + 1 ] = numVerts + 1;
tess.indexes[ numIndexes + 2 ] = numVerts + 2;
*(int *)tess.vertexColors[ numVerts ] =
*(int *)tess.vertexColors[ numVerts + 1 ] =
*(int *)tess.vertexColors[ numVerts + 2 ] = *(int *)backEnd.color2D;
tess.xyz[ numVerts ][0] = cmd->x0;
tess.xyz[ numVerts ][1] = cmd->y0;
tess.xyz[ numVerts ][2] = 0;
tess.texCoords[ numVerts ][0] = cmd->s0;
tess.texCoords[ numVerts ][1] = cmd->t0;
tess.xyz[ numVerts + 1 ][0] = cmd->x1;
tess.xyz[ numVerts + 1 ][1] = cmd->y1;
tess.xyz[ numVerts + 1 ][2] = 0;
tess.texCoords[ numVerts + 1 ][0] = cmd->s1;
tess.texCoords[ numVerts + 1 ][1] = cmd->t1;
tess.xyz[ numVerts + 2 ][0] = cmd->x2;
tess.xyz[ numVerts + 2 ][1] = cmd->y2;
tess.xyz[ numVerts + 2 ][2] = 0;
tess.texCoords[ numVerts + 2 ][0] = cmd->s2;
tess.texCoords[ numVerts + 2 ][1] = cmd->t2;
return (const void*)(cmd + 1);
}
static qbool AreShadersStillBatchable( const shader_t* a, const shader_t* b )
{
if ( a->lightmapIndex != b->lightmapIndex ||
a->sort != b->sort ||
a->fogPass != FP_NONE ||
b->fogPass != FP_NONE ||
a->cullType != b->cullType ||
a->polygonOffset != b->polygonOffset ||
a->imgflags != b->imgflags ||
a->numStages != b->numStages ||
a->dfType != b->dfType )
return qfalse;
for ( int i = 0; i < a->numStages; ++i ) {
const shaderStage_t* const sa = a->stages[i];
const shaderStage_t* const sb = b->stages[i];
if ( sa->active != sb->active ||
sa->type != ST_DIFFUSE ||
sb->type != ST_DIFFUSE ||
sa->stateBits != sb->stateBits ||
sa->type != sb->type ||
sa->tcGen != sb->tcGen ||
sa->mtStages != sb->mtStages ||
sa->bundle.isVideoMap != qfalse ||
sb->bundle.isVideoMap != qfalse ||
sa->bundle.image[0] != sb->bundle.image[0] )
return qfalse;
}
return qtrue;
}
static void RB_RenderDrawSurfList( const drawSurf_t* drawSurfs, int numDrawSurfs, qbool beginView )
{
int i;
const shader_t* shader = NULL;
unsigned int sort = (unsigned int)-1;
// save original time for entity shader offsets
double originalTime = backEnd.refdef.floatTime;
// we will need to change the projection matrix before drawing 2D images again
backEnd.projection2D = qfalse;
backEnd.pc = backEnd.pc3D;
// @TODO: gal
/*if (beginView)
gal.Begin3D();*/
// draw everything
int oldEntityNum = -1;
backEnd.currentEntity = &tr.worldEntity;
qbool oldDepthRange = qfalse;
qbool depthRange = qfalse;
backEnd.pc[RB_SURFACES] += numDrawSurfs;
const drawSurf_t* drawSurf;
for ( i = 0, drawSurf = drawSurfs; i < numDrawSurfs; ++i, ++drawSurf ) {
if ( drawSurf->sort == sort ) {
// fast path, same as previous sort
const int firstVertex = tess.numVertexes;
const int firstIndex = tess.numIndexes;
R_TessellateSurface( drawSurf->surface );
if ( tess.deformsPreApplied ) {
// across multiple shaders though, so we need to compute all the results now
const int numVertexes = tess.numVertexes - firstVertex;
const int numIndexes = tess.numIndexes - firstIndex;
RB_DeformTessGeometry( firstVertex, numVertexes, firstIndex, numIndexes );
for ( int s = 0; s < shader->numStages; ++s ) {
R_ComputeColors( shader->stages[s], tess.svars[s], firstVertex, numVertexes );
R_ComputeTexCoords( shader->stages[s], tess.svars[s], firstVertex, numVertexes, qfalse );
}
}
continue;
}
int fogNum;
const shader_t* shaderPrev = shader;
int entityNum;
R_DecomposeSort( drawSurf->sort, &entityNum, &shader, &fogNum );
const qbool depthFadeChange = shader->dfType != tess.depthFade;
// detect and batch surfaces across different (but sufficiently similar) shaders
if ( !depthFadeChange &&
oldEntityNum == ENTITYNUM_WORLD &&
entityNum == ENTITYNUM_WORLD &&
AreShadersStillBatchable( shaderPrev, shader ) ) {
if ( !tess.deformsPreApplied ) {
// this is the second shader in the sequence,
// so we need to compute everything added with the first one now
tess.shader = shaderPrev;
RB_DeformTessGeometry( 0, tess.numVertexes, 0, tess.numIndexes );
for ( int s = 0; s < shaderPrev->numStages; ++s ) {
R_ComputeColors( shaderPrev->stages[s], tess.svars[s], 0, tess.numVertexes );
R_ComputeTexCoords( shaderPrev->stages[s], tess.svars[s], 0, tess.numVertexes, qfalse );
}
}
tess.shader = shader;
tess.deformsPreApplied = qtrue;
const int firstVertex = tess.numVertexes;
const int firstIndex = tess.numIndexes;
R_TessellateSurface( drawSurf->surface );
const int numVertexes = tess.numVertexes - firstVertex;
const int numIndexes = tess.numIndexes - firstIndex;
RB_DeformTessGeometry( firstVertex, numVertexes, firstIndex, numIndexes );
for ( int s = 0; s < shader->numStages; ++s ) {
R_ComputeColors( shader->stages[s], tess.svars[s], firstVertex, numVertexes );
R_ComputeTexCoords( shader->stages[s], tess.svars[s], firstVertex, numVertexes, qfalse );
}
sort = drawSurf->sort;
oldEntityNum = entityNum;
continue;
}
// "entityMergable" shaders can have surfaces from multiple refentities
// merged into a single batch, like (CONCEPTUALLY) smoke and blood puff sprites
// only legacy code still uses them though, because refents are so heavyweight:
// modern code just billboards in cgame and submits raw polys, all of which are
// ENTITYNUM_WORLD and thus automatically take the "same sort" fast path
if ( !shader->entityMergable || ((sort ^ drawSurf->sort) & ~QSORT_ENTITYNUM_MASK) || depthFadeChange ) {
if (shaderPrev)
RB_EndSurface();
RB_BeginSurface( shader, fogNum );
tess.depthFade = shader->dfType;
tess.greyscale = drawSurf->greyscale;
}
sort = drawSurf->sort;
//
// change the modelview matrix if needed
//
if ( entityNum != oldEntityNum ) {
depthRange = qfalse;
if ( entityNum != ENTITYNUM_WORLD ) {
backEnd.currentEntity = &backEnd.refdef.entities[entityNum];
if (backEnd.currentEntity->intShaderTime)
backEnd.refdef.floatTime = originalTime - (double)backEnd.currentEntity->e.shaderTime.iShaderTime / 1000.0;
else
backEnd.refdef.floatTime = originalTime - backEnd.currentEntity->e.shaderTime.fShaderTime;
// we have to reset the shaderTime as well otherwise image animations start
// from the wrong frame
tess.shaderTime = backEnd.refdef.floatTime - tess.shader->timeOffset;
// set up the transformation matrix
R_RotateForEntity( backEnd.currentEntity, &backEnd.viewParms, &backEnd.orient );
if ( backEnd.currentEntity->e.renderfx & RF_DEPTHHACK ) {
// hack the depth range to prevent view model from poking into walls
depthRange = qtrue;
}
} else {
backEnd.currentEntity = &tr.worldEntity;
backEnd.refdef.floatTime = originalTime;
backEnd.orient = backEnd.viewParms.world;
// we have to reset the shaderTime as well otherwise image animations on
// the world (like water) continue with the wrong frame
tess.shaderTime = backEnd.refdef.floatTime - tess.shader->timeOffset;
}
//@TODO: gal.SetModelViewMatrix( backEnd.orient.modelMatrix );
//
// change depthrange if needed
//
if ( oldDepthRange != depthRange ) {
if ( depthRange ) {
//@TODO: gal.SetDepthRange( 0, 0.3 );
} else {
//@TODO: gal.SetDepthRange( 0, 1 );
}
oldDepthRange = depthRange;
}
oldEntityNum = entityNum;
}
// add the triangles for this surface
R_TessellateSurface( drawSurf->surface );
}
backEnd.refdef.floatTime = originalTime;
// draw the contents of the last shader batch
if (shader) {
RB_EndSurface();
}
// go back to the world modelview matrix
//@TODO: gal.SetModelViewMatrix( backEnd.viewParms.world.modelMatrix );
if ( depthRange ) {
//@TODO: gal.SetDepthRange( 0, 1 );
}
}
static void RB_RenderLitSurfList( dlight_t* dl, qbool opaque )
{
if (!dl->head)
return;
const shader_t* shader = NULL;
int entityNum, oldEntityNum;
qbool depthRange, oldDepthRange;
unsigned int sort = (unsigned int)-1;
// save original time for entity shader offsets
double originalTime = backEnd.refdef.floatTime;
// draw everything
const int liquidFlags = CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_WATER;
oldEntityNum = -1;
backEnd.currentEntity = &tr.worldEntity;
backEnd.dlOpaque = opaque;
oldDepthRange = qfalse;
depthRange = qfalse;
tess.light = dl;
for ( litSurf_t* litSurf = dl->head; litSurf; litSurf = litSurf->next ) {
++backEnd.pc[RB_LIT_SURFACES];
if ( litSurf->sort == sort ) {
// fast path, same as previous sort
R_TessellateSurface( litSurf->surface );
continue;
}
int fogNum;
const shader_t* shaderPrev = shader;
R_DecomposeSort( litSurf->sort, &entityNum, &shader, &fogNum );
if (opaque && shader->sort > SS_OPAQUE)
continue;
if (!opaque && shader->sort <= SS_OPAQUE)
continue;
const int stageIndex = shader->lightingStages[ST_DIFFUSE];
if (stageIndex < 0 || stageIndex >= shader->numStages)
continue;
if (shaderPrev)
RB_EndSurface();
RB_BeginSurface( shader, fogNum );
tess.greyscale = litSurf->greyscale;
const shaderStage_t* const stage = shader->stages[stageIndex];
backEnd.dlIntensity = (shader->contentFlags & liquidFlags) != 0 ? 0.5f : 1.0f;
backEnd.dlStateBits =
(opaque || (stage->stateBits & GLS_ATEST_BITS) != 0) ?
(GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL):
(GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE);
sort = litSurf->sort;
//
// change the modelview matrix if needed
//
if ( entityNum != oldEntityNum ) {
depthRange = qfalse;
if ( entityNum != ENTITYNUM_WORLD ) {
backEnd.currentEntity = &backEnd.refdef.entities[entityNum];
if (backEnd.currentEntity->intShaderTime)
backEnd.refdef.floatTime = originalTime - (double)backEnd.currentEntity->e.shaderTime.iShaderTime / 1000.0;
else
backEnd.refdef.floatTime = originalTime - backEnd.currentEntity->e.shaderTime.fShaderTime;
// we have to reset the shaderTime as well otherwise image animations start
// from the wrong frame
tess.shaderTime = backEnd.refdef.floatTime - tess.shader->timeOffset;
// set up the transformation matrix
R_RotateForEntity( backEnd.currentEntity, &backEnd.viewParms, &backEnd.orient );
if ( backEnd.currentEntity->e.renderfx & RF_DEPTHHACK ) {
// hack the depth range to prevent view model from poking into walls
depthRange = qtrue;
}
} else {
backEnd.currentEntity = &tr.worldEntity;
backEnd.refdef.floatTime = originalTime;
backEnd.orient = backEnd.viewParms.world;
// we have to reset the shaderTime as well otherwise image animations on
// the world (like water) continue with the wrong frame
tess.shaderTime = backEnd.refdef.floatTime - tess.shader->timeOffset;
R_TransformDlights( 1, dl, &backEnd.orient );
}
R_TransformDlights( 1, dl, &backEnd.orient );
//@TODO: gal.BeginDynamicLight();
//@TODO: gal.SetModelViewMatrix( backEnd.orient.modelMatrix );
//
// change depthrange if needed
//
if ( oldDepthRange != depthRange ) {
if ( depthRange ) {
//@TODO: gal.SetDepthRange( 0, 0.3 );
} else {
//@TODO: gal.SetDepthRange( 0, 1 );
}
oldDepthRange = depthRange;
}
oldEntityNum = entityNum;
}
// add the triangles for this surface
R_TessellateSurface( litSurf->surface );
}
backEnd.refdef.floatTime = originalTime;
// draw the contents of the last shader batch
if (shader) {
RB_EndSurface();
}
// go back to the world modelview matrix
//@TODO: gal.SetModelViewMatrix( backEnd.viewParms.world.modelMatrix );
if ( depthRange ) {
//@TODO: gal.SetDepthRange( 0, 1 );
}
}
static void R_DebugPolygon( int colorMask, int numPoints, const float* points )
{
RB_PushSingleStageShader( GLS_DEPTHMASK_TRUE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE, CT_FRONT_SIDED );
shaderStage_t& stage = *tess.shader->stages[0];
// solid
for ( int i = 0; i < numPoints; ++i ) {
tess.xyz[i][0] = points[i * 3 + 0];
tess.xyz[i][1] = points[i * 3 + 1];
tess.xyz[i][2] = points[i * 3 + 2];
tess.xyz[i][3] = 1.0f;
}
for ( int i = 1, n = 0; i < numPoints - 1; ++i ) {
tess.indexes[n++] = 0;
tess.indexes[n++] = i + 0;
tess.indexes[n++] = i + 1;
}
tess.numVertexes = numPoints;
tess.numIndexes = (numPoints - 2) * 3;
stage.rgbGen = CGEN_CONST;
stage.constantColor[0] = (colorMask & 1) ? 255 : 0;
stage.constantColor[1] = ((colorMask >> 1) & 1) ? 255 : 0;
stage.constantColor[2] = ((colorMask >> 2) & 1) ? 255 : 0;
stage.constantColor[3] = 255;
R_ComputeColors( &stage, tess.svars[0], 0, numPoints );
//@TODO: gal.Draw( DT_GENERIC );
// wireframe
for ( int i = 0, n = 0; i < numPoints; ++i ) {
tess.indexes[n++] = i;
tess.indexes[n++] = i;
tess.indexes[n++] = (i + 1) % numPoints;
}
tess.numIndexes = numPoints * 3;
stage.stateBits |= GLS_POLYMODE_LINE;
stage.rgbGen = CGEN_IDENTITY;
R_ComputeColors( &stage, tess.svars[0], 0, numPoints );
//@TODO: gal.SetDepthRange( 0, 0 );
//@TODO: gal.Draw( DT_GENERIC );
//@TODO: gal.SetDepthRange( 0, 1 );
RB_PopShader();
tess.numVertexes = 0;
tess.numIndexes = 0;
}
static const void* RB_DrawSurfs( const void* data )
{
const drawSceneViewCommand_t* cmd = (const drawSceneViewCommand_t*)data;
// finish any 2D drawing if needed
if ( tess.numIndexes )
RB_EndSurface();
backEnd.refdef = cmd->refdef;
backEnd.viewParms = cmd->viewParms;
const int opaqueCount = cmd->numDrawSurfs - cmd->numTranspSurfs;
const int transpCount = cmd->numTranspSurfs;
tess.pass = shaderCommands_t::TP_BASE;
RB_RenderDrawSurfList( cmd->drawSurfs, opaqueCount, qtrue );
tess.pass = shaderCommands_t::TP_LIGHT;
for ( int i = 0; i < backEnd.refdef.num_dlights; ++i ) {
RB_RenderLitSurfList( &backEnd.refdef.dlights[i], qtrue );
}
tess.pass = shaderCommands_t::TP_BASE;
RB_RenderDrawSurfList( cmd->drawSurfs + opaqueCount, transpCount, qfalse );
tess.pass = shaderCommands_t::TP_LIGHT;
for ( int i = 0; i < backEnd.refdef.num_dlights; ++i ) {
RB_RenderLitSurfList( &backEnd.refdef.dlights[i], qfalse );
}
tess.pass = shaderCommands_t::TP_BASE;
// draw main system development information (surface outlines, etc)
if ( r_debugSurface->integer )
ri.CM_DrawDebugSurface( R_DebugPolygon );
return (const void*)(cmd + 1);
}
#endif
static const shader_t* prevShader = NULL;
static const shaderStage_t** prevStages = NULL;
static shader_t shader;

View file

@ -1087,35 +1087,6 @@ static qbool R_MirrorViewBySurface( drawSurf_t* drawSurf, int entityNum )
}
// see if a sprite is inside a fog volume
static int R_SpriteFogNum( const trRefEntity_t* ent )
{
int i, j;
if ( tr.refdef.rdflags & RDF_NOWORLDMODEL ) {
return 0;
}
for ( i = 1 ; i < tr.world->numfogs ; i++ ) {
const fog_t* fog = &tr.world->fogs[i];
for ( j = 0 ; j < 3 ; j++ ) {
if ( ent->e.origin[j] - ent->e.radius >= fog->bounds[1][j] ) {
break;
}
if ( ent->e.origin[j] + ent->e.radius <= fog->bounds[0][j] ) {
break;
}
}
if ( j == 3 ) {
return i;
}
}
return 0;
}
/*
==========================================================================================

View file

@ -208,36 +208,6 @@ static int R_ComputeLOD( const trRefEntity_t* ent )
}
static int R_ComputeFogNum( const md3Header_t* header, const trRefEntity_t *ent )
{
int i, j;
if ( tr.refdef.rdflags & RDF_NOWORLDMODEL )
return 0;
// FIXME: non-normalized axis issues
vec3_t localOrigin;
const md3Frame_t* md3Frame = (const md3Frame_t*)((byte *)header + header->ofsFrames) + ent->e.frame;
VectorAdd( ent->e.origin, md3Frame->localOrigin, localOrigin );
for ( i = 1 ; i < tr.world->numfogs ; i++ ) {
const fog_t* fog = &tr.world->fogs[i];
for ( j = 0 ; j < 3 ; j++ ) {
if ( localOrigin[j] - md3Frame->radius >= fog->bounds[1][j] ) {
break;
}
if ( localOrigin[j] + md3Frame->radius <= fog->bounds[0][j] ) {
break;
}
}
if ( j == 3 ) {
return i;
}
}
return 0;
}
void R_AddMD3Surfaces( trRefEntity_t* ent )
{
// don't add third_person objects if not in a portal
@ -276,9 +246,6 @@ void R_AddMD3Surfaces( trRefEntity_t* ent )
if (!personalModel)
R_SetupEntityLighting( &tr.refdef, ent );
// see if we are in a fog volume
int fogNum = R_ComputeFogNum( header, ent );
// draw all surfaces
const shader_t* shader;
const md3Surface_t* surface = (const md3Surface_t*)((byte *)header + header->ofsSurfaces);

View file

@ -1,260 +0,0 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
Quake III Arena source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// tr_shade.c
#include "tr_local.h"
/*
=============================================================
SURFACE SHADERS
=============================================================
*/
shaderCommands_t tess;
// @TODO: remove all this...
#if 0
// we must set some things up before beginning any tesselation
// because a surface may be forced to perform a RB_End due to overflow
void RB_BeginSurface( const shader_t* shader, int fogNum )
{
Q_assert(!"RB_BeginSurface");
tess.numIndexes = 0;
tess.numVertexes = 0;
tess.shader = shader;
tess.fogNum = fogNum;
tess.xstages = (const shaderStage_t**)shader->stages;
tess.depthFade = DFT_NONE;
tess.deformsPreApplied = qfalse;
tess.shaderTime = backEnd.refdef.floatTime - tess.shader->timeOffset;
if (tess.shader->clampTime && tess.shaderTime >= tess.shader->clampTime) {
tess.shaderTime = tess.shader->clampTime;
}
}
static void RB_DrawDynamicLight()
{
backEnd.pc[RB_LIT_VERTICES_LATECULLTEST] += tess.numVertexes;
static byte clipBits[SHADER_MAX_VERTEXES];
const dlight_t* dl = tess.light;
const cullType_t cullType = tess.shader->cullType;
for (int i = 0; i < tess.numVertexes; ++i) {
vec3_t dist;
VectorSubtract(dl->transformed, tess.xyz[i], dist);
const float dp = DotProduct(dist, tess.normal[i]);
if ((cullType == CT_FRONT_SIDED && dp <= 0.0f) ||
(cullType == CT_BACK_SIDED && dp >= 0.0f)) {
clipBits[i] = byte(-1);
continue;
}
int clip = 0;
if (dist[0] > dl->radius)
clip |= 1;
else if (dist[0] < -dl->radius)
clip |= 2;
if (dist[1] > dl->radius)
clip |= 4;
else if (dist[1] < -dl->radius)
clip |= 8;
if (dist[2] > dl->radius)
clip |= 16;
else if (dist[2] < -dl->radius)
clip |= 32;
clipBits[i] = clip;
}
// build a list of triangles that need light
int numIndexes = 0;
for (int i = 0; i < tess.numIndexes; i += 3) {
const int a = tess.indexes[i + 0];
const int b = tess.indexes[i + 1];
const int c = tess.indexes[i + 2];
if (!(clipBits[a] & clipBits[b] & clipBits[c])) {
tess.dlIndexes[numIndexes + 0] = a;
tess.dlIndexes[numIndexes + 1] = b;
tess.dlIndexes[numIndexes + 2] = c;
numIndexes += 3;
}
}
tess.dlNumIndexes = numIndexes;
backEnd.pc[RB_LIT_INDICES_LATECULL_IN] += numIndexes;
backEnd.pc[RB_LIT_INDICES_LATECULL_OUT] += tess.numIndexes - numIndexes;
if (numIndexes <= 0)
return;
backEnd.pc[RB_LIT_BATCHES]++;
backEnd.pc[RB_LIT_VERTICES] += tess.numVertexes;
backEnd.pc[RB_LIT_INDICES] += tess.numIndexes;
//@TODO: gal.Draw(DT_DYNAMIC_LIGHT);
}
static void RB_DrawGeneric()
{
if (tess.depthFade == DFT_NONE && tess.fogNum && tess.shader->fogPass) {
tess.drawFog = qtrue;
unsigned int fogStateBits = GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA;
if (tess.shader->fogPass == FP_EQUAL)
fogStateBits |= GLS_DEPTHFUNC_EQUAL;
tess.fogStateBits = fogStateBits;
const fog_t* fog = tr.world->fogs + tess.fogNum;
for (int i = 0; i < tess.numVertexes; ++i) {
*(int*)&tess.svarsFog.colors[i] = fog->colorInt;
}
RB_CalcFogTexCoords((float*)tess.svarsFog.texcoords, 0, tess.numVertexes);
tess.svarsFog.texcoordsptr = tess.svarsFog.texcoords;
} else {
tess.drawFog = qfalse;
}
backEnd.pc[RB_BATCHES]++;
backEnd.pc[RB_VERTICES] += tess.numVertexes;
backEnd.pc[RB_INDICES] += tess.numIndexes;
//@TODO: gal.Draw(tess.depthFade != DFT_NONE ? DT_SOFT_SPRITE : DT_GENERIC);
}
static void RB_DrawDebug( const shaderCommands_t* input, qbool drawNormals, int options )
{
if (drawNormals) {
// we only draw the normals for the first (SHADER_MAX_VERTEXES / 2 - 1) vertices
int nv = tess.numVertexes;
if (nv >= SHADER_MAX_VERTEXES / 2)
nv = SHADER_MAX_VERTEXES / 2 - 1;
for (int i = 0, j = nv; i < nv; ++i, ++j) {
VectorMA(input->xyz[i], 2, input->normal[i], tess.xyz[j]);
}
for (int i = 0, j = 0; i < nv; ++i, j += 3) {
tess.indexes[j + 0] = i;
tess.indexes[j + 1] = i;
tess.indexes[j + 2] = i + nv;
}
tess.numVertexes = nv * 2;
tess.numIndexes = nv * 3;
}
const cullType_t cull = (options & SHOWTRIS_BACKFACE_BIT) ? CT_BACK_SIDED : CT_FRONT_SIDED;
RB_PushSingleStageShader(GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE, cull);
shaderStage_t* const stage = tess.shader->stages[0];
if (options & SHOWTRIS_VERTEX_COLOR_BIT) {
stage->rgbGen = CGEN_EXACT_VERTEX;
} else if (options & SHOWTRIS_VERTEX_ALPHA_BIT) {
stage->rgbGen = CGEN_DEBUG_ALPHA;
} else {
stage->rgbGen = CGEN_CONST;
stage->constantColor[0] = drawNormals ? 0 : 255;
stage->constantColor[1] = drawNormals ? 0 : 255;
stage->constantColor[2] = 255;
stage->constantColor[3] = 255;
}
stage->alphaGen = AGEN_SKIP;
R_ComputeColors(tess.shader->stages[0], tess.svars[0], 0, tess.numVertexes);
if ((options & SHOWTRIS_OCCLUDE_BIT) == 0) {
//@TODO: gal.SetDepthRange(0, 0);
}
//@TODO: gal.Draw(DT_GENERIC);
//@TODO: gal.SetDepthRange(0, 1);
RB_PopShader();
}
void RB_EndSurface()
{
Q_assert(!"RB_EndSurface");
shaderCommands_t* input = &tess;
if (!input->numIndexes || !input->numVertexes)
return;
if (input->indexes[SHADER_MAX_INDEXES-1] != 0) {
ri.Error( ERR_DROP, "RB_EndSurface() - SHADER_MAX_INDEXES hit" );
}
if (input->xyz[SHADER_MAX_VERTEXES-1][0] != 0) {
ri.Error( ERR_DROP, "RB_EndSurface() - SHADER_MAX_VERTEXES hit" );
}
// for debugging of sort order issues, stop rendering after a given sort value
if ( r_debugSort->value > 0.0f && r_debugSort->value < tess.shader->sort ) {
return;
}
const shader_t* shader = input->shader;
if (shader->sort == SS_ENVIRONMENT) {
RB_DrawSky();
} else {
if (!tess.deformsPreApplied) {
RB_DeformTessGeometry(0, tess.numVertexes, 0, tess.numIndexes);
for (int i = 0; i < shader->numStages; ++i) {
R_ComputeColors(shader->stages[i], tess.svars[i], 0, tess.numVertexes);
R_ComputeTexCoords(shader->stages[i], tess.svars[i], 0, tess.numVertexes, qtrue);
}
}
if (input->pass == shaderCommands_t::TP_LIGHT)
RB_DrawDynamicLight();
else
RB_DrawGeneric();
}
// draw debugging stuff
const qbool showTris = r_showtris->integer & SHOWTRIS_ENABLE_BIT;
const qbool showNormals = r_shownormals->integer & SHOWTRIS_ENABLE_BIT;
if (!backEnd.projection2D &&
(tess.pass == shaderCommands_t::TP_BASE) &&
tess.numIndexes > 0 &&
tess.numVertexes > 0 &&
(showTris || showNormals)) {
if (showTris)
RB_DrawDebug(input, qfalse, r_showtris->integer);
if (showNormals)
RB_DrawDebug(input, qtrue, r_shownormals->integer);
}
// clear shader so we can tell we don't have any unclosed surfaces
tess.numIndexes = 0;
}
#endif

View file

@ -29,6 +29,9 @@ static byte check_srfVertTC[(offsetof(srfVert_t, st2) == offsetof(srfVert_t, st)
static byte check_drawVertTC[(offsetof(drawVert_t, lightmap) == offsetof(drawVert_t, st) + 8) ? 1 : -1];
#endif
shaderCommands_t tess;
/*
THIS ENTIRE FILE IS BACK END

View file

@ -248,7 +248,6 @@
<ClCompile Include="..\..\code\renderer\tr_noise.cpp" />
<ClCompile Include="..\..\code\renderer\tr_renderdoc.cpp" />
<ClCompile Include="..\..\code\renderer\tr_scene.cpp" />
<ClCompile Include="..\..\code\renderer\tr_shade.cpp" />
<ClCompile Include="..\..\code\renderer\tr_shade_calc.cpp" />
<ClCompile Include="..\..\code\renderer\tr_shader.cpp" />
<ClCompile Include="..\..\code\renderer\tr_sky.cpp" />

View file

@ -45,7 +45,6 @@
<ClCompile Include="..\..\code\renderer\tr_noise.cpp" />
<ClCompile Include="..\..\code\renderer\tr_renderdoc.cpp" />
<ClCompile Include="..\..\code\renderer\tr_scene.cpp" />
<ClCompile Include="..\..\code\renderer\tr_shade.cpp" />
<ClCompile Include="..\..\code\renderer\tr_shade_calc.cpp" />
<ClCompile Include="..\..\code\renderer\tr_shader.cpp" />
<ClCompile Include="..\..\code\renderer\tr_sky.cpp" />

View file

@ -252,7 +252,6 @@
<ClCompile Include="..\..\code\renderer\tr_noise.cpp" />
<ClCompile Include="..\..\code\renderer\tr_renderdoc.cpp" />
<ClCompile Include="..\..\code\renderer\tr_scene.cpp" />
<ClCompile Include="..\..\code\renderer\tr_shade.cpp" />
<ClCompile Include="..\..\code\renderer\tr_shade_calc.cpp" />
<ClCompile Include="..\..\code\renderer\tr_shader.cpp" />
<ClCompile Include="..\..\code\renderer\tr_sky.cpp" />

View file

@ -45,7 +45,6 @@
<ClCompile Include="..\..\code\renderer\tr_noise.cpp" />
<ClCompile Include="..\..\code\renderer\tr_renderdoc.cpp" />
<ClCompile Include="..\..\code\renderer\tr_scene.cpp" />
<ClCompile Include="..\..\code\renderer\tr_shade.cpp" />
<ClCompile Include="..\..\code\renderer\tr_shade_calc.cpp" />
<ClCompile Include="..\..\code\renderer\tr_shader.cpp" />
<ClCompile Include="..\..\code\renderer\tr_sky.cpp" />