/* ================= R_PushPoly ================= */ void R_PushPoly( const meshbuffer_t *mb ) { int i, j; poly_t *p; ref_shader_t *shader; int features; MB_NUM2SHADER( mb->shaderkey, shader ); features = shader->features | MF_TRIFAN; for( i = -mb->infokey-1, p = r_polys + i; i < mb->lastPoly; i++, p++ ) { poly_mesh.numVertexes = p->numverts; poly_mesh.xyzArray = inVertsArray; poly_mesh.normalsArray = inNormalsArray; poly_mesh.stArray = p->stcoords; poly_mesh.colorsArray[0] = p->colors; for( j = 0; j < p->numverts; j++ ) { Vector4Set( inVertsArray[r_backacc.numVerts+j], p->verts[j][0], p->verts[j][1], p->verts[j][2], 1 ); VectorCopy( p->normal, inNormalsArray[r_backacc.numVerts+j] ); } R_PushMesh( &poly_mesh, features ); } }
/* * R_DrawAliasModel */ void R_DrawAliasModel( const meshbuffer_t *mb ) { entity_t *e; float depthmin = gldepthmin, depthmax = gldepthmax; MB_NUM2ENTITY( mb->sortkey, e ); if( OCCLUSION_QUERIES_ENABLED( ri ) && OCCLUSION_TEST_ENTITY( e ) ) { shader_t *shader; MB_NUM2SHADER( mb->shaderkey, shader ); if( !R_GetOcclusionQueryResultBool( shader->type == SHADER_PLANAR_SHADOW ? OQ_PLANARSHADOW : OQ_ENTITY, e - r_entities, qtrue ) ) return; } // hack the depth range to prevent view model from poking into walls if( e->flags & RF_WEAPONMODEL ) GL_DepthRange( depthmin, depthmin + 0.3 * ( depthmax - depthmin ) ); // backface culling for left-handed weapons if( e->flags & RF_CULLHACK ) GL_FrontFace( !glState.frontFace ); if( !r_lerpmodels->integer ) e->backlerp = 0; R_DrawAliasFrameLerp( mb, e->backlerp ); if( e->flags & RF_WEAPONMODEL ) GL_DepthRange( depthmin, depthmax ); if( e->flags & RF_CULLHACK ) GL_FrontFace( !glState.frontFace ); }
/* * R_DrawAliasFrameLerp * * Interpolates between two frames and origins */ static void R_DrawAliasFrameLerp( const meshbuffer_t *mb, float backlerp ) { int i, meshnum; int features; float backv[3], frontv[3]; vec3_t normal, oldnormal; qboolean calcVerts, calcNormals, calcSTVectors; vec3_t move; maliasframe_t *frame, *oldframe; maliasmesh_t *mesh; maliasvertex_t *v, *ov; entity_t *e; model_t *mod; maliasmodel_t *model; shader_t *shader; MB_NUM2ENTITY( mb->sortkey, e ); mod = Mod_ForHandle( mb->LODModelHandle ); model = ( maliasmodel_t * )mod->extradata; meshnum = -mb->infokey - 1; if( meshnum < 0 || meshnum >= model->nummeshes ) return; mesh = model->meshes + meshnum; frame = model->frames + e->frame; oldframe = model->frames + e->oldframe; for( i = 0; i < 3; i++ ) move[i] = frame->translate[i] + ( oldframe->translate[i] - frame->translate[i] ) * backlerp; MB_NUM2SHADER( mb->shaderkey, shader ); features = MF_NONBATCHED | shader->features; if( !mb->vboIndex ) { features &= ~MF_HARDWARE; } if( ri.params & RP_SHADOWMAPVIEW ) { features &= ~( MF_COLORS|MF_SVECTORS|MF_ENABLENORMALS ); if( !( shader->features & MF_DEFORMVS ) ) features &= ~MF_NORMALS; } else { if( features & MF_SVECTORS ) features |= MF_NORMALS; #ifdef HARDWARE_OUTLINES if( e->outlineHeight ) features |= MF_NORMALS|(glConfig.ext.GLSL ? MF_ENABLENORMALS : 0); #endif } calcNormals = calcSTVectors = qfalse; calcNormals = ( ( features & MF_NORMALS ) != 0 ) && ( ( e->frame != 0 ) || ( e->oldframe != 0 ) ); calcSTVectors = ( ( features & MF_SVECTORS ) != 0 ) && calcNormals; if( mb->vboIndex != 0 ) { calcVerts = calcNormals = calcSTVectors = qfalse; } else { if( !e->frame && !e->oldframe ) { calcVerts = qfalse; if( calcNormals ) { v = mesh->vertexes; for( i = 0; i < mesh->numverts; i++, v++ ) R_LatLongToNorm( v->latlong, inNormalsArray[i] ); } } else if( e->frame == e->oldframe ) { calcVerts = qtrue; for( i = 0; i < 3; i++ ) frontv[i] = frame->scale[i]; v = mesh->vertexes + e->frame * mesh->numverts; for( i = 0; i < mesh->numverts; i++, v++ ) { Vector4Set( inVertsArray[i], move[0] + v->point[0]*frontv[0], move[1] + v->point[1]*frontv[1], move[2] + v->point[2]*frontv[2], 1 ); if( calcNormals ) R_LatLongToNorm( v->latlong, inNormalsArray[i] ); } } else { calcVerts = qtrue; for( i = 0; i < 3; i++ ) { backv[i] = backlerp * oldframe->scale[i]; frontv[i] = ( 1.0f - backlerp ) * frame->scale[i]; } v = mesh->vertexes + e->frame * mesh->numverts; ov = mesh->vertexes + e->oldframe * mesh->numverts; for( i = 0; i < mesh->numverts; i++, v++, ov++ ) { Vector4Set( inVertsArray[i], move[0] + v->point[0]*frontv[0] + ov->point[0]*backv[0], move[1] + v->point[1]*frontv[1] + ov->point[1]*backv[1], move[2] + v->point[2]*frontv[2] + ov->point[2]*backv[2], 1 ); if( calcNormals ) { R_LatLongToNorm( v->latlong, normal ); R_LatLongToNorm( ov->latlong, oldnormal ); VectorSet( inNormalsArray[i], normal[0] + ( oldnormal[0] - normal[0] ) * backlerp, normal[1] + ( oldnormal[1] - normal[1] ) * backlerp, normal[2] + ( oldnormal[2] - normal[2] ) * backlerp ); } } } if( calcSTVectors ) R_BuildTangentVectors( mesh->numverts, inVertsArray, inNormalsArray, mesh->stArray, mesh->numtris, mesh->elems, inSVectorsArray ); } alias_mesh.xyzArray = calcVerts ? inVertsArray : mesh->xyzArray; alias_mesh.elems = mesh->elems; alias_mesh.numElems = mesh->numtris * 3; alias_mesh.numVerts = mesh->numverts; alias_mesh.stArray = mesh->stArray; if( features & MF_NORMALS ) alias_mesh.normalsArray = calcNormals ? inNormalsArray : mesh->normalsArray; if( features & MF_SVECTORS ) alias_mesh.sVectorsArray = calcSTVectors ? inSVectorsArray : mesh->sVectorsArray; R_RotateForEntity( e ); R_PushMesh( &alias_mesh, mb->vboIndex != 0, features ); R_RenderMeshBuffer( mb, NULL ); }