📄 tr_surface.c
字号:
==============
RB_SurfaceFace
==============
*/
void RB_SurfaceFace( srfSurfaceFace_t *surf ) {
int i;
unsigned *indices, *tessIndexes;
float *v;
float *normal;
int ndx;
int Bob;
int numPoints;
int dlightBits;
RB_CHECKOVERFLOW( surf->numPoints, surf->numIndices );
dlightBits = surf->dlightBits[backEnd.smpFrame];
tess.dlightBits |= dlightBits;
indices = ( unsigned * ) ( ( ( char * ) surf ) + surf->ofsIndices );
Bob = tess.numVertexes;
tessIndexes = tess.indexes + tess.numIndexes;
for ( i = surf->numIndices-1 ; i >= 0 ; i-- ) {
tessIndexes[i] = indices[i] + Bob;
}
tess.numIndexes += surf->numIndices;
v = surf->points[0];
ndx = tess.numVertexes;
numPoints = surf->numPoints;
if ( tess.shader->needsNormal ) {
normal = surf->plane.normal;
for ( i = 0, ndx = tess.numVertexes; i < numPoints; i++, ndx++ ) {
VectorCopy( normal, tess.normal[ndx] );
}
}
for ( i = 0, v = surf->points[0], ndx = tess.numVertexes; i < numPoints; i++, v += VERTEXSIZE, ndx++ ) {
VectorCopy( v, tess.xyz[ndx]);
tess.texCoords[ndx][0][0] = v[3];
tess.texCoords[ndx][0][1] = v[4];
tess.texCoords[ndx][1][0] = v[5];
tess.texCoords[ndx][1][1] = v[6];
* ( unsigned int * ) &tess.vertexColors[ndx] = * ( unsigned int * ) &v[7];
tess.vertexDlightBits[ndx] = dlightBits;
}
tess.numVertexes += surf->numPoints;
}
static float LodErrorForVolume( vec3_t local, float radius ) {
vec3_t world;
float d;
// never let it go negative
if ( r_lodCurveError->value < 0 ) {
return 0;
}
world[0] = local[0] * backEnd.or.axis[0][0] + local[1] * backEnd.or.axis[1][0] +
local[2] * backEnd.or.axis[2][0] + backEnd.or.origin[0];
world[1] = local[0] * backEnd.or.axis[0][1] + local[1] * backEnd.or.axis[1][1] +
local[2] * backEnd.or.axis[2][1] + backEnd.or.origin[1];
world[2] = local[0] * backEnd.or.axis[0][2] + local[1] * backEnd.or.axis[1][2] +
local[2] * backEnd.or.axis[2][2] + backEnd.or.origin[2];
VectorSubtract( world, backEnd.viewParms.or.origin, world );
d = DotProduct( world, backEnd.viewParms.or.axis[0] );
if ( d < 0 ) {
d = -d;
}
d -= radius;
if ( d < 1 ) {
d = 1;
}
return r_lodCurveError->value / d;
}
/*
=============
RB_SurfaceGrid
Just copy the grid of points and triangulate
=============
*/
void RB_SurfaceGrid( srfGridMesh_t *cv ) {
int i, j;
float *xyz;
float *texCoords;
float *normal;
unsigned char *color;
drawVert_t *dv;
int rows, irows, vrows;
int used;
int widthTable[MAX_GRID_SIZE];
int heightTable[MAX_GRID_SIZE];
float lodError;
int lodWidth, lodHeight;
int numVertexes;
int dlightBits;
int *vDlightBits;
qboolean needsNormal;
dlightBits = cv->dlightBits[backEnd.smpFrame];
tess.dlightBits |= dlightBits;
// determine the allowable discrepance
lodError = LodErrorForVolume( cv->lodOrigin, cv->lodRadius );
// determine which rows and columns of the subdivision
// we are actually going to use
widthTable[0] = 0;
lodWidth = 1;
for ( i = 1 ; i < cv->width-1 ; i++ ) {
if ( cv->widthLodError[i] <= lodError ) {
widthTable[lodWidth] = i;
lodWidth++;
}
}
widthTable[lodWidth] = cv->width-1;
lodWidth++;
heightTable[0] = 0;
lodHeight = 1;
for ( i = 1 ; i < cv->height-1 ; i++ ) {
if ( cv->heightLodError[i] <= lodError ) {
heightTable[lodHeight] = i;
lodHeight++;
}
}
heightTable[lodHeight] = cv->height-1;
lodHeight++;
// very large grids may have more points or indexes than can be fit
// in the tess structure, so we may have to issue it in multiple passes
used = 0;
rows = 0;
while ( used < lodHeight - 1 ) {
// see how many rows of both verts and indexes we can add without overflowing
do {
vrows = ( SHADER_MAX_VERTEXES - tess.numVertexes ) / lodWidth;
irows = ( SHADER_MAX_INDEXES - tess.numIndexes ) / ( lodWidth * 6 );
// if we don't have enough space for at least one strip, flush the buffer
if ( vrows < 2 || irows < 1 ) {
RB_EndSurface();
RB_BeginSurface(tess.shader, tess.fogNum );
} else {
break;
}
} while ( 1 );
rows = irows;
if ( vrows < irows + 1 ) {
rows = vrows - 1;
}
if ( used + rows > lodHeight ) {
rows = lodHeight - used;
}
numVertexes = tess.numVertexes;
xyz = tess.xyz[numVertexes];
normal = tess.normal[numVertexes];
texCoords = tess.texCoords[numVertexes][0];
color = ( unsigned char * ) &tess.vertexColors[numVertexes];
vDlightBits = &tess.vertexDlightBits[numVertexes];
needsNormal = tess.shader->needsNormal;
for ( i = 0 ; i < rows ; i++ ) {
for ( j = 0 ; j < lodWidth ; j++ ) {
dv = cv->verts + heightTable[ used + i ] * cv->width
+ widthTable[ j ];
xyz[0] = dv->xyz[0];
xyz[1] = dv->xyz[1];
xyz[2] = dv->xyz[2];
texCoords[0] = dv->st[0];
texCoords[1] = dv->st[1];
texCoords[2] = dv->lightmap[0];
texCoords[3] = dv->lightmap[1];
if ( needsNormal ) {
normal[0] = dv->normal[0];
normal[1] = dv->normal[1];
normal[2] = dv->normal[2];
}
* ( unsigned int * ) color = * ( unsigned int * ) dv->color;
*vDlightBits++ = dlightBits;
xyz += 4;
normal += 4;
texCoords += 4;
color += 4;
}
}
// add the indexes
{
int numIndexes;
int w, h;
h = rows - 1;
w = lodWidth - 1;
numIndexes = tess.numIndexes;
for (i = 0 ; i < h ; i++) {
for (j = 0 ; j < w ; j++) {
int v1, v2, v3, v4;
// vertex order to be reckognized as tristrips
v1 = numVertexes + i*lodWidth + j + 1;
v2 = v1 - 1;
v3 = v2 + lodWidth;
v4 = v3 + 1;
tess.indexes[numIndexes] = v2;
tess.indexes[numIndexes+1] = v3;
tess.indexes[numIndexes+2] = v1;
tess.indexes[numIndexes+3] = v1;
tess.indexes[numIndexes+4] = v3;
tess.indexes[numIndexes+5] = v4;
numIndexes += 6;
}
}
tess.numIndexes = numIndexes;
}
tess.numVertexes += rows * lodWidth;
used += rows - 1;
}
}
/*
===========================================================================
NULL MODEL
===========================================================================
*/
/*
===================
RB_SurfaceAxis
Draws x/y/z lines from the origin for orientation debugging
===================
*/
void RB_SurfaceAxis( void ) {
GL_Bind( tr.whiteImage );
qglLineWidth( 3 );
qglBegin( GL_LINES );
qglColor3f( 1,0,0 );
qglVertex3f( 0,0,0 );
qglVertex3f( 16,0,0 );
qglColor3f( 0,1,0 );
qglVertex3f( 0,0,0 );
qglVertex3f( 0,16,0 );
qglColor3f( 0,0,1 );
qglVertex3f( 0,0,0 );
qglVertex3f( 0,0,16 );
qglEnd();
qglLineWidth( 1 );
}
//===========================================================================
/*
====================
RB_SurfaceEntity
Entities that have a single procedurally generated surface
====================
*/
void RB_SurfaceEntity( surfaceType_t *surfType ) {
switch( backEnd.currentEntity->e.reType ) {
case RT_SPRITE:
RB_SurfaceSprite();
break;
case RT_BEAM:
RB_SurfaceBeam();
break;
case RT_RAIL_CORE:
RB_SurfaceRailCore();
break;
case RT_RAIL_RINGS:
RB_SurfaceRailRings();
break;
case RT_LIGHTNING:
RB_SurfaceLightningBolt();
break;
default:
RB_SurfaceAxis();
break;
}
return;
}
void RB_SurfaceBad( surfaceType_t *surfType ) {
ri.Printf( PRINT_ALL, "Bad surface tesselated.\n" );
}
#if 0
void RB_SurfaceFlare( srfFlare_t *surf ) {
vec3_t left, up;
float radius;
byte color[4];
vec3_t dir;
vec3_t origin;
float d;
// calculate the xyz locations for the four corners
radius = 30;
VectorScale( backEnd.viewParms.or.axis[1], radius, left );
VectorScale( backEnd.viewParms.or.axis[2], radius, up );
if ( backEnd.viewParms.isMirror ) {
VectorSubtract( vec3_origin, left, left );
}
color[0] = color[1] = color[2] = color[3] = 255;
VectorMA( surf->origin, 3, surf->normal, origin );
VectorSubtract( origin, backEnd.viewParms.or.origin, dir );
VectorNormalize( dir );
VectorMA( origin, r_ignore->value, dir, origin );
d = -DotProduct( dir, surf->normal );
if ( d < 0 ) {
return;
}
#if 0
color[0] *= d;
color[1] *= d;
color[2] *= d;
#endif
RB_AddQuadStamp( origin, left, up, color );
}
#else
void RB_SurfaceFlare( srfFlare_t *surf ) {
#if 0
vec3_t left, up;
byte color[4];
color[0] = surf->color[0] * 255;
color[1] = surf->color[1] * 255;
color[2] = surf->color[2] * 255;
color[3] = 255;
VectorClear( left );
VectorClear( up );
left[0] = r_ignore->value;
up[1] = r_ignore->value;
RB_AddQuadStampExt( surf->origin, left, up, color, 0, 0, 1, 1 );
#endif
}
#endif
void RB_SurfaceDisplayList( srfDisplayList_t *surf ) {
// all apropriate state must be set in RB_BeginSurface
// this isn't implemented yet...
qglCallList( surf->listNum );
}
void RB_SurfaceSkip( void *surf ) {
}
void (*rb_surfaceTable[SF_NUM_SURFACE_TYPES])( void *) = {
(void(*)(void*))RB_SurfaceBad, // SF_BAD,
(void(*)(void*))RB_SurfaceSkip, // SF_SKIP,
(void(*)(void*))RB_SurfaceFace, // SF_FACE,
(void(*)(void*))RB_SurfaceGrid, // SF_GRID,
(void(*)(void*))RB_SurfaceTriangles, // SF_TRIANGLES,
(void(*)(void*))RB_SurfacePolychain, // SF_POLY,
(void(*)(void*))RB_SurfaceMesh, // SF_MD3,
(void(*)(void*))RB_SurfaceAnim, // SF_MD4,
(void(*)(void*))RB_SurfaceFlare, // SF_FLARE,
(void(*)(void*))RB_SurfaceEntity, // SF_ENTITY
(void(*)(void*))RB_SurfaceDisplayList // SF_DISPLAY_LIST
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -