Example #1
0
/**
 * @brief Manages all state for the specified surface and stage.
 * @sa R_DrawMaterialSurfaces
 */
static void R_SetSurfaceStageState (const mBspSurface_t *surf, const materialStage_t *stage)
{
	/* bind the texture */
	R_BindTexture(stage->image->texnum);

	/* and optionally the lightmap */
	R_StageLighting(surf, stage);

	R_StageGlow(stage);

	/* load the texture matrix for rotations, stretches, etc.. */
	R_StageTextureMatrix(surf, stage);

	/* set the blend function, ensuring a good default */
	if (stage->flags & STAGE_BLEND)
		R_BlendFunc(stage->blend.src, stage->blend.dest);
	else
		R_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	/* for terrain, enable the color array */
	if (stage->flags & (STAGE_TAPE | STAGE_TERRAIN | STAGE_DIRTMAP))
		R_EnableColorArray(true);
	else
		R_EnableColorArray(false);

	/* when not using the color array, resolve the shade color */
	if (!r_state.color_array_enabled) {
		vec4_t color;

		if (stage->flags & STAGE_COLOR)  /* explicit */
			VectorCopy(stage->color, color);

		else if (stage->flags & STAGE_ENVMAP)  /* implied */
			VectorCopy(surf->lightColor, color); /** @todo WTF? surely it was supposed to use the specular color */

		else  /* default */
			VectorSet(color, 1.0, 1.0, 1.0);

		/* modulate the alpha value for pulses */
		if (stage->flags & STAGE_PULSE) {
			/* disable fog, since it also sets alpha */
			R_EnableFog(false);
			color[3] = stage->pulse.dhz;
		} else {
			/* ensure fog is available */
			R_EnableFog(true);
			color[3] = 1.0;
		}

		R_Color(color);
	}
}
Example #2
0
/*
 * @brief Main entry point for drawing the scene (world and entities).
 */
void R_DrawView(void) {

	R_UpdateFrustum();

	R_UpdateVis();

	R_MarkBspSurfaces();

	R_EnableFog(true);

	R_DrawSkyBox();

	// wait for the client to populate our lights array
	Thread_Wait(&r_view.thread);

	// now dispatch another thread to cull entities while we draw the world
	r_view.thread = Thread_Create(R_CullEntities, NULL);

	R_MarkLights();

	const r_sorted_bsp_surfaces_t *surfs = r_model_state.world->bsp->sorted_surfaces;

	R_DrawOpaqueBspSurfaces(&surfs->opaque);

	R_DrawOpaqueWarpBspSurfaces(&surfs->opaque_warp);

	R_DrawAlphaTestBspSurfaces(&surfs->alpha_test);

	R_EnableBlend(true);

	R_DrawBackBspSurfaces(&surfs->back);

	R_DrawMaterialBspSurfaces(&surfs->material);

	R_DrawFlareBspSurfaces(&surfs->flare);

	R_EnableBlend(false);

	R_DrawBspNormals();

	// ensure the thread has finished culling entities
	Thread_Wait(&r_view.thread);

	// now dispatch another thread to update particles while we draw entities
	r_view.thread = Thread_Create(R_UpdateParticles, NULL);

	R_DrawEntities();

	R_EnableBlend(true);

	R_DrawBspLights();

	R_DrawBlendBspSurfaces(&surfs->blend);

	R_DrawBlendWarpBspSurfaces(&surfs->blend_warp);

	// ensure the thread has finished updating particles
	Thread_Wait(&r_view.thread);

	R_DrawParticles();

	R_EnableFog(false);

	R_DrawCoronas();

	R_DrawBspLeafs();

	R_EnableBlend(false);

	R_ResetArrayState();
}
Example #3
0
/**
 * @brief Iterates the specified surfaces list, updating materials as they are
 * encountered, and rendering all visible stages. State is lazily managed
 * throughout the iteration, so there is a concerted effort to restore the
 * state after all surface stages have been rendered.
 */
void R_DrawMaterialSurfaces (const mBspSurfaces_t *surfs, GLushort *indexPtr)
{
	int i;

	if (!r_materials->integer || r_wire->integer)
		return;

	if (!surfs->count)
		return;

	assert(r_state.blend_enabled);

	/** @todo - integrate BSP lighting with model lighting */
	R_EnableModelLights(nullptr, 0, false, false);

	R_EnableColorArray(true);

	R_ResetArrayState();

	R_EnableColorArray(false);

	R_EnableLighting(nullptr, false);

	R_EnableTexture(&texunit_lightmap, false);

#ifndef GL_VERSION_ES_CM_1_0
	glEnable(GL_POLYGON_OFFSET_FILL);
#endif
	glPolygonOffset(-1.f, -1.f);

	glMatrixMode(GL_TEXTURE);  /* some stages will manipulate texcoords */

	for (i = 0; i < surfs->count; i++) {
		materialStage_t *s;
		mBspSurface_t *surf = surfs->surfaces[i];
		material_t *m = &surf->texinfo->image->material;
		int j = -1;

		if (surf->frame != r_locals.frame)
			continue;

		R_UpdateMaterial(m);

		for (s = m->stages; s; s = s->next, j--) {
			if (!(s->flags & STAGE_RENDER))
				continue;

			R_SetSurfaceStageState(surf, s);

			R_DrawSurfaceStage(surf, s);
		}
	}

	R_Color(nullptr);

	/* polygon offset parameters */
	glPolygonOffset(0.0, 0.0);
#ifndef GL_VERSION_ES_CM_1_0
	glDisable(GL_POLYGON_OFFSET_FILL);
#endif

	glLoadIdentity();
	glMatrixMode(GL_MODELVIEW);

	R_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	R_EnableFog(true);

	R_EnableColorArray(false);

	R_EnableTexture(&texunit_lightmap, false);

	R_EnableBumpmap(nullptr);

	R_EnableLighting(nullptr, false);

	R_EnableGlowMap(nullptr);

	R_Color(nullptr);
}
Example #4
0
/*
 * @brief Main entry point for drawing the scene (world and entities).
 */
void R_DrawView(void) {

	R_UpdateFrustum();

	R_UpdateVis();

	R_MarkBspSurfaces();

	R_EnableFog(true);

	R_DrawSkyBox();

	// wait for the client to fully populate the scene
	Thread_Wait(r_view.thread);

	// dispatch threads to cull entities and sort elements while we draw the world
	thread_t *cull_entities = Thread_Create(R_CullEntities, NULL);
	thread_t *sort_elements = Thread_Create(R_SortElements, NULL);

	R_MarkLights();

	const r_sorted_bsp_surfaces_t *surfs = r_model_state.world->bsp->sorted_surfaces;

	R_DrawOpaqueBspSurfaces(&surfs->opaque);

	R_DrawOpaqueWarpBspSurfaces(&surfs->opaque_warp);

	R_DrawAlphaTestBspSurfaces(&surfs->alpha_test);

	R_EnableBlend(true);

	R_DrawBackBspSurfaces(&surfs->back);

	R_DrawMaterialBspSurfaces(&surfs->material);

	R_DrawFlareBspSurfaces(&surfs->flare);

	R_EnableBlend(false);

	// wait for entity culling to complete
	Thread_Wait(cull_entities);

	R_DrawEntities();

	R_EnableBlend(true);

	// wait for element sorting to complete
	Thread_Wait(sort_elements);

	R_DrawElements();

	R_EnableFog(false);

	R_DrawDeveloperTools();

	R_DrawCoronas();

	R_EnableBlend(false);

	R_ResetArrayState();

#if 0
	vec3_t tmp;
	VectorMA(r_view.origin, MAX_WORLD_DIST, r_view.forward, tmp);

	cm_trace_t tr = Cl_Trace(r_view.origin, tmp, NULL, NULL, cl.client_num + 1, MASK_SOLID);
	if (tr.fraction > 0.0 && tr.fraction < 1.0) {
		Com_Print("%s: %d: %s\n", tr.surface->name, tr.plane.num, vtos(tr.plane.normal));
	}

#endif
}
Example #5
0
/**
 * @sa R_BeginFrame
 * @sa R_EndFrame
 */
void R_RenderFrame (void)
{
	R_Setup3D();

	/* activate wire mode */
	if (r_wire->integer)
		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

	if (!(refdef.rendererFlags & RDF_NOWORLDMODEL)) {
		int tile;
		if (r_threads->integer) {
			while (r_threadstate.state != THREAD_RENDERER)
				Sys_Sleep(0);

			r_threadstate.state = THREAD_CLIENT;
		} else {
			R_SetupFrustum();

			/* draw brushes on current worldlevel */
			R_GetLevelSurfaceLists();
		}

		R_UpdateSustainedLights();

		R_CheckError();

		for (tile = 0; tile < r_numMapTiles; tile++) {
			const model_t *mapTile = r_mapTiles[tile];
			const mBspModel_t *bsp = &mapTile->bsp;

			R_AddBspRRef(bsp, vec3_origin, vec3_origin, false);
		}

		R_GetEntityLists();

		R_EnableFog(true);

		R_RenderOpaqueBspRRefs();
		R_RenderOpaqueWarpBspRRefs();
		R_DrawOpaqueMeshEntities(r_opaque_mesh_entities);

		R_RenderAlphaTestBspRRefs();

		R_EnableBlend(true);
		R_RenderMaterialBspRRefs();

		R_EnableFog(false);

		R_RenderBlendBspRRefs();
		R_RenderBlendWarpBspRRefs();
		R_DrawBlendMeshEntities(r_blend_mesh_entities);

		R_EnableFog(true);
		R_RenderFlareBspRRefs();
		R_EnableFog(false);

		if (r_debug_lights->integer) {
			int i;

			for (i = 0; i < refdef.numStaticLights; i++) {
				const light_t *l = &refdef.staticLights[i];
				R_AddCorona(l->origin, l->radius, l->color);
			}
			for (i = 0; i < refdef.numDynamicLights; i++) {
				const light_t *l = &refdef.dynamicLights[i];
				R_AddCorona(l->origin, l->radius, l->color);
			}
		}

		R_DrawCoronas();
		R_EnableBlend(false);

		for (tile = 0; tile < r_numMapTiles; tile++) {
			R_DrawBspNormals(tile);
		}

		R_Color(NULL);
		R_DrawSpecialEntities(r_special_entities);
		R_DrawNullEntities(r_null_entities);
		R_DrawEntityEffects();
	} else {
		glClear(GL_DEPTH_BUFFER_BIT);

		R_GetEntityLists();

		R_RenderOpaqueBspRRefs();
		R_RenderOpaqueWarpBspRRefs();
		R_DrawOpaqueMeshEntities(r_opaque_mesh_entities);
		R_RenderAlphaTestBspRRefs();

		R_EnableBlend(true);

		R_RenderMaterialBspRRefs();

		R_RenderBlendBspRRefs();
		R_RenderBlendWarpBspRRefs();
		R_DrawBlendMeshEntities(r_blend_mesh_entities);

		R_RenderFlareBspRRefs();

		R_EnableBlend(false);

		R_Color(NULL);
		R_DrawSpecialEntities(r_special_entities);
		R_DrawNullEntities(r_null_entities);
		R_DrawEntityEffects();
	}

	R_EnableBlend(true);

	R_DrawParticles();

	R_EnableBlend(false);

	/* leave wire mode again */
	if (r_wire->integer)
		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

	R_DrawBloom();

	R_DrawBoundingBoxes();

	R_ResetArrayState();

	/* go back into 2D mode for hud and the like */
	R_Setup2D();

	R_CheckError();
}