1
0
forked from 0ad/0ad

Removes direct access to shaders, leaves only techniques.

Tested By: Langbart
Differential Revision: https://code.wildfiregames.com/D4353
This was SVN commit r26020.
This commit is contained in:
Vladislav Belov 2021-11-27 15:01:14 +00:00
parent 4c26a2d11f
commit e1374252b7
10 changed files with 131 additions and 117 deletions

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<effect>
<technique>
<require shaders="arb"/>
<pass shader="arb/dummy"/>
</technique>
<technique>
<require shaders="glsl"/>
<pass shader="glsl/dummy"/>
</technique>
</effect>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<effect>
<technique>
<require shaders="arb"/>
<pass shader="arb/overlayline"/>
</technique>
<technique>
<require shaders="glsl"/>
<pass shader="glsl/overlayline"/>
</technique>
</effect>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<effect>
<technique>
<require shaders="glsl"/>
<pass shader="glsl/water_high"/>
</technique>
</effect>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<effect>
<technique>
<require shaders="glsl"/>
<pass shader="glsl/waves"/>
</technique>
</effect>

View File

@ -380,18 +380,6 @@ bool CShaderManager::NewEffect(const char* name, const CShaderDefines& baseDefin
PROFILE2("loading effect");
PROFILE2_ATTR("name: %s", name);
// Shortcut syntax for effects that just contain a single shader
if (strncmp(name, "shader:", 7) == 0)
{
CShaderProgramPtr program = LoadProgram(name+7, baseDefines);
if (!program)
return false;
CShaderPass pass;
pass.SetShader(program);
tech->AddPass(pass);
return true;
}
VfsPath xmlFilename = L"shaders/effects/" + wstring_from_utf8(name) + L".xml";
CXeromyces XeroFile;
@ -543,7 +531,7 @@ bool CShaderManager::NewEffect(const char* name, const CShaderDefines& baseDefin
return true;
}
size_t CShaderManager::GetNumEffectsLoaded()
size_t CShaderManager::GetNumEffectsLoaded() const
{
return m_EffectCache.size();
}

View File

@ -38,14 +38,6 @@ public:
CShaderManager();
~CShaderManager();
/**
* Load a shader program.
* @param name name of shader XML specification (file is loaded from shaders/${name}.xml)
* @param defines key/value set of preprocessor definitions
* @return loaded program, or null pointer on error
*/
CShaderProgramPtr LoadProgram(const char* name, const CShaderDefines& defines);
/**
* Load a shader effect.
* Effects can be implemented via many techniques; this returns the best usable technique.
@ -63,10 +55,9 @@ public:
/**
* Returns the number of shader effects that are currently loaded.
*/
size_t GetNumEffectsLoaded();
size_t GetNumEffectsLoaded() const;
private:
struct CacheKey
{
std::string name;
@ -114,6 +105,14 @@ private:
using HotloadFilesMap = std::unordered_map<VfsPath, std::set<std::weak_ptr<CShaderProgram>, std::owner_less<std::weak_ptr<CShaderProgram> > > >;
HotloadFilesMap m_HotloadFiles;
/**
* Load a shader program.
* @param name name of shader XML specification (file is loaded from shaders/${name}.xml)
* @param defines key/value set of preprocessor definitions
* @return loaded program, or null pointer on error
*/
CShaderProgramPtr LoadProgram(const char* name, const CShaderDefines& defines);
bool NewProgram(const char* name, const CShaderDefines& defines, CShaderProgramPtr& program);
bool NewEffect(const char* name, const CShaderDefines& defines, CShaderTechniquePtr& tech);

View File

@ -107,6 +107,7 @@ X(debug_line)
X(debug_overlay)
X(delta)
X(depthTex)
X(dummy)
X(foamTex)
X(fogColor)
X(fogParams)
@ -129,6 +130,7 @@ X(murkiness)
X(normalMap)
X(normalMap2)
X(objectColor)
X(overlay_line)
X(overlay_solid)
X(particle)
X(particle_solid)
@ -171,7 +173,9 @@ X(tint)
X(transform)
X(translation)
X(viewInvTransform)
X(water_high)
X(water_simple)
X(water_waves)
X(waterEffectsTex)
X(waterTex)
X(waveTex)

View File

@ -47,14 +47,10 @@
namespace
{
CShaderProgramPtr GetOverlayLineShader(const CShaderDefines& defines)
CShaderTechniquePtr GetOverlayLineShaderTechnique(const CShaderDefines& defines)
{
const char* shaderName;
if (g_RenderingOptions.GetPreferGLSL())
shaderName = "glsl/overlayline";
else
shaderName = "arb/overlayline";
return g_Renderer.GetShaderManager().LoadProgram(shaderName, defines);
return g_Renderer.GetShaderManager().LoadEffect(
str_overlay_line, g_Renderer.GetSystemShaderDefines(), defines);
}
} // anonymous namespace
@ -426,13 +422,15 @@ void OverlayRenderer::RenderTexturedOverlayLines()
CLOSTexture& los = g_Renderer.GetScene().GetLOSTexture();
CShaderProgramPtr shaderTexLineNormal = GetOverlayLineShader(m->defsOverlayLineNormal);
CShaderProgramPtr shaderTexLineAlwaysVisible = GetOverlayLineShader(m->defsOverlayLineAlwaysVisible);
// ----------------------------------------------------------------------------------------
if (shaderTexLineNormal)
CShaderTechniquePtr shaderTechTexLineNormal = GetOverlayLineShaderTechnique(m->defsOverlayLineNormal);
if (shaderTechTexLineNormal)
{
shaderTechTexLineNormal->BeginPass();
CShaderProgramPtr shaderTexLineNormal = shaderTechTexLineNormal->GetShader();
shaderTexLineNormal->Bind();
shaderTexLineNormal->BindTexture(str_losTex, los.GetTexture());
shaderTexLineNormal->Uniform(str_losTransform, los.GetTextureMatrix()[0], los.GetTextureMatrix()[12], 0.f, 0.f);
@ -442,13 +440,18 @@ void OverlayRenderer::RenderTexturedOverlayLines()
// batch render only the non-always-visible overlay lines using the normal shader
RenderTexturedOverlayLines(shaderTexLineNormal, false);
shaderTexLineNormal->Unbind();
shaderTechTexLineNormal->EndPass();
}
// ----------------------------------------------------------------------------------------
if (shaderTexLineAlwaysVisible)
CShaderTechniquePtr shaderTechTexLineAlwaysVisible = GetOverlayLineShaderTechnique(m->defsOverlayLineAlwaysVisible);
if (shaderTechTexLineAlwaysVisible)
{
shaderTechTexLineAlwaysVisible->BeginPass();
CShaderProgramPtr shaderTexLineAlwaysVisible = shaderTechTexLineAlwaysVisible->GetShader();
shaderTexLineAlwaysVisible->Bind();
// TODO: losTex and losTransform are unused in the always visible shader; see if these can be safely omitted
shaderTexLineAlwaysVisible->BindTexture(str_losTex, los.GetTexture());
@ -459,7 +462,7 @@ void OverlayRenderer::RenderTexturedOverlayLines()
// batch render only the always-visible overlay lines using the LoS-ignored shader
RenderTexturedOverlayLines(shaderTexLineAlwaysVisible, true);
shaderTexLineAlwaysVisible->Unbind();
shaderTechTexLineAlwaysVisible->EndPass();
}
// ----------------------------------------------------------------------------------------
@ -506,11 +509,15 @@ void OverlayRenderer::RenderQuadOverlays()
if (m->quadBatchMap.empty())
return;
CShaderProgramPtr shader = GetOverlayLineShader(m->defsQuadOverlay);
CShaderTechniquePtr shaderTech = GetOverlayLineShaderTechnique(m->defsQuadOverlay);
if (!shader)
if (!shaderTech)
return;
shaderTech->BeginPass();
CShaderProgramPtr shader = shaderTech->GetShader();
#if !CONFIG2_GLES
if (g_Renderer.GetOverlayRenderMode() == WIREFRAME)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
@ -569,7 +576,7 @@ void OverlayRenderer::RenderQuadOverlays()
g_Renderer.GetStats().m_OverlayTris += batchNumQuads*2;
}
shader->Unbind();
shaderTech->EndPass();
// TODO: the shader should probably be responsible for unbinding its textures
g_Renderer.BindTexture(1, 0);

View File

@ -51,21 +51,6 @@
#include "renderer/VertexArray.h"
#include "renderer/WaterManager.h"
namespace
{
CShaderProgramPtr GetDummyShader()
{
const char* shaderName;
if (g_RenderingOptions.GetPreferGLSL())
shaderName = "glsl/dummy";
else
shaderName = "arb/dummy";
return g_Renderer.GetShaderManager().LoadProgram(shaderName, CShaderDefines());
}
} // anonymous namespace
/**
* TerrainRenderer keeps track of which phase it is in, to detect
* when Submit, PrepareForRendering etc. are called in the wrong order.
@ -91,7 +76,7 @@ struct TerrainRendererInternals
std::vector<CDecalRData*> visibleDecals[CRenderer::CULL_MAX];
/// Fancy water shader
CShaderProgramPtr fancyWaterShader;
CShaderTechniquePtr fancyWaterTech;
CSimulation2* simulation;
};
@ -320,14 +305,15 @@ void TerrainRenderer::RenderPatches(int cullGroup, const CColor& color)
#if CONFIG2_GLES
#warning TODO: implement TerrainRenderer::RenderPatches for GLES
#else
CShaderProgramPtr dummyShader = GetDummyShader();
dummyShader->Bind();
CShaderTechniquePtr dummyTech = g_Renderer.GetShaderManager().LoadEffect(str_dummy);
dummyTech->BeginPass();
CShaderProgramPtr dummyShader = dummyTech->GetShader();
dummyShader->Uniform(str_transform, g_Renderer.GetViewCamera().GetViewProjection());
dummyShader->Uniform(str_color, color);
CPatchRData::RenderStreams(visiblePatches, dummyShader, STREAM_POS);
dummyShader->Unbind();
dummyTech->EndPass();
#endif
}
@ -377,7 +363,7 @@ bool TerrainRenderer::RenderFancyWater(const CShaderDefines& context, int cullGr
CShaderDefines defines = context;
// If we're using fancy water, make sure its shader is loaded
if (!m->fancyWaterShader || WaterMgr->m_NeedsReloading)
if (!m->fancyWaterTech || WaterMgr->m_NeedsReloading)
{
if (WaterMgr->m_WaterRealDepth)
defines.Add(str_USE_REAL_DEPTH, str_1);
@ -388,15 +374,12 @@ bool TerrainRenderer::RenderFancyWater(const CShaderDefines& context, int cullGr
if (WaterMgr->m_WaterReflection)
defines.Add(str_USE_REFLECTION, str_1);
// haven't updated the ARB shader yet so I'll always load the GLSL
/*if (!g_RenderingOptions.GetPreferGLSL() && !superFancy)
m->fancyWaterShader = g_Renderer.GetShaderManager().LoadProgram("arb/water_high", defines);
else*/
m->fancyWaterShader = g_Renderer.GetShaderManager().LoadProgram("glsl/water_high", defines);
m->fancyWaterTech = g_Renderer.GetShaderManager().LoadEffect(
str_water_high, g_Renderer.GetSystemShaderDefines(), defines);
if (!m->fancyWaterShader)
if (!m->fancyWaterTech)
{
LOGERROR("Failed to load water shader. Falling back to fixed pipeline water.\n");
LOGERROR("Failed to load water shader. Falling back to a simple water.\n");
WaterMgr->m_RenderWater = false;
return false;
}
@ -456,91 +439,92 @@ bool TerrainRenderer::RenderFancyWater(const CShaderDefines& context, int cullGr
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
m->fancyWaterShader->Bind();
m->fancyWaterTech->BeginPass();
CShaderProgramPtr fancyWaterShader = m->fancyWaterTech->GetShader();
const CCamera& camera = g_Renderer.GetViewCamera();
m->fancyWaterShader->BindTexture(str_normalMap, WaterMgr->m_NormalMap[curTex]);
m->fancyWaterShader->BindTexture(str_normalMap2, WaterMgr->m_NormalMap[nexTex]);
fancyWaterShader->BindTexture(str_normalMap, WaterMgr->m_NormalMap[curTex]);
fancyWaterShader->BindTexture(str_normalMap2, WaterMgr->m_NormalMap[nexTex]);
if (WaterMgr->m_WaterFancyEffects)
{
m->fancyWaterShader->BindTexture(str_waterEffectsTex, WaterMgr->m_FancyTexture);
fancyWaterShader->BindTexture(str_waterEffectsTex, WaterMgr->m_FancyTexture);
}
if (WaterMgr->m_WaterRefraction && WaterMgr->m_WaterRealDepth)
{
m->fancyWaterShader->BindTexture(str_depthTex, WaterMgr->m_RefrFboDepthTexture);
m->fancyWaterShader->Uniform(str_projInvTransform, WaterMgr->m_RefractionProjInvMatrix);
m->fancyWaterShader->Uniform(str_viewInvTransform, WaterMgr->m_RefractionViewInvMatrix);
fancyWaterShader->BindTexture(str_depthTex, WaterMgr->m_RefrFboDepthTexture);
fancyWaterShader->Uniform(str_projInvTransform, WaterMgr->m_RefractionProjInvMatrix);
fancyWaterShader->Uniform(str_viewInvTransform, WaterMgr->m_RefractionViewInvMatrix);
}
if (WaterMgr->m_WaterRefraction)
m->fancyWaterShader->BindTexture(str_refractionMap, WaterMgr->m_RefractionTexture);
fancyWaterShader->BindTexture(str_refractionMap, WaterMgr->m_RefractionTexture);
if (WaterMgr->m_WaterReflection)
m->fancyWaterShader->BindTexture(str_reflectionMap, WaterMgr->m_ReflectionTexture);
m->fancyWaterShader->BindTexture(str_losTex, losTexture.GetTextureSmooth());
fancyWaterShader->BindTexture(str_reflectionMap, WaterMgr->m_ReflectionTexture);
fancyWaterShader->BindTexture(str_losTex, losTexture.GetTextureSmooth());
const CLightEnv& lightEnv = g_Renderer.GetLightEnv();
m->fancyWaterShader->Uniform(str_transform, g_Renderer.GetViewCamera().GetViewProjection());
fancyWaterShader->Uniform(str_transform, g_Renderer.GetViewCamera().GetViewProjection());
m->fancyWaterShader->BindTexture(str_skyCube, g_Renderer.GetSkyManager()->GetSkyCube());
fancyWaterShader->BindTexture(str_skyCube, g_Renderer.GetSkyManager()->GetSkyCube());
// TODO: check that this rotates in the right direction.
CMatrix3D skyBoxRotation;
skyBoxRotation.SetIdentity();
skyBoxRotation.RotateY(M_PI + lightEnv.GetRotation());
m->fancyWaterShader->Uniform(str_skyBoxRot, skyBoxRotation);
fancyWaterShader->Uniform(str_skyBoxRot, skyBoxRotation);
if (WaterMgr->m_WaterRefraction)
m->fancyWaterShader->Uniform(str_refractionMatrix, WaterMgr->m_RefractionMatrix);
fancyWaterShader->Uniform(str_refractionMatrix, WaterMgr->m_RefractionMatrix);
if (WaterMgr->m_WaterReflection)
m->fancyWaterShader->Uniform(str_reflectionMatrix, WaterMgr->m_ReflectionMatrix);
fancyWaterShader->Uniform(str_reflectionMatrix, WaterMgr->m_ReflectionMatrix);
m->fancyWaterShader->Uniform(str_ambient, lightEnv.m_AmbientColor);
m->fancyWaterShader->Uniform(str_sunDir, lightEnv.GetSunDir());
m->fancyWaterShader->Uniform(str_sunColor, lightEnv.m_SunColor);
m->fancyWaterShader->Uniform(str_color, WaterMgr->m_WaterColor);
m->fancyWaterShader->Uniform(str_tint, WaterMgr->m_WaterTint);
m->fancyWaterShader->Uniform(str_waviness, WaterMgr->m_Waviness);
m->fancyWaterShader->Uniform(str_murkiness, WaterMgr->m_Murkiness);
m->fancyWaterShader->Uniform(str_windAngle, WaterMgr->m_WindAngle);
m->fancyWaterShader->Uniform(str_repeatScale, 1.0f / repeatPeriod);
m->fancyWaterShader->Uniform(str_losTransform, losTexture.GetTextureMatrix()[0], losTexture.GetTextureMatrix()[12], 0.f, 0.f);
fancyWaterShader->Uniform(str_ambient, lightEnv.m_AmbientColor);
fancyWaterShader->Uniform(str_sunDir, lightEnv.GetSunDir());
fancyWaterShader->Uniform(str_sunColor, lightEnv.m_SunColor);
fancyWaterShader->Uniform(str_color, WaterMgr->m_WaterColor);
fancyWaterShader->Uniform(str_tint, WaterMgr->m_WaterTint);
fancyWaterShader->Uniform(str_waviness, WaterMgr->m_Waviness);
fancyWaterShader->Uniform(str_murkiness, WaterMgr->m_Murkiness);
fancyWaterShader->Uniform(str_windAngle, WaterMgr->m_WindAngle);
fancyWaterShader->Uniform(str_repeatScale, 1.0f / repeatPeriod);
fancyWaterShader->Uniform(str_losTransform, losTexture.GetTextureMatrix()[0], losTexture.GetTextureMatrix()[12], 0.f, 0.f);
m->fancyWaterShader->Uniform(str_cameraPos, camera.GetOrientation().GetTranslation());
fancyWaterShader->Uniform(str_cameraPos, camera.GetOrientation().GetTranslation());
m->fancyWaterShader->Uniform(str_fogColor, lightEnv.m_FogColor);
m->fancyWaterShader->Uniform(str_fogParams, lightEnv.m_FogFactor, lightEnv.m_FogMax, 0.f, 0.f);
m->fancyWaterShader->Uniform(str_time, (float)time);
m->fancyWaterShader->Uniform(str_screenSize, (float)g_Renderer.GetWidth(), (float)g_Renderer.GetHeight(), 0.0f, 0.0f);
fancyWaterShader->Uniform(str_fogColor, lightEnv.m_FogColor);
fancyWaterShader->Uniform(str_fogParams, lightEnv.m_FogFactor, lightEnv.m_FogMax, 0.f, 0.f);
fancyWaterShader->Uniform(str_time, (float)time);
fancyWaterShader->Uniform(str_screenSize, (float)g_Renderer.GetWidth(), (float)g_Renderer.GetHeight(), 0.0f, 0.0f);
if (WaterMgr->m_WaterType == L"clap")
{
m->fancyWaterShader->Uniform(str_waveParams1, 30.0f,1.5f,20.0f,0.03f);
m->fancyWaterShader->Uniform(str_waveParams2, 0.5f,0.0f,0.0f,0.0f);
fancyWaterShader->Uniform(str_waveParams1, 30.0f,1.5f,20.0f,0.03f);
fancyWaterShader->Uniform(str_waveParams2, 0.5f,0.0f,0.0f,0.0f);
}
else if (WaterMgr->m_WaterType == L"lake")
{
m->fancyWaterShader->Uniform(str_waveParams1, 8.5f,1.5f,15.0f,0.03f);
m->fancyWaterShader->Uniform(str_waveParams2, 0.2f,0.0f,0.0f,0.07f);
fancyWaterShader->Uniform(str_waveParams1, 8.5f,1.5f,15.0f,0.03f);
fancyWaterShader->Uniform(str_waveParams2, 0.2f,0.0f,0.0f,0.07f);
}
else
{
m->fancyWaterShader->Uniform(str_waveParams1, 15.0f,0.8f,10.0f,0.1f);
m->fancyWaterShader->Uniform(str_waveParams2, 0.3f,0.0f,0.1f,0.3f);
fancyWaterShader->Uniform(str_waveParams1, 15.0f,0.8f,10.0f,0.1f);
fancyWaterShader->Uniform(str_waveParams2, 0.3f,0.0f,0.1f,0.3f);
}
if (shadow)
shadow->BindTo(m->fancyWaterShader);
shadow->BindTo(fancyWaterShader);
std::vector<CPatchRData*>& visiblePatches = m->visiblePatches[cullGroup];
for (size_t i = 0; i < visiblePatches.size(); ++i)
{
CPatchRData* data = visiblePatches[i];
data->RenderWater(m->fancyWaterShader);
data->RenderWater(fancyWaterShader);
}
m->fancyWaterShader->Unbind();
m->fancyWaterTech->EndPass();
glDepthFunc(GL_LEQUAL);
glDisable(GL_BLEND);

View File

@ -15,10 +15,6 @@
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Water settings (speed, height) and texture management
*/
#include "precompiled.h"
#include "graphics/Terrain.h"
@ -50,7 +46,8 @@ struct CoastalPoint
CVector2D position;
};
struct SWavesVertex {
struct SWavesVertex
{
// vertex position
CVector3D m_BasePosition;
CVector3D m_ApexPosition;
@ -864,10 +861,9 @@ void WaterManager::RenderWaves(const CFrustum& frustrum)
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_ALWAYS);
CShaderDefines none;
CShaderProgramPtr shader = g_Renderer.GetShaderManager().LoadProgram("glsl/waves", none);
shader->Bind();
CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect(str_water_waves);
tech->BeginPass();
CShaderProgramPtr shader = tech->GetShader();
shader->BindTexture(str_waveTex, m_WaveTex);
shader->BindTexture(str_foamTex, m_FoamTex);
@ -910,7 +906,7 @@ void WaterManager::RenderWaves(const CFrustum& frustrum)
CVertexBuffer::Unbind();
}
shader->Unbind();
tech->EndPass();
pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glDisable(GL_BLEND);