osgMyGUI: add support for layers to insert custom rendering state

openmw-37
scrawl 9 years ago
parent 13c7235b6b
commit 7ff168b787

@ -45,6 +45,9 @@ namespace osgMyGUI
class Drawable : public osg::Drawable { class Drawable : public osg::Drawable {
osgMyGUI::RenderManager *mParent; osgMyGUI::RenderManager *mParent;
osg::ref_ptr<osg::StateSet> mStateSet;
public:
// Stage 0: update widget animations and controllers. Run during the Update traversal. // Stage 0: update widget animations and controllers. Run during the Update traversal.
class FrameUpdate : public osg::Drawable::UpdateCallback class FrameUpdate : public osg::Drawable::UpdateCallback
@ -101,6 +104,10 @@ class Drawable : public osg::Drawable {
virtual void drawImplementation(osg::RenderInfo &renderInfo) const virtual void drawImplementation(osg::RenderInfo &renderInfo) const
{ {
osg::State *state = renderInfo.getState(); osg::State *state = renderInfo.getState();
state->pushStateSet(mStateSet);
state->apply();
state->disableAllVertexArrays(); state->disableAllVertexArrays();
state->setClientActiveTextureUnit(0); state->setClientActiveTextureUnit(0);
glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_VERTEX_ARRAY);
@ -113,6 +120,13 @@ class Drawable : public osg::Drawable {
{ {
const Batch& batch = *it; const Batch& batch = *it;
osg::VertexBufferObject *vbo = batch.mVertexBuffer; osg::VertexBufferObject *vbo = batch.mVertexBuffer;
if (batch.mStateSet)
{
state->pushStateSet(batch.mStateSet);
state->apply();
}
osg::Texture2D* texture = batch.mTexture; osg::Texture2D* texture = batch.mTexture;
if(texture) if(texture)
state->applyTextureAttribute(0, texture); state->applyTextureAttribute(0, texture);
@ -135,12 +149,20 @@ class Drawable : public osg::Drawable {
} }
glDrawArrays(GL_TRIANGLES, 0, batch.mVertexCount); glDrawArrays(GL_TRIANGLES, 0, batch.mVertexCount);
if (batch.mStateSet)
{
state->popStateSet();
state->apply();
}
} }
glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_COLOR_ARRAY);
state->popStateSet();
state->unbindVertexBufferObject(); state->unbindVertexBufferObject();
state->dirtyAllVertexArrays(); state->dirtyAllVertexArrays();
state->disableAllVertexArrays(); state->disableAllVertexArrays();
@ -161,10 +183,17 @@ public:
osg::ref_ptr<FrameUpdate> frameUpdate = new FrameUpdate; osg::ref_ptr<FrameUpdate> frameUpdate = new FrameUpdate;
frameUpdate->setRenderManager(mParent); frameUpdate->setRenderManager(mParent);
setUpdateCallback(frameUpdate); setUpdateCallback(frameUpdate);
mStateSet = new osg::StateSet;
mStateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
mStateSet->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON);
mStateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
mStateSet->setMode(GL_BLEND, osg::StateAttribute::ON);
} }
Drawable(const Drawable &copy, const osg::CopyOp &copyop=osg::CopyOp::SHALLOW_COPY) Drawable(const Drawable &copy, const osg::CopyOp &copyop=osg::CopyOp::SHALLOW_COPY)
: osg::Drawable(copy, copyop) : osg::Drawable(copy, copyop)
, mParent(copy.mParent) , mParent(copy.mParent)
, mStateSet(copy.mStateSet)
, mWriteTo(0) , mWriteTo(0)
, mReadFrom(0) , mReadFrom(0)
{ {
@ -180,6 +209,9 @@ public:
// need to hold on to this too as the mVertexBuffer does not hold a ref to its own array // need to hold on to this too as the mVertexBuffer does not hold a ref to its own array
osg::ref_ptr<osg::UByteArray> mArray; osg::ref_ptr<osg::UByteArray> mArray;
// optional
osg::ref_ptr<osg::StateSet> mStateSet;
size_t mVertexCount; size_t mVertexCount;
}; };
@ -321,6 +353,7 @@ RenderManager::RenderManager(osgViewer::Viewer *viewer, osg::Group *sceneroot, R
, mUpdate(false) , mUpdate(false)
, mIsInitialise(false) , mIsInitialise(false)
, mInvScalingFactor(1.f) , mInvScalingFactor(1.f)
, mInjectState(NULL)
{ {
if (scalingFactor != 0.f) if (scalingFactor != 0.f)
mInvScalingFactor = 1.f / scalingFactor; mInvScalingFactor = 1.f / scalingFactor;
@ -364,12 +397,6 @@ void RenderManager::initialise()
camera->setViewMatrix(osg::Matrix::identity()); camera->setViewMatrix(osg::Matrix::identity());
camera->setRenderOrder(osg::Camera::POST_RENDER); camera->setRenderOrder(osg::Camera::POST_RENDER);
camera->setClearMask(GL_NONE); camera->setClearMask(GL_NONE);
osg::StateSet *state = new osg::StateSet;
state->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON);
state->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
state->setMode(GL_BLEND, osg::StateAttribute::ON);
state->setAttribute(new osg::BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
geode->setStateSet(state);
geode->setCullingActive(false); geode->setCullingActive(false);
camera->addChild(geode.get()); camera->addChild(geode.get());
@ -418,10 +445,17 @@ void RenderManager::doRender(MyGUI::IVertexBuffer *buffer, MyGUI::ITexture *text
if (batch.mTexture->getDataVariance() == osg::Object::DYNAMIC) if (batch.mTexture->getDataVariance() == osg::Object::DYNAMIC)
mDrawable->setDataVariance(osg::Object::DYNAMIC); // only for this frame, reset in begin() mDrawable->setDataVariance(osg::Object::DYNAMIC); // only for this frame, reset in begin()
} }
if (mInjectState)
batch.mStateSet = mInjectState;
mDrawable->addBatch(batch); mDrawable->addBatch(batch);
} }
void RenderManager::setInjectState(osg::StateSet* stateSet)
{
mInjectState = stateSet;
}
void RenderManager::end() void RenderManager::end()
{ {
} }

@ -20,6 +20,7 @@ namespace osg
class Group; class Group;
class Camera; class Camera;
class RenderInfo; class RenderInfo;
class StateSet;
} }
namespace osgMyGUI namespace osgMyGUI
@ -48,6 +49,8 @@ class RenderManager : public MyGUI::RenderManager, public MyGUI::IRenderTarget
float mInvScalingFactor; float mInvScalingFactor;
osg::StateSet* mInjectState;
void destroyAllResources(); void destroyAllResources();
public: public:
@ -95,6 +98,9 @@ public:
/** @see IRenderTarget::doRender */ /** @see IRenderTarget::doRender */
virtual void doRender(MyGUI::IVertexBuffer *buffer, MyGUI::ITexture *texture, size_t count); virtual void doRender(MyGUI::IVertexBuffer *buffer, MyGUI::ITexture *texture, size_t count);
/** specify a StateSet to inject for rendering. The StateSet will be used by future doRender calls until you reset it to NULL again. */
void setInjectState(osg::StateSet* stateSet);
/** @see IRenderTarget::getInfo */ /** @see IRenderTarget::getInfo */
virtual const MyGUI::RenderTargetInfo& getInfo() { return mInfo; } virtual const MyGUI::RenderTargetInfo& getInfo() { return mInfo; }

Loading…
Cancel
Save