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 {
osgMyGUI::RenderManager *mParent;
osg::ref_ptr<osg::StateSet> mStateSet;
public:
// Stage 0: update widget animations and controllers. Run during the Update traversal.
class FrameUpdate : public osg::Drawable::UpdateCallback
@ -101,6 +104,10 @@ class Drawable : public osg::Drawable {
virtual void drawImplementation(osg::RenderInfo &renderInfo) const
{
osg::State *state = renderInfo.getState();
state->pushStateSet(mStateSet);
state->apply();
state->disableAllVertexArrays();
state->setClientActiveTextureUnit(0);
glEnableClientState(GL_VERTEX_ARRAY);
@ -113,6 +120,13 @@ class Drawable : public osg::Drawable {
{
const Batch& batch = *it;
osg::VertexBufferObject *vbo = batch.mVertexBuffer;
if (batch.mStateSet)
{
state->pushStateSet(batch.mStateSet);
state->apply();
}
osg::Texture2D* texture = batch.mTexture;
if(texture)
state->applyTextureAttribute(0, texture);
@ -135,12 +149,20 @@ class Drawable : public osg::Drawable {
}
glDrawArrays(GL_TRIANGLES, 0, batch.mVertexCount);
if (batch.mStateSet)
{
state->popStateSet();
state->apply();
}
}
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
state->popStateSet();
state->unbindVertexBufferObject();
state->dirtyAllVertexArrays();
state->disableAllVertexArrays();
@ -161,10 +183,17 @@ public:
osg::ref_ptr<FrameUpdate> frameUpdate = new FrameUpdate;
frameUpdate->setRenderManager(mParent);
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)
: osg::Drawable(copy, copyop)
, mParent(copy.mParent)
, mStateSet(copy.mStateSet)
, mWriteTo(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
osg::ref_ptr<osg::UByteArray> mArray;
// optional
osg::ref_ptr<osg::StateSet> mStateSet;
size_t mVertexCount;
};
@ -321,6 +353,7 @@ RenderManager::RenderManager(osgViewer::Viewer *viewer, osg::Group *sceneroot, R
, mUpdate(false)
, mIsInitialise(false)
, mInvScalingFactor(1.f)
, mInjectState(NULL)
{
if (scalingFactor != 0.f)
mInvScalingFactor = 1.f / scalingFactor;
@ -364,12 +397,6 @@ void RenderManager::initialise()
camera->setViewMatrix(osg::Matrix::identity());
camera->setRenderOrder(osg::Camera::POST_RENDER);
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);
camera->addChild(geode.get());
@ -418,10 +445,17 @@ void RenderManager::doRender(MyGUI::IVertexBuffer *buffer, MyGUI::ITexture *text
if (batch.mTexture->getDataVariance() == osg::Object::DYNAMIC)
mDrawable->setDataVariance(osg::Object::DYNAMIC); // only for this frame, reset in begin()
}
if (mInjectState)
batch.mStateSet = mInjectState;
mDrawable->addBatch(batch);
}
void RenderManager::setInjectState(osg::StateSet* stateSet)
{
mInjectState = stateSet;
}
void RenderManager::end()
{
}

@ -20,6 +20,7 @@ namespace osg
class Group;
class Camera;
class RenderInfo;
class StateSet;
}
namespace osgMyGUI
@ -48,6 +49,8 @@ class RenderManager : public MyGUI::RenderManager, public MyGUI::IRenderTarget
float mInvScalingFactor;
osg::StateSet* mInjectState;
void destroyAllResources();
public:
@ -95,6 +98,9 @@ public:
/** @see IRenderTarget::doRender */
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 */
virtual const MyGUI::RenderTargetInfo& getInfo() { return mInfo; }

Loading…
Cancel
Save