mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-06 23:45:35 +00:00
experimental point light bindings
This commit is contained in:
parent
fee639a74f
commit
0cb63ca4e6
13 changed files with 168 additions and 12 deletions
|
@ -94,6 +94,8 @@ namespace MWRender
|
||||||
, mNormals(false)
|
, mNormals(false)
|
||||||
, mPrevNormals(false)
|
, mPrevNormals(false)
|
||||||
, mNormalsSupported(false)
|
, mNormalsSupported(false)
|
||||||
|
, mPassLights(false)
|
||||||
|
, mPrevPassLights(false)
|
||||||
, mMainTemplate(new osg::Texture2D)
|
, mMainTemplate(new osg::Texture2D)
|
||||||
{
|
{
|
||||||
mSoftParticles = Settings::Manager::getBool("soft particles", "Shaders") && !Stereo::getStereo() && !Stereo::getMultiview();
|
mSoftParticles = Settings::Manager::getBool("soft particles", "Shaders") && !Stereo::getStereo() && !Stereo::getMultiview();
|
||||||
|
@ -393,9 +395,10 @@ namespace MWRender
|
||||||
mDirty = false;
|
mDirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mNormalsSupported && mNormals != mPrevNormals)
|
if ((mNormalsSupported && mNormals != mPrevNormals) || (mPassLights != mPrevPassLights))
|
||||||
{
|
{
|
||||||
mPrevNormals = mNormals;
|
mPrevNormals = mNormals;
|
||||||
|
mPrevPassLights = mPassLights;
|
||||||
|
|
||||||
mViewer->stopThreading();
|
mViewer->stopThreading();
|
||||||
|
|
||||||
|
@ -404,10 +407,15 @@ namespace MWRender
|
||||||
defines["disableNormals"] = mNormals ? "0" : "1";
|
defines["disableNormals"] = mNormals ? "0" : "1";
|
||||||
shaderManager.setGlobalDefines(defines);
|
shaderManager.setGlobalDefines(defines);
|
||||||
|
|
||||||
|
mRendering.getLightRoot()->setCollectPPLights(mPassLights);
|
||||||
|
mStateUpdater->bindPointLights(mPassLights ? mRendering.getLightRoot()->getPPLightsBuffer() : nullptr);
|
||||||
|
mStateUpdater->reset();
|
||||||
|
|
||||||
mViewer->startThreading();
|
mViewer->startThreading();
|
||||||
|
|
||||||
createTexturesAndCamera(frameId);
|
createTexturesAndCamera(frameId);
|
||||||
createObjectsForFrame(frameId);
|
createObjectsForFrame(frameId);
|
||||||
|
|
||||||
mDirty = true;
|
mDirty = true;
|
||||||
mDirtyFrameId = !frameId;
|
mDirtyFrameId = !frameId;
|
||||||
}
|
}
|
||||||
|
@ -491,6 +499,7 @@ namespace MWRender
|
||||||
bool sunglare = true;
|
bool sunglare = true;
|
||||||
mHDR = false;
|
mHDR = false;
|
||||||
mNormals = false;
|
mNormals = false;
|
||||||
|
mPassLights = false;
|
||||||
|
|
||||||
for (const auto& technique : mTechniques)
|
for (const auto& technique : mTechniques)
|
||||||
{
|
{
|
||||||
|
@ -513,6 +522,9 @@ namespace MWRender
|
||||||
if (technique->getNormals())
|
if (technique->getNormals())
|
||||||
mNormals = true;
|
mNormals = true;
|
||||||
|
|
||||||
|
if (technique->getLights())
|
||||||
|
mPassLights = true;
|
||||||
|
|
||||||
if (node.mFlags & fx::Technique::Flag_Disable_SunGlare)
|
if (node.mFlags & fx::Technique::Flag_Disable_SunGlare)
|
||||||
sunglare = false;
|
sunglare = false;
|
||||||
|
|
||||||
|
|
|
@ -212,6 +212,8 @@ namespace MWRender
|
||||||
bool mNormals;
|
bool mNormals;
|
||||||
bool mPrevNormals;
|
bool mPrevNormals;
|
||||||
bool mNormalsSupported;
|
bool mNormalsSupported;
|
||||||
|
bool mPassLights;
|
||||||
|
bool mPrevPassLights;
|
||||||
bool mUBO;
|
bool mUBO;
|
||||||
int mGLSLVersion;
|
int mGLSLVersion;
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,8 @@
|
||||||
#include <components/sceneutil/writescene.hpp>
|
#include <components/sceneutil/writescene.hpp>
|
||||||
#include <components/sceneutil/shadow.hpp>
|
#include <components/sceneutil/shadow.hpp>
|
||||||
|
|
||||||
|
#include <components/misc/constants.hpp>
|
||||||
|
|
||||||
#include <components/terrain/terraingrid.hpp>
|
#include <components/terrain/terraingrid.hpp>
|
||||||
#include <components/terrain/quadtreeworld.hpp>
|
#include <components/terrain/quadtreeworld.hpp>
|
||||||
|
|
||||||
|
@ -558,10 +560,9 @@ namespace MWRender
|
||||||
cullingMode |= osg::CullStack::SMALL_FEATURE_CULLING;
|
cullingMode |= osg::CullStack::SMALL_FEATURE_CULLING;
|
||||||
}
|
}
|
||||||
|
|
||||||
mViewer->getCamera()->setCullingMode( cullingMode );
|
|
||||||
|
|
||||||
mViewer->getCamera()->setComputeNearFarMode(osg::Camera::DO_NOT_COMPUTE_NEAR_FAR);
|
mViewer->getCamera()->setComputeNearFarMode(osg::Camera::DO_NOT_COMPUTE_NEAR_FAR);
|
||||||
mViewer->getCamera()->setCullingMode(cullingMode);
|
mViewer->getCamera()->setCullingMode(cullingMode);
|
||||||
|
mViewer->getCamera()->setName(Constants::SceneCamera);
|
||||||
|
|
||||||
auto mask = ~(Mask_UpdateVisitor | Mask_SimpleWater);
|
auto mask = ~(Mask_UpdateVisitor | Mask_SimpleWater);
|
||||||
MWBase::Environment::get().getWindowManager()->setCullMask(mask);
|
MWBase::Environment::get().getWindowManager()->setCullMask(mask);
|
||||||
|
@ -650,7 +651,7 @@ namespace MWRender
|
||||||
return mViewer->getFrameStamp()->getReferenceTime();
|
return mViewer->getFrameStamp()->getReferenceTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::Group* RenderingManager::getLightRoot()
|
SceneUtil::LightManager* RenderingManager::getLightRoot()
|
||||||
{
|
{
|
||||||
return mSceneRoot.get();
|
return mSceneRoot.get();
|
||||||
}
|
}
|
||||||
|
@ -1360,7 +1361,7 @@ namespace MWRender
|
||||||
it->second == "light fade start" ||
|
it->second == "light fade start" ||
|
||||||
it->second == "max lights"))
|
it->second == "max lights"))
|
||||||
{
|
{
|
||||||
auto* lightManager = static_cast<SceneUtil::LightManager*>(getLightRoot());
|
auto* lightManager = getLightRoot();
|
||||||
lightManager->processChangedSettings(changed);
|
lightManager->processChangedSettings(changed);
|
||||||
|
|
||||||
if (it->second == "max lights" && !lightManager->usingFFP())
|
if (it->second == "max lights" && !lightManager->usingFFP())
|
||||||
|
|
|
@ -59,6 +59,7 @@ namespace SceneUtil
|
||||||
{
|
{
|
||||||
class ShadowManager;
|
class ShadowManager;
|
||||||
class WorkQueue;
|
class WorkQueue;
|
||||||
|
class LightManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace DetourNavigator
|
namespace DetourNavigator
|
||||||
|
@ -116,7 +117,7 @@ namespace MWRender
|
||||||
|
|
||||||
double getReferenceTime() const;
|
double getReferenceTime() const;
|
||||||
|
|
||||||
osg::Group* getLightRoot();
|
SceneUtil::LightManager* getLightRoot();
|
||||||
|
|
||||||
void setNightEyeFactor(float factor);
|
void setNightEyeFactor(float factor);
|
||||||
|
|
||||||
|
@ -271,7 +272,7 @@ namespace MWRender
|
||||||
|
|
||||||
osg::ref_ptr<osgViewer::Viewer> mViewer;
|
osg::ref_ptr<osgViewer::Viewer> mViewer;
|
||||||
osg::ref_ptr<osg::Group> mRootNode;
|
osg::ref_ptr<osg::Group> mRootNode;
|
||||||
osg::ref_ptr<osg::Group> mSceneRoot;
|
osg::ref_ptr<SceneUtil::LightManager> mSceneRoot;
|
||||||
Resource::ResourceSystem* mResourceSystem;
|
Resource::ResourceSystem* mResourceSystem;
|
||||||
|
|
||||||
osg::ref_ptr<SceneUtil::WorkQueue> mWorkQueue;
|
osg::ref_ptr<SceneUtil::WorkQueue> mWorkQueue;
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <components/resource/resourcesystem.hpp>
|
#include <components/resource/resourcesystem.hpp>
|
||||||
|
|
||||||
#include <components/sceneutil/positionattitudetransform.hpp>
|
#include <components/sceneutil/positionattitudetransform.hpp>
|
||||||
|
#include <components/sceneutil/lightmanager.hpp>
|
||||||
|
|
||||||
#include <components/detournavigator/navigator.hpp>
|
#include <components/detournavigator/navigator.hpp>
|
||||||
#include <components/detournavigator/settings.hpp>
|
#include <components/detournavigator/settings.hpp>
|
||||||
|
@ -197,7 +198,7 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
|
|
||||||
mRendering.reset(new MWRender::RenderingManager(viewer, rootNode, resourceSystem, workQueue, resourcePath, *mNavigator, mGroundcoverStore));
|
mRendering.reset(new MWRender::RenderingManager(viewer, rootNode, resourceSystem, workQueue, resourcePath, *mNavigator, mGroundcoverStore));
|
||||||
mProjectileManager.reset(new ProjectileManager(mRendering->getLightRoot(), resourceSystem, mRendering.get(), mPhysics.get()));
|
mProjectileManager.reset(new ProjectileManager(mRendering->getLightRoot()->asGroup(), resourceSystem, mRendering.get(), mPhysics.get()));
|
||||||
mRendering->preloadCommonAssets();
|
mRendering->preloadCommonAssets();
|
||||||
|
|
||||||
mWeatherManager.reset(new MWWorld::WeatherManager(*mRendering, mStore));
|
mWeatherManager.reset(new MWWorld::WeatherManager(*mRendering, mStore));
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#include <components/misc/stringops.hpp>
|
#include <components/misc/stringops.hpp>
|
||||||
#include <components/sceneutil/util.hpp>
|
#include <components/sceneutil/util.hpp>
|
||||||
|
#include <components/sceneutil/lightmanager.hpp>
|
||||||
#include <components/sceneutil/clearcolor.hpp>
|
#include <components/sceneutil/clearcolor.hpp>
|
||||||
#include <components/resource/scenemanager.hpp>
|
#include <components/resource/scenemanager.hpp>
|
||||||
#include <components/stereo/multiview.hpp>
|
#include <components/stereo/multiview.hpp>
|
||||||
|
@ -77,6 +78,34 @@ uniform @builtinSampler omw_SamplerLastPass;
|
||||||
uniform @builtinSampler omw_SamplerDepth;
|
uniform @builtinSampler omw_SamplerDepth;
|
||||||
uniform @builtinSampler omw_SamplerNormals;
|
uniform @builtinSampler omw_SamplerNormals;
|
||||||
|
|
||||||
|
uniform vec4 omw_PointLights[@pointLightCount];
|
||||||
|
uniform int omw_PointLightsCount;
|
||||||
|
|
||||||
|
int omw_GetPointLightCount()
|
||||||
|
{
|
||||||
|
return omw_PointLightsCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 omw_GetPointLightViewPos(int index)
|
||||||
|
{
|
||||||
|
return omw_PointLights[(index * 3)].xyz;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 omw_GetPointLightDiffuse(int index)
|
||||||
|
{
|
||||||
|
return omw_PointLights[(index * 3) + 1].xyz;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 omw_GetPointLightAttenuation(int index)
|
||||||
|
{
|
||||||
|
return omw_PointLights[(index * 3) + 2].xyz;
|
||||||
|
}
|
||||||
|
|
||||||
|
float omw_GetPointLightRadius(int index)
|
||||||
|
{
|
||||||
|
return omw_PointLights[(index * 3) + 2].w;
|
||||||
|
}
|
||||||
|
|
||||||
#if @ubo
|
#if @ubo
|
||||||
layout(std140) uniform _data { _omw_data omw; };
|
layout(std140) uniform _data { _omw_data omw; };
|
||||||
#else
|
#else
|
||||||
|
@ -143,6 +172,7 @@ uniform @builtinSampler omw_SamplerNormals;
|
||||||
extBlock << "#ifdef " << extension << '\n' << "\t#extension " << extension << ": enable" << '\n' << "#endif" << '\n';
|
extBlock << "#ifdef " << extension << '\n' << "\t#extension " << extension << ": enable" << '\n' << "#endif" << '\n';
|
||||||
|
|
||||||
const std::vector<std::pair<std::string,std::string>> defines = {
|
const std::vector<std::pair<std::string,std::string>> defines = {
|
||||||
|
{"@pointLightCount", std::to_string(SceneUtil::PPLightBuffer::sMaxPPLightsArraySize)},
|
||||||
{"@version", std::to_string(technique.getGLSLVersion())},
|
{"@version", std::to_string(technique.getGLSLVersion())},
|
||||||
{"@multiview", Stereo::getMultiview() ? "1" : "0"},
|
{"@multiview", Stereo::getMultiview() ? "1" : "0"},
|
||||||
{"@builtinSampler", Stereo::getMultiview() ? "sampler2DArray" : "sampler2D"},
|
{"@builtinSampler", Stereo::getMultiview() ? "sampler2DArray" : "sampler2D"},
|
||||||
|
|
|
@ -56,5 +56,8 @@ namespace fx
|
||||||
|
|
||||||
std::apply([&] (const auto& ... v) { (setUniform(v) , ...); }, mData.getData());
|
std::apply([&] (const auto& ... v) { (setUniform(v) , ...); }, mData.getData());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mPointLightBuffer)
|
||||||
|
mPointLightBuffer->applyUniforms(nv->getTraversalNumber(), stateset);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <osg/BufferTemplate>
|
#include <osg/BufferTemplate>
|
||||||
|
|
||||||
|
#include <components/sceneutil/lightmanager.hpp>
|
||||||
#include <components/sceneutil/statesetupdater.hpp>
|
#include <components/sceneutil/statesetupdater.hpp>
|
||||||
#include <components/std140/ubo.hpp>
|
#include <components/std140/ubo.hpp>
|
||||||
|
|
||||||
|
@ -86,12 +87,21 @@ namespace fx
|
||||||
|
|
||||||
void setWeatherTransition(float transition) { mData.get<WeatherTransition>() = transition; }
|
void setWeatherTransition(float transition) { mData.get<WeatherTransition>() = transition; }
|
||||||
|
|
||||||
|
void bindPointLights(std::shared_ptr<SceneUtil::PPLightBuffer> buffer)
|
||||||
|
{
|
||||||
|
mPointLightBuffer = buffer;
|
||||||
|
}
|
||||||
|
|
||||||
static std::string getStructDefinition()
|
static std::string getStructDefinition()
|
||||||
{
|
{
|
||||||
static std::string definition = UniformData::getDefinition("_omw_data");
|
static std::string definition = UniformData::getDefinition("_omw_data");
|
||||||
return definition;
|
return definition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setDefaults(osg::StateSet* stateset) override;
|
||||||
|
|
||||||
|
void apply(osg::StateSet* stateset, osg::NodeVisitor* nv) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct ProjectionMatrix : std140::Mat4 { static constexpr std::string_view sName = "projectionMatrix"; };
|
struct ProjectionMatrix : std140::Mat4 { static constexpr std::string_view sName = "projectionMatrix"; };
|
||||||
|
|
||||||
|
@ -180,12 +190,10 @@ namespace fx
|
||||||
IsInterior
|
IsInterior
|
||||||
>;
|
>;
|
||||||
|
|
||||||
private:
|
|
||||||
void setDefaults(osg::StateSet* stateset) override;
|
|
||||||
void apply(osg::StateSet* stateset, osg::NodeVisitor* nv) override;
|
|
||||||
|
|
||||||
UniformData mData;
|
UniformData mData;
|
||||||
bool mUseUBO;
|
bool mUseUBO;
|
||||||
|
|
||||||
|
std::shared_ptr<SceneUtil::PPLightBuffer> mPointLightBuffer;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,7 @@ namespace fx
|
||||||
mValid = false;
|
mValid = false;
|
||||||
mHDR = false;
|
mHDR = false;
|
||||||
mNormals = false;
|
mNormals = false;
|
||||||
|
mLights = false;
|
||||||
mEnabled = true;
|
mEnabled = true;
|
||||||
mPassMap.clear();
|
mPassMap.clear();
|
||||||
mPasses.clear();
|
mPasses.clear();
|
||||||
|
@ -238,6 +239,8 @@ namespace fx
|
||||||
mHDR = parseBool();
|
mHDR = parseBool();
|
||||||
else if (key == "pass_normals")
|
else if (key == "pass_normals")
|
||||||
mNormals = parseBool() && mSupportsNormals;
|
mNormals = parseBool() && mSupportsNormals;
|
||||||
|
else if (key == "pass_lights")
|
||||||
|
mLights = parseBool();
|
||||||
else if (key == "glsl_profile")
|
else if (key == "glsl_profile")
|
||||||
{
|
{
|
||||||
expect<Lexer::String>();
|
expect<Lexer::String>();
|
||||||
|
|
|
@ -129,6 +129,8 @@ namespace fx
|
||||||
|
|
||||||
bool getNormals() const { return mNormals && mSupportsNormals; }
|
bool getNormals() const { return mNormals && mSupportsNormals; }
|
||||||
|
|
||||||
|
bool getLights() const { return mLights; }
|
||||||
|
|
||||||
const PassList& getPasses() { return mPasses; }
|
const PassList& getPasses() { return mPasses; }
|
||||||
|
|
||||||
const TexList& getTextures() const { return mTextures; }
|
const TexList& getTextures() const { return mTextures; }
|
||||||
|
@ -253,6 +255,7 @@ namespace fx
|
||||||
bool mValid;
|
bool mValid;
|
||||||
bool mHDR;
|
bool mHDR;
|
||||||
bool mNormals;
|
bool mNormals;
|
||||||
|
bool mLights;
|
||||||
int mWidth;
|
int mWidth;
|
||||||
int mHeight;
|
int mHeight;
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,9 @@ const float TorsoHeight = 0.75f;
|
||||||
static constexpr float sStepSizeUp = 34.0f;
|
static constexpr float sStepSizeUp = 34.0f;
|
||||||
static constexpr float sMaxSlope = 46.0f;
|
static constexpr float sMaxSlope = 46.0f;
|
||||||
|
|
||||||
|
// Identifier for main scene camera
|
||||||
|
const std::string SceneCamera = "SceneCam";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include <components/misc/hash.hpp>
|
#include <components/misc/hash.hpp>
|
||||||
#include <components/misc/stringops.hpp>
|
#include <components/misc/stringops.hpp>
|
||||||
|
#include <components/misc/constants.hpp>
|
||||||
|
|
||||||
#include <components/debug/debuglog.hpp>
|
#include <components/debug/debuglog.hpp>
|
||||||
|
|
||||||
|
@ -839,6 +840,7 @@ namespace SceneUtil
|
||||||
, mPointLightFadeEnd(copy.mPointLightFadeEnd)
|
, mPointLightFadeEnd(copy.mPointLightFadeEnd)
|
||||||
, mPointLightFadeStart(copy.mPointLightFadeStart)
|
, mPointLightFadeStart(copy.mPointLightFadeStart)
|
||||||
, mMaxLights(copy.mMaxLights)
|
, mMaxLights(copy.mMaxLights)
|
||||||
|
, mPPLightBuffer(copy.mPPLightBuffer)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1001,6 +1003,9 @@ namespace SceneUtil
|
||||||
|
|
||||||
void LightManager::update(size_t frameNum)
|
void LightManager::update(size_t frameNum)
|
||||||
{
|
{
|
||||||
|
if (mPPLightBuffer)
|
||||||
|
mPPLightBuffer->clear(frameNum);
|
||||||
|
|
||||||
getLightIndexMap(frameNum).clear();
|
getLightIndexMap(frameNum).clear();
|
||||||
mLights.clear();
|
mLights.clear();
|
||||||
mLightsInViewSpace.clear();
|
mLightsInViewSpace.clear();
|
||||||
|
@ -1132,6 +1137,17 @@ namespace SceneUtil
|
||||||
l.mLightSource = transform.mLightSource;
|
l.mLightSource = transform.mLightSource;
|
||||||
l.mViewBound = viewBound;
|
l.mViewBound = viewBound;
|
||||||
it->second.push_back(l);
|
it->second.push_back(l);
|
||||||
|
|
||||||
|
if (mPPLightBuffer && it->first->getName() == Constants::SceneCamera)
|
||||||
|
{
|
||||||
|
const auto* light = l.mLightSource->getLight(frameNum);
|
||||||
|
mPPLightBuffer->setLight(frameNum, light->getPosition() * (*viewMatrix),
|
||||||
|
light->getDiffuse(),
|
||||||
|
light->getConstantAttenuation(),
|
||||||
|
light->getLinearAttenuation(),
|
||||||
|
light->getQuadraticAttenuation(),
|
||||||
|
l.mLightSource->getRadius());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1168,6 +1184,14 @@ namespace SceneUtil
|
||||||
return uniform;
|
return uniform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LightManager::setCollectPPLights(bool enabled)
|
||||||
|
{
|
||||||
|
if (enabled)
|
||||||
|
mPPLightBuffer = std::make_shared<PPLightBuffer>();
|
||||||
|
else
|
||||||
|
mPPLightBuffer = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
LightSource::LightSource()
|
LightSource::LightSource()
|
||||||
: mRadius(0.f)
|
: mRadius(0.f)
|
||||||
, mActorFade(1.f)
|
, mActorFade(1.f)
|
||||||
|
|
|
@ -26,6 +26,64 @@ namespace SceneUtil
|
||||||
class LightBuffer;
|
class LightBuffer;
|
||||||
struct StateSetGenerator;
|
struct StateSetGenerator;
|
||||||
|
|
||||||
|
class PPLightBuffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline static constexpr auto sMaxPPLights = 30;
|
||||||
|
inline static constexpr auto sMaxPPLightsArraySize = sMaxPPLights * 3;
|
||||||
|
|
||||||
|
PPLightBuffer()
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < 2; ++i)
|
||||||
|
{
|
||||||
|
mIndex[i] = 0;
|
||||||
|
mUniformBuffers[i] = new osg::Uniform(osg::Uniform::FLOAT_VEC4, "omw_PointLights", sMaxPPLightsArraySize);
|
||||||
|
mUniformCount[i] = new osg::Uniform("omw_PointLightsCount", static_cast<int>(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void applyUniforms(size_t frame, osg::StateSet* stateset)
|
||||||
|
{
|
||||||
|
size_t frameId = frame % 2;
|
||||||
|
|
||||||
|
if (!stateset->getUniform("omw_PointLights"))
|
||||||
|
stateset->addUniform(mUniformBuffers[frameId]);
|
||||||
|
if (!stateset->getUniform("omw_PointLightsCount"))
|
||||||
|
stateset->addUniform(mUniformCount[frameId]);
|
||||||
|
|
||||||
|
mUniformBuffers[frameId]->dirty();
|
||||||
|
mUniformCount[frameId]->dirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear(size_t frame)
|
||||||
|
{
|
||||||
|
mIndex[frame % 2] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setLight(size_t frame, const osg::Vec4f& position, osg::Vec4f diffuse, float ac, float al, float aq, float radius)
|
||||||
|
{
|
||||||
|
size_t frameId = frame % 2;
|
||||||
|
size_t i = mIndex[frameId];
|
||||||
|
|
||||||
|
if (i >= (sMaxPPLights - 1))
|
||||||
|
return;
|
||||||
|
|
||||||
|
i *= 3;
|
||||||
|
|
||||||
|
mUniformBuffers[frameId]->setElement(i + 0, position);
|
||||||
|
mUniformBuffers[frameId]->setElement(i + 1, diffuse);
|
||||||
|
mUniformBuffers[frameId]->setElement(i + 2, osg::Vec4f(ac, al, aq, radius));
|
||||||
|
|
||||||
|
mIndex[frameId]++;
|
||||||
|
mUniformCount[frameId]->set(static_cast<int>(mIndex[frameId]));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::array<size_t, 2> mIndex;
|
||||||
|
std::array<osg::ref_ptr<osg::Uniform>, 2> mUniformBuffers;
|
||||||
|
std::array<osg::ref_ptr<osg::Uniform>, 2> mUniformCount;
|
||||||
|
};
|
||||||
|
|
||||||
enum class LightingMethod
|
enum class LightingMethod
|
||||||
{
|
{
|
||||||
FFP,
|
FFP,
|
||||||
|
@ -227,6 +285,11 @@ namespace SceneUtil
|
||||||
|
|
||||||
osg::ref_ptr<osg::Uniform> generateLightBufferUniform(const osg::Matrixf& sun);
|
osg::ref_ptr<osg::Uniform> generateLightBufferUniform(const osg::Matrixf& sun);
|
||||||
|
|
||||||
|
// Whether to collect main scene camera points lights into a buffer to be later sent to postprocessing shaders
|
||||||
|
void setCollectPPLights(bool enabled);
|
||||||
|
|
||||||
|
std::shared_ptr<PPLightBuffer> getPPLightsBuffer() { return mPPLightBuffer; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initFFP(int targetLights);
|
void initFFP(int targetLights);
|
||||||
void initPerObjectUniform(int targetLights);
|
void initPerObjectUniform(int targetLights);
|
||||||
|
@ -285,6 +348,8 @@ namespace SceneUtil
|
||||||
static constexpr auto mFFPMaxLights = 8;
|
static constexpr auto mFFPMaxLights = 8;
|
||||||
|
|
||||||
static const std::unordered_map<std::string, LightingMethod> mLightingMethodSettingMap;
|
static const std::unordered_map<std::string, LightingMethod> mLightingMethodSettingMap;
|
||||||
|
|
||||||
|
std::shared_ptr<PPLightBuffer> mPPLightBuffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// To receive lighting, objects must be decorated by a LightListCallback. Light list callbacks must be added via
|
/// To receive lighting, objects must be decorated by a LightListCallback. Light list callbacks must be added via
|
||||||
|
|
Loading…
Reference in a new issue