Index: ps/trunk/binaries/data/mods/public/shaders/effects/dummy.xml =================================================================== --- ps/trunk/binaries/data/mods/public/shaders/effects/dummy.xml +++ ps/trunk/binaries/data/mods/public/shaders/effects/dummy.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + Index: ps/trunk/binaries/data/mods/public/shaders/effects/overlay_line.xml =================================================================== --- ps/trunk/binaries/data/mods/public/shaders/effects/overlay_line.xml +++ ps/trunk/binaries/data/mods/public/shaders/effects/overlay_line.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + Index: ps/trunk/binaries/data/mods/public/shaders/effects/water_high.xml =================================================================== --- ps/trunk/binaries/data/mods/public/shaders/effects/water_high.xml +++ ps/trunk/binaries/data/mods/public/shaders/effects/water_high.xml @@ -0,0 +1,7 @@ + + + + + + + Index: ps/trunk/binaries/data/mods/public/shaders/effects/water_waves.xml =================================================================== --- ps/trunk/binaries/data/mods/public/shaders/effects/water_waves.xml +++ ps/trunk/binaries/data/mods/public/shaders/effects/water_waves.xml @@ -0,0 +1,7 @@ + + + + + + + Index: ps/trunk/source/graphics/ShaderManager.h =================================================================== --- ps/trunk/source/graphics/ShaderManager.h +++ ps/trunk/source/graphics/ShaderManager.h @@ -39,14 +39,6 @@ ~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. * @param name name of effect XML specification (file is loaded from shaders/effects/${name}.xml) @@ -63,10 +55,9 @@ /** * 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 @@ using HotloadFilesMap = std::unordered_map, std::owner_less > > >; 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); Index: ps/trunk/source/graphics/ShaderManager.cpp =================================================================== --- ps/trunk/source/graphics/ShaderManager.cpp +++ ps/trunk/source/graphics/ShaderManager.cpp @@ -380,18 +380,6 @@ 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 @@ return true; } -size_t CShaderManager::GetNumEffectsLoaded() +size_t CShaderManager::GetNumEffectsLoaded() const { return m_EffectCache.size(); } Index: ps/trunk/source/ps/CStrInternStatic.h =================================================================== --- ps/trunk/source/ps/CStrInternStatic.h +++ ps/trunk/source/ps/CStrInternStatic.h @@ -107,6 +107,7 @@ X(debug_overlay) X(delta) X(depthTex) +X(dummy) X(foamTex) X(fogColor) X(fogParams) @@ -129,6 +130,7 @@ X(normalMap) X(normalMap2) X(objectColor) +X(overlay_line) X(overlay_solid) X(particle) X(particle_solid) @@ -171,7 +173,9 @@ X(transform) X(translation) X(viewInvTransform) +X(water_high) X(water_simple) +X(water_waves) X(waterEffectsTex) X(waterTex) X(waveTex) Index: ps/trunk/source/renderer/OverlayRenderer.cpp =================================================================== --- ps/trunk/source/renderer/OverlayRenderer.cpp +++ ps/trunk/source/renderer/OverlayRenderer.cpp @@ -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 @@ 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 @@ // 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 @@ // batch render only the always-visible overlay lines using the LoS-ignored shader RenderTexturedOverlayLines(shaderTexLineAlwaysVisible, true); - shaderTexLineAlwaysVisible->Unbind(); + shaderTechTexLineAlwaysVisible->EndPass(); } // ---------------------------------------------------------------------------------------- @@ -506,11 +509,15 @@ 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 @@ 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); Index: ps/trunk/source/renderer/TerrainRenderer.cpp =================================================================== --- ps/trunk/source/renderer/TerrainRenderer.cpp +++ ps/trunk/source/renderer/TerrainRenderer.cpp @@ -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 @@ std::vector visibleDecals[CRenderer::CULL_MAX]; /// Fancy water shader - CShaderProgramPtr fancyWaterShader; + CShaderTechniquePtr fancyWaterTech; CSimulation2* simulation; }; @@ -320,14 +305,15 @@ #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 @@ 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 @@ 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 @@ 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); - - m->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_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); + + fancyWaterShader->Uniform(str_cameraPos, camera.GetOrientation().GetTranslation()); + + 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& 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); Index: ps/trunk/source/renderer/WaterManager.cpp =================================================================== --- ps/trunk/source/renderer/WaterManager.cpp +++ ps/trunk/source/renderer/WaterManager.cpp @@ -15,10 +15,6 @@ * along with 0 A.D. If not, see . */ -/* - * Water settings (speed, height) and texture management - */ - #include "precompiled.h" #include "graphics/Terrain.h" @@ -50,7 +46,8 @@ CVector2D position; }; -struct SWavesVertex { +struct SWavesVertex +{ // vertex position CVector3D m_BasePosition; CVector3D m_ApexPosition; @@ -864,10 +861,9 @@ 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 @@ CVertexBuffer::Unbind(); } - shader->Unbind(); + tech->EndPass(); pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glDisable(GL_BLEND);