/* ================= 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_AddOccludingSurface */ void R_AddOccludingSurface( msurface_t *surf, shader_t *shader ) { int diff = shader->flags ^ r_occlusionShader->flags; if( R_MeshOverflow( surf->mesh ) || ( diff & ( SHADER_CULL_FRONT|SHADER_CULL_BACK ) ) || r_occlusionEntity != ri.currententity ) { R_RenderOccludingSurfaces(); r_occlusionShader->flags ^= diff; r_occlusionEntity = ri.currententity; } r_occludersQueued = qtrue; R_PushMesh( surf->mesh, surf->vbo != NULL, MF_NOCOLORWRITE ); }
/* * R_IssueOcclusionQuery */ int R_IssueOcclusionQuery( int query, entity_t *e, vec3_t mins, vec3_t maxs ) { static vec4_t verts[8]; static mesh_t mesh; static elem_t indices[] = { 0, 1, 2, 1, 2, 3, // top 7, 5, 6, 5, 6, 4, // bottom 4, 0, 6, 0, 6, 2, // front 3, 7, 1, 7, 1, 5, // back 0, 1, 4, 1, 4, 5, // left 7, 6, 3, 6, 3, 2, // right }; int i; vec3_t bbox[8]; if( query < 0 ) return -1; if( r_queriesBits[query>>3] & ( 1<<( query&7 ) ) ) return -1; r_queriesBits[query>>3] |= ( 1<<( query&7 ) ); R_RenderOccludingSurfaces(); mesh.numVerts = 8; mesh.xyzArray = verts; mesh.numElems = 36; mesh.elems = indices; r_occlusionShader->flags &= ~( SHADER_CULL_BACK | SHADER_CULL_FRONT ); qglBeginQueryARB( GL_SAMPLES_PASSED_ARB, r_occlusionQueries[query] ); R_TransformEntityBBox( e, mins, maxs, bbox, qfalse ); for( i = 0; i < 8; i++ ) Vector4Set( verts[i], bbox[i][0], bbox[i][1], bbox[i][2], 1 ); R_RotateForEntity( e ); R_BackendSetPassMask( GLSTATE_MASK & ~GLSTATE_DEPTHWRITE ); R_PushMesh( &mesh, qfalse, MF_NONBATCHED|MF_NOCULL ); R_RenderMeshBuffer( &r_occluderMB, NULL ); qglEndQueryARB( GL_SAMPLES_PASSED_ARB ); return query; }
/* * 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 ); }