示例#1
0
/*
=================
R_AddIQMSurfaces

Add all surfaces of this model
=================
*/
void R_AddIQMSurfaces( trRefEntity_t *ent ) {
	IQModel_t		*IQModel;
	srfIQModel_t		*surface;
	int                     i, j;
	bool                personalModel;
	int                     fogNum;
	shader_t                *shader;
	skin_t                  *skin;

	IQModel = tr.currentModel->iqm;
	surface = IQModel->surfaces;

	// don't add third_person objects if not in a portal
	personalModel = (ent->e.renderfx & RF_THIRD_PERSON) &&
	  tr.viewParms.portalLevel == 0;

	//
	// cull the entire model if merged bounding box of both frames
	// is outside the view frustum.
	//
	R_CullIQM( ent );

	if ( ent->cull == cullResult_t::CULL_OUT )
	{
		return;
	}

	//
	// set up lighting now that we know we aren't culled
	//
	if ( !personalModel || r_shadows->integer > Util::ordinal(shadowingMode_t::SHADOWING_BLOB) ) {
		R_SetupEntityLighting( &tr.refdef, ent, nullptr );
	}

	//
	// see if we are in a fog volume
	//
	fogNum = R_FogWorldBox( ent->worldBounds );

	for ( i = 0 ; i < IQModel->num_surfaces ; i++ ) {
		if(ent->e.customShader)
			shader = R_GetShaderByHandle( ent->e.customShader );
		else if(ent->e.customSkin > 0 && ent->e.customSkin < tr.numSkins)
		{
			skin = R_GetSkinByHandle(ent->e.customSkin);
			shader = tr.defaultShader;

			if (surface->name && *surface->name) {
				for(j = 0; j < skin->numSurfaces; j++)
				{
					if (!strcmp(skin->surfaces[j]->name, surface->name))
					{
						shader = skin->surfaces[j]->shader;
						break;
					}
				}
			}

			if ( shader == tr.defaultShader && i >= 0 && i < skin->numSurfaces && skin->surfaces[ i ] )
			{
				shader = skin->surfaces[ i ]->shader;
			}
		} else {

			shader = surface->shader;

			if ( ent->e.altShaderIndex > 0 && ent->e.altShaderIndex < MAX_ALTSHADERS &&
				shader->altShader[ ent->e.altShaderIndex ].index )
			{
				shader = R_GetShaderByHandle( shader->altShader[ ent->e.altShaderIndex ].index );
			}
		}

		// we will add shadows even if the main object isn't visible in the view

		if( !personalModel ) {
			R_AddDrawSurf( ( surfaceType_t *)surface, shader, -1, fogNum );
		}

		surface++;
	}
}
示例#2
0
/*
==============
R_AddMD5Surfaces
==============
*/
void R_AddMD5Surfaces(trRefEntity_t * ent)
{
	md5Model_t     *model;
	md5Surface_t   *surface;
	shader_t       *shader;
	int             i;
	qboolean        personalModel;
	int				fogNum;

	model = tr.currentModel->md5;

	// don't add third_person objects if not in a portal
	personalModel = (ent->e.renderfx & RF_THIRD_PERSON) && !tr.viewParms.isPortal;

	// cull the entire model if merged bounding box of both frames
	// is outside the view frustum
	R_CullMD5(ent);
	if(ent->cull == CULL_OUT)
	{
		return;
	}

	// set up world bounds for light intersection tests
	R_SetupEntityWorldBounds(ent);

	// set up lighting now that we know we aren't culled
	if(!personalModel || r_shadows->integer > SHADOWING_BLOB)
	{
		R_SetupEntityLighting(&tr.refdef, ent, NULL);
	}

	// see if we are in a fog volume
	fogNum = R_FogWorldBox(ent->worldBounds);

	if(!r_vboModels->integer || !model->numVBOSurfaces ||
	   (!glConfig2.vboVertexSkinningAvailable && ent->e.skeleton.type == SK_ABSOLUTE))
	{
		// finally add surfaces
		for(i = 0, surface = model->surfaces; i < model->numSurfaces; i++, surface++)
		{
			if(ent->e.customShader)
			{
				shader = R_GetShaderByHandle(ent->e.customShader);
			}
			else if(ent->e.customSkin > 0 && ent->e.customSkin < tr.numSkins)
			{
				skin_t         *skin;

				skin = R_GetSkinByHandle(ent->e.customSkin);

				// match the surface name to something in the skin file
				shader = tr.defaultShader;

				// FIXME: replace MD3_MAX_SURFACES for skin_t::surfaces
				if(i >= 0 && i < skin->numSurfaces && skin->surfaces[i])
				{
					shader = skin->surfaces[i]->shader;
				}
				if(shader == tr.defaultShader)
				{
					ri.Printf(PRINT_DEVELOPER, "WARNING: no shader for surface %i in skin %s\n", i, skin->name);
				}
				else if(shader->defaultShader)
				{
					ri.Printf(PRINT_DEVELOPER, "WARNING: shader %s in skin %s not found\n", shader->name, skin->name);
				}
			}
			else
			{
				shader = R_GetShaderByHandle(surface->shaderIndex);
			}

			// we will add shadows even if the main object isn't visible in the view

			// don't add third_person objects if not viewing through a portal
			if(!personalModel)
			{
				R_AddDrawSurf((void *)surface, shader, -1, fogNum);
			}
		}
	}
	else
	{
		int             i;
		srfVBOMD5Mesh_t *vboSurface;
		shader_t       *shader;

		for(i = 0; i < model->numVBOSurfaces; i++)
		{
			vboSurface = model->vboSurfaces[i];

			if(ent->e.customShader)
			{
				shader = R_GetShaderByHandle(ent->e.customShader);
			}
			else if(ent->e.customSkin > 0 && ent->e.customSkin < tr.numSkins)
			{
				skin_t         *skin;

				skin = R_GetSkinByHandle(ent->e.customSkin);

				// match the surface name to something in the skin file
				shader = tr.defaultShader;

				// FIXME: replace MD3_MAX_SURFACES for skin_t::surfaces
				//if(i >= 0 && i < skin->numSurfaces && skin->surfaces[i])
				if(vboSurface->skinIndex >= 0 && vboSurface->skinIndex < skin->numSurfaces && skin->surfaces[vboSurface->skinIndex])
				{
					shader = skin->surfaces[vboSurface->skinIndex]->shader;
				}

				if(shader == tr.defaultShader)
				{
					ri.Printf(PRINT_DEVELOPER, "WARNING: no shader for surface %i in skin %s\n", i, skin->name);
				}
				else if(shader->defaultShader)
				{
					ri.Printf(PRINT_DEVELOPER, "WARNING: shader %s in skin %s not found\n", shader->name, skin->name);
				}
			}
			else
			{
				shader = vboSurface->shader;
			}

			// don't add third_person objects if not viewing through a portal
			if(!personalModel)
			{
				R_AddDrawSurf((void *)vboSurface, shader, -1, fogNum);
			}
		}
	}
}
示例#3
0
/**
 * @brief R_AddMDVSurfaces
 * @param[in,out] ent
 */
void R_AddMDVSurfaces(trRefEntity_t *ent)
{
	int          i;
	mdvModel_t   *model      = 0;
	mdvSurface_t *mdvSurface = 0;
	shader_t     *shader     = 0;
	int          lod;
	qboolean     personalModel;
	int          fogNum;

	// don't add third_person objects if not in a portal
	personalModel = (ent->e.renderfx & RF_THIRD_PERSON) && !tr.viewParms.isPortal;

	if (ent->e.renderfx & RF_WRAP_FRAMES)
	{
		ent->e.frame    %= tr.currentModel->mdv[0]->numFrames;
		ent->e.oldframe %= tr.currentModel->mdv[0]->numFrames;
	}

	// compute LOD
	if (ent->e.renderfx & RF_FORCENOLOD)
	{
		lod = 0;
	}
	else
	{
		lod = R_ComputeLOD(ent);
	}

	// Validate the frames so there is no chance of a crash.
	// This will write directly into the entity structure, so
	// when the surfaces are rendered, they don't need to be
	// range checked again.
	if ((ent->e.frame >= tr.currentModel->mdv[lod]->numFrames)
	    || (ent->e.frame < 0) || (ent->e.oldframe >= tr.currentModel->mdv[lod]->numFrames) || (ent->e.oldframe < 0))
	{
		//Only spam if the lod level is 0 (lods usually don't have animation frames as they are only seen from a far)
		if (lod == 0)
		{
			Ren_Developer("R_AddMDVSurfaces: no such frame %d to %d for '%s' (%d)\n",
			              ent->e.oldframe, ent->e.frame, tr.currentModel->name, tr.currentModel->mdv[lod]->numFrames);
		}
		ent->e.frame    = 0;
		ent->e.oldframe = 0;
	}

	model = tr.currentModel->mdv[lod];

	// cull the entire model if merged bounding box of both frames
	// is outside the view frustum.
	R_CullMDV(model, ent);
	if (ent->cull == CULL_OUT)
	{
		return;
	}

	// set up lighting now that we know we aren't culled
	if (!personalModel || r_shadows->integer > SHADOWING_BLOB)
	{
		R_SetupEntityLighting(&tr.refdef, ent, NULL);
	}

	// see if we are in a fog volume
	fogNum = R_FogWorldBox(ent->worldBounds);

	// draw all surfaces
	if (r_vboModels->integer && model->numVBOSurfaces)
	{
		int             i;
		srfVBOMDVMesh_t *vboSurface;
		shader_t        *shader;

		for (i = 0; i < model->numVBOSurfaces; i++)
		{
			vboSurface = model->vboSurfaces[i];
			mdvSurface = vboSurface->mdvSurface;

			shader = GetMDVSurfaceShader(ent, mdvSurface);

			// don't add third_person objects if not viewing through a portal
			if (!personalModel)
			{
				R_AddDrawSurf((surfaceType_t *)vboSurface, shader, LIGHTMAP_NONE, fogNum);
			}
		}
	}
	else
	{
		for (i = 0, mdvSurface = model->surfaces; i < model->numSurfaces; i++, mdvSurface++)
		{
			shader = GetMDVSurfaceShader(ent, mdvSurface);

			// we will add shadows even if the main object isn't visible in the view

			// don't add third_person objects if not viewing through a portal
			if (!personalModel)
			{
				R_AddDrawSurf((surfaceType_t *)mdvSurface, shader, LIGHTMAP_NONE, fogNum);
			}
		}
	}
}