OpenCS: port lighting toolbar, fix multiple context GL objects issue

pull/638/head
scrawl 10 years ago
parent c5fd92fde1
commit 232e34bddd

@ -1,10 +1,13 @@
#ifndef OPENCS_VIEW_LIGHTING_H
#define OPENCS_VIEW_LIGHTING_H
namespace Ogre
namespace osgViewer
{
class SceneManager;
class ColourValue;
class View;
}
namespace osg
{
class Vec4f;
}
namespace CSVRender
@ -15,12 +18,12 @@ namespace CSVRender
virtual ~Lighting();
virtual void activate (Ogre::SceneManager *sceneManager,
const Ogre::ColourValue *defaultAmbient = 0) = 0;
virtual void activate (osgViewer::View* view,
const osg::Vec4f *defaultAmbient = 0) = 0;
virtual void deactivate() = 0;
virtual void setDefaultAmbient (const Ogre::ColourValue& colour) = 0;
virtual void setDefaultAmbient (const osg::Vec4f& colour) = 0;
};
}

@ -3,28 +3,28 @@
#include <OgreSceneManager.h>
CSVRender::LightingBright::LightingBright() : mSceneManager (0), mLight (0) {}
#include <osgViewer/View>
void CSVRender::LightingBright::activate (Ogre::SceneManager *sceneManager,
const Ogre::ColourValue *defaultAmbient)
CSVRender::LightingBright::LightingBright() : mView(NULL) {}
void CSVRender::LightingBright::activate (osgViewer::View* view,
const osg::Vec4f* /*defaultAmbient*/)
{
mSceneManager = sceneManager;
mView = view;
// FIXME: ambient should be applied to LightModel instead of the light
mSceneManager->setAmbientLight (Ogre::ColourValue (1.0, 1.0, 1.0, 1));
osg::ref_ptr<osg::Light> light (new osg::Light);
light->setConstantAttenuation(1.f);
light->setDirection(osg::Vec3f(0.f, 0.f, -1.f));
light->setDiffuse(osg::Vec4f(1.f, 1.f, 1.f, 1.f));
light->setAmbient(osg::Vec4f(1.f, 1.f, 1.f, 1.f));
mLight = mSceneManager->createLight();
mLight->setType (Ogre::Light::LT_DIRECTIONAL);
mLight->setDirection (Ogre::Vector3 (0, 0, -1));
mLight->setDiffuseColour (Ogre::ColourValue (1.0, 1.0, 1.0));
mView->setLight(light);
}
void CSVRender::LightingBright::deactivate()
{
if (mLight)
{
mSceneManager->destroyLight (mLight);
mLight = 0;
}
}
void CSVRender::LightingBright::setDefaultAmbient (const Ogre::ColourValue& colour) {}
void CSVRender::LightingBright::setDefaultAmbient (const osg::Vec4f& colour) {}

@ -12,19 +12,18 @@ namespace CSVRender
{
class LightingBright : public Lighting
{
Ogre::SceneManager *mSceneManager;
Ogre::Light *mLight;
osgViewer::View* mView;
public:
LightingBright();
virtual void activate (Ogre::SceneManager *sceneManager,
const Ogre::ColourValue *defaultAmbient = 0);
virtual void activate (osgViewer::View* view,
const osg::Vec4f *defaultAmbient = 0);
virtual void deactivate();
virtual void setDefaultAmbient (const Ogre::ColourValue& colour);
virtual void setDefaultAmbient (const osg::Vec4f& colour);
};
}

@ -1,36 +1,33 @@
#include "lightingday.hpp"
#include <OgreSceneManager.h>
#include <osgViewer/View>
CSVRender::LightingDay::LightingDay() : mSceneManager (0), mLight (0) {}
CSVRender::LightingDay::LightingDay() : mView(NULL) {}
void CSVRender::LightingDay::activate (Ogre::SceneManager *sceneManager,
const Ogre::ColourValue *defaultAmbient)
void CSVRender::LightingDay::activate (osgViewer::View* view,
const osg::Vec4f *defaultAmbient)
{
mSceneManager = sceneManager;
mView = view;
osg::ref_ptr<osg::Light> light (new osg::Light);
light->setDirection(osg::Vec3f(0.f, 0.f, -1.f));
light->setDiffuse(osg::Vec4f(1.f, 1.f, 1.f, 1.f));
light->setConstantAttenuation(1.f);
if (defaultAmbient)
mSceneManager->setAmbientLight (*defaultAmbient);
light->setAmbient(*defaultAmbient);
else
mSceneManager->setAmbientLight (Ogre::ColourValue (0.7, 0.7, 0.7, 1));
light->setAmbient(osg::Vec4f(0.7f, 0.7f, 0.7f, 1.f));
mLight = mSceneManager->createLight();
mLight->setType (Ogre::Light::LT_DIRECTIONAL);
mLight->setDirection (Ogre::Vector3 (0, 0, -1));
mLight->setDiffuseColour (Ogre::ColourValue (1, 1, 1));
mView->setLight(light);
}
void CSVRender::LightingDay::deactivate()
{
if (mLight)
{
mSceneManager->destroyLight (mLight);
mLight = 0;
}
}
void CSVRender::LightingDay::setDefaultAmbient (const Ogre::ColourValue& colour)
void CSVRender::LightingDay::setDefaultAmbient (const osg::Vec4f& colour)
{
mSceneManager->setAmbientLight (colour);
if (mView)
mView->getLight()->setAmbient(colour);
}

@ -12,19 +12,18 @@ namespace CSVRender
{
class LightingDay : public Lighting
{
Ogre::SceneManager *mSceneManager;
Ogre::Light *mLight;
osgViewer::View* mView;
public:
LightingDay();
virtual void activate (Ogre::SceneManager *sceneManager,
const Ogre::ColourValue *defaultAmbient = 0);
virtual void activate (osgViewer::View* view,
const osg::Vec4f *defaultAmbient = 0);
virtual void deactivate();
virtual void setDefaultAmbient (const Ogre::ColourValue& colour);
virtual void setDefaultAmbient (const osg::Vec4f& colour);
};
}

@ -1,36 +1,33 @@
#include "lightingnight.hpp"
#include <OgreSceneManager.h>
#include <osgViewer/View>
CSVRender::LightingNight::LightingNight() : mSceneManager (0), mLight (0) {}
CSVRender::LightingNight::LightingNight() : mView(NULL) {}
void CSVRender::LightingNight::activate (Ogre::SceneManager *sceneManager,
const Ogre::ColourValue *defaultAmbient)
void CSVRender::LightingNight::activate (osgViewer::View* view,
const osg::Vec4f *defaultAmbient)
{
mSceneManager = sceneManager;
mView = view;
osg::ref_ptr<osg::Light> light (new osg::Light);
light->setDirection(osg::Vec3f(0.f, 0.f, -1.f));
light->setDiffuse(osg::Vec4f(0.2f, 0.2f, 0.2f, 1.f));
light->setConstantAttenuation(1.f);
if (defaultAmbient)
mSceneManager->setAmbientLight (*defaultAmbient);
light->setAmbient(*defaultAmbient);
else
mSceneManager->setAmbientLight (Ogre::ColourValue (0.2, 0.2, 0.2, 1));
light->setAmbient(osg::Vec4f(0.2f, 0.2f, 0.2f, 1.f));
mLight = mSceneManager->createLight();
mLight->setType (Ogre::Light::LT_DIRECTIONAL);
mLight->setDirection (Ogre::Vector3 (0, 0, -1));
mLight->setDiffuseColour (Ogre::ColourValue (0.2, 0.2, 0.2));
mView->setLight(light);
}
void CSVRender::LightingNight::deactivate()
{
if (mLight)
{
mSceneManager->destroyLight (mLight);
mLight = 0;
}
}
void CSVRender::LightingNight::setDefaultAmbient (const Ogre::ColourValue& colour)
void CSVRender::LightingNight::setDefaultAmbient (const osg::Vec4f& colour)
{
mSceneManager->setAmbientLight (colour);
if (mView)
mView->getLight()->setAmbient(colour);
}

@ -12,19 +12,18 @@ namespace CSVRender
{
class LightingNight : public Lighting
{
Ogre::SceneManager *mSceneManager;
Ogre::Light *mLight;
osgViewer::View* mView;
public:
LightingNight();
virtual void activate (Ogre::SceneManager *sceneManager,
const Ogre::ColourValue *defaultAmbient = 0);
virtual void activate (osgViewer::View* view,
const osg::Vec4f *defaultAmbient = 0);
virtual void deactivate();
virtual void setDefaultAmbient (const Ogre::ColourValue& colour);
virtual void setDefaultAmbient (const osg::Vec4f& colour);
};
}

@ -8,7 +8,7 @@
CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data,
const std::string& id, bool referenceable, QWidget *parent)
: SceneWidget (parent), mData (data), mObject(data, mRootNode, id, referenceable)
: SceneWidget (data.getResourceSystem()->getSceneManager(), parent), mData (data), mObject(data, mRootNode, id, referenceable)
{
mView->setCameraManipulator(new osgGA::TrackballManipulator);

@ -6,21 +6,23 @@
#include <QShortcut>
#include <QLayout>
#include <osgQt/GraphicsWindowQt>
#include <osg/GraphicsContext>
#include <osgViewer/CompositeViewer>
#include <osgViewer/ViewerEventHandlers>
#include <components/resource/scenemanager.hpp>
#include "../widget/scenetoolmode.hpp"
#include "../../model/settings/usersettings.hpp"
#include "navigation.hpp"
#include "lighting.hpp"
#include <osgQt/GraphicsWindowQt>
#include <osg/GraphicsContext>
#include <osgViewer/CompositeViewer>
#include <osgViewer/ViewerEventHandlers>
namespace CSVRender
{
SceneWidget::SceneWidget(QWidget *parent, Qt::WindowFlags f)
RenderWidget::RenderWidget(QWidget *parent, Qt::WindowFlags f)
: QWidget(parent, f)
, mRootNode(0)
{
@ -58,9 +60,8 @@ SceneWidget::SceneWidget(QWidget *parent, Qt::WindowFlags f)
mView->getCamera()->setProjectionMatrixAsPerspective(30.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 1.0f, 10000.0f );
mRootNode = new osg::Group;
// TODO: move to utility file
mRootNode->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
mRootNode->getOrCreateStateSet()->setMode(GL_CULL_FACE, osg::StateAttribute::ON);
addDefaultRootState(mRootNode->getOrCreateStateSet());
mView->setSceneData(mRootNode);
@ -74,22 +75,30 @@ SceneWidget::SceneWidget(QWidget *parent, Qt::WindowFlags f)
viewer.realize();
}
SceneWidget::~SceneWidget()
void RenderWidget::addDefaultRootState(osg::StateSet* stateset)
{
stateset->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
stateset->setMode(GL_CULL_FACE, osg::StateAttribute::ON);
}
RenderWidget::~RenderWidget()
{
CompositeViewer::get().removeView(mView);
}
void SceneWidget::flagAsModified()
void RenderWidget::flagAsModified()
{
mView->requestRedraw();
}
void SceneWidget::setVisibilityMask(int mask)
void RenderWidget::setVisibilityMask(int mask)
{
// 0x1 reserved for separating cull and update visitors
mView->getCamera()->setCullMask(mask<<1);
}
// --------------------------------------------------
CompositeViewer::CompositeViewer()
{
#if QT_VERSION >= 0x050000
@ -109,7 +118,7 @@ CompositeViewer::CompositeViewer()
setRunFrameScheme(osgViewer::ViewerBase::CONTINUOUS);
connect( &mTimer, SIGNAL(timeout()), this, SLOT(update()) );
mTimer.start( 0 );
mTimer.start( 10 );
}
CompositeViewer &CompositeViewer::get()
@ -123,4 +132,80 @@ void CompositeViewer::update()
frame();
}
// ---------------------------------------------------
SceneWidget::SceneWidget(Resource::SceneManager* sceneManager, QWidget *parent, Qt::WindowFlags f)
: RenderWidget(parent, f)
, mSceneManager(sceneManager)
, mLighting(NULL)
{
//mView->setLightingMode(osgViewer::View::NO_LIGHT);
setLighting(&mLightingDay);
}
SceneWidget::~SceneWidget()
{
// Since we're holding on to the scene templates past the existance of this graphics context, we'll need to manually release the created objects
mSceneManager->releaseGLObjects(mView->getCamera()->getGraphicsContext()->getState());
}
void SceneWidget::setLighting(Lighting *lighting)
{
if (mLighting)
mLighting->deactivate();
mLighting = lighting;
mLighting->activate (mView.get(), mHasDefaultAmbient ? &mDefaultAmbient : 0);
flagAsModified();
}
void SceneWidget::selectLightingMode (const std::string& mode)
{
if (mode=="day")
setLighting (&mLightingDay);
else if (mode=="night")
setLighting (&mLightingNight);
else if (mode=="bright")
setLighting (&mLightingBright);
}
CSVWidget::SceneToolMode *SceneWidget::makeLightingSelector (CSVWidget::SceneToolbar *parent)
{
CSVWidget::SceneToolMode *tool = new CSVWidget::SceneToolMode (parent, "Lighting Mode");
/// \todo replace icons
tool->addButton (":scenetoolbar/day", "day",
"Day"
"<ul><li>Cell specific ambient in interiors</li>"
"<li>Low ambient in exteriors</li>"
"<li>Strong directional light source</li>"
"<li>This mode closely resembles day time in-game</li></ul>");
tool->addButton (":scenetoolbar/night", "night",
"Night"
"<ul><li>Cell specific ambient in interiors</li>"
"<li>Low ambient in exteriors</li>"
"<li>Weak directional light source</li>"
"<li>This mode closely resembles night time in-game</li></ul>");
tool->addButton (":scenetoolbar/bright", "bright",
"Bright"
"<ul><li>Maximum ambient</li>"
"<li>Strong directional light source</li></ul>");
connect (tool, SIGNAL (modeChanged (const std::string&)),
this, SLOT (selectLightingMode (const std::string&)));
return tool;
}
void SceneWidget::setDefaultAmbient (const osg::Vec4f& colour)
{
mDefaultAmbient = colour;
mHasDefaultAmbient = true;
if (mLighting)
mLighting->setDefaultAmbient (colour);
}
}

@ -11,6 +11,11 @@
#include <osgViewer/View>
#include <osgViewer/CompositeViewer>
namespace Resource
{
class SceneManager;
}
namespace osg
{
class Group;
@ -27,13 +32,13 @@ namespace CSVRender
class Navigation;
class Lighting;
class SceneWidget : public QWidget
class RenderWidget : public QWidget
{
Q_OBJECT
public:
SceneWidget(QWidget* parent = 0, Qt::WindowFlags f = 0);
~SceneWidget();
RenderWidget(QWidget* parent = 0, Qt::WindowFlags f = 0);
virtual ~RenderWidget();
void flagAsModified();
@ -41,6 +46,8 @@ namespace CSVRender
protected:
void addDefaultRootState(osg::StateSet* stateset);
osg::ref_ptr<osgViewer::View> mView;
osg::Group* mRootNode;
@ -48,6 +55,39 @@ namespace CSVRender
QTimer mTimer;
};
// Extension of RenderWidget to support lighting mode selection & toolbar
class SceneWidget : public RenderWidget
{
Q_OBJECT
public:
SceneWidget(Resource::SceneManager* sceneManager, QWidget* parent = 0, Qt::WindowFlags f = 0);
virtual ~SceneWidget();
CSVWidget::SceneToolMode *makeLightingSelector (CSVWidget::SceneToolbar *parent);
///< \attention The created tool is not added to the toolbar (via addTool). Doing that
/// is the responsibility of the calling function.
void setDefaultAmbient (const osg::Vec4f& colour);
///< \note The actual ambient colour may differ based on lighting settings.
protected:
void setLighting (Lighting *lighting);
///< \attention The ownership of \a lighting is not transferred to *this.
Resource::SceneManager* mSceneManager;
Lighting* mLighting;
osg::Vec4f mDefaultAmbient;
bool mHasDefaultAmbient;
LightingDay mLightingDay;
LightingNight mLightingNight;
LightingBright mLightingBright;
private slots:
void selectLightingMode (const std::string& mode);
};
// There are rendering glitches when using multiple Viewer instances, work around using CompositeViewer with multiple views

@ -23,9 +23,12 @@ void CSVRender::UnpagedWorldspaceWidget::update()
const CSMWorld::Record<CSMWorld::Cell>& record =
dynamic_cast<const CSMWorld::Record<CSMWorld::Cell>&> (mCellsModel->getRecord (mCellId));
Ogre::ColourValue colour;
colour.setAsABGR (record.get().mAmbi.mAmbient);
//setDefaultAmbient (colour);
ESM::Color clr = record.get().mAmbi.mAmbient;
osg::Vec4f colour(((clr >> 0) & 0xFF) / 255.0f,
((clr >> 8) & 0xFF) / 255.0f,
((clr >> 16) & 0xFF) / 255.0f, 1.f);
setDefaultAmbient (colour);
/// \todo deal with mSunlight and mFog/mForDensity
@ -51,7 +54,6 @@ CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string&
mCell.reset (new Cell (document.getData(), mRootNode, mCellId));
mView->setCameraManipulator(new osgGA::TrackballManipulator);
//mView->setCameraManipulator(new osgGA::FirstPersonManipulator);
}
void CSVRender::UnpagedWorldspaceWidget::cellDataChanged (const QModelIndex& topLeft,
@ -93,7 +95,7 @@ bool CSVRender::UnpagedWorldspaceWidget::handleDrop (const std::vector<CSMWorld:
return false;
mCellId = data.begin()->getId();
// FIXME: we shouldn't need to rebuild the whole cell
mCell.reset (new Cell (getDocument().getData(), mRootNode, mCellId));
update();

@ -19,7 +19,7 @@
#include "editmode.hpp"
CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent)
: SceneWidget (parent), mDocument(document), mSceneElements(0), mRun(0),
: SceneWidget (document.getData().getResourceSystem()->getSceneManager(), parent), mDocument(document), mSceneElements(0), mRun(0),
mInteractionMask (0)
{
setAcceptDrops(true);
@ -361,7 +361,7 @@ void CSVRender::WorldspaceWidget::mouseMoveEvent (QMouseEvent *event)
{
//mMouse->mouseMoveEvent(event);
}
SceneWidget::mouseMoveEvent(event);
RenderWidget::mouseMoveEvent(event);
}
void CSVRender::WorldspaceWidget::mousePressEvent (QMouseEvent *event)
@ -386,7 +386,7 @@ void CSVRender::WorldspaceWidget::mouseReleaseEvent (QMouseEvent *event)
*/
//mMouse->mouseReleaseEvent(event);
}
SceneWidget::mouseReleaseEvent(event);
RenderWidget::mouseReleaseEvent(event);
}
void CSVRender::WorldspaceWidget::mouseDoubleClickEvent (QMouseEvent *event)
@ -401,7 +401,7 @@ void CSVRender::WorldspaceWidget::mouseDoubleClickEvent (QMouseEvent *event)
void CSVRender::WorldspaceWidget::wheelEvent (QWheelEvent *event)
{
//if(!mMouse->wheelEvent(event))
SceneWidget::wheelEvent(event);
RenderWidget::wheelEvent(event);
}
void CSVRender::WorldspaceWidget::keyPressEvent (QKeyEvent *event)
@ -411,5 +411,5 @@ void CSVRender::WorldspaceWidget::keyPressEvent (QKeyEvent *event)
//mMouse->cancelDrag();
}
else
SceneWidget::keyPressEvent(event);
RenderWidget::keyPressEvent(event);
}

@ -30,8 +30,8 @@ CSVWorld::PreviewSubView::PreviewSubView (const CSMWorld::UniversalId& id, CSMDo
CSVWidget::SceneToolbar *toolbar = new CSVWidget::SceneToolbar (48+6, this);
//CSVWidget::SceneToolMode *lightingTool = mScene->makeLightingSelector (toolbar);
//toolbar->addTool (lightingTool);
CSVWidget::SceneToolMode *lightingTool = mScene->makeLightingSelector (toolbar);
toolbar->addTool (lightingTool);
layout->addWidget (toolbar, 0);

@ -107,8 +107,8 @@ CSVWidget::SceneToolbar* CSVWorld::SceneSubView::makeToolbar (CSVRender::Worldsp
CSVWidget::SceneToolMode *navigationTool = widget->makeNavigationSelector (toolbar);
toolbar->addTool (navigationTool);
//CSVWidget::SceneToolMode *lightingTool = widget->makeLightingSelector (toolbar);
//toolbar->addTool (lightingTool);
CSVWidget::SceneToolMode *lightingTool = widget->makeLightingSelector (toolbar);
toolbar->addTool (lightingTool);
CSVWidget::SceneToolToggle2 *sceneVisibilityTool =
widget->makeSceneVisibilitySelector (toolbar);

@ -13,7 +13,7 @@ struct TimeStamp
};
// Pixel color value. Standard four-byte rr,gg,bb,aa format.
typedef int32_t Color;
typedef uint32_t Color;
enum Specialization
{

@ -115,4 +115,12 @@ namespace Resource
instance->accept(visitor);
}
void SceneManager::releaseGLObjects(osg::State *state)
{
for (Index::iterator it = mIndex.begin(); it != mIndex.end(); ++it)
{
it->second->releaseGLObjects(state);
}
}
}

@ -41,6 +41,8 @@ namespace Resource
/// @note Assumes the given instance was not attached to any parents before.
void attachTo(osg::Node* instance, osg::Group* parentNode) const;
void releaseGLObjects(osg::State* state);
private:
const VFS::Manager* mVFS;
Resource::TextureManager* mTextureManager;

Loading…
Cancel
Save