mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-04-28 21:07:59 +03:00
Apply clang-format to code base
This commit is contained in:
parent
f37d0be806
commit
ddb0522bbf
2199 changed files with 118692 additions and 114392 deletions
|
@ -1,22 +1,22 @@
|
|||
#include "lightmanager.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
#include <osg/BufferObject>
|
||||
#include <osg/BufferIndexBinding>
|
||||
#include <osg/BufferObject>
|
||||
#include <osg/Endian>
|
||||
#include <osg/ValueObject>
|
||||
|
||||
#include <osgUtil/CullVisitor>
|
||||
|
||||
#include <components/sceneutil/util.hpp>
|
||||
#include <components/resource/scenemanager.hpp>
|
||||
#include <components/sceneutil/util.hpp>
|
||||
|
||||
#include <components/misc/hash.hpp>
|
||||
#include <components/misc/constants.hpp>
|
||||
#include <components/misc/hash.hpp>
|
||||
|
||||
#include <components/debug/debuglog.hpp>
|
||||
|
||||
|
@ -26,10 +26,12 @@ namespace
|
|||
constexpr int maxLightsUpperLimit = 64;
|
||||
constexpr int ffpMaxLights = 8;
|
||||
|
||||
bool sortLights(const SceneUtil::LightManager::LightSourceViewBound* left, const SceneUtil::LightManager::LightSourceViewBound* right)
|
||||
bool sortLights(const SceneUtil::LightManager::LightSourceViewBound* left,
|
||||
const SceneUtil::LightManager::LightSourceViewBound* right)
|
||||
{
|
||||
static auto constexpr illuminationBias = 81.f;
|
||||
return left->mViewBound.center().length2() - left->mViewBound.radius2()*illuminationBias < right->mViewBound.center().length2() - right->mViewBound.radius2()*illuminationBias;
|
||||
return left->mViewBound.center().length2() - left->mViewBound.radius2() * illuminationBias
|
||||
< right->mViewBound.center().length2() - right->mViewBound.radius2() * illuminationBias;
|
||||
}
|
||||
|
||||
void configurePosition(osg::Matrixf& mat, const osg::Vec4& pos)
|
||||
|
@ -75,19 +77,19 @@ namespace SceneUtil
|
|||
namespace
|
||||
{
|
||||
const std::unordered_map<std::string, LightingMethod> lightingMethodSettingMap = {
|
||||
{"legacy", LightingMethod::FFP},
|
||||
{"shaders compatibility", LightingMethod::PerObjectUniform},
|
||||
{"shaders", LightingMethod::SingleUBO},
|
||||
{ "legacy", LightingMethod::FFP },
|
||||
{ "shaders compatibility", LightingMethod::PerObjectUniform },
|
||||
{ "shaders", LightingMethod::SingleUBO },
|
||||
};
|
||||
}
|
||||
|
||||
static int sLightId = 0;
|
||||
|
||||
// Handles a GLSL shared layout by using configured offsets and strides to fill a continuous buffer, making the data upload to GPU simpler.
|
||||
// Handles a GLSL shared layout by using configured offsets and strides to fill a continuous buffer, making the data
|
||||
// upload to GPU simpler.
|
||||
class LightBuffer : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
|
||||
enum LayoutOffset
|
||||
{
|
||||
Diffuse,
|
||||
|
@ -99,7 +101,7 @@ namespace SceneUtil
|
|||
};
|
||||
|
||||
LightBuffer(int count)
|
||||
: mData(new osg::FloatArray(3*4*count))
|
||||
: mData(new osg::FloatArray(3 * 4 * count))
|
||||
, mEndian(osg::getCpuByteOrder())
|
||||
, mCount(count)
|
||||
, mCachedSunPos(osg::Vec4())
|
||||
|
@ -145,25 +147,13 @@ namespace SceneUtil
|
|||
std::memcpy(&(*mData)[getOffset(index, AttenuationRadius)], value.ptr(), sizeof(osg::Vec4f));
|
||||
}
|
||||
|
||||
auto& getData()
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
auto& getData() { return mData; }
|
||||
|
||||
void dirty()
|
||||
{
|
||||
mData->dirty();
|
||||
}
|
||||
void dirty() { mData->dirty(); }
|
||||
|
||||
static constexpr int queryBlockSize(int sz)
|
||||
{
|
||||
return 3 * osg::Vec4::num_components * sizeof(GLfloat) * sz;
|
||||
}
|
||||
static constexpr int queryBlockSize(int sz) { return 3 * osg::Vec4::num_components * sizeof(GLfloat) * sz; }
|
||||
|
||||
void setCachedSunPos(const osg::Vec4& pos)
|
||||
{
|
||||
mCachedSunPos = pos;
|
||||
}
|
||||
void setCachedSunPos(const osg::Vec4& pos) { mCachedSunPos = pos; }
|
||||
|
||||
void uploadCachedSunPos(const osg::Matrix& viewMat)
|
||||
{
|
||||
|
@ -176,10 +166,7 @@ namespace SceneUtil
|
|||
return mEndian == osg::BigEndian ? value.asABGR() : value.asRGBA();
|
||||
}
|
||||
|
||||
int getOffset(int index, LayoutOffset slot) const
|
||||
{
|
||||
return mOffsets.get(index, slot);
|
||||
}
|
||||
int getOffset(int index, LayoutOffset slot) const { return mOffsets.get(index, slot); }
|
||||
|
||||
void configureLayout(int offsetColors, int offsetPosition, int offsetAttenuationRadius, int size, int stride)
|
||||
{
|
||||
|
@ -197,40 +184,37 @@ namespace SceneUtil
|
|||
private:
|
||||
class Offsets
|
||||
{
|
||||
public:
|
||||
Offsets()
|
||||
: mStride(12)
|
||||
{
|
||||
mValues[Diffuse] = 0;
|
||||
mValues[Ambient] = 1;
|
||||
mValues[Specular] = 2;
|
||||
mValues[DiffuseSign] = 3;
|
||||
mValues[Position] = 4;
|
||||
mValues[AttenuationRadius] = 8;
|
||||
}
|
||||
public:
|
||||
Offsets()
|
||||
: mStride(12)
|
||||
{
|
||||
mValues[Diffuse] = 0;
|
||||
mValues[Ambient] = 1;
|
||||
mValues[Specular] = 2;
|
||||
mValues[DiffuseSign] = 3;
|
||||
mValues[Position] = 4;
|
||||
mValues[AttenuationRadius] = 8;
|
||||
}
|
||||
|
||||
Offsets(int offsetColors, int offsetPosition, int offsetAttenuationRadius, int stride)
|
||||
: mStride((offsetAttenuationRadius + sizeof(GLfloat) * osg::Vec4::num_components + stride) / 4)
|
||||
{
|
||||
constexpr auto sizeofFloat = sizeof(GLfloat);
|
||||
const auto diffuseOffset = offsetColors / sizeofFloat;
|
||||
Offsets(int offsetColors, int offsetPosition, int offsetAttenuationRadius, int stride)
|
||||
: mStride((offsetAttenuationRadius + sizeof(GLfloat) * osg::Vec4::num_components + stride) / 4)
|
||||
{
|
||||
constexpr auto sizeofFloat = sizeof(GLfloat);
|
||||
const auto diffuseOffset = offsetColors / sizeofFloat;
|
||||
|
||||
mValues[Diffuse] = diffuseOffset;
|
||||
mValues[Ambient] = diffuseOffset + 1;
|
||||
mValues[Specular] = diffuseOffset + 2;
|
||||
mValues[DiffuseSign] = diffuseOffset + 3;
|
||||
mValues[Position] = offsetPosition / sizeofFloat;
|
||||
mValues[AttenuationRadius] = offsetAttenuationRadius / sizeofFloat;
|
||||
}
|
||||
mValues[Diffuse] = diffuseOffset;
|
||||
mValues[Ambient] = diffuseOffset + 1;
|
||||
mValues[Specular] = diffuseOffset + 2;
|
||||
mValues[DiffuseSign] = diffuseOffset + 3;
|
||||
mValues[Position] = offsetPosition / sizeofFloat;
|
||||
mValues[AttenuationRadius] = offsetAttenuationRadius / sizeofFloat;
|
||||
}
|
||||
|
||||
int get(int index, LayoutOffset slot) const
|
||||
{
|
||||
return mStride * index + mValues[slot];
|
||||
}
|
||||
int get(int index, LayoutOffset slot) const { return mStride * index + mValues[slot]; }
|
||||
|
||||
private:
|
||||
int mStride;
|
||||
std::array<int, 6> mValues;
|
||||
private:
|
||||
int mStride;
|
||||
std::array<int, 6> mValues;
|
||||
};
|
||||
|
||||
void configureLayout(const Offsets& offsets, int size)
|
||||
|
@ -241,9 +225,12 @@ namespace SceneUtil
|
|||
mData->resizeArray(static_cast<unsigned>(size));
|
||||
for (int i = 0; i < mCount; ++i)
|
||||
{
|
||||
std::memcpy(&(*mData)[offsets.get(i, Diffuse)], data.data() + getOffset(i, Diffuse), sizeof(osg::Vec4f));
|
||||
std::memcpy(&(*mData)[offsets.get(i, Position)], data.data() + getOffset(i, Position), sizeof(osg::Vec4f));
|
||||
std::memcpy(&(*mData)[offsets.get(i, AttenuationRadius)], data.data() + getOffset(i, AttenuationRadius), sizeof(osg::Vec4f));
|
||||
std::memcpy(
|
||||
&(*mData)[offsets.get(i, Diffuse)], data.data() + getOffset(i, Diffuse), sizeof(osg::Vec4f));
|
||||
std::memcpy(
|
||||
&(*mData)[offsets.get(i, Position)], data.data() + getOffset(i, Position), sizeof(osg::Vec4f));
|
||||
std::memcpy(&(*mData)[offsets.get(i, AttenuationRadius)], data.data() + getOffset(i, AttenuationRadius),
|
||||
sizeof(osg::Vec4f));
|
||||
}
|
||||
mOffsets = offsets;
|
||||
}
|
||||
|
@ -263,22 +250,23 @@ namespace SceneUtil
|
|||
LightStateCache* getLightStateCache(size_t contextid, size_t size = 8)
|
||||
{
|
||||
static std::vector<LightStateCache> cacheVector;
|
||||
if (cacheVector.size() < contextid+1)
|
||||
cacheVector.resize(contextid+1);
|
||||
if (cacheVector.size() < contextid + 1)
|
||||
cacheVector.resize(contextid + 1);
|
||||
cacheVector[contextid].lastAppliedLight.resize(size);
|
||||
return &cacheVector[contextid];
|
||||
}
|
||||
|
||||
void configureStateSetSunOverride(LightManager* lightManager, const osg::Light* light, osg::StateSet* stateset, int mode)
|
||||
void configureStateSetSunOverride(
|
||||
LightManager* lightManager, const osg::Light* light, osg::StateSet* stateset, int mode)
|
||||
{
|
||||
auto method = lightManager->getLightingMethod();
|
||||
switch (method)
|
||||
{
|
||||
case LightingMethod::FFP:
|
||||
case LightingMethod::FFP:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case LightingMethod::PerObjectUniform:
|
||||
case LightingMethod::PerObjectUniform:
|
||||
{
|
||||
osg::Matrixf lightMat;
|
||||
configurePosition(lightMat, light->getPosition());
|
||||
|
@ -289,7 +277,7 @@ namespace SceneUtil
|
|||
stateset->addUniform(lightManager->generateLightBufferUniform(lightMat), mode);
|
||||
break;
|
||||
}
|
||||
case LightingMethod::SingleUBO:
|
||||
case LightingMethod::SingleUBO:
|
||||
{
|
||||
osg::ref_ptr<LightBuffer> buffer = new LightBuffer(lightManager->getMaxLightsInScene());
|
||||
|
||||
|
@ -300,7 +288,9 @@ namespace SceneUtil
|
|||
|
||||
osg::ref_ptr<osg::UniformBufferObject> ubo = new osg::UniformBufferObject;
|
||||
buffer->getData()->setBufferObject(ubo);
|
||||
osg::ref_ptr<osg::UniformBufferBinding> ubb = new osg::UniformBufferBinding(static_cast<int>(Resource::SceneManager::UBOBinding::LightBuffer), buffer->getData(), 0, buffer->getData()->getTotalDataSize());
|
||||
osg::ref_ptr<osg::UniformBufferBinding> ubb
|
||||
= new osg::UniformBufferBinding(static_cast<int>(Resource::SceneManager::UBOBinding::LightBuffer),
|
||||
buffer->getData(), 0, buffer->getData()->getTotalDataSize());
|
||||
stateset->setAttributeAndModes(ubb, mode);
|
||||
|
||||
break;
|
||||
|
@ -311,15 +301,24 @@ namespace SceneUtil
|
|||
class DisableLight : public osg::StateAttribute
|
||||
{
|
||||
public:
|
||||
DisableLight() : mIndex(0) {}
|
||||
DisableLight(int index) : mIndex(index) {}
|
||||
DisableLight()
|
||||
: mIndex(0)
|
||||
{
|
||||
}
|
||||
DisableLight(int index)
|
||||
: mIndex(index)
|
||||
{
|
||||
}
|
||||
|
||||
DisableLight(const DisableLight& copy,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY)
|
||||
: osg::StateAttribute(copy,copyop), mIndex(copy.mIndex) {}
|
||||
DisableLight(const DisableLight& copy, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY)
|
||||
: osg::StateAttribute(copy, copyop)
|
||||
, mIndex(copy.mIndex)
|
||||
{
|
||||
}
|
||||
|
||||
META_StateAttribute(SceneUtil, DisableLight, osg::StateAttribute::LIGHT)
|
||||
|
||||
unsigned int getMember() const override
|
||||
unsigned int getMember() const override
|
||||
{
|
||||
return mIndex;
|
||||
}
|
||||
|
@ -354,16 +353,25 @@ namespace SceneUtil
|
|||
class FFPLightStateAttribute : public osg::StateAttribute
|
||||
{
|
||||
public:
|
||||
FFPLightStateAttribute() : mIndex(0) {}
|
||||
FFPLightStateAttribute(size_t index, const std::vector<osg::ref_ptr<osg::Light>>& lights) : mIndex(index), mLights(lights) {}
|
||||
|
||||
FFPLightStateAttribute(const FFPLightStateAttribute& copy,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY)
|
||||
: osg::StateAttribute(copy,copyop), mIndex(copy.mIndex), mLights(copy.mLights) {}
|
||||
|
||||
unsigned int getMember() const override
|
||||
FFPLightStateAttribute()
|
||||
: mIndex(0)
|
||||
{
|
||||
return mIndex;
|
||||
}
|
||||
FFPLightStateAttribute(size_t index, const std::vector<osg::ref_ptr<osg::Light>>& lights)
|
||||
: mIndex(index)
|
||||
, mLights(lights)
|
||||
{
|
||||
}
|
||||
|
||||
FFPLightStateAttribute(
|
||||
const FFPLightStateAttribute& copy, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY)
|
||||
: osg::StateAttribute(copy, copyop)
|
||||
, mIndex(copy.mIndex)
|
||||
, mLights(copy.mLights)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned int getMember() const override { return mIndex; }
|
||||
|
||||
bool getModeUsage(ModeUsage& usage) const override
|
||||
{
|
||||
|
@ -379,7 +387,7 @@ namespace SceneUtil
|
|||
|
||||
META_StateAttribute(SceneUtil, FFPLightStateAttribute, osg::StateAttribute::LIGHT)
|
||||
|
||||
void apply(osg::State& state) const override
|
||||
void apply(osg::State& state) const override
|
||||
{
|
||||
if (mLights.empty())
|
||||
return;
|
||||
|
@ -391,11 +399,11 @@ namespace SceneUtil
|
|||
|
||||
for (size_t i = 0; i < mLights.size(); ++i)
|
||||
{
|
||||
osg::Light* current = cache->lastAppliedLight[i+mIndex];
|
||||
osg::Light* current = cache->lastAppliedLight[i + mIndex];
|
||||
if (current != mLights[i].get())
|
||||
{
|
||||
applyLight((GLenum)((int)GL_LIGHT0 + i + mIndex), mLights[i].get());
|
||||
cache->lastAppliedLight[i+mIndex] = mLights[i].get();
|
||||
cache->lastAppliedLight[i + mIndex] = mLights[i].get();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -410,9 +418,9 @@ namespace SceneUtil
|
|||
glLightfv(lightNum, GL_POSITION, light->getPosition().ptr());
|
||||
// TODO: enable this once spot lights are supported
|
||||
// need to transform SPOT_DIRECTION by the world matrix?
|
||||
//glLightfv(lightNum, GL_SPOT_DIRECTION, light->getDirection().ptr());
|
||||
//glLightf(lightNum, GL_SPOT_EXPONENT, light->getSpotExponent());
|
||||
//glLightf(lightNum, GL_SPOT_CUTOFF, light->getSpotCutoff());
|
||||
// glLightfv(lightNum, GL_SPOT_DIRECTION, light->getDirection().ptr());
|
||||
// glLightf(lightNum, GL_SPOT_EXPONENT, light->getSpotExponent());
|
||||
// glLightf(lightNum, GL_SPOT_CUTOFF, light->getSpotCutoff());
|
||||
glLightf(lightNum, GL_CONSTANT_ATTENUATION, light->getConstantAttenuation());
|
||||
glLightf(lightNum, GL_LINEAR_ATTENUATION, light->getLinearAttenuation());
|
||||
glLightf(lightNum, GL_QUADRATIC_ATTENUATION, light->getQuadraticAttenuation());
|
||||
|
@ -450,7 +458,8 @@ namespace SceneUtil
|
|||
// the first light state attribute handles the actual state setting for all lights
|
||||
// it's best to batch these up so that we don't need to touch the modelView matrix more than necessary
|
||||
// don't use setAttributeAndModes, that does not support light indices!
|
||||
stateset->setAttribute(new FFPLightStateAttribute(mLightManager->getStartLight(), std::move(lights)), osg::StateAttribute::ON);
|
||||
stateset->setAttribute(
|
||||
new FFPLightStateAttribute(mLightManager->getStartLight(), std::move(lights)), osg::StateAttribute::ON);
|
||||
|
||||
for (size_t i = 0; i < lightList.size(); ++i)
|
||||
stateset->setMode(GL_LIGHT0 + mLightManager->getStartLight() + i, osg::StateAttribute::ON);
|
||||
|
@ -458,7 +467,8 @@ namespace SceneUtil
|
|||
// need to push some dummy attributes to ensure proper state tracking
|
||||
// lights need to reset to their default when the StateSet is popped
|
||||
for (size_t i = 1; i < lightList.size(); ++i)
|
||||
stateset->setAttribute(mLightManager->getDummies()[i + mLightManager->getStartLight()].get(), osg::StateAttribute::ON);
|
||||
stateset->setAttribute(
|
||||
mLightManager->getDummies()[i + mLightManager->getStartLight()].get(), osg::StateAttribute::ON);
|
||||
|
||||
return stateset;
|
||||
}
|
||||
|
@ -470,7 +480,8 @@ namespace SceneUtil
|
|||
{
|
||||
osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet;
|
||||
|
||||
osg::ref_ptr<osg::Uniform> indicesUni = new osg::Uniform(osg::Uniform::Type::INT, "PointLightIndex", mLightManager->getMaxLights());
|
||||
osg::ref_ptr<osg::Uniform> indicesUni
|
||||
= new osg::Uniform(osg::Uniform::Type::INT, "PointLightIndex", mLightManager->getMaxLights());
|
||||
int pointCount = 0;
|
||||
|
||||
for (size_t i = 0; i < lightList.size(); ++i)
|
||||
|
@ -519,7 +530,8 @@ namespace SceneUtil
|
|||
osg::ref_ptr<osg::StateSet> generate(const LightManager::LightList& lightList, size_t frameNum) override
|
||||
{
|
||||
osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet;
|
||||
osg::ref_ptr<osg::Uniform> data = mLightManager->generateLightBufferUniform(mLightManager->getSunlightBuffer(frameNum));
|
||||
osg::ref_ptr<osg::Uniform> data
|
||||
= mLightManager->generateLightBufferUniform(mLightManager->getSunlightBuffer(frameNum));
|
||||
|
||||
for (size_t i = 0; i < lightList.size(); ++i)
|
||||
{
|
||||
|
@ -528,9 +540,10 @@ namespace SceneUtil
|
|||
configurePosition(lightMat, light->getPosition() * mViewMatrix);
|
||||
configureAmbient(lightMat, light->getAmbient());
|
||||
configureDiffuse(lightMat, light->getDiffuse());
|
||||
configureAttenuation(lightMat, light->getConstantAttenuation(), light->getLinearAttenuation(), light->getQuadraticAttenuation(), lightList[i]->mLightSource->getRadius());
|
||||
configureAttenuation(lightMat, light->getConstantAttenuation(), light->getLinearAttenuation(),
|
||||
light->getQuadraticAttenuation(), lightList[i]->mLightSource->getRadius());
|
||||
|
||||
data->setElement(i+1, lightMat);
|
||||
data->setElement(i + 1, lightMat);
|
||||
}
|
||||
|
||||
stateset->addUniform(data);
|
||||
|
@ -551,16 +564,21 @@ namespace SceneUtil
|
|||
}
|
||||
|
||||
// Set on a LightSource. Adds the light source to its light manager for the current frame.
|
||||
// This allows us to keep track of the current lights in the scene graph without tying creation & destruction to the manager.
|
||||
// This allows us to keep track of the current lights in the scene graph without tying creation & destruction to the
|
||||
// manager.
|
||||
class CollectLightCallback : public NodeCallback<CollectLightCallback>
|
||||
{
|
||||
public:
|
||||
CollectLightCallback()
|
||||
: mLightManager(nullptr) { }
|
||||
: mLightManager(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
CollectLightCallback(const CollectLightCallback& copy, const osg::CopyOp& copyop)
|
||||
: NodeCallback<CollectLightCallback>(copy, copyop)
|
||||
, mLightManager(nullptr) { }
|
||||
, mLightManager(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
META_Object(SceneUtil, CollectLightCallback)
|
||||
|
||||
|
@ -574,7 +592,8 @@ namespace SceneUtil
|
|||
throw std::runtime_error("can't find parent LightManager");
|
||||
}
|
||||
|
||||
mLightManager->addLight(static_cast<LightSource*>(node), osg::computeLocalToWorld(nv->getNodePath()), nv->getTraversalNumber());
|
||||
mLightManager->addLight(
|
||||
static_cast<LightSource*>(node), osg::computeLocalToWorld(nv->getNodePath()), nv->getTraversalNumber());
|
||||
|
||||
traverse(node, nv);
|
||||
}
|
||||
|
@ -587,7 +606,6 @@ namespace SceneUtil
|
|||
class LightManagerUpdateCallback : public SceneUtil::NodeCallback<LightManagerUpdateCallback>
|
||||
{
|
||||
public:
|
||||
|
||||
void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||
{
|
||||
LightManager* lightManager = static_cast<LightManager*>(node);
|
||||
|
@ -597,7 +615,8 @@ namespace SceneUtil
|
|||
}
|
||||
};
|
||||
|
||||
class LightManagerCullCallback : public SceneUtil::NodeCallback<LightManagerCullCallback, LightManager*, osgUtil::CullVisitor*>
|
||||
class LightManagerCullCallback
|
||||
: public SceneUtil::NodeCallback<LightManagerCullCallback, LightManager*, osgUtil::CullVisitor*>
|
||||
{
|
||||
public:
|
||||
LightManagerCullCallback(LightManager* lightManager)
|
||||
|
@ -608,7 +627,9 @@ namespace SceneUtil
|
|||
for (size_t i = 0; i < mUBBs.size(); ++i)
|
||||
{
|
||||
auto& buffer = lightManager->getUBOManager()->getLightBuffer(i);
|
||||
mUBBs[i] = new osg::UniformBufferBinding(static_cast<int>(Resource::SceneManager::UBOBinding::LightBuffer), buffer->getData(), 0, buffer->getData()->getTotalDataSize());
|
||||
mUBBs[i]
|
||||
= new osg::UniformBufferBinding(static_cast<int>(Resource::SceneManager::UBOBinding::LightBuffer),
|
||||
buffer->getData(), 0, buffer->getData()->getTotalDataSize());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -636,7 +657,8 @@ namespace SceneUtil
|
|||
if (auto sun = node->getSunlight())
|
||||
{
|
||||
osg::Matrixf lightMat;
|
||||
configurePosition(lightMat, sun->getPosition() * (*cv->getCurrentRenderStage()->getInitialViewMatrix()));
|
||||
configurePosition(
|
||||
lightMat, sun->getPosition() * (*cv->getCurrentRenderStage()->getInitialViewMatrix()));
|
||||
configureAmbient(lightMat, sun->getAmbient());
|
||||
configureDiffuse(lightMat, sun->getDiffuse());
|
||||
configureSpecular(lightMat, sun->getSpecular());
|
||||
|
@ -664,10 +686,11 @@ namespace SceneUtil
|
|||
{
|
||||
static const std::string dummyVertSource = generateDummyShader(lightCount);
|
||||
|
||||
// Needed to query the layout of the buffer object. The layout specifier needed to use the std140 layout is not reliably
|
||||
// available, regardless of extensions, until GLSL 140.
|
||||
// Needed to query the layout of the buffer object. The layout specifier needed to use the std140 layout is not
|
||||
// reliably available, regardless of extensions, until GLSL 140.
|
||||
mDummyProgram->addShader(new osg::Shader(osg::Shader::VERTEX, dummyVertSource));
|
||||
mDummyProgram->addBindUniformBlock("LightBufferBinding", static_cast<int>(Resource::SceneManager::UBOBinding::LightBuffer));
|
||||
mDummyProgram->addBindUniformBlock(
|
||||
"LightBufferBinding", static_cast<int>(Resource::SceneManager::UBOBinding::LightBuffer));
|
||||
|
||||
for (size_t i = 0; i < mLightBuffers.size(); ++i)
|
||||
{
|
||||
|
@ -680,14 +703,19 @@ namespace SceneUtil
|
|||
}
|
||||
}
|
||||
|
||||
UBOManager::UBOManager(const UBOManager& copy, const osg::CopyOp& copyop) : osg::StateAttribute(copy,copyop), mDummyProgram(copy.mDummyProgram), mInitLayout(copy.mInitLayout) {}
|
||||
UBOManager::UBOManager(const UBOManager& copy, const osg::CopyOp& copyop)
|
||||
: osg::StateAttribute(copy, copyop)
|
||||
, mDummyProgram(copy.mDummyProgram)
|
||||
, mInitLayout(copy.mInitLayout)
|
||||
{
|
||||
}
|
||||
|
||||
void UBOManager::releaseGLObjects(osg::State* state) const
|
||||
{
|
||||
mDummyProgram->releaseGLObjects(state);
|
||||
}
|
||||
|
||||
int UBOManager::compare(const StateAttribute &sa) const
|
||||
int UBOManager::compare(const StateAttribute& sa) const
|
||||
{
|
||||
throw std::runtime_error("LightManagerStateAttribute::compare: unimplemented");
|
||||
}
|
||||
|
@ -750,7 +778,8 @@ namespace SceneUtil
|
|||
|
||||
void UBOManager::initSharedLayout(osg::GLExtensions* ext, int handle, unsigned int frame) const
|
||||
{
|
||||
constexpr std::array<unsigned int, 1> index = { static_cast<unsigned int>(Resource::SceneManager::UBOBinding::LightBuffer) };
|
||||
constexpr std::array<unsigned int, 1> index
|
||||
= { static_cast<unsigned int>(Resource::SceneManager::UBOBinding::LightBuffer) };
|
||||
int totalBlockSize = -1;
|
||||
int stride = -1;
|
||||
|
||||
|
@ -822,14 +851,16 @@ namespace SceneUtil
|
|||
if (lightingMethod == LightingMethod::SingleUBO && !hasLoggedWarnings)
|
||||
{
|
||||
if (!supportsUBO)
|
||||
Log(Debug::Warning) << "GL_ARB_uniform_buffer_object not supported: switching to shader compatibility lighting mode";
|
||||
Log(Debug::Warning)
|
||||
<< "GL_ARB_uniform_buffer_object not supported: switching to shader compatibility lighting mode";
|
||||
if (!supportsGPU4)
|
||||
Log(Debug::Warning) << "GL_EXT_gpu_shader4 not supported: switching to shader compatibility lighting mode";
|
||||
Log(Debug::Warning)
|
||||
<< "GL_EXT_gpu_shader4 not supported: switching to shader compatibility lighting mode";
|
||||
hasLoggedWarnings = true;
|
||||
}
|
||||
|
||||
const int targetLights = std::clamp(Settings::Manager::getInt("max lights", "Shaders"),
|
||||
maxLightsLowerLimit, maxLightsUpperLimit);
|
||||
const int targetLights
|
||||
= std::clamp(Settings::Manager::getInt("max lights", "Shaders"), maxLightsLowerLimit, maxLightsUpperLimit);
|
||||
|
||||
if (!supportsUBO || !supportsGPU4 || lightingMethod == LightingMethod::PerObjectUniform)
|
||||
initPerObjectUniform(targetLights);
|
||||
|
@ -843,7 +874,7 @@ namespace SceneUtil
|
|||
addCullCallback(new LightManagerCullCallback(this));
|
||||
}
|
||||
|
||||
LightManager::LightManager(const LightManager ©, const osg::CopyOp ©op)
|
||||
LightManager::LightManager(const LightManager& copy, const osg::CopyOp& copyop)
|
||||
: osg::Group(copy, copyop)
|
||||
, mStartLight(copy.mStartLight)
|
||||
, mLightingMask(copy.mLightingMask)
|
||||
|
@ -896,7 +927,7 @@ namespace SceneUtil
|
|||
// exposes bitwise operators
|
||||
defines["useGPUShader4"] = std::to_string(getLightingMethod() == LightingMethod::SingleUBO);
|
||||
defines["getLight"] = getLightingMethod() == LightingMethod::FFP ? "gl_LightSource" : "LightBuffer";
|
||||
defines["startLight"] = getLightingMethod() == LightingMethod::SingleUBO ? "0" : "1";
|
||||
defines["startLight"] = getLightingMethod() == LightingMethod::SingleUBO ? "0" : "1";
|
||||
defines["endLight"] = getLightingMethod() == LightingMethod::FFP ? defines["maxLights"] : "PointLightCount";
|
||||
|
||||
return defines;
|
||||
|
@ -912,7 +943,8 @@ namespace SceneUtil
|
|||
if (usingFFP())
|
||||
return;
|
||||
|
||||
setMaxLights(std::clamp(Settings::Manager::getInt("max lights", "Shaders"), maxLightsLowerLimit, maxLightsUpperLimit));
|
||||
setMaxLights(
|
||||
std::clamp(Settings::Manager::getInt("max lights", "Shaders"), maxLightsLowerLimit, maxLightsUpperLimit));
|
||||
|
||||
if (getLightingMethod() == LightingMethod::PerObjectUniform)
|
||||
{
|
||||
|
@ -929,7 +961,8 @@ namespace SceneUtil
|
|||
if (getLightingMethod() == LightingMethod::FFP)
|
||||
return;
|
||||
|
||||
mPointLightRadiusMultiplier = std::clamp(Settings::Manager::getFloat("light bounds multiplier", "Shaders"), 0.f, 5.f);
|
||||
mPointLightRadiusMultiplier
|
||||
= std::clamp(Settings::Manager::getFloat("light bounds multiplier", "Shaders"), 0.f, 5.f);
|
||||
|
||||
mPointLightFadeEnd = std::max(0.f, Settings::Manager::getFloat("maximum light distance", "Shaders"));
|
||||
if (mPointLightFadeEnd > 0)
|
||||
|
@ -970,15 +1003,15 @@ namespace SceneUtil
|
|||
mLightingMethod = method;
|
||||
switch (method)
|
||||
{
|
||||
case LightingMethod::FFP:
|
||||
mStateSetGenerator = std::make_unique<StateSetGeneratorFFP>();
|
||||
break;
|
||||
case LightingMethod::SingleUBO:
|
||||
mStateSetGenerator = std::make_unique<StateSetGeneratorSingleUBO>();
|
||||
break;
|
||||
case LightingMethod::PerObjectUniform:
|
||||
mStateSetGenerator = std::make_unique<StateSetGeneratorPerObjectUniform>();
|
||||
break;
|
||||
case LightingMethod::FFP:
|
||||
mStateSetGenerator = std::make_unique<StateSetGeneratorFFP>();
|
||||
break;
|
||||
case LightingMethod::SingleUBO:
|
||||
mStateSetGenerator = std::make_unique<StateSetGeneratorSingleUBO>();
|
||||
break;
|
||||
case LightingMethod::PerObjectUniform:
|
||||
mStateSetGenerator = std::make_unique<StateSetGeneratorPerObjectUniform>();
|
||||
break;
|
||||
}
|
||||
mStateSetGenerator->mLightManager = this;
|
||||
}
|
||||
|
@ -997,14 +1030,15 @@ namespace SceneUtil
|
|||
{
|
||||
mStartLight = start;
|
||||
|
||||
if (!usingFFP()) return;
|
||||
if (!usingFFP())
|
||||
return;
|
||||
|
||||
// Set default light state to zero
|
||||
// This is necessary because shaders don't respect glDisable(GL_LIGHTX) so in addition to disabling
|
||||
// we'll have to set a light state that has no visible effect
|
||||
for (int i = start; i < getMaxLights(); ++i)
|
||||
{
|
||||
osg::ref_ptr<DisableLight> defaultLight (new DisableLight(i));
|
||||
osg::ref_ptr<DisableLight> defaultLight(new DisableLight(i));
|
||||
getOrCreateStateSet()->setAttributeAndModes(defaultLight, osg::StateAttribute::OFF);
|
||||
}
|
||||
}
|
||||
|
@ -1044,7 +1078,8 @@ namespace SceneUtil
|
|||
|
||||
void LightManager::setSunlight(osg::ref_ptr<osg::Light> sun)
|
||||
{
|
||||
if (usingFFP()) return;
|
||||
if (usingFFP())
|
||||
return;
|
||||
|
||||
mSun = sun;
|
||||
}
|
||||
|
@ -1062,7 +1097,8 @@ namespace SceneUtil
|
|||
return hash;
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::StateSet> LightManager::getLightListStateSet(const LightList& lightList, size_t frameNum, const osg::RefMatrix* viewMatrix)
|
||||
osg::ref_ptr<osg::StateSet> LightManager::getLightListStateSet(
|
||||
const LightList& lightList, size_t frameNum, const osg::RefMatrix* viewMatrix)
|
||||
{
|
||||
if (getLightingMethod() == LightingMethod::PerObjectUniform)
|
||||
{
|
||||
|
@ -1070,7 +1106,8 @@ namespace SceneUtil
|
|||
return mStateSetGenerator->generate(lightList, frameNum);
|
||||
}
|
||||
|
||||
// possible optimization: return a StateSet containing all requested lights plus some extra lights (if a suitable one exists)
|
||||
// possible optimization: return a StateSet containing all requested lights plus some extra lights (if a
|
||||
// suitable one exists)
|
||||
|
||||
if (getLightingMethod() == LightingMethod::SingleUBO)
|
||||
{
|
||||
|
@ -1086,11 +1123,12 @@ namespace SceneUtil
|
|||
}
|
||||
}
|
||||
|
||||
auto& stateSetCache = mStateSetCache[frameNum%2];
|
||||
auto& stateSetCache = mStateSetCache[frameNum % 2];
|
||||
|
||||
LightIdList lightIdList;
|
||||
lightIdList.reserve(lightList.size());
|
||||
std::transform(lightList.begin(), lightList.end(), std::back_inserter(lightIdList), [] (const LightSourceViewBound* l) { return l->mLightSource->getId(); });
|
||||
std::transform(lightList.begin(), lightList.end(), std::back_inserter(lightIdList),
|
||||
[](const LightSourceViewBound* l) { return l->mLightSource->getId(); });
|
||||
|
||||
auto found = stateSetCache.find(lightIdList);
|
||||
if (found != stateSetCache.end())
|
||||
|
@ -1104,11 +1142,12 @@ namespace SceneUtil
|
|||
return stateset;
|
||||
}
|
||||
|
||||
const std::vector<LightManager::LightSourceViewBound>& LightManager::getLightsInViewSpace(osgUtil::CullVisitor* cv, const osg::RefMatrix* viewMatrix, size_t frameNum)
|
||||
const std::vector<LightManager::LightSourceViewBound>& LightManager::getLightsInViewSpace(
|
||||
osgUtil::CullVisitor* cv, const osg::RefMatrix* viewMatrix, size_t frameNum)
|
||||
{
|
||||
osg::Camera* camera = cv->getCurrentCamera();
|
||||
|
||||
osg::observer_ptr<osg::Camera> camPtr (camera);
|
||||
osg::observer_ptr<osg::Camera> camPtr(camera);
|
||||
auto it = mLightsInViewSpace.find(camPtr);
|
||||
|
||||
if (it == mLightsInViewSpace.end())
|
||||
|
@ -1121,7 +1160,7 @@ namespace SceneUtil
|
|||
|
||||
float radius = transform.mLightSource->getRadius();
|
||||
|
||||
osg::BoundingSphere viewBound = osg::BoundingSphere(osg::Vec3f(0,0,0), radius);
|
||||
osg::BoundingSphere viewBound = osg::BoundingSphere(osg::Vec3f(0, 0, 0), radius);
|
||||
transformBoundingSphere(worldViewMat, viewBound);
|
||||
|
||||
if (transform.mLightSource->getLastAppliedFrame() != frameNum && mPointLightFadeEnd != 0.f)
|
||||
|
@ -1156,8 +1195,9 @@ namespace SceneUtil
|
|||
|
||||
if (fillPPLights || getLightingMethod() == LightingMethod::SingleUBO)
|
||||
{
|
||||
auto sorter = [] (const LightSourceViewBound& left, const LightSourceViewBound& right) {
|
||||
return left.mViewBound.center().length2() - left.mViewBound.radius2() < right.mViewBound.center().length2() - right.mViewBound.radius2();
|
||||
auto sorter = [](const LightSourceViewBound& left, const LightSourceViewBound& right) {
|
||||
return left.mViewBound.center().length2() - left.mViewBound.radius2()
|
||||
< right.mViewBound.center().length2() - right.mViewBound.radius2();
|
||||
};
|
||||
|
||||
std::sort(it->second.begin(), it->second.end(), sorter);
|
||||
|
@ -1182,13 +1222,16 @@ namespace SceneUtil
|
|||
return it->second;
|
||||
}
|
||||
|
||||
void LightManager::updateGPUPointLight(int index, LightSource* lightSource, size_t frameNum,const osg::RefMatrix* viewMatrix)
|
||||
void LightManager::updateGPUPointLight(
|
||||
int index, LightSource* lightSource, size_t frameNum, const osg::RefMatrix* viewMatrix)
|
||||
{
|
||||
auto* light = lightSource->getLight(frameNum);
|
||||
auto& buf = getUBOManager()->getLightBuffer(frameNum);
|
||||
buf->setDiffuse(index, light->getDiffuse());
|
||||
buf->setAmbient(index, light->getAmbient());
|
||||
buf->setAttenuationRadius(index, osg::Vec4(light->getConstantAttenuation(), light->getLinearAttenuation(), light->getQuadraticAttenuation(), lightSource->getRadius()));
|
||||
buf->setAttenuationRadius(index,
|
||||
osg::Vec4(light->getConstantAttenuation(), light->getLinearAttenuation(), light->getQuadraticAttenuation(),
|
||||
lightSource->getRadius()));
|
||||
buf->setPosition(index, light->getPosition() * (*viewMatrix));
|
||||
}
|
||||
|
||||
|
@ -1217,7 +1260,7 @@ namespace SceneUtil
|
|||
mId = sLightId++;
|
||||
}
|
||||
|
||||
LightSource::LightSource(const LightSource ©, const osg::CopyOp ©op)
|
||||
LightSource::LightSource(const LightSource& copy, const osg::CopyOp& copyop)
|
||||
: osg::Node(copy, copyop)
|
||||
, mRadius(copy.mRadius)
|
||||
, mActorFade(copy.mActorFade)
|
||||
|
@ -1229,7 +1272,7 @@ namespace SceneUtil
|
|||
mLight[i] = new osg::Light(*copy.mLight[i].get(), copyop);
|
||||
}
|
||||
|
||||
void LightListCallback::operator()(osg::Node *node, osgUtil::CullVisitor *cv)
|
||||
void LightListCallback::operator()(osg::Node* node, osgUtil::CullVisitor* cv)
|
||||
{
|
||||
bool pushedState = pushLightState(node, cv);
|
||||
traverse(node, cv);
|
||||
|
@ -1237,7 +1280,7 @@ namespace SceneUtil
|
|||
cv->popStateSet();
|
||||
}
|
||||
|
||||
bool LightListCallback::pushLightState(osg::Node *node, osgUtil::CullVisitor *cv)
|
||||
bool LightListCallback::pushLightState(osg::Node* node, osgUtil::CullVisitor* cv)
|
||||
{
|
||||
if (!mLightManager)
|
||||
{
|
||||
|
@ -1252,12 +1295,12 @@ namespace SceneUtil
|
|||
// Possible optimizations:
|
||||
// - organize lights in a quad tree
|
||||
|
||||
|
||||
mLastFrameNumber = cv->getTraversalNumber();
|
||||
|
||||
// Don't use Camera::getViewMatrix, that one might be relative to another camera!
|
||||
const osg::RefMatrix* viewMatrix = cv->getCurrentRenderStage()->getInitialViewMatrix();
|
||||
const std::vector<LightManager::LightSourceViewBound>& lights = mLightManager->getLightsInViewSpace(cv, viewMatrix, mLastFrameNumber);
|
||||
const std::vector<LightManager::LightSourceViewBound>& lights
|
||||
= mLightManager->getLightsInViewSpace(cv, viewMatrix, mLastFrameNumber);
|
||||
|
||||
// get the node bounds in view space
|
||||
// NB do not node->getBound() * modelView, that would apply the node's transformation twice
|
||||
|
@ -1312,11 +1355,12 @@ namespace SceneUtil
|
|||
std::sort(lightList.begin(), lightList.end(), sortLights);
|
||||
while (lightList.size() > maxLights)
|
||||
lightList.pop_back();
|
||||
stateset = mLightManager->getLightListStateSet(lightList, cv->getTraversalNumber(), cv->getCurrentRenderStage()->getInitialViewMatrix());
|
||||
stateset = mLightManager->getLightListStateSet(
|
||||
lightList, cv->getTraversalNumber(), cv->getCurrentRenderStage()->getInitialViewMatrix());
|
||||
}
|
||||
else
|
||||
stateset = mLightManager->getLightListStateSet(mLightList, cv->getTraversalNumber(), cv->getCurrentRenderStage()->getInitialViewMatrix());
|
||||
|
||||
stateset = mLightManager->getLightListStateSet(
|
||||
mLightList, cv->getTraversalNumber(), cv->getCurrentRenderStage()->getInitialViewMatrix());
|
||||
|
||||
cv->pushStateSet(stateset);
|
||||
return true;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue