mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-05-11 13:06:56 +03:00
shade refactor
This commit is contained in:
parent
cc5f20d66a
commit
ac4787aeec
84 changed files with 737 additions and 658 deletions
|
@ -339,12 +339,8 @@ Debug::DebugDrawer::DebugDrawer(Shader::ShaderManager& shaderManager, osg::ref_p
|
|||
: mParentNode(parentNode)
|
||||
{
|
||||
mCurrentFrame = 0;
|
||||
auto vertexShader
|
||||
= shaderManager.getShader("debug_vertex.glsl", Shader::ShaderManager::DefineMap(), osg::Shader::Type::VERTEX);
|
||||
auto fragmentShader = shaderManager.getShader(
|
||||
"debug_fragment.glsl", Shader::ShaderManager::DefineMap(), osg::Shader::Type::FRAGMENT);
|
||||
|
||||
auto program = shaderManager.getProgram(vertexShader, fragmentShader);
|
||||
auto program = shaderManager.getProgram("debug");
|
||||
|
||||
mDebugDrawSceneObjects = new osg::Group;
|
||||
mDebugDrawSceneObjects->setCullingActive(false);
|
||||
|
|
|
@ -416,9 +416,7 @@ namespace osgMyGUI
|
|||
|
||||
void RenderManager::enableShaders(Shader::ShaderManager& shaderManager)
|
||||
{
|
||||
auto vertexShader = shaderManager.getShader("gui_vertex.glsl", {}, osg::Shader::VERTEX);
|
||||
auto fragmentShader = shaderManager.getShader("gui_fragment.glsl", {}, osg::Shader::FRAGMENT);
|
||||
auto program = shaderManager.getProgram(vertexShader, fragmentShader);
|
||||
auto program = shaderManager.getProgram("gui");
|
||||
|
||||
mDrawable->getDrawableStateSet()->setAttributeAndModes(program, osg::StateAttribute::ON);
|
||||
mDrawable->getDrawableStateSet()->addUniform(new osg::Uniform("diffuseMap", 0));
|
||||
|
|
|
@ -1991,9 +1991,9 @@ namespace NifOsg
|
|||
switch (static_cast<Nif::BSShaderType>(type))
|
||||
{
|
||||
case Nif::BSShaderType::ShaderType_Default:
|
||||
return "nv_default";
|
||||
return "bs/default";
|
||||
case Nif::BSShaderType::ShaderType_NoLighting:
|
||||
return "nv_nolighting";
|
||||
return "bs/nolighting";
|
||||
case Nif::BSShaderType::ShaderType_TallGrass:
|
||||
case Nif::BSShaderType::ShaderType_Sky:
|
||||
case Nif::BSShaderType::ShaderType_Skin:
|
||||
|
@ -2001,10 +2001,10 @@ namespace NifOsg
|
|||
case Nif::BSShaderType::ShaderType_Lighting30:
|
||||
case Nif::BSShaderType::ShaderType_Tile:
|
||||
Log(Debug::Warning) << "Unhandled BSShaderType " << type << " in " << mFilename;
|
||||
return "nv_default";
|
||||
return "bs/default";
|
||||
}
|
||||
Log(Debug::Warning) << "Unknown BSShaderType " << type << " in " << mFilename;
|
||||
return "nv_default";
|
||||
return "bs/default";
|
||||
}
|
||||
|
||||
std::string_view getBSLightingShaderPrefix(unsigned int type) const
|
||||
|
@ -2012,7 +2012,7 @@ namespace NifOsg
|
|||
switch (static_cast<Nif::BSLightingShaderType>(type))
|
||||
{
|
||||
case Nif::BSLightingShaderType::ShaderType_Default:
|
||||
return "nv_default";
|
||||
return "bs/default";
|
||||
case Nif::BSLightingShaderType::ShaderType_EnvMap:
|
||||
case Nif::BSLightingShaderType::ShaderType_Glow:
|
||||
case Nif::BSLightingShaderType::ShaderType_Parallax:
|
||||
|
@ -2034,10 +2034,10 @@ namespace NifOsg
|
|||
case Nif::BSLightingShaderType::ShaderType_MultitexLandLODBlend:
|
||||
case Nif::BSLightingShaderType::ShaderType_Dismemberment:
|
||||
Log(Debug::Warning) << "Unhandled BSLightingShaderType " << type << " in " << mFilename;
|
||||
return "nv_default";
|
||||
return "bs/default";
|
||||
}
|
||||
Log(Debug::Warning) << "Unknown BSLightingShaderType " << type << " in " << mFilename;
|
||||
return "nv_default";
|
||||
return "bs/default";
|
||||
}
|
||||
|
||||
void handleProperty(const Nif::Property* property, osg::Node* node,
|
||||
|
|
|
@ -922,7 +922,7 @@ void SceneUtil::MWShadowTechnique::setupCastingShader(Shader::ShaderManager & sh
|
|||
{
|
||||
// This can't be part of the constructor as OSG mandates that there be a trivial constructor available
|
||||
|
||||
osg::ref_ptr<osg::Shader> castingVertexShader = shaderManager.getShader("shadowcasting_vertex.glsl", { }, osg::Shader::VERTEX);
|
||||
osg::ref_ptr<osg::Shader> castingVertexShader = shaderManager.getShader("shadowcasting.vert");
|
||||
osg::ref_ptr<osg::GLExtensions> exts = osg::GLExtensions::Get(0, false);
|
||||
std::string useGPUShader4 = exts && exts->isGpuShader4Supported ? "1" : "0";
|
||||
for (int alphaFunc = GL_NEVER; alphaFunc <= GL_ALWAYS; ++alphaFunc)
|
||||
|
@ -930,11 +930,11 @@ void SceneUtil::MWShadowTechnique::setupCastingShader(Shader::ShaderManager & sh
|
|||
auto& program = _castingPrograms[alphaFunc - GL_NEVER];
|
||||
program = new osg::Program();
|
||||
program->addShader(castingVertexShader);
|
||||
program->addShader(shaderManager.getShader("shadowcasting_fragment.glsl", { {"alphaFunc", std::to_string(alphaFunc)},
|
||||
program->addShader(shaderManager.getShader("shadowcasting.frag", { {"alphaFunc", std::to_string(alphaFunc)},
|
||||
{"alphaToCoverage", "0"},
|
||||
{"adjustCoverage", "1"},
|
||||
{"useGPUShader4", useGPUShader4}
|
||||
}, osg::Shader::FRAGMENT));
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,29 @@
|
|||
#include <sstream>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace
|
||||
{
|
||||
osg::Shader::Type getShaderType(const std::string& templateName)
|
||||
{
|
||||
auto ext = std::filesystem::path(templateName).extension();
|
||||
|
||||
if (ext == ".vert")
|
||||
return osg::Shader::VERTEX;
|
||||
if (ext == ".frag")
|
||||
return osg::Shader::FRAGMENT;
|
||||
if (ext == ".geom")
|
||||
return osg::Shader::GEOMETRY;
|
||||
if (ext == ".comp")
|
||||
return osg::Shader::COMPUTE;
|
||||
if (ext == ".tese")
|
||||
return osg::Shader::TESSEVALUATION;
|
||||
if (ext == ".tesc")
|
||||
return osg::Shader::TESSCONTROL;
|
||||
|
||||
throw std::runtime_error("unrecognized shader template name: " + templateName);
|
||||
}
|
||||
}
|
||||
|
||||
namespace Shader
|
||||
{
|
||||
|
||||
|
@ -106,7 +129,11 @@ namespace Shader
|
|||
return false;
|
||||
}
|
||||
std::string includeFilename = source.substr(start + 1, end - (start + 1));
|
||||
std::filesystem::path includePath = shaderPath / includeFilename;
|
||||
std::filesystem::path includePath
|
||||
= shaderPath / std::filesystem::path(fileName).parent_path() / includeFilename;
|
||||
|
||||
if (!std::filesystem::exists(includePath))
|
||||
includePath = shaderPath / includeFilename;
|
||||
|
||||
// Determine the line number that will be used for the #line directive following the included source
|
||||
size_t lineDirectivePosition = source.rfind("#line", foundPos);
|
||||
|
@ -471,10 +498,16 @@ namespace Shader
|
|||
};
|
||||
|
||||
osg::ref_ptr<osg::Shader> ShaderManager::getShader(
|
||||
const std::string& templateName, const ShaderManager::DefineMap& defines, osg::Shader::Type shaderType)
|
||||
std::string templateName, const ShaderManager::DefineMap& defines, std::optional<osg::Shader::Type> type)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mMutex);
|
||||
|
||||
// TODO: Implement mechanism to switch to core or compatibility profile shaders.
|
||||
// This logic is temporary until core support is supported.
|
||||
if (!templateName.starts_with("lib") && !templateName.starts_with("compatibility")
|
||||
&& !templateName.starts_with("core"))
|
||||
templateName = "compatibility/" + templateName;
|
||||
|
||||
// read the template if we haven't already
|
||||
TemplateMap::iterator templateIt = mShaderTemplates.find(templateName);
|
||||
std::set<std::filesystem::path> insertedPaths;
|
||||
|
@ -514,7 +547,7 @@ namespace Shader
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Shader> shader(new osg::Shader(shaderType));
|
||||
osg::ref_ptr<osg::Shader> shader(new osg::Shader(type ? *type : getShaderType(templateName)));
|
||||
shader->setShaderSource(shaderSource);
|
||||
// Assign a unique prefix to allow the SharedStateManager to compare shaders efficiently.
|
||||
// Append shader source filename for debugging.
|
||||
|
@ -532,6 +565,18 @@ namespace Shader
|
|||
return shaderIt->second;
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Program> ShaderManager::getProgram(
|
||||
const std::string& templateName, const DefineMap& defines, const osg::Program* programTemplate)
|
||||
{
|
||||
auto vert = getShader(templateName + ".vert", defines);
|
||||
auto frag = getShader(templateName + ".frag", defines);
|
||||
|
||||
if (!vert || !frag)
|
||||
throw std::runtime_error("failed initializing shader: " + templateName);
|
||||
|
||||
return getProgram(vert, frag, programTemplate);
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Program> ShaderManager::getProgram(osg::ref_ptr<osg::Shader> vertexShader,
|
||||
osg::ref_ptr<osg::Shader> fragmentShader, const osg::Program* programTemplate)
|
||||
{
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
@ -36,13 +37,16 @@ namespace Shader
|
|||
typedef std::map<std::string, std::string> DefineMap;
|
||||
|
||||
/// Create or retrieve a shader instance.
|
||||
/// @param shaderTemplate The filename of the shader template.
|
||||
/// @param templateName The path of the shader template.
|
||||
/// @param defines Define values that can be retrieved by the shader template.
|
||||
/// @param shaderType The type of shader (usually vertex or fragment shader).
|
||||
/// @note May return nullptr on failure.
|
||||
/// @note Thread safe.
|
||||
osg::ref_ptr<osg::Shader> getShader(
|
||||
const std::string& templateName, const DefineMap& defines, osg::Shader::Type shaderType);
|
||||
osg::ref_ptr<osg::Shader> getShader(std::string templateName, const DefineMap& defines = {},
|
||||
std::optional<osg::Shader::Type> type = std::nullopt);
|
||||
|
||||
osg::ref_ptr<osg::Program> getProgram(const std::string& templateName, const DefineMap& defines = {},
|
||||
const osg::Program* programTemplate = nullptr);
|
||||
|
||||
osg::ref_ptr<osg::Program> getProgram(osg::ref_ptr<osg::Shader> vertexShader,
|
||||
osg::ref_ptr<osg::Shader> fragmentShader, const osg::Program* programTemplate = nullptr);
|
||||
|
|
|
@ -715,24 +715,14 @@ namespace Shader
|
|||
if (!node.getUserValue("shaderPrefix", shaderPrefix))
|
||||
shaderPrefix = mDefaultShaderPrefix;
|
||||
|
||||
osg::ref_ptr<osg::Shader> vertexShader(
|
||||
mShaderManager.getShader(shaderPrefix + "_vertex.glsl", defineMap, osg::Shader::VERTEX));
|
||||
osg::ref_ptr<osg::Shader> fragmentShader(
|
||||
mShaderManager.getShader(shaderPrefix + "_fragment.glsl", defineMap, osg::Shader::FRAGMENT));
|
||||
auto program = mShaderManager.getProgram(shaderPrefix, defineMap, mProgramTemplate);
|
||||
writableStateSet->setAttributeAndModes(program, osg::StateAttribute::ON);
|
||||
addedState->setAttributeAndModes(program);
|
||||
|
||||
if (vertexShader && fragmentShader)
|
||||
for (const auto& [unit, name] : reqs.mTextures)
|
||||
{
|
||||
auto program = mShaderManager.getProgram(vertexShader, fragmentShader, mProgramTemplate);
|
||||
writableStateSet->setAttributeAndModes(program, osg::StateAttribute::ON);
|
||||
addedState->setAttributeAndModes(program);
|
||||
|
||||
for (std::map<int, std::string>::const_iterator texIt = reqs.mTextures.begin();
|
||||
texIt != reqs.mTextures.end(); ++texIt)
|
||||
{
|
||||
writableStateSet->addUniform(
|
||||
new osg::Uniform(texIt->second.c_str(), texIt->first), osg::StateAttribute::ON);
|
||||
addedState->addUniform(texIt->second);
|
||||
}
|
||||
writableStateSet->addUniform(new osg::Uniform(name.c_str(), unit), osg::StateAttribute::ON);
|
||||
addedState->addUniform(name);
|
||||
}
|
||||
|
||||
if (!addedState->empty())
|
||||
|
|
|
@ -285,17 +285,7 @@ namespace Terrain
|
|||
defineMap["writeNormals"] = (it == layers.end() - 1) ? "1" : "0";
|
||||
Stereo::Manager::instance().shaderStereoDefines(defineMap);
|
||||
|
||||
osg::ref_ptr<osg::Shader> vertexShader
|
||||
= shaderManager.getShader("terrain_vertex.glsl", defineMap, osg::Shader::VERTEX);
|
||||
osg::ref_ptr<osg::Shader> fragmentShader
|
||||
= shaderManager.getShader("terrain_fragment.glsl", defineMap, osg::Shader::FRAGMENT);
|
||||
if (!vertexShader || !fragmentShader)
|
||||
{
|
||||
// Try again without shader. Error already logged by above
|
||||
return createPasses(false, sceneManager, layers, blendmaps, blendmapScale, layerTileSize);
|
||||
}
|
||||
|
||||
stateset->setAttributeAndModes(shaderManager.getProgram(vertexShader, fragmentShader));
|
||||
stateset->setAttributeAndModes(shaderManager.getProgram("terrain", defineMap));
|
||||
stateset->addUniform(UniformCollection::value().mColorMode);
|
||||
}
|
||||
else
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue