コード例 #1
0
ファイル: TerrainRenderer.cpp プロジェクト: Gallaecio/0ad
void TerrainRenderer::RenderTerrainShader(ShadowMap* shadow, bool filtered)
{
	ENSURE(m->phase == Phase_Render);

	std::vector<CPatchRData*>& visiblePatches = filtered ? m->filteredPatches : m->visiblePatches;
	std::vector<CDecalRData*>& visibleDecals = filtered ? m->filteredDecals : m->visibleDecals;
	if (visiblePatches.empty() && visibleDecals.empty())
		return;

	CShaderManager& shaderManager = g_Renderer.GetShaderManager();

	typedef std::map<CStr, CStr> Defines;
	Defines defBasic;
	if (shadow)
	{
		defBasic["USE_SHADOW"] = "1";
		if (g_Renderer.m_Caps.m_ARBProgramShadow && g_Renderer.m_Options.m_ARBProgramShadow)
			defBasic["USE_FP_SHADOW"] = "1";
		if (g_Renderer.m_Options.m_ShadowPCF)
			defBasic["USE_SHADOW_PCF"] = "1";
#if !CONFIG2_GLES
		defBasic["USE_SHADOW_SAMPLER"] = "1";
#endif
	}

	defBasic["LIGHTING_MODEL_" + g_Renderer.GetLightEnv().GetLightingModel()] = "1";

	CShaderTechniquePtr techBase(shaderManager.LoadEffect("terrain_base", defBasic));
	CShaderTechniquePtr techBlend(shaderManager.LoadEffect("terrain_blend", defBasic));
	CShaderTechniquePtr techDecal(shaderManager.LoadEffect("terrain_decal", defBasic));

	// render the solid black sides of the map first
	CShaderTechniquePtr techSolid = g_Renderer.GetShaderManager().LoadEffect("gui_solid");
	techSolid->BeginPass();
	CShaderProgramPtr shaderSolid = techSolid->GetShader();
	shaderSolid->Uniform("transform", g_Renderer.GetViewCamera().GetViewProjection());
	shaderSolid->Uniform("color", 0.0f, 0.0f, 0.0f, 1.0f);

	PROFILE_START("render terrain sides");
	for (size_t i = 0; i < visiblePatches.size(); ++i)
		visiblePatches[i]->RenderSides(shaderSolid);
	PROFILE_END("render terrain sides");

	techSolid->EndPass();

	techBase->BeginPass();
	PrepareShader(techBase->GetShader(), shadow);

	PROFILE_START("render terrain base");
	CPatchRData::RenderBases(visiblePatches, techBase->GetShader(), false);
	PROFILE_END("render terrain base");

	techBase->EndPass();

	// render blends

	techBlend->BeginPass();
	PrepareShader(techBlend->GetShader(), shadow);

	// switch on blending
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	// no need to write to the depth buffer a second time
	glDepthMask(0);

	// render blend passes for each patch
	PROFILE_START("render terrain blends");
	CPatchRData::RenderBlends(visiblePatches, techBlend->GetShader(), false);
	PROFILE_END("render terrain blends");

	techBlend->EndPass();

	// Render terrain decals

	techDecal->BeginPass();
	PrepareShader(techDecal->GetShader(), shadow);

	PROFILE_START("render terrain decals");
	for (size_t i = 0; i < visibleDecals.size(); ++i)
		visibleDecals[i]->Render(techDecal->GetShader(), false);
	PROFILE_END("render terrain decals");

	techDecal->EndPass();

	// restore OpenGL state
	g_Renderer.BindTexture(1, 0);
	g_Renderer.BindTexture(2, 0);
	g_Renderer.BindTexture(3, 0);

	glDepthMask(1);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glDisable(GL_BLEND);
}
コード例 #2
0
ファイル: TerrainRenderer.cpp プロジェクト: wdmchaft/0ad
void TerrainRenderer::RenderTerrainShader(const CShaderDefines& context, ShadowMap* shadow, bool filtered)
{
    ENSURE(m->phase == Phase_Render);

    std::vector<CPatchRData*>& visiblePatches = filtered ? m->filteredPatches : m->visiblePatches;
    std::vector<CDecalRData*>& visibleDecals = filtered ? m->filteredDecals : m->visibleDecals;
    if (visiblePatches.empty() && visibleDecals.empty())
        return;

    CShaderManager& shaderManager = g_Renderer.GetShaderManager();

    CShaderTechniquePtr techBase(shaderManager.LoadEffect(CStrIntern("terrain_base"), context, CShaderDefines()));
    CShaderTechniquePtr techBlend(shaderManager.LoadEffect(CStrIntern("terrain_blend"), context, CShaderDefines()));
    CShaderTechniquePtr techDecal(shaderManager.LoadEffect(CStrIntern("terrain_decal"), context, CShaderDefines()));

    // render the solid black sides of the map first
    CShaderTechniquePtr techSolid = g_Renderer.GetShaderManager().LoadEffect("gui_solid");
    techSolid->BeginPass();
    CShaderProgramPtr shaderSolid = techSolid->GetShader();
    shaderSolid->Uniform("transform", g_Renderer.GetViewCamera().GetViewProjection());
    shaderSolid->Uniform("color", 0.0f, 0.0f, 0.0f, 1.0f);

    PROFILE_START("render terrain sides");
    for (size_t i = 0; i < visiblePatches.size(); ++i)
        visiblePatches[i]->RenderSides(shaderSolid);
    PROFILE_END("render terrain sides");

    techSolid->EndPass();

    techBase->BeginPass();
    PrepareShader(techBase->GetShader(), shadow);

    PROFILE_START("render terrain base");
    CPatchRData::RenderBases(visiblePatches, techBase->GetShader(), false);
    PROFILE_END("render terrain base");

    techBase->EndPass();

    // render blends

    techBlend->BeginPass();
    PrepareShader(techBlend->GetShader(), shadow);

    // switch on blending
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    // no need to write to the depth buffer a second time
    glDepthMask(0);

    // render blend passes for each patch
    PROFILE_START("render terrain blends");
    CPatchRData::RenderBlends(visiblePatches, techBlend->GetShader(), false);
    PROFILE_END("render terrain blends");

    techBlend->EndPass();

    // Render terrain decals

    techDecal->BeginPass();
    PrepareShader(techDecal->GetShader(), shadow);

    PROFILE_START("render terrain decals");
    for (size_t i = 0; i < visibleDecals.size(); ++i)
        visibleDecals[i]->Render(techDecal->GetShader(), false);
    PROFILE_END("render terrain decals");

    techDecal->EndPass();

    // restore OpenGL state
    g_Renderer.BindTexture(1, 0);
    g_Renderer.BindTexture(2, 0);
    g_Renderer.BindTexture(3, 0);

    glDepthMask(1);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glDisable(GL_BLEND);
}