mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-04 03:15:32 +00:00
working commit
This commit is contained in:
parent
aa094b568e
commit
b3f2373875
14 changed files with 152 additions and 22 deletions
|
@ -15,6 +15,7 @@
|
|||
#include <osg/ComputeBoundsVisitor>
|
||||
#include <osg/ShapeDrawable>
|
||||
#include <osg/TextureCubeMap>
|
||||
#include <osg/ViewportIndexed>
|
||||
|
||||
#include <osgUtil/LineSegmentIntersector>
|
||||
|
||||
|
@ -207,8 +208,9 @@ namespace MWRender
|
|||
resourceSystem->getSceneManager()->setParticleSystemMask(MWRender::Mask_ParticleSystem);
|
||||
resourceSystem->getSceneManager()->setShaderPath(resourcePath + "/shaders");
|
||||
// Shadows and radial fog have problems with fixed-function mode
|
||||
bool forceShaders = Settings::Manager::getBool("radial fog", "Shaders") || Settings::Manager::getBool("force shaders", "Shaders") || Settings::Manager::getBool("enable shadows", "Shadows");
|
||||
resourceSystem->getSceneManager()->setForceShaders(forceShaders);
|
||||
//bool forceShaders = Settings::Manager::getBool("radial fog", "Shaders") || Settings::Manager::getBool("force shaders", "Shaders") || Settings::Manager::getBool("enable shadows", "Shadows");
|
||||
//resourceSystem->getSceneManager()->setForceShaders(forceShaders);
|
||||
resourceSystem->getSceneManager()->setForceShaders(true);
|
||||
// FIXME: calling dummy method because terrain needs to know whether lighting is clamped
|
||||
resourceSystem->getSceneManager()->setClampLighting(Settings::Manager::getBool("clamp lighting", "Shaders"));
|
||||
resourceSystem->getSceneManager()->setAutoUseNormalMaps(Settings::Manager::getBool("auto use object normal maps", "Shaders"));
|
||||
|
@ -370,11 +372,27 @@ namespace MWRender
|
|||
mFirstPersonFieldOfView = std::min(std::max(1.f, firstPersonFov), 179.f);
|
||||
mStateUpdater->setFogEnd(mViewDistance);
|
||||
|
||||
////// Indexed viewports and related uniforms
|
||||
sceneRoot->getOrCreateStateSet()->addUniform(new osg::Uniform(osg::Uniform::FLOAT_MAT4, "stereoViewOffsets", 2));
|
||||
sceneRoot->getOrCreateStateSet()->addUniform(new osg::Uniform(osg::Uniform::FLOAT_MAT4, "stereoProjections", 2));
|
||||
mUniformStereoViewOffsets = sceneRoot->getOrCreateStateSet()->getUniform("stereoViewOffsets");
|
||||
mUniformStereoProjections = sceneRoot->getOrCreateStateSet()->getUniform("stereoProjections");
|
||||
mUniformStereoViewOffsets->setElement(0, osg::Matrix::identity());
|
||||
mUniformStereoViewOffsets->setElement(1, osg::Matrix::identity());
|
||||
|
||||
auto width = mViewer->getCamera()->getViewport()->width();
|
||||
auto height = mViewer->getCamera()->getViewport()->height();
|
||||
|
||||
sceneRoot->getOrCreateStateSet()->setAttribute(new osg::ViewportIndexed(0, 0, 0, width / 2, height));
|
||||
sceneRoot->getOrCreateStateSet()->setAttribute(new osg::ViewportIndexed(1, width / 2, 0, width / 2, height));
|
||||
|
||||
////// Near far uniforms
|
||||
mRootNode->getOrCreateStateSet()->addUniform(new osg::Uniform("near", mNearClip));
|
||||
mRootNode->getOrCreateStateSet()->addUniform(new osg::Uniform("far", mViewDistance));
|
||||
|
||||
mUniformNear = mRootNode->getOrCreateStateSet()->getUniform("near");
|
||||
mUniformFar = mRootNode->getOrCreateStateSet()->getUniform("far");
|
||||
|
||||
updateProjectionMatrix();
|
||||
}
|
||||
|
||||
|
@ -1225,6 +1243,9 @@ namespace MWRender
|
|||
fov = mFieldOfViewOverride;
|
||||
mViewer->getCamera()->setProjectionMatrixAsPerspective(fov, aspect, mNearClip, mViewDistance);
|
||||
|
||||
mUniformStereoProjections->setElement(0, mViewer->getCamera()->getProjectionMatrix());
|
||||
mUniformStereoProjections->setElement(1, mViewer->getCamera()->getProjectionMatrix());
|
||||
|
||||
mUniformNear->set(mNearClip);
|
||||
mUniformFar->set(mViewDistance);
|
||||
|
||||
|
|
|
@ -108,6 +108,8 @@ namespace MWRender
|
|||
|
||||
osg::Uniform* mUniformNear;
|
||||
osg::Uniform* mUniformFar;
|
||||
osg::Uniform* mUniformStereoViewOffsets;
|
||||
osg::Uniform* mUniformStereoProjections;
|
||||
|
||||
void preloadCommonAssets();
|
||||
|
||||
|
|
|
@ -763,7 +763,7 @@ namespace Resource
|
|||
|
||||
Shader::ShaderVisitor *SceneManager::createShaderVisitor()
|
||||
{
|
||||
Shader::ShaderVisitor* shaderVisitor = new Shader::ShaderVisitor(*mShaderManager.get(), *mImageManager, "objects_vertex.glsl", "objects_fragment.glsl");
|
||||
Shader::ShaderVisitor* shaderVisitor = new Shader::ShaderVisitor(*mShaderManager.get(), *mImageManager, "objects_vertex.glsl", "objects_fragment.glsl", "objects_geometry.glsl");
|
||||
shaderVisitor->setForceShaders(mForceShaders);
|
||||
shaderVisitor->setAutoUseNormalMaps(mAutoUseNormalMaps);
|
||||
shaderVisitor->setNormalMapPattern(mNormalMapPattern);
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace Shader
|
|||
|
||||
}
|
||||
|
||||
ShaderVisitor::ShaderVisitor(ShaderManager& shaderManager, Resource::ImageManager& imageManager, const std::string &defaultVsTemplate, const std::string &defaultFsTemplate)
|
||||
ShaderVisitor::ShaderVisitor(ShaderManager& shaderManager, Resource::ImageManager& imageManager, const std::string &defaultVsTemplate, const std::string &defaultFsTemplate, const std::string& defaultGsTemplate)
|
||||
: osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
|
||||
, mForceShaders(false)
|
||||
, mAllowedToModifyStateSets(true)
|
||||
|
@ -47,6 +47,7 @@ namespace Shader
|
|||
, mImageManager(imageManager)
|
||||
, mDefaultVsTemplate(defaultVsTemplate)
|
||||
, mDefaultFsTemplate(defaultFsTemplate)
|
||||
, mDefaultGsTemplate(defaultGsTemplate)
|
||||
{
|
||||
mRequirements.push_back(ShaderRequirements());
|
||||
}
|
||||
|
@ -349,10 +350,12 @@ namespace Shader
|
|||
|
||||
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> geometryShader (mShaderManager.getShader(mDefaultGsTemplate, defineMap, osg::Shader::GEOMETRY));
|
||||
//osg::ref_ptr<osg::Shader> geometryShader = nullptr;
|
||||
|
||||
if (vertexShader && fragmentShader)
|
||||
{
|
||||
writableStateSet->setAttributeAndModes(mShaderManager.getProgram(vertexShader, fragmentShader), osg::StateAttribute::ON);
|
||||
writableStateSet->setAttributeAndModes(mShaderManager.getProgram(vertexShader, fragmentShader, geometryShader), osg::StateAttribute::ON);
|
||||
|
||||
for (std::map<int, std::string>::const_iterator texIt = reqs.mTextures.begin(); texIt != reqs.mTextures.end(); ++texIt)
|
||||
{
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace Shader
|
|||
class ShaderVisitor : public osg::NodeVisitor
|
||||
{
|
||||
public:
|
||||
ShaderVisitor(ShaderManager& shaderManager, Resource::ImageManager& imageManager, const std::string& defaultVsTemplate, const std::string& defaultFsTemplate);
|
||||
ShaderVisitor(ShaderManager& shaderManager, Resource::ImageManager& imageManager, const std::string& defaultVsTemplate, const std::string& defaultFsTemplate, const std::string& defaultGsTemplate);
|
||||
|
||||
/// 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.
|
||||
|
@ -89,6 +89,7 @@ namespace Shader
|
|||
|
||||
std::string mDefaultVsTemplate;
|
||||
std::string mDefaultFsTemplate;
|
||||
std::string mDefaultGsTemplate;
|
||||
|
||||
void createProgram(const ShaderRequirements& reqs);
|
||||
bool adjustGeometry(osg::Geometry& sourceGeometry, const ShaderRequirements& reqs);
|
||||
|
|
|
@ -234,6 +234,8 @@ namespace Terrain
|
|||
defineMap["parallax"] = (it->mNormalMap && it->mParallax) ? "1" : "0";
|
||||
|
||||
osg::ref_ptr<osg::Shader> vertexShader = shaderManager->getShader("terrain_vertex.glsl", defineMap, osg::Shader::VERTEX);
|
||||
osg::ref_ptr<osg::Shader> geometryShader = shaderManager->getShader("terrain_geometry.glsl", defineMap, osg::Shader::GEOMETRY);
|
||||
//osg::ref_ptr<osg::Shader> geometryShader = nullptr;
|
||||
osg::ref_ptr<osg::Shader> fragmentShader = shaderManager->getShader("terrain_fragment.glsl", defineMap, osg::Shader::FRAGMENT);
|
||||
if (!vertexShader || !fragmentShader)
|
||||
{
|
||||
|
@ -241,7 +243,7 @@ namespace Terrain
|
|||
return createPasses(false, shaderManager, layers, blendmaps, blendmapScale, layerTileSize);
|
||||
}
|
||||
|
||||
stateset->setAttributeAndModes(shaderManager->getProgram(vertexShader, fragmentShader));
|
||||
stateset->setAttributeAndModes(shaderManager->getProgram(vertexShader, fragmentShader, geometryShader));
|
||||
stateset->addUniform(new osg::Uniform("colorMode", 2));
|
||||
}
|
||||
else
|
||||
|
|
|
@ -11,17 +11,21 @@ set(SHADER_FILES
|
|||
water_fragment.glsl
|
||||
water_nm.png
|
||||
objects_vertex.glsl
|
||||
objects_geometry.glsl
|
||||
objects_fragment.glsl
|
||||
terrain_vertex.glsl
|
||||
terrain_geometry.glsl
|
||||
terrain_fragment.glsl
|
||||
lighting.glsl
|
||||
parallax.glsl
|
||||
s360_fragment.glsl
|
||||
s360_vertex.glsl
|
||||
shadows_vertex.glsl
|
||||
shadows_geometry.glsl
|
||||
shadows_fragment.glsl
|
||||
shadowcasting_vertex.glsl
|
||||
shadowcasting_fragment.glsl
|
||||
interface_util.glsl
|
||||
)
|
||||
|
||||
copy_all_resource_files(${CMAKE_CURRENT_SOURCE_DIR} ${OPENMW_SHADERS_ROOT} ${DDIRRELATIVE} "${SHADER_FILES}")
|
||||
|
|
12
files/shaders/interface_util.glsl
Normal file
12
files/shaders/interface_util.glsl
Normal file
|
@ -0,0 +1,12 @@
|
|||
// Because GLSL is an abomination we have to mangle the names of all
|
||||
// vertex outputs when using a geometry shader.
|
||||
#ifndef INTERFACE_UTIL_GLSL
|
||||
#define INTERFACE_UTIL_GLSL
|
||||
|
||||
#if 1 // Placeholder
|
||||
#define VS_NAME(name) vertex_##name
|
||||
#else
|
||||
#define VS_NAME(name) name
|
||||
#endif
|
||||
|
||||
#endif // INTERFACE_UTIL_GLSL
|
17
files/shaders/objects_geometry.glsl
Normal file
17
files/shaders/objects_geometry.glsl
Normal file
|
@ -0,0 +1,17 @@
|
|||
#version 330 core
|
||||
#extension GL_NV_viewport_array : enable
|
||||
#extension GL_ARB_gpu_shader5 : enable
|
||||
layout (triangles, invocations = 2) in;
|
||||
layout (triangle_strip, max_vertices = 3) out;
|
||||
|
||||
#include "interface_util.glsl"
|
||||
|
||||
void main() {
|
||||
for(int i = 0; i < gl_in.length(); i++)
|
||||
{
|
||||
gl_ViewportIndex = gl_InvocationID;
|
||||
gl_Position = gl_in[i].gl_Position;
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
#version 120
|
||||
|
||||
#include "interface_util.glsl"
|
||||
|
||||
#if @diffuseMap
|
||||
varying vec2 diffuseMapUV;
|
||||
#endif
|
||||
|
|
0
files/shaders/shadows_geometry.glsl
Normal file
0
files/shaders/shadows_geometry.glsl
Normal file
|
@ -110,4 +110,6 @@ void main()
|
|||
gl_FragData[0].xyz = mix(gl_FragData[0].xyz, gl_Fog.color.xyz, fogValue);
|
||||
|
||||
applyShadowDebugOverlay();
|
||||
|
||||
//gl_FragData[0] = vec4(passNormal,1);
|
||||
}
|
||||
|
|
61
files/shaders/terrain_geometry.glsl
Normal file
61
files/shaders/terrain_geometry.glsl
Normal file
|
@ -0,0 +1,61 @@
|
|||
#version 330 core
|
||||
#extension GL_NV_viewport_array : enable
|
||||
#extension GL_ARB_gpu_shader5 : enable
|
||||
layout (triangles, invocations = 2) in;
|
||||
layout (triangle_strip, max_vertices = 3) out;
|
||||
|
||||
#include "interface_util.glsl"
|
||||
|
||||
#define PER_PIXEL_LIGHTING (@normalMap || @forcePPL)
|
||||
|
||||
#if !PER_PIXEL_LIGHTING
|
||||
centroid in vec4 VS_NAME(lighting)[];
|
||||
centroid in vec3 VS_NAME(shadowDiffuseLighting)[];
|
||||
centroid out vec4 lighting;
|
||||
centroid out vec3 shadowDiffuseLighting;
|
||||
#endif
|
||||
|
||||
// TERRAIN INPUT
|
||||
in vec2 VS_NAME(uv)[];
|
||||
in float VS_NAME(euclideanDepth)[];
|
||||
in float VS_NAME(linearDepth)[];
|
||||
centroid in vec4 VS_NAME(passColor)[];
|
||||
in vec3 VS_NAME(passViewPos)[];
|
||||
in vec3 VS_NAME(passNormal)[];
|
||||
|
||||
#if(@shadows_enabled)
|
||||
#endif
|
||||
|
||||
// TERRAIN OUTPUT
|
||||
out vec2 uv;
|
||||
out float euclideanDepth;
|
||||
out float linearDepth;
|
||||
centroid out vec4 passColor;
|
||||
out vec3 passViewPos;
|
||||
out vec3 passNormal;
|
||||
|
||||
void main() {
|
||||
for(int i = 0; i < gl_in.length(); i++)
|
||||
{
|
||||
gl_ViewportIndex = gl_InvocationID;
|
||||
gl_Position = gl_in[i].gl_Position;
|
||||
uv = VS_NAME(uv)[i];
|
||||
euclideanDepth = VS_NAME(euclideanDepth)[i];
|
||||
linearDepth = VS_NAME(linearDepth)[i];
|
||||
|
||||
#if !PER_PIXEL_LIGHTING
|
||||
lighting = VS_NAME(lighting)[i];
|
||||
shadowDiffuseLighting = VS_NAME(shadowDiffuseLighting)[i];
|
||||
#endif
|
||||
|
||||
passColor = VS_NAME(passColor)[i];
|
||||
passViewPos = VS_NAME(passViewPos)[i];
|
||||
passNormal = VS_NAME(passNormal)[i];
|
||||
|
||||
#if(@shadows_enabled)
|
||||
#endif
|
||||
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
|
@ -1,44 +1,47 @@
|
|||
#version 120
|
||||
|
||||
varying vec2 uv;
|
||||
varying float euclideanDepth;
|
||||
varying float linearDepth;
|
||||
#include "interface_util.glsl"
|
||||
|
||||
varying vec2 VS_NAME(uv);
|
||||
varying float VS_NAME(euclideanDepth);
|
||||
varying float VS_NAME(linearDepth);
|
||||
|
||||
#define PER_PIXEL_LIGHTING (@normalMap || @forcePPL)
|
||||
|
||||
#if !PER_PIXEL_LIGHTING
|
||||
centroid varying vec4 lighting;
|
||||
centroid varying vec3 shadowDiffuseLighting;
|
||||
centroid varying vec4 VS_NAME(lighting);
|
||||
centroid varying vec3 VS_NAME(shadowDiffuseLighting);
|
||||
#endif
|
||||
centroid varying vec4 passColor;
|
||||
varying vec3 passViewPos;
|
||||
varying vec3 passNormal;
|
||||
centroid varying vec4 VS_NAME(passColor);
|
||||
varying vec3 VS_NAME(passViewPos);
|
||||
varying vec3 VS_NAME(passNormal);
|
||||
|
||||
#include "shadows_vertex.glsl"
|
||||
|
||||
#include "lighting.glsl"
|
||||
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
|
||||
vec4 viewPos = (gl_ModelViewMatrix * gl_Vertex);
|
||||
gl_ClipVertex = viewPos;
|
||||
euclideanDepth = length(viewPos.xyz);
|
||||
linearDepth = gl_Position.z;
|
||||
VS_NAME(euclideanDepth) = length(viewPos.xyz);
|
||||
VS_NAME(linearDepth) = gl_Position.z;
|
||||
|
||||
#if (!PER_PIXEL_LIGHTING || @shadows_enabled)
|
||||
vec3 viewNormal = normalize((gl_NormalMatrix * gl_Normal).xyz);
|
||||
#endif
|
||||
|
||||
#if !PER_PIXEL_LIGHTING
|
||||
lighting = doLighting(viewPos.xyz, viewNormal, gl_Color, shadowDiffuseLighting);
|
||||
VS_NAME(lighting) = doLighting(viewPos.xyz, viewNormal, gl_Color, VS_NAME(shadowDiffuseLighting));
|
||||
#endif
|
||||
passColor = gl_Color;
|
||||
passNormal = gl_Normal.xyz;
|
||||
passViewPos = viewPos.xyz;
|
||||
VS_NAME(passColor) = gl_Color;
|
||||
VS_NAME(passNormal) = gl_Normal.xyz;
|
||||
VS_NAME(passViewPos) = viewPos.xyz;
|
||||
|
||||
uv = gl_MultiTexCoord0.xy;
|
||||
VS_NAME(uv) = gl_MultiTexCoord0.xy;
|
||||
|
||||
#if (@shadows_enabled)
|
||||
setupShadowCoords(viewPos, viewNormal);
|
||||
|
|
Loading…
Reference in a new issue