mirror of
https://github.com/OpenMW/openmw.git
synced 2025-03-03 15:39:41 +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
|
||||
|
||||
add_component_dir (bindlesstexture
|
||||
bindlesstexture
|
||||
)
|
||||
|
||||
add_component_dir (lua
|
||||
luastate scriptscontainer asyncpackage utilpackage serialization configuration l10n storage utf8
|
||||
shapes/box inputactions
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include <components/nifosg/controller.hpp>
|
||||
#include <components/nifosg/nifloader.hpp>
|
||||
#include <components/nifosg/particle.hpp>
|
||||
|
||||
#include <components/nif/niffile.hpp>
|
||||
|
||||
|
@ -33,13 +34,16 @@
|
|||
|
||||
#include <components/vfs/manager.hpp>
|
||||
#include <components/vfs/pathutil.hpp>
|
||||
#include <components/vfs/recursivedirectoryiterator.hpp>
|
||||
|
||||
#include <components/sceneutil/clone.hpp>
|
||||
#include <components/sceneutil/controller.hpp>
|
||||
#include <components/sceneutil/depth.hpp>
|
||||
#include <components/sceneutil/extradata.hpp>
|
||||
#include <components/sceneutil/lightmanager.hpp>
|
||||
#include <components/sceneutil/morphgeometry.hpp>
|
||||
#include <components/sceneutil/optimizer.hpp>
|
||||
#include <components/sceneutil/riggeometry.hpp>
|
||||
#include <components/sceneutil/riggeometryosgaextension.hpp>
|
||||
#include <components/sceneutil/util.hpp>
|
||||
#include <components/sceneutil/visitor.hpp>
|
||||
|
@ -352,6 +356,139 @@ namespace Resource
|
|||
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,
|
||||
Resource::NifFileManager* nifFileManager, double expiryDelay)
|
||||
: ResourceManager(vfs, expiryDelay)
|
||||
|
@ -374,6 +511,17 @@ namespace Resource
|
|||
, mUnRefImageDataAfterApply(false)
|
||||
, 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)
|
||||
|
@ -900,6 +1048,11 @@ namespace Resource
|
|||
SceneUtil::ReplaceDepthVisitor replaceDepthVisitor;
|
||||
loaded->accept(replaceDepthVisitor);
|
||||
|
||||
TextureAtlasVisitor tav;
|
||||
tav.mTexture = mTexture;
|
||||
loaded->accept(tav);
|
||||
shareState(loaded);
|
||||
|
||||
osg::ref_ptr<Shader::ShaderVisitor> shaderVisitor(createShaderVisitor());
|
||||
loaded->accept(*shaderVisitor);
|
||||
|
||||
|
@ -1134,6 +1287,10 @@ namespace Resource
|
|||
shaderVisitor->setAdjustCoverageForAlphaTest(mAdjustCoverageForAlphaTest);
|
||||
shaderVisitor->setSupportsNormalsRT(mSupportsNormalsRT);
|
||||
shaderVisitor->setWeatherParticleOcclusion(mWeatherParticleOcclusion);
|
||||
|
||||
shaderVisitor->mBuffer = mBuffer;
|
||||
shaderVisitor->mTexture = mTexture;
|
||||
|
||||
return shaderVisitor;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "resourcemanager.hpp"
|
||||
|
||||
#include <components/sceneutil/lightmanager.hpp>
|
||||
#include <components/bindlesstexture/bindlesstexture.hpp>
|
||||
#include <filesystem>
|
||||
|
||||
namespace VFS
|
||||
|
@ -230,6 +231,9 @@ namespace Resource
|
|||
void setWeatherParticleOcclusion(bool value) { mWeatherParticleOcclusion = value; }
|
||||
|
||||
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<osg::Node> loadErrorMarker();
|
||||
osg::ref_ptr<osg::Node> cloneErrorMarker();
|
||||
|
|
|
@ -361,6 +361,10 @@ namespace Shader
|
|||
mRequirements.back().mTexStageRequiringTangents = unit;
|
||||
}
|
||||
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")
|
||||
specularMap = texture;
|
||||
|
@ -739,6 +743,7 @@ namespace Shader
|
|||
shaderPrefix = mDefaultShaderPrefix;
|
||||
|
||||
auto program = mShaderManager.getProgram(shaderPrefix, defineMap, mProgramTemplate);
|
||||
program->addBindAttribLocation("index", 7);
|
||||
writableStateSet->setAttributeAndModes(program, osg::StateAttribute::ON);
|
||||
addedState->setAttributeAndModes(std::move(program));
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <osg/NodeVisitor>
|
||||
#include <osg/Program>
|
||||
#include <components/bindlesstexture/bindlesstexture.hpp>
|
||||
|
||||
namespace Resource
|
||||
{
|
||||
|
@ -63,6 +64,9 @@ namespace Shader
|
|||
void pushRequirements(osg::Node& node);
|
||||
void popRequirements();
|
||||
|
||||
osg::ref_ptr<BindlessBuffer> mBuffer;
|
||||
osg::ref_ptr<BindlessTexture> mTexture;
|
||||
|
||||
private:
|
||||
bool mForceShaders;
|
||||
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)
|
||||
|
||||
#if @useUBO
|
||||
|
@ -14,6 +16,13 @@ uniform sampler2D diffuseMap;
|
|||
varying vec2 diffuseMapUV;
|
||||
#endif
|
||||
|
||||
flat in int textureIndex;
|
||||
|
||||
layout (binding = 0, std140) uniform TEXTURE_BLOCK
|
||||
{
|
||||
uint64_t tex[4096];
|
||||
};
|
||||
|
||||
#if @darkMap
|
||||
uniform sampler2D darkMap;
|
||||
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
|
||||
vec2 offset = vec2(0.0);
|
||||
|
||||
int tIndex = (int)(textureIndex);
|
||||
sampler2D myText = sampler2D(tex[tIndex]);
|
||||
|
||||
#if @parallax || @diffuseParallax
|
||||
#if @parallax
|
||||
float height = texture2D(normalMap, normalMapUV).a;
|
||||
float flipY = (passTangent.w > 0.0) ? -1.f : 1.f;
|
||||
#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
|
||||
float flipY = -1.f;
|
||||
#endif
|
||||
|
@ -139,7 +151,7 @@ void main()
|
|||
vec2 screenCoords = gl_FragCoord.xy / screenRes;
|
||||
|
||||
#if @diffuseMap
|
||||
gl_FragData[0] = texture2D(diffuseMap, diffuseMapUV + offset);
|
||||
gl_FragData[0] = texture2D(myText, diffuseMapUV + offset);
|
||||
|
||||
#if defined(DISTORTION) && DISTORTION
|
||||
gl_FragData[0].a = getDiffuseColor().a;
|
||||
|
@ -150,7 +162,7 @@ vec2 screenCoords = gl_FragCoord.xy / screenRes;
|
|||
#if @diffuseParallax
|
||||
gl_FragData[0].a = 1.0;
|
||||
#else
|
||||
gl_FragData[0].a *= coveragePreservingAlphaScale(diffuseMap, diffuseMapUV + offset);
|
||||
gl_FragData[0].a *= coveragePreservingAlphaScale(myText, diffuseMapUV + offset);
|
||||
#endif
|
||||
#else
|
||||
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
|
||||
#extension GL_ARB_uniform_buffer_object : require
|
||||
|
@ -8,6 +10,9 @@
|
|||
#extension GL_EXT_gpu_shader4: require
|
||||
#endif
|
||||
|
||||
attribute float index;
|
||||
flat out int textureIndex;
|
||||
|
||||
#include "lib/core/vertex.h.glsl"
|
||||
#if @diffuseMap
|
||||
varying vec2 diffuseMapUV;
|
||||
|
@ -94,6 +99,7 @@ void main(void)
|
|||
passViewPos = viewPos.xyz;
|
||||
passNormal = gl_Normal.xyz;
|
||||
normalToViewMatrix = gl_NormalMatrix;
|
||||
textureIndex = (int)(index + 0.5);
|
||||
|
||||
#if @normalMap || @diffuseParallax
|
||||
passTangent = gl_MultiTexCoord7.xyzw;
|
||||
|
|
Loading…
Reference in a new issue