mirror of
https://github.com/OpenMW/openmw.git
synced 2025-06-27 01:11:37 +00:00
Bunch of stuff
This commit is contained in:
parent
8545fb920e
commit
9c50fd3f44
7 changed files with 197 additions and 5 deletions
|
@ -42,6 +42,10 @@ list (APPEND COMPONENT_FILES "${OpenMW_BINARY_DIR}/${VERSION_CPP_FILE}")
|
||||||
|
|
||||||
# source files
|
# source files
|
||||||
|
|
||||||
|
add_component_dir (bindlesstexture
|
||||||
|
bindlesstexture
|
||||||
|
)
|
||||||
|
|
||||||
add_component_dir (lua
|
add_component_dir (lua
|
||||||
luastate scriptscontainer asyncpackage utilpackage serialization configuration l10n storage utf8
|
luastate scriptscontainer asyncpackage utilpackage serialization configuration l10n storage utf8
|
||||||
shapes/box inputactions
|
shapes/box inputactions
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#include <components/nifosg/controller.hpp>
|
#include <components/nifosg/controller.hpp>
|
||||||
#include <components/nifosg/nifloader.hpp>
|
#include <components/nifosg/nifloader.hpp>
|
||||||
|
#include <components/nifosg/particle.hpp>
|
||||||
|
|
||||||
#include <components/nif/niffile.hpp>
|
#include <components/nif/niffile.hpp>
|
||||||
|
|
||||||
|
@ -33,13 +34,16 @@
|
||||||
|
|
||||||
#include <components/vfs/manager.hpp>
|
#include <components/vfs/manager.hpp>
|
||||||
#include <components/vfs/pathutil.hpp>
|
#include <components/vfs/pathutil.hpp>
|
||||||
|
#include <components/vfs/recursivedirectoryiterator.hpp>
|
||||||
|
|
||||||
#include <components/sceneutil/clone.hpp>
|
#include <components/sceneutil/clone.hpp>
|
||||||
#include <components/sceneutil/controller.hpp>
|
#include <components/sceneutil/controller.hpp>
|
||||||
#include <components/sceneutil/depth.hpp>
|
#include <components/sceneutil/depth.hpp>
|
||||||
#include <components/sceneutil/extradata.hpp>
|
#include <components/sceneutil/extradata.hpp>
|
||||||
#include <components/sceneutil/lightmanager.hpp>
|
#include <components/sceneutil/lightmanager.hpp>
|
||||||
|
#include <components/sceneutil/morphgeometry.hpp>
|
||||||
#include <components/sceneutil/optimizer.hpp>
|
#include <components/sceneutil/optimizer.hpp>
|
||||||
|
#include <components/sceneutil/riggeometry.hpp>
|
||||||
#include <components/sceneutil/riggeometryosgaextension.hpp>
|
#include <components/sceneutil/riggeometryosgaextension.hpp>
|
||||||
#include <components/sceneutil/util.hpp>
|
#include <components/sceneutil/util.hpp>
|
||||||
#include <components/sceneutil/visitor.hpp>
|
#include <components/sceneutil/visitor.hpp>
|
||||||
|
@ -352,6 +356,139 @@ namespace Resource
|
||||||
std::vector<osg::ref_ptr<SceneUtil::RigGeometryHolder>> mRigGeometryHolders;
|
std::vector<osg::ref_ptr<SceneUtil::RigGeometryHolder>> mRigGeometryHolders;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TextureAtlasVisitor : public osg::NodeVisitor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// default to traversing all children.
|
||||||
|
TextureAtlasVisitor()
|
||||||
|
: osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void apply(osg::Node& node) override
|
||||||
|
{
|
||||||
|
bool pushedStateState = false;
|
||||||
|
|
||||||
|
osg::StateSet* ss = node.getStateSet();
|
||||||
|
if (ss)
|
||||||
|
pushedStateState = pushStateSet(ss);
|
||||||
|
|
||||||
|
traverse(node);
|
||||||
|
|
||||||
|
if (pushedStateState)
|
||||||
|
popStateSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
void apply(osg::Drawable& node) override
|
||||||
|
{
|
||||||
|
if (auto rig = dynamic_cast<SceneUtil::RigGeometry*>(&node))
|
||||||
|
return apply(*rig->getSourceGeometry());
|
||||||
|
if (auto morph = dynamic_cast<SceneUtil::MorphGeometry*>(&node))
|
||||||
|
return apply(*morph->getSourceGeometry());
|
||||||
|
|
||||||
|
if (dynamic_cast<NifOsg::ParticleSystem*>(&node))
|
||||||
|
return;
|
||||||
|
//if (dynamic_cast<osgParticle::ParticleSystemUpdater*>(&node))
|
||||||
|
// toskip = true;
|
||||||
|
if (dynamic_cast<osgParticle::ParticleProcessor*>(&node))
|
||||||
|
return;
|
||||||
|
if (dynamic_cast<osgParticle::Particle*>(&node))
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool pushedStateState = false;
|
||||||
|
|
||||||
|
osg::StateSet* ss = node.getStateSet();
|
||||||
|
if (ss)
|
||||||
|
pushedStateState = pushStateSet(ss);
|
||||||
|
|
||||||
|
[&] {
|
||||||
|
osg::Geometry* geom = node.asGeometry();
|
||||||
|
if (!geom || _statesetStack.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const osg::StateSet::TextureAttributeList& tal = _statesetStack.back()->getTextureAttributeList();
|
||||||
|
for (unsigned int unit = 0; unit < tal.size(); ++unit)
|
||||||
|
{
|
||||||
|
osg::ref_ptr<osg::Texture2D> texture = dynamic_cast<osg::Texture2D*>(
|
||||||
|
_statesetStack.back()->getTextureAttribute(unit, osg::StateAttribute::TEXTURE));
|
||||||
|
if (!texture)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto it
|
||||||
|
= std::find(mTexture->_textureList.begin(), mTexture->_textureList.end(), texture->getImage());
|
||||||
|
if (it == mTexture->_textureList.end())
|
||||||
|
continue;
|
||||||
|
unsigned int d = std::distance(mTexture->_textureList.begin(), it);
|
||||||
|
auto indices = new osg::IntArray(geom->getVertexArray()->getNumElements());
|
||||||
|
for (unsigned int i = 0; i < geom->getVertexArray()->getNumElements(); ++i)
|
||||||
|
(*indices)[i] = d;
|
||||||
|
geom->setVertexAttribArray(7, indices, osg::Array::BIND_PER_VERTEX);
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
|
||||||
|
|
||||||
|
if (pushedStateState)
|
||||||
|
popStateSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::ref_ptr<BindlessTexture> mTexture;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool pushStateSet(osg::StateSet* stateset)
|
||||||
|
{
|
||||||
|
const osg::StateSet::TextureAttributeList& tal = stateset->getTextureAttributeList();
|
||||||
|
|
||||||
|
// if no textures ignore
|
||||||
|
if (tal.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool pushStateState = false;
|
||||||
|
|
||||||
|
// if already in stateset list ignore
|
||||||
|
if (_statesetMap.count(stateset) > 0)
|
||||||
|
{
|
||||||
|
pushStateState = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool containsTexture2D = false;
|
||||||
|
for (unsigned int unit = 0; unit < tal.size(); ++unit)
|
||||||
|
{
|
||||||
|
osg::Texture2D* texture2D = dynamic_cast<osg::Texture2D*>(
|
||||||
|
stateset->getTextureAttribute(unit, osg::StateAttribute::TEXTURE));
|
||||||
|
if (texture2D)
|
||||||
|
{
|
||||||
|
containsTexture2D = true;
|
||||||
|
_textures.insert(texture2D);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (containsTexture2D)
|
||||||
|
{
|
||||||
|
_statesetMap[stateset];
|
||||||
|
pushStateState = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pushStateState)
|
||||||
|
{
|
||||||
|
_statesetStack.push_back(stateset);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pushStateState;
|
||||||
|
}
|
||||||
|
void popStateSet() { _statesetStack.pop_back(); }
|
||||||
|
|
||||||
|
typedef std::set<osg::Drawable*> Drawables;
|
||||||
|
typedef std::map<osg::StateSet*, Drawables> StateSetMap;
|
||||||
|
typedef std::set<osg::Texture2D*> Textures;
|
||||||
|
typedef std::vector<osg::StateSet*> StateSetStack;
|
||||||
|
|
||||||
|
StateSetMap _statesetMap;
|
||||||
|
StateSetStack _statesetStack;
|
||||||
|
Textures _textures;
|
||||||
|
};
|
||||||
|
|
||||||
SceneManager::SceneManager(const VFS::Manager* vfs, Resource::ImageManager* imageManager,
|
SceneManager::SceneManager(const VFS::Manager* vfs, Resource::ImageManager* imageManager,
|
||||||
Resource::NifFileManager* nifFileManager, double expiryDelay)
|
Resource::NifFileManager* nifFileManager, double expiryDelay)
|
||||||
: ResourceManager(vfs, expiryDelay)
|
: ResourceManager(vfs, expiryDelay)
|
||||||
|
@ -374,6 +511,17 @@ namespace Resource
|
||||||
, mUnRefImageDataAfterApply(false)
|
, mUnRefImageDataAfterApply(false)
|
||||||
, mParticleSystemMask(~0u)
|
, mParticleSystemMask(~0u)
|
||||||
{
|
{
|
||||||
|
mBuffer = BindlessBuffer::Make(4800);
|
||||||
|
|
||||||
|
BindlessTexture::TextureList images;
|
||||||
|
images.reserve(4800);
|
||||||
|
for (auto const& tex : vfs->getRecursiveDirectoryIterator("textures/"))
|
||||||
|
{
|
||||||
|
auto image = imageManager->getImage(tex);
|
||||||
|
if (image->s() > 16 || image->t() > 16)
|
||||||
|
images.push_back(image);
|
||||||
|
}
|
||||||
|
mTexture = new BindlessTexture(mBuffer, images);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneManager::setForceShaders(bool force)
|
void SceneManager::setForceShaders(bool force)
|
||||||
|
@ -900,6 +1048,11 @@ namespace Resource
|
||||||
SceneUtil::ReplaceDepthVisitor replaceDepthVisitor;
|
SceneUtil::ReplaceDepthVisitor replaceDepthVisitor;
|
||||||
loaded->accept(replaceDepthVisitor);
|
loaded->accept(replaceDepthVisitor);
|
||||||
|
|
||||||
|
TextureAtlasVisitor tav;
|
||||||
|
tav.mTexture = mTexture;
|
||||||
|
loaded->accept(tav);
|
||||||
|
shareState(loaded);
|
||||||
|
|
||||||
osg::ref_ptr<Shader::ShaderVisitor> shaderVisitor(createShaderVisitor());
|
osg::ref_ptr<Shader::ShaderVisitor> shaderVisitor(createShaderVisitor());
|
||||||
loaded->accept(*shaderVisitor);
|
loaded->accept(*shaderVisitor);
|
||||||
|
|
||||||
|
@ -1134,6 +1287,10 @@ namespace Resource
|
||||||
shaderVisitor->setAdjustCoverageForAlphaTest(mAdjustCoverageForAlphaTest);
|
shaderVisitor->setAdjustCoverageForAlphaTest(mAdjustCoverageForAlphaTest);
|
||||||
shaderVisitor->setSupportsNormalsRT(mSupportsNormalsRT);
|
shaderVisitor->setSupportsNormalsRT(mSupportsNormalsRT);
|
||||||
shaderVisitor->setWeatherParticleOcclusion(mWeatherParticleOcclusion);
|
shaderVisitor->setWeatherParticleOcclusion(mWeatherParticleOcclusion);
|
||||||
|
|
||||||
|
shaderVisitor->mBuffer = mBuffer;
|
||||||
|
shaderVisitor->mTexture = mTexture;
|
||||||
|
|
||||||
return shaderVisitor;
|
return shaderVisitor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "resourcemanager.hpp"
|
#include "resourcemanager.hpp"
|
||||||
|
|
||||||
#include <components/sceneutil/lightmanager.hpp>
|
#include <components/sceneutil/lightmanager.hpp>
|
||||||
|
#include <components/bindlesstexture/bindlesstexture.hpp>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
namespace VFS
|
namespace VFS
|
||||||
|
@ -230,6 +231,9 @@ namespace Resource
|
||||||
void setWeatherParticleOcclusion(bool value) { mWeatherParticleOcclusion = value; }
|
void setWeatherParticleOcclusion(bool value) { mWeatherParticleOcclusion = value; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
osg::ref_ptr<BindlessBuffer> mBuffer;
|
||||||
|
osg::ref_ptr <BindlessTexture> mTexture;
|
||||||
|
|
||||||
osg::ref_ptr<Shader::ShaderVisitor> createShaderVisitor(const std::string& shaderPrefix = "objects");
|
osg::ref_ptr<Shader::ShaderVisitor> createShaderVisitor(const std::string& shaderPrefix = "objects");
|
||||||
osg::ref_ptr<osg::Node> loadErrorMarker();
|
osg::ref_ptr<osg::Node> loadErrorMarker();
|
||||||
osg::ref_ptr<osg::Node> cloneErrorMarker();
|
osg::ref_ptr<osg::Node> cloneErrorMarker();
|
||||||
|
|
|
@ -361,6 +361,10 @@ namespace Shader
|
||||||
mRequirements.back().mTexStageRequiringTangents = unit;
|
mRequirements.back().mTexStageRequiringTangents = unit;
|
||||||
}
|
}
|
||||||
diffuseMap = texture;
|
diffuseMap = texture;
|
||||||
|
if (!writableStateSet)
|
||||||
|
writableStateSet = getWritableStateSet(node);
|
||||||
|
writableStateSet->setTextureAttribute(unit, mTexture, osg::StateAttribute::ON);
|
||||||
|
writableStateSet->setAttributeAndModes(mBuffer->Binding(), osg::StateAttribute::ON);
|
||||||
}
|
}
|
||||||
else if (texName == "specularMap")
|
else if (texName == "specularMap")
|
||||||
specularMap = texture;
|
specularMap = texture;
|
||||||
|
@ -739,6 +743,7 @@ namespace Shader
|
||||||
shaderPrefix = mDefaultShaderPrefix;
|
shaderPrefix = mDefaultShaderPrefix;
|
||||||
|
|
||||||
auto program = mShaderManager.getProgram(shaderPrefix, defineMap, mProgramTemplate);
|
auto program = mShaderManager.getProgram(shaderPrefix, defineMap, mProgramTemplate);
|
||||||
|
program->addBindAttribLocation("index", 7);
|
||||||
writableStateSet->setAttributeAndModes(program, osg::StateAttribute::ON);
|
writableStateSet->setAttributeAndModes(program, osg::StateAttribute::ON);
|
||||||
addedState->setAttributeAndModes(std::move(program));
|
addedState->setAttributeAndModes(std::move(program));
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <osg/NodeVisitor>
|
#include <osg/NodeVisitor>
|
||||||
#include <osg/Program>
|
#include <osg/Program>
|
||||||
|
#include <components/bindlesstexture/bindlesstexture.hpp>
|
||||||
|
|
||||||
namespace Resource
|
namespace Resource
|
||||||
{
|
{
|
||||||
|
@ -63,6 +64,9 @@ namespace Shader
|
||||||
void pushRequirements(osg::Node& node);
|
void pushRequirements(osg::Node& node);
|
||||||
void popRequirements();
|
void popRequirements();
|
||||||
|
|
||||||
|
osg::ref_ptr<BindlessBuffer> mBuffer;
|
||||||
|
osg::ref_ptr<BindlessTexture> mTexture;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool mForceShaders;
|
bool mForceShaders;
|
||||||
bool mAllowedToModifyStateSets;
|
bool mAllowedToModifyStateSets;
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
#version 120
|
#version 450 compatibility
|
||||||
|
#extension GL_ARB_bindless_texture : require
|
||||||
|
#extension GL_NV_gpu_shader5 : require // uint64_t
|
||||||
#pragma import_defines(FORCE_OPAQUE, DISTORTION)
|
#pragma import_defines(FORCE_OPAQUE, DISTORTION)
|
||||||
|
|
||||||
#if @useUBO
|
#if @useUBO
|
||||||
|
@ -14,6 +16,13 @@ uniform sampler2D diffuseMap;
|
||||||
varying vec2 diffuseMapUV;
|
varying vec2 diffuseMapUV;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
flat in int textureIndex;
|
||||||
|
|
||||||
|
layout (binding = 0, std140) uniform TEXTURE_BLOCK
|
||||||
|
{
|
||||||
|
uint64_t tex[4096];
|
||||||
|
};
|
||||||
|
|
||||||
#if @darkMap
|
#if @darkMap
|
||||||
uniform sampler2D darkMap;
|
uniform sampler2D darkMap;
|
||||||
varying vec2 darkMapUV;
|
varying vec2 darkMapUV;
|
||||||
|
@ -124,12 +133,15 @@ void main()
|
||||||
// only offset diffuse and normal maps for now, other textures are more likely to be using a completely different UV set
|
// only offset diffuse and normal maps for now, other textures are more likely to be using a completely different UV set
|
||||||
vec2 offset = vec2(0.0);
|
vec2 offset = vec2(0.0);
|
||||||
|
|
||||||
|
int tIndex = (int)(textureIndex);
|
||||||
|
sampler2D myText = sampler2D(tex[tIndex]);
|
||||||
|
|
||||||
#if @parallax || @diffuseParallax
|
#if @parallax || @diffuseParallax
|
||||||
#if @parallax
|
#if @parallax
|
||||||
float height = texture2D(normalMap, normalMapUV).a;
|
float height = texture2D(normalMap, normalMapUV).a;
|
||||||
float flipY = (passTangent.w > 0.0) ? -1.f : 1.f;
|
float flipY = (passTangent.w > 0.0) ? -1.f : 1.f;
|
||||||
#else
|
#else
|
||||||
float height = texture2D(diffuseMap, diffuseMapUV).a;
|
float height = texture2D(myText, diffuseMapUV).a;
|
||||||
// FIXME: shouldn't be necessary, but in this path false-positives are common
|
// FIXME: shouldn't be necessary, but in this path false-positives are common
|
||||||
float flipY = -1.f;
|
float flipY = -1.f;
|
||||||
#endif
|
#endif
|
||||||
|
@ -139,7 +151,7 @@ void main()
|
||||||
vec2 screenCoords = gl_FragCoord.xy / screenRes;
|
vec2 screenCoords = gl_FragCoord.xy / screenRes;
|
||||||
|
|
||||||
#if @diffuseMap
|
#if @diffuseMap
|
||||||
gl_FragData[0] = texture2D(diffuseMap, diffuseMapUV + offset);
|
gl_FragData[0] = texture2D(myText, diffuseMapUV + offset);
|
||||||
|
|
||||||
#if defined(DISTORTION) && DISTORTION
|
#if defined(DISTORTION) && DISTORTION
|
||||||
gl_FragData[0].a = getDiffuseColor().a;
|
gl_FragData[0].a = getDiffuseColor().a;
|
||||||
|
@ -150,7 +162,7 @@ vec2 screenCoords = gl_FragCoord.xy / screenRes;
|
||||||
#if @diffuseParallax
|
#if @diffuseParallax
|
||||||
gl_FragData[0].a = 1.0;
|
gl_FragData[0].a = 1.0;
|
||||||
#else
|
#else
|
||||||
gl_FragData[0].a *= coveragePreservingAlphaScale(diffuseMap, diffuseMapUV + offset);
|
gl_FragData[0].a *= coveragePreservingAlphaScale(myText, diffuseMapUV + offset);
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
gl_FragData[0] = vec4(1.0);
|
gl_FragData[0] = vec4(1.0);
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
#version 120
|
#version 450 compatibility
|
||||||
|
#extension GL_ARB_bindless_texture : require
|
||||||
|
#extension GL_NV_gpu_shader5 : require // uint64_t
|
||||||
|
|
||||||
#if @useUBO
|
#if @useUBO
|
||||||
#extension GL_ARB_uniform_buffer_object : require
|
#extension GL_ARB_uniform_buffer_object : require
|
||||||
|
@ -8,6 +10,9 @@
|
||||||
#extension GL_EXT_gpu_shader4: require
|
#extension GL_EXT_gpu_shader4: require
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
attribute float index;
|
||||||
|
flat out int textureIndex;
|
||||||
|
|
||||||
#include "lib/core/vertex.h.glsl"
|
#include "lib/core/vertex.h.glsl"
|
||||||
#if @diffuseMap
|
#if @diffuseMap
|
||||||
varying vec2 diffuseMapUV;
|
varying vec2 diffuseMapUV;
|
||||||
|
@ -94,6 +99,7 @@ void main(void)
|
||||||
passViewPos = viewPos.xyz;
|
passViewPos = viewPos.xyz;
|
||||||
passNormal = gl_Normal.xyz;
|
passNormal = gl_Normal.xyz;
|
||||||
normalToViewMatrix = gl_NormalMatrix;
|
normalToViewMatrix = gl_NormalMatrix;
|
||||||
|
textureIndex = (int)(index + 0.5);
|
||||||
|
|
||||||
#if @normalMap || @diffuseParallax
|
#if @normalMap || @diffuseParallax
|
||||||
passTangent = gl_MultiTexCoord7.xyzw;
|
passTangent = gl_MultiTexCoord7.xyzw;
|
||||||
|
|
Loading…
Reference in a new issue