本文整理汇总了C++中RB_BeginSurface函数的典型用法代码示例。如果您正苦于以下问题:C++ RB_BeginSurface函数的具体用法?C++ RB_BeginSurface怎么用?C++ RB_BeginSurface使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了RB_BeginSurface函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: RB_DrawSun
/*
** RB_DrawSun
*/
void RB_DrawSun( float scale, shader_t *shader ) {
float size;
float dist;
vec3_t origin, vec1, vec2;
byte sunColor[4] = { 255, 255, 255, 255 };
if ( !backEnd.skyRenderedThisView ) {
return;
}
qglLoadMatrixf( backEnd.viewParms.world.modelMatrix );
qglTranslatef (backEnd.viewParms.or.origin[0], backEnd.viewParms.or.origin[1], backEnd.viewParms.or.origin[2]);
dist = backEnd.viewParms.zFar / 1.75; // div sqrt(3)
size = dist * scale;
VectorScale( tr.sunDirection, dist, origin );
PerpendicularVector( vec1, tr.sunDirection );
CrossProduct( tr.sunDirection, vec1, vec2 );
VectorScale( vec1, size, vec1 );
VectorScale( vec2, size, vec2 );
// farthest depth range
qglDepthRange( 1.0, 1.0 );
RB_BeginSurface( shader, 0 );
RB_AddQuadStamp(origin, vec1, vec2, sunColor);
RB_EndSurface();
// back to normal depth range
qglDepthRange( 0.0, 1.0 );
}
示例2: RB_StretchPic
/*
=============
RB_StretchPic
=============
*/
static void RB_StretchPic ( const void *data ) {
const stretchPicCommand_t *cmd;
shader_t *shader;
int *indexes;
vec2_t *texCoords;
vecSimd_t *xyz;
color4ub_t *colors;
cmd = (const stretchPicCommand_t *)data;
if ( !backEnd.projection2D ) {
RB_SetGL2D();
}
shader = cmd->shader;
if ( shader != tess.shader ) {
RB_EndSurface();
RB_BeginSurface( shader, 0 );
}
RB_CheckOverflow( 4, 6 );
indexes = tess.indexes + tess.numIndexes;
indexes[0] = tess.numVertexes + 3;
indexes[1] = tess.numVertexes + 0;
indexes[2] = tess.numVertexes + 2;
indexes[3] = tess.numVertexes + 2;
indexes[4] = tess.numVertexes + 0;
indexes[5] = tess.numVertexes + 1;
colors = tess.colors + tess.numVertexes;
Byte4Copy( backEnd.color2D, colors[0] );
Byte4Copy( backEnd.color2D, colors[1] );
Byte4Copy( backEnd.color2D, colors[2] );
Byte4Copy( backEnd.color2D, colors[3] );
xyz = tess.xyz + tess.numVertexes;
VectorSet( xyz[0], cmd->x, cmd->y, 0 );
VectorSet( xyz[1], cmd->x + cmd->w, cmd->y, 0 );
VectorSet( xyz[2], cmd->x + cmd->w, cmd->y + cmd->h, 0 );
VectorSet( xyz[3], cmd->x, cmd->y + cmd->h, 0 );
texCoords = tess.texCoords + tess.numVertexes;
texCoords[0][0] = cmd->s1;
texCoords[0][1] = cmd->t1;
texCoords[1][0] = cmd->s2;
texCoords[1][1] = cmd->t1;
texCoords[2][0] = cmd->s2;
texCoords[2][1] = cmd->t2;
texCoords[3][0] = cmd->s1;
texCoords[3][1] = cmd->t2;
tess.numVertexes += 4;
tess.numIndexes += 6;
}
示例3: RB_SetGL2D
const void *RB_Draw2dPolys( const void *data )
{
const poly2dCommand_t *cmd;
shader_t *shader;
int i;
cmd = ( const poly2dCommand_t * ) data;
if ( !backEnd.projection2D )
{
RB_SetGL2D();
}
shader = cmd->shader;
if ( shader != tess.shader )
{
if ( tess.numIndexes )
{
RB_EndSurface();
}
backEnd.currentEntity = &backEnd.entity2D;
RB_BeginSurface( shader, 0 );
}
RB_CHECKOVERFLOW( cmd->numverts, ( cmd->numverts - 2 ) * 3 );
for ( i = 0; i < cmd->numverts - 2; i++ )
{
tess.indexes[ tess.numIndexes + 0 ] = tess.numVertexes;
tess.indexes[ tess.numIndexes + 1 ] = tess.numVertexes + i + 1;
tess.indexes[ tess.numIndexes + 2 ] = tess.numVertexes + i + 2;
tess.numIndexes += 3;
}
for ( i = 0; i < cmd->numverts; i++ )
{
tess.xyz[ tess.numVertexes ].v[ 0 ] = cmd->verts[ i ].xyz[ 0 ];
tess.xyz[ tess.numVertexes ].v[ 1 ] = cmd->verts[ i ].xyz[ 1 ];
tess.xyz[ tess.numVertexes ].v[ 2 ] = 0;
tess.texCoords0[ tess.numVertexes ].v[ 0 ] = cmd->verts[ i ].st[ 0 ];
tess.texCoords0[ tess.numVertexes ].v[ 1 ] = cmd->verts[ i ].st[ 1 ];
tess.vertexColors[ tess.numVertexes ].v[ 0 ] = cmd->verts[ i ].modulate[ 0 ];
tess.vertexColors[ tess.numVertexes ].v[ 1 ] = cmd->verts[ i ].modulate[ 1 ];
tess.vertexColors[ tess.numVertexes ].v[ 2 ] = cmd->verts[ i ].modulate[ 2 ];
tess.vertexColors[ tess.numVertexes ].v[ 3 ] = cmd->verts[ i ].modulate[ 3 ];
tess.numVertexes++;
}
return ( const void * )( cmd + 1 );
}
示例4: RB_CheckVao
void RB_CheckVao(vao_t *vao)
{
if (vao != glState.currentVao)
{
RB_EndSurface();
RB_BeginSurface(tess.shader, tess.fogNum, tess.cubemapIndex);
R_BindVao(vao);
}
if (vao != tess.vao)
tess.useInternalVao = qfalse;
}
示例5: RB_CheckVao
void RB_CheckVao(vao_t *vao)
{
if (vao != glState.currentVao || tess.multiDrawPrimitives >= MAX_MULTIDRAW_PRIMITIVES)
{
RB_EndSurface();
RB_BeginSurface(tess.shader, tess.fogNum, tess.cubemapIndex);
R_BindVao(vao);
}
if (vao != tess.vao)
tess.useInternalVao = qfalse;
}
示例6: RB_CheckOverflow
/*
==============
RB_CheckOverflow
==============
*/
void RB_CheckOverflow( int verts, int indexes ) {
if (tess.numVertexes + verts < SHADER_MAX_VERTEXES
&& tess.numIndexes + indexes < SHADER_MAX_INDEXES) {
return;
}
RB_EndSurface();
if ( verts >= SHADER_MAX_VERTEXES ) {
ri.Error(ERR_DROP, "RB_CheckOverflow: verts > MAX (%d > %d)", verts, SHADER_MAX_VERTEXES );
}
if ( indexes >= SHADER_MAX_INDEXES ) {
ri.Error(ERR_DROP, "RB_CheckOverflow: indices > MAX (%d > %d)", indexes, SHADER_MAX_INDEXES );
}
RB_BeginSurface(tess.shader, tess.fogNum, tess.cubemapIndex );
}
示例7: RB_CheckOverflow
void RB_CheckOverflow( int verts, int indexes ) {
if (tess.numVertexes + verts < ACTUAL_SHADER_MAX_VERTEXES
&& tess.numIndexes + indexes < ACTUAL_SHADER_MAX_INDEXES) {
return;
}
RB_EndSurface();
if ( verts >= ACTUAL_SHADER_MAX_VERTEXES ) {
ri.Error(ERR_DROP, "RB_CheckOverflow: verts > MAX (%d > %d)", verts, ACTUAL_SHADER_MAX_VERTEXES );
}
if ( indexes >= ACTUAL_SHADER_MAX_INDEXES ) {
ri.Error(ERR_DROP, "RB_CheckOverflow: indices > MAX (%d > %d)", indexes, ACTUAL_SHADER_MAX_INDEXES );
}
RB_BeginSurface(NULL/*MODVIEWREM tess.shader*/, 0/*MODVIEWREM tess.fogNum*/, tess.gluiTextureBind );
}
示例8: RB_SurfaceVaoCached
static qboolean RB_SurfaceVaoCached(int numVerts, srfVert_t *verts, int numIndexes, glIndex_t *indexes, int dlightBits, int pshadowBits)
{
qboolean recycleVertexBuffer = qfalse;
qboolean recycleIndexBuffer = qfalse;
qboolean endSurface = qfalse;
if (!(!ShaderRequiresCPUDeforms(tess.shader) && !tess.shader->isSky && !tess.shader->isPortal))
return qfalse;
if (!numIndexes || !numVerts)
return qfalse;
VaoCache_BindVao();
tess.dlightBits |= dlightBits;
tess.pshadowBits |= pshadowBits;
VaoCache_CheckAdd(&endSurface, &recycleVertexBuffer, &recycleIndexBuffer, numVerts, numIndexes);
if (endSurface)
{
RB_EndSurface();
RB_BeginSurface(tess.shader, tess.fogNum, tess.cubemapIndex);
}
if (recycleVertexBuffer)
VaoCache_RecycleVertexBuffer();
if (recycleIndexBuffer)
VaoCache_RecycleIndexBuffer();
if (!tess.numVertexes)
VaoCache_InitQueue();
VaoCache_AddSurface(verts, numVerts, indexes, numIndexes);
tess.numIndexes += numIndexes;
tess.numVertexes += numVerts;
tess.useInternalVao = qfalse;
tess.useCacheVao = qtrue;
return qtrue;
}
示例9: RB_DrawSun
/*
** RB_DrawSun
*/
void RB_DrawSun( float scale, shader_t *shader ) {
float size;
float dist;
vec3_t origin, vec1, vec2;
if ( !backEnd.skyRenderedThisView ) {
return;
}
//qglLoadMatrixf( backEnd.viewParms.world.modelMatrix );
//qglTranslatef (backEnd.viewParms.or.origin[0], backEnd.viewParms.or.origin[1], backEnd.viewParms.or.origin[2]);
{
// FIXME: this could be a lot cleaner
mat4_t translation, modelview;
Mat4Translation( backEnd.viewParms.or.origin, translation );
Mat4Multiply( backEnd.viewParms.world.modelMatrix, translation, modelview );
GL_SetModelviewMatrix( modelview );
}
dist = backEnd.viewParms.zFar / 1.75; // div sqrt(3)
size = dist * scale;
VectorScale( tr.sunDirection, dist, origin );
PerpendicularVector( vec1, tr.sunDirection );
CrossProduct( tr.sunDirection, vec1, vec2 );
VectorScale( vec1, size, vec1 );
VectorScale( vec2, size, vec2 );
// farthest depth range
qglDepthRange( 1.0, 1.0 );
RB_BeginSurface( shader, 0, 0 );
RB_AddQuadStamp(origin, vec1, vec2, colorWhite);
RB_EndSurface();
// back to normal depth range
qglDepthRange( 0.0, 1.0 );
}
示例10: RB_EndSurface
const void *RB_WorldEffects( const void *data )
{
const setModeCommand_t *cmd;
cmd = (const setModeCommand_t *)data;
// Always flush the tess buffer
if ( tess.shader && tess.numIndexes )
{
RB_EndSurface();
}
RB_RenderWorldEffects();
if(tess.shader)
{
RB_BeginSurface( tess.shader, tess.fogNum );
}
return (const void *)(cmd + 1);
}
示例11: RB_RenderFlare
/*
==================
RB_RenderFlare
==================
*/
void RB_RenderFlare( flare_t *f ) {
float size;
vec3_t color;
int iColor[3];
backEnd.pc.c_flareRenders++;
VectorScale( f->color, f->drawIntensity*tr.identityLight, color );
iColor[0] = color[0] * 255;
iColor[1] = color[1] * 255;
iColor[2] = color[2] * 255;
size = f->lightScale * backEnd.viewParms.viewportWidth * ( r_flareSize->value/640.0 + 8 / -f->eyeZ );
RB_BeginSurface( tr.flareShader, f->fogNum );
// FIXME: use quadstamp?
tess.xyz[tess.numVertexes][0] = f->windowX - size;
tess.xyz[tess.numVertexes][1] = f->windowY - size;
tess.texCoords[tess.numVertexes][0][0] = 0;
tess.texCoords[tess.numVertexes][0][1] = 0;
tess.vertexColors[tess.numVertexes][0] = iColor[0];
tess.vertexColors[tess.numVertexes][1] = iColor[1];
tess.vertexColors[tess.numVertexes][2] = iColor[2];
tess.vertexColors[tess.numVertexes][3] = 255;
tess.numVertexes++;
tess.xyz[tess.numVertexes][0] = f->windowX - size;
tess.xyz[tess.numVertexes][1] = f->windowY + size;
tess.texCoords[tess.numVertexes][0][0] = 0;
tess.texCoords[tess.numVertexes][0][1] = 1;
tess.vertexColors[tess.numVertexes][0] = iColor[0];
tess.vertexColors[tess.numVertexes][1] = iColor[1];
tess.vertexColors[tess.numVertexes][2] = iColor[2];
tess.vertexColors[tess.numVertexes][3] = 255;
tess.numVertexes++;
tess.xyz[tess.numVertexes][0] = f->windowX + size;
tess.xyz[tess.numVertexes][1] = f->windowY + size;
tess.texCoords[tess.numVertexes][0][0] = 1;
tess.texCoords[tess.numVertexes][0][1] = 1;
tess.vertexColors[tess.numVertexes][0] = iColor[0];
tess.vertexColors[tess.numVertexes][1] = iColor[1];
tess.vertexColors[tess.numVertexes][2] = iColor[2];
tess.vertexColors[tess.numVertexes][3] = 255;
tess.numVertexes++;
tess.xyz[tess.numVertexes][0] = f->windowX + size;
tess.xyz[tess.numVertexes][1] = f->windowY - size;
tess.texCoords[tess.numVertexes][0][0] = 1;
tess.texCoords[tess.numVertexes][0][1] = 0;
tess.vertexColors[tess.numVertexes][0] = iColor[0];
tess.vertexColors[tess.numVertexes][1] = iColor[1];
tess.vertexColors[tess.numVertexes][2] = iColor[2];
tess.vertexColors[tess.numVertexes][3] = 255;
tess.numVertexes++;
tess.indexes[tess.numIndexes++] = 0;
tess.indexes[tess.numIndexes++] = 1;
tess.indexes[tess.numIndexes++] = 2;
tess.indexes[tess.numIndexes++] = 0;
tess.indexes[tess.numIndexes++] = 2;
tess.indexes[tess.numIndexes++] = 3;
RB_EndSurface();
}
示例12: RB_RenderDrawSurfList
/*
==================
RB_RenderDrawSurfList
==================
*/
void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
shader_t *shader, *oldShader;
int fogNum, oldFogNum;
int entityNum, oldEntityNum;
int dlighted, oldDlighted;
qboolean depthRange, oldDepthRange;
int i;
drawSurf_t *drawSurf;
int oldSort;
float originalTime;
int oldNumVerts, oldNumIndex;
//GR - tessellation flag
int atiTess = 0, oldAtiTess;
#ifdef __MACOS__
int macEventTime;
Sys_PumpEvents(); // crutch up the mac's limited buffer queue size
// we don't want to pump the event loop too often and waste time, so
// we are going to check every shader change
macEventTime = ri.Milliseconds() + MAC_EVENT_PUMP_MSEC;
#endif
// save original time for entity shader offsets
originalTime = backEnd.refdef.floatTime;
// clear the z buffer, set the modelview, etc
RB_BeginDrawingView();
// draw everything
oldEntityNum = -1;
backEnd.currentEntity = &tr.worldEntity;
oldShader = NULL;
oldFogNum = -1;
oldDepthRange = qfalse;
oldDlighted = qfalse;
oldSort = -1;
depthRange = qfalse;
// GR - tessellation also forces to draw everything
oldAtiTess = -1;
backEnd.pc.c_surfaces += numDrawSurfs;
for ( i = 0, drawSurf = drawSurfs ; i < numDrawSurfs ; i++, drawSurf++ ) {
if ( drawSurf->sort == oldSort ) {
// fast path, same as previous sort
oldNumVerts = tess.numVertexes;
oldNumIndex = tess.numIndexes;
rb_surfaceTable[ *drawSurf->surface ]( drawSurf->surface );
/*
// RF, convert the newly created vertexes into dust particles, and overwrite
if (backEnd.currentEntity->e.reFlags & REFLAG_ZOMBIEFX) {
RB_ZombieFX( 0, drawSurf, oldNumVerts, oldNumIndex );
}
else if (backEnd.currentEntity->e.reFlags & REFLAG_ZOMBIEFX2) {
RB_ZombieFX( 1, drawSurf, oldNumVerts, oldNumIndex );
}
*/
continue;
}
oldSort = drawSurf->sort;
// GR - also extract tesselation flag
R_DecomposeSort( drawSurf->sort, &entityNum, &shader, &fogNum, &dlighted, &atiTess );
//
// change the tess parameters if needed
// a "entityMergable" shader is a shader that can have surfaces from seperate
// entities merged into a single batch, like smoke and blood puff sprites
if ( shader != oldShader || fogNum != oldFogNum || dlighted != oldDlighted
// GR - force draw on tessellation flag change
|| ( atiTess != oldAtiTess )
|| ( entityNum != oldEntityNum && !shader->entityMergable ) ) {
if ( oldShader != NULL ) {
#ifdef __MACOS__ // crutch up the mac's limited buffer queue size
int t;
t = ri.Milliseconds();
if ( t > macEventTime ) {
macEventTime = t + MAC_EVENT_PUMP_MSEC;
Sys_PumpEvents();
}
#endif
// GR - pass tessellation flag to the shader command
// make sure to use oldAtiTess!!!
tess.ATI_tess = ( oldAtiTess == ATI_TESS_TRUFORM );
RB_EndSurface();
}
RB_BeginSurface( shader, fogNum );
oldShader = shader;
oldFogNum = fogNum;
oldDlighted = dlighted;
// GR - update old tessellation flag
oldAtiTess = atiTess;
//.........这里部分代码省略.........
示例13: RB_RenderDrawSurfList
//.........这里部分代码省略.........
shader = oldShader;
entityNum = oldEntityNum;
fogNum = oldFogNum;
dlighted = oldDlighted;
oldSort = (unsigned int)-1; //invalidate this thing, cause we may want to postrender more surfs of the same sort
//continue without bothering to begin a draw surf
continue;
}
}
if (shader != oldShader || fogNum != oldFogNum || dlighted != oldDlighted
|| ( entityNum != oldEntityNum && !shader->entityMergable ) )
{
if (oldShader != NULL) {
#ifdef __MACOS__ // crutch up the mac's limited buffer queue size
int t;
t = ri.Milliseconds();
if ( t > macEventTime ) {
macEventTime = t + MAC_EVENT_PUMP_MSEC;
Sys_PumpEvents();
}
#endif
RB_EndSurface();
if (!didShadowPass && shader && shader->sort > SS_BANNER)
{
RB_ShadowFinish();
didShadowPass = true;
}
}
RB_BeginSurface( shader, fogNum );
oldShader = shader;
oldFogNum = fogNum;
oldDlighted = dlighted;
}
//
// change the modelview matrix if needed
//
if ( entityNum != oldEntityNum ) {
depthRange = qfalse;
if ( entityNum != TR_WORLDENT ) {
backEnd.currentEntity = &backEnd.refdef.entities[entityNum];
backEnd.refdef.floatTime = originalTime - backEnd.currentEntity->e.shaderTime;
// set up the transformation matrix
R_RotateForEntity( backEnd.currentEntity, &backEnd.viewParms, &backEnd.ori );
// set up the dynamic lighting if needed
if ( backEnd.currentEntity->needDlights ) {
#ifdef VV_LIGHTING
VVLightMan.R_TransformDlights( &backEnd.ori );
#else
R_TransformDlights( backEnd.refdef.num_dlights, backEnd.refdef.dlights, &backEnd.ori );
#endif
}
if ( backEnd.currentEntity->e.renderfx & RF_NODEPTH ) {
// No depth at all, very rare but some things for seeing through walls
depthRange = 2;
}
else if ( backEnd.currentEntity->e.renderfx & RF_DEPTHHACK ) {
示例14: RB_RenderFlare
/*
==================
RB_RenderFlare
==================
*/
void RB_RenderFlare( flare_t *f ) {
float size;
vec3_t color;
int iColor[3];
float distance, intensity, factor;
byte fogFactors[3] = {255, 255, 255};
backEnd.pc.c_flareRenders++;
// We don't want too big values anyways when dividing by distance.
if(f->eyeZ > -1.0f)
distance = 1.0f;
else
distance = -f->eyeZ;
// calculate the flare size..
size = backEnd.viewParms.viewportWidth * ( r_flareSize->value/640.0f + 8 / distance );
/*
* This is an alternative to intensity scaling. It changes the size of the flare on screen instead
* with growing distance. See in the description at the top why this is not the way to go.
// size will change ~ 1/r.
size = backEnd.viewParms.viewportWidth * (r_flareSize->value / (distance * -2.0f));
*/
/*
* As flare sizes stay nearly constant with increasing distance we must decrease the intensity
* to achieve a reasonable visual result. The intensity is ~ (size^2 / distance^2) which can be
* got by considering the ratio of
* (flaresurface on screen) : (Surface of sphere defined by flare origin and distance from flare)
* An important requirement is:
* intensity <= 1 for all distances.
*
* The formula used here to compute the intensity is as follows:
* intensity = flareCoeff * size^2 / (distance + size*sqrt(flareCoeff))^2
* As you can see, the intensity will have a max. of 1 when the distance is 0.
* The coefficient flareCoeff will determine the falloff speed with increasing distance.
*/
factor = distance + size * sqrt(flareCoeff);
intensity = flareCoeff * size * size / (factor * factor);
VectorScale(f->color, f->drawIntensity * intensity, color);
// Calculations for fogging
if(tr.world && f->fogNum < tr.world->numfogs)
{
tess.numVertexes = 1;
VectorCopy(f->origin, tess.xyz[0]);
tess.fogNum = f->fogNum;
RB_CalcModulateColorsByFog(fogFactors);
// We don't need to render the flare if colors are 0 anyways.
if(!(fogFactors[0] || fogFactors[1] || fogFactors[2]))
return;
}
iColor[0] = color[0] * fogFactors[0];
iColor[1] = color[1] * fogFactors[1];
iColor[2] = color[2] * fogFactors[2];
RB_BeginSurface( tr.flareShader, f->fogNum );
// FIXME: use quadstamp?
tess.xyz[tess.numVertexes][0] = f->windowX - size;
tess.xyz[tess.numVertexes][1] = f->windowY - size;
tess.texCoords[tess.numVertexes][0][0] = 0;
tess.texCoords[tess.numVertexes][0][1] = 0;
tess.vertexColors[tess.numVertexes][0] = iColor[0];
tess.vertexColors[tess.numVertexes][1] = iColor[1];
tess.vertexColors[tess.numVertexes][2] = iColor[2];
tess.vertexColors[tess.numVertexes][3] = 255;
tess.numVertexes++;
tess.xyz[tess.numVertexes][0] = f->windowX - size;
tess.xyz[tess.numVertexes][1] = f->windowY + size;
tess.texCoords[tess.numVertexes][0][0] = 0;
tess.texCoords[tess.numVertexes][0][1] = 1;
tess.vertexColors[tess.numVertexes][0] = iColor[0];
tess.vertexColors[tess.numVertexes][1] = iColor[1];
tess.vertexColors[tess.numVertexes][2] = iColor[2];
tess.vertexColors[tess.numVertexes][3] = 255;
tess.numVertexes++;
tess.xyz[tess.numVertexes][0] = f->windowX + size;
tess.xyz[tess.numVertexes][1] = f->windowY + size;
tess.texCoords[tess.numVertexes][0][0] = 1;
tess.texCoords[tess.numVertexes][0][1] = 1;
tess.vertexColors[tess.numVertexes][0] = iColor[0];
tess.vertexColors[tess.numVertexes][1] = iColor[1];
tess.vertexColors[tess.numVertexes][2] = iColor[2];
tess.vertexColors[tess.numVertexes][3] = 255;
tess.numVertexes++;
//.........这里部分代码省略.........
示例15: RB_RenderDrawSurfList
/**
* @brief RB_RenderDrawSurfList
* @param[in] drawSurfs
* @param[in] numDrawSurfs
*/
void RB_RenderDrawSurfList(drawSurf_t *drawSurfs, int numDrawSurfs)
{
shader_t *shader, *oldShader;
int fogNum, oldFogNum;
int entityNum, oldEntityNum;
int frontFace;
int dlighted, oldDlighted;
qboolean depthRange, oldDepthRange;
int i;
drawSurf_t *drawSurf;
int oldSort;
double originalTime = backEnd.refdef.floatTime; // save original time for entity shader offsets
// clear the z buffer, set the modelview, etc
RB_BeginDrawingView();
// draw everything
oldEntityNum = -1;
backEnd.currentEntity = &tr.worldEntity;
oldShader = NULL;
oldFogNum = -1;
oldDepthRange = qfalse;
oldDlighted = qfalse;
oldSort = -1;
depthRange = qfalse;
backEnd.pc.c_surfaces += numDrawSurfs;
for (i = 0, drawSurf = drawSurfs ; i < numDrawSurfs ; i++, drawSurf++)
{
if (drawSurf->sort == oldSort)
{
// fast path, same as previous sort
rb_surfaceTable[*drawSurf->surface] (drawSurf->surface);
continue;
}
oldSort = drawSurf->sort;
R_DecomposeSort(drawSurf->sort, &entityNum, &shader, &fogNum, &frontFace, &dlighted);
// change the tess parameters if needed
// a "entityMergable" shader is a shader that can have surfaces from seperate
// entities merged into a single batch, like smoke and blood puff sprites
if (shader && (shader != oldShader || fogNum != oldFogNum || dlighted != oldDlighted
|| (entityNum != oldEntityNum && !shader->entityMergable)))
{
if (oldShader != NULL)
{
RB_EndSurface();
}
RB_BeginSurface(shader, fogNum);
oldShader = shader;
oldFogNum = fogNum;
oldDlighted = dlighted;
}
// change the modelview matrix if needed
if (entityNum != oldEntityNum)
{
depthRange = qfalse;
if (entityNum != ENTITYNUM_WORLD)
{
backEnd.currentEntity = &backEnd.refdef.entities[entityNum];
// FIXME: e.shaderTime must be passed as int to avoid fp-precision loss issues
backEnd.refdef.floatTime = originalTime; // - backEnd.currentEntity->e.shaderTime; // JPW NERVE pulled this to match q3ta
// 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.orientation);
// set up the dynamic lighting if needed
if (backEnd.currentEntity->needDlights)
{
R_TransformDlights(backEnd.refdef.num_dlights, backEnd.refdef.dlights, &backEnd.orientation);
}
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.orientation = 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;
//.........这里部分代码省略.........