Add shader settings to settings.cfg

move
scrawl 9 years ago
parent 3969675afa
commit a73512afb7

@ -169,6 +169,9 @@ namespace MWRender
{ {
resourceSystem->getSceneManager()->setParticleSystemMask(MWRender::Mask_ParticleSystem); resourceSystem->getSceneManager()->setParticleSystemMask(MWRender::Mask_ParticleSystem);
resourceSystem->getSceneManager()->setShaderPath(resourcePath + "/shaders"); resourceSystem->getSceneManager()->setShaderPath(resourcePath + "/shaders");
resourceSystem->getSceneManager()->setForceShaders(Settings::Manager::getBool("force shaders", "Shaders"));
resourceSystem->getSceneManager()->setClampLighting(Settings::Manager::getBool("clamp lighting", "Shaders"));
resourceSystem->getSceneManager()->setForcePerPixelLighting(Settings::Manager::getBool("force per pixel lighting", "Shaders"));
osg::ref_ptr<SceneUtil::LightManager> sceneRoot = new SceneUtil::LightManager; osg::ref_ptr<SceneUtil::LightManager> sceneRoot = new SceneUtil::LightManager;
sceneRoot->setLightingMask(Mask_Lighting); sceneRoot->setLightingMask(Mask_Lighting);

@ -209,6 +209,9 @@ namespace Resource
SceneManager::SceneManager(const VFS::Manager *vfs, Resource::ImageManager* imageManager, Resource::NifFileManager* nifFileManager) SceneManager::SceneManager(const VFS::Manager *vfs, Resource::ImageManager* imageManager, Resource::NifFileManager* nifFileManager)
: ResourceManager(vfs) : ResourceManager(vfs)
, mShaderManager(new Shader::ShaderManager) , mShaderManager(new Shader::ShaderManager)
, mForceShaders(false)
, mClampLighting(false)
, mForcePerPixelLighting(false)
, mInstanceCache(new MultiObjectCache) , mInstanceCache(new MultiObjectCache)
, mImageManager(imageManager) , mImageManager(imageManager)
, mNifFileManager(nifFileManager) , mNifFileManager(nifFileManager)
@ -220,6 +223,21 @@ namespace Resource
{ {
} }
void SceneManager::setForceShaders(bool force)
{
mForceShaders = force;
}
void SceneManager::setClampLighting(bool clamp)
{
mClampLighting = clamp;
}
void SceneManager::setForcePerPixelLighting(bool force)
{
mForcePerPixelLighting = force;
}
SceneManager::~SceneManager() SceneManager::~SceneManager()
{ {
// this has to be defined in the .cpp file as we can't delete incomplete types // this has to be defined in the .cpp file as we can't delete incomplete types
@ -339,6 +357,9 @@ namespace Resource
loaded->accept(setFilterSettingsControllerVisitor); loaded->accept(setFilterSettingsControllerVisitor);
Shader::ShaderVisitor shaderVisitor(*mShaderManager.get(), "objects_vertex.glsl", "objects_fragment.glsl"); Shader::ShaderVisitor shaderVisitor(*mShaderManager.get(), "objects_vertex.glsl", "objects_fragment.glsl");
shaderVisitor.setForceShaders(mForceShaders);
shaderVisitor.setClampLighting(mClampLighting);
shaderVisitor.setForcePerPixelLighting(mForcePerPixelLighting);
loaded->accept(shaderVisitor); loaded->accept(shaderVisitor);
// share state // share state

@ -40,6 +40,15 @@ namespace Resource
SceneManager(const VFS::Manager* vfs, Resource::ImageManager* imageManager, Resource::NifFileManager* nifFileManager); SceneManager(const VFS::Manager* vfs, Resource::ImageManager* imageManager, Resource::NifFileManager* nifFileManager);
~SceneManager(); ~SceneManager();
/// @see ShaderVisitor::setForceShaders
void setForceShaders(bool force);
/// @see ShaderVisitor::setClampLighting
void setClampLighting(bool clamp);
/// @see ShaderVisitor::setForcePerPixelLighting
void setForcePerPixelLighting(bool force);
void setShaderPath(const std::string& path); void setShaderPath(const std::string& path);
/// Get a read-only copy of this scene "template" /// Get a read-only copy of this scene "template"
@ -106,6 +115,10 @@ namespace Resource
osg::ref_ptr<osg::Node> createInstance(const std::string& name); osg::ref_ptr<osg::Node> createInstance(const std::string& name);
std::auto_ptr<Shader::ShaderManager> mShaderManager; std::auto_ptr<Shader::ShaderManager> mShaderManager;
bool mForceShaders;
bool mClampLighting;
bool mForcePerPixelLighting;
osg::ref_ptr<MultiObjectCache> mInstanceCache; osg::ref_ptr<MultiObjectCache> mInstanceCache;
OpenThreads::Mutex mSharedStateMutex; OpenThreads::Mutex mSharedStateMutex;

@ -16,7 +16,8 @@ namespace Shader
{ {
ShaderVisitor::ShaderRequirements::ShaderRequirements() ShaderVisitor::ShaderRequirements::ShaderRequirements()
: mColorMaterial(false) : mHasNormalMap(false)
, mColorMaterial(false)
, mVertexColorMode(GL_AMBIENT_AND_DIFFUSE) , mVertexColorMode(GL_AMBIENT_AND_DIFFUSE)
, mTexStageRequiringTangents(-1) , mTexStageRequiringTangents(-1)
{ {
@ -24,6 +25,9 @@ namespace Shader
ShaderVisitor::ShaderVisitor(ShaderManager& shaderManager, const std::string &defaultVsTemplate, const std::string &defaultFsTemplate) ShaderVisitor::ShaderVisitor(ShaderManager& shaderManager, const std::string &defaultVsTemplate, const std::string &defaultFsTemplate)
: osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
, mForceShaders(false)
, mClampLighting(false)
, mForcePerPixelLighting(false)
, mShaderManager(shaderManager) , mShaderManager(shaderManager)
, mDefaultVsTemplate(defaultVsTemplate) , mDefaultVsTemplate(defaultVsTemplate)
, mDefaultFsTemplate(defaultFsTemplate) , mDefaultFsTemplate(defaultFsTemplate)
@ -31,6 +35,21 @@ namespace Shader
mRequirements.push_back(ShaderRequirements()); mRequirements.push_back(ShaderRequirements());
} }
void ShaderVisitor::setForceShaders(bool force)
{
mForceShaders = force;
}
void ShaderVisitor::setClampLighting(bool clamp)
{
mClampLighting = clamp;
}
void ShaderVisitor::setForcePerPixelLighting(bool force)
{
mForcePerPixelLighting = force;
}
void ShaderVisitor::apply(osg::Node& node) void ShaderVisitor::apply(osg::Node& node)
{ {
if (node.getStateSet()) if (node.getStateSet())
@ -61,6 +80,7 @@ namespace Shader
if (texture->getName() == "normalMap") if (texture->getName() == "normalMap")
{ {
mRequirements.back().mTexStageRequiringTangents = unit; mRequirements.back().mTexStageRequiringTangents = unit;
mRequirements.back().mHasNormalMap = true;
// normal maps are by default off since the FFP can't render them, now that we'll use shaders switch to On // normal maps are by default off since the FFP can't render them, now that we'll use shaders switch to On
stateset->setTextureMode(unit, GL_TEXTURE_2D, osg::StateAttribute::ON); stateset->setTextureMode(unit, GL_TEXTURE_2D, osg::StateAttribute::ON);
} }
@ -126,6 +146,9 @@ namespace Shader
} }
} }
defineMap["forcePPL"] = mForcePerPixelLighting ? "1" : "0";
defineMap["clamp"] = mClampLighting ? "1" : "0";
osg::ref_ptr<osg::Shader> vertexShader (mShaderManager.getShader(mDefaultVsTemplate, defineMap, osg::Shader::VERTEX)); osg::ref_ptr<osg::Shader> vertexShader (mShaderManager.getShader(mDefaultVsTemplate, defineMap, osg::Shader::VERTEX));
osg::ref_ptr<osg::Shader> fragmentShader (mShaderManager.getShader(mDefaultFsTemplate, defineMap, osg::Shader::FRAGMENT)); osg::ref_ptr<osg::Shader> fragmentShader (mShaderManager.getShader(mDefaultFsTemplate, defineMap, osg::Shader::FRAGMENT));
@ -161,6 +184,7 @@ namespace Shader
} }
// TODO: find a better place for the stateset // TODO: find a better place for the stateset
if (reqs.mHasNormalMap || mForceShaders)
createProgram(reqs, geometry.getOrCreateStateSet()); createProgram(reqs, geometry.getOrCreateStateSet());
} }
@ -181,8 +205,10 @@ namespace Shader
if (!mRequirements.empty()) if (!mRequirements.empty())
{ {
const ShaderRequirements& reqs = mRequirements.back();
// TODO: find a better place for the stateset // TODO: find a better place for the stateset
createProgram(mRequirements.back(), drawable.getOrCreateStateSet()); if (reqs.mHasNormalMap || mForceShaders)
createProgram(reqs, drawable.getOrCreateStateSet());
} }
if (needPop) if (needPop)

@ -14,6 +14,17 @@ namespace Shader
public: public:
ShaderVisitor(ShaderManager& shaderManager, const std::string& defaultVsTemplate, const std::string& defaultFsTemplate); ShaderVisitor(ShaderManager& shaderManager, const std::string& defaultVsTemplate, const std::string& defaultFsTemplate);
/// By default, only bump mapped objects will have a shader added to them.
/// Setting force = true will cause all objects to render using shaders, regardless of having a bump map.
void setForceShaders(bool force);
/// Set whether lighting is clamped for visual compatibility with the fixed function pipeline.
void setClampLighting(bool clamp);
/// By default, only bump mapped objects use per-pixel lighting.
/// Setting force = true will cause all shaders to use per-pixel lighting, regardless of having a bump map.
void setForcePerPixelLighting(bool force);
virtual void apply(osg::Node& node); virtual void apply(osg::Node& node);
virtual void apply(osg::Drawable& drawable); virtual void apply(osg::Drawable& drawable);
@ -25,6 +36,10 @@ namespace Shader
void popRequirements(); void popRequirements();
private: private:
bool mForceShaders;
bool mClampLighting;
bool mForcePerPixelLighting;
ShaderManager& mShaderManager; ShaderManager& mShaderManager;
struct ShaderRequirements struct ShaderRequirements
@ -34,6 +49,8 @@ namespace Shader
// <texture stage, texture name> // <texture stage, texture name>
std::map<int, std::string> mTextures; std::map<int, std::string> mTextures;
bool mHasNormalMap;
bool mColorMaterial; bool mColorMaterial;
// osg::Material::ColorMode // osg::Material::ColorMode
int mVertexColorMode; int mVertexColorMode;

@ -157,6 +157,27 @@ texture min filter = linear
# Texture mipmap type. (none, nearest, or linear). # Texture mipmap type. (none, nearest, or linear).
texture mipmap = nearest texture mipmap = nearest
[Shaders]
# Force rendering with shaders. By default, only bump-mapped objects will use shaders.
# Enabling this option may cause slightly different visuals if the "clamp lighting" option
# is set to false. Otherwise, there should not be a visual difference.
force shaders = false
# Force the use of per pixel lighting. By default, only bump mapped objects use per-pixel lighting.
# Has no effect if the 'force shaders' option is false.
# Enabling per-pixel lighting can result in visual differences to the original MW engine. It is not
# recommended to enable this option when using vanilla Morrowind files, because certain lights in Morrowind
# rely on vertex lighting to look as intended.
force per pixel lighting = false
# Restrict the amount of lighting that an object can receive to a maximum of (1,1,1).
# Only affects objects that render with shaders (see 'force shaders' option).
# Setting this option to 'true' results in fixed-function compatible lighting, but the lighting
# may appear 'dull' and there might be color shifts.
# Setting this option to 'false' results in more realistic lighting.
clamp lighting = false
[Input] [Input]
# Capture control of the cursor prevent movement outside the window. # Capture control of the cursor prevent movement outside the window.

@ -33,9 +33,10 @@ vec4 doLighting(vec3 viewPos, vec3 viewNormal, vec4 vertexColor)
lightResult.xyz += gl_FrontMaterial.emission.xyz; lightResult.xyz += gl_FrontMaterial.emission.xyz;
#endif #endif
// TODO: make clamp configurable #if @clamp
// the following produces fixed-function compatible lighting, w/o clamp arguably looks better lightResult = clamp(lightResult, vec4(0.0, 0.0, 0.0, 0.0), vec4(1.0, 1.0, 1.0, 1.0));
//lightResult = clamp(lightResult, vec4(0.0, 0.0, 0.0, 0.0), vec4(1.0, 1.0, 1.0, 1.0)); #else
lightResult = max(lightResult, 0.0);
#endif
return lightResult; return lightResult;
} }

@ -28,7 +28,7 @@ varying vec3 viewTangent;
varying float depth; varying float depth;
#define PER_PIXEL_LIGHTING @normalMap #define PER_PIXEL_LIGHTING (@normalMap || @forcePPL)
#if !PER_PIXEL_LIGHTING #if !PER_PIXEL_LIGHTING
varying vec4 lighting; varying vec4 lighting;
@ -56,8 +56,11 @@ void main()
gl_FragData[0].xyz *= texture2D(darkMap, darkMapUV).xyz; gl_FragData[0].xyz *= texture2D(darkMap, darkMapUV).xyz;
#endif #endif
#if @normalMap #if PER_PIXEL_LIGHTING
vec3 viewNormal = passViewNormal; vec3 viewNormal = passViewNormal;
#endif
#if @normalMap
vec3 normalTex = texture2D(normalMap, normalMapUV).xyz; vec3 normalTex = texture2D(normalMap, normalMapUV).xyz;
vec3 viewBinormal = cross(viewTangent, viewNormal); vec3 viewBinormal = cross(viewTangent, viewNormal);

@ -23,7 +23,7 @@ varying vec3 viewTangent;
varying float depth; varying float depth;
#define PER_PIXEL_LIGHTING @normalMap #define PER_PIXEL_LIGHTING (@normalMap || @forcePPL)
#if !PER_PIXEL_LIGHTING #if !PER_PIXEL_LIGHTING
varying vec4 lighting; varying vec4 lighting;

Loading…
Cancel
Save