Hi everyone,
I ran into the very same problem, which seems to remain in the svn/trunk branch
of the project at least.
Follows as attachment a small program showing the issue: it only consists of a
basic scene where one should be able to turn an overriding shader program on
and off with the up and down keys respectively.
While the overriding shader does update the rendering once added, its removal
seems to corrupt the state graph (transform matrices are then erroneous and the
removed shading still active).
I am running the OSG code from the svn/trunk, compiled with VC11 on Windows 7
64bits.
Is there any workaround ? Thanks in advance. :)
Cheers!
------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=60045#60045
#include <iostream>
#include <osg/MatrixTransform>
#include <osg/ShapeDrawable>
#include <osgViewer/Viewer>
using namespace osg;
using namespace osgViewer;
using namespace osgGA;
ref_ptr<Program> redProgram = nullptr;
ref_ptr<Program> greenProgram = nullptr;
ref_ptr<Program> normalProgram = nullptr;
void
initializePrograms();
void
initializeCamera(Camera*);
ref_ptr<Node>
initializeScene();
class ShaderSwitch: public GUIEventHandler
{
private:
ref_ptr<Node> _node;
bool _activated;
public:
ShaderSwitch(Node* node): _node(node), _activated(false) {}
bool
handle(const GUIEventAdapter&, GUIActionAdapter&);
};
int
main(int argc, char** argv)
{
Viewer viewer;
ref_ptr<Node> scene = initializeScene();
initializeCamera(viewer.getCamera());
viewer.setSceneData(scene.get());
viewer.addEventHandler(new ShaderSwitch(scene.get()));
return viewer.run();
}
void
initializeCamera(Camera* camera)
{
const unsigned int W = 800;
const unsigned int H = 600;
ref_ptr<GraphicsContext::Traits> traits = new GraphicsContext::Traits();
traits->x = 50;
traits->y = 50;
traits->width = W;
traits->height = H;
traits->doubleBuffer = true;
traits->windowDecoration = true;
traits->glContextVersion = "3.1";
ref_ptr<GraphicsContext> context =
GraphicsContext::createGraphicsContext(traits.get());
context->getState()->setUseModelViewAndProjectionUniforms(true);
context->getState()->setUseVertexAttributeAliasing(true);
camera->setGraphicsContext(context.get());
camera->setViewport(0, 0, W, H);
camera->setProjectionMatrixAsPerspective(45.0, W/double(H), 1e-3, 1e+6);
}
ref_ptr<Node>
initializeScene()
{
initializePrograms();
ref_ptr<Group> scene = new Group();
ref_ptr<MatrixTransform> groupSphere = new MatrixTransform();
ref_ptr<MatrixTransform> groupCone = new MatrixTransform();
ref_ptr<Geode> geodeSphere = new Geode();
ref_ptr<Geode> geodeCone = new Geode();
ref_ptr<ShapeDrawable> sphere = new ShapeDrawable(new
Sphere());
ref_ptr<ShapeDrawable> cone = new ShapeDrawable(new
Cone());
sphere->getOrCreateStateSet()->setAttribute(redProgram);
cone->getOrCreateStateSet()->setAttribute(greenProgram);
scene->setName("scene");
groupSphere->setName("groupSphere");
groupCone->setName("groupCone");
geodeSphere->setName("geodeSphere");
geodeCone->setName("geodeCone");
sphere->setName("sphere");
cone->setName("cone");
groupSphere->setMatrix(Matrix::translate(-5.0f, 0.0f, -5.0f));
groupCone->setMatrix(Matrix::translate(5.0f, 0.0f, -5.0f));
geodeSphere->addDrawable(sphere.get());
geodeCone->addDrawable(cone.get());
groupSphere->addChild(geodeSphere.get());
groupCone->addChild(geodeCone.get());
scene->addChild(groupSphere.get());
scene->addChild(groupCone.get());
return scene;
}
void
initializePrograms()
{
const std::string vertexSource =
"#version 140 \n"
"uniform mat4 osg_ModelViewProjectionMatrix; \n"
"uniform mat3 osg_NormalMatrix; \n"
"in vec4 osg_Vertex; \n"
"in vec3 osg_Normal; \n"
"out vec3 vNormal; \n"
"\n"
"void main() \n"
"{ \n"
" vNormal = normalize( osg_NormalMatrix * osg_Normal ); \n"
" gl_Position = osg_ModelViewProjectionMatrix * osg_Vertex; \n"
"} \n";
const std::string redFragmentSource =
"#version 140 \n"
"out vec4 fragData; \n"
" \n"
"void main() \n"
"{ \n"
" fragData = vec4(1.0, 0.0, 0.0, 1.0); \n"
"} \n";
const std::string greenFragmentSource =
"#version 140 \n"
"out vec4 fragData; \n"
" \n"
"void main() \n"
"{ \n"
" fragData = vec4(0.0, 1.0, 0.0, 1.0); \n"
"} \n";
const std::string normalFragmentSource =
"#version 140 \n"
"in vec3 vNormal; \n"
"out vec4 fragData; \n"
" \n"
"void main() \n"
"{ \n"
" fragData = vec4(0.5 * normalize(vNormal) + 0.5, 0.5); \n"
"} \n";
osg::Shader* vShader = new osg::Shader(osg::Shader::VERTEX,
vertexSource);
osg::Shader* fRedShader = new
osg::Shader(osg::Shader::FRAGMENT, redFragmentSource);
osg::Shader* fGreenShader = new
osg::Shader(osg::Shader::FRAGMENT, greenFragmentSource);
osg::Shader* fNormalShader = new
osg::Shader(osg::Shader::FRAGMENT, normalFragmentSource);
redProgram = new Program();
greenProgram = new Program();
normalProgram = new Program();
redProgram->addShader(vShader);
redProgram->addShader(fRedShader);
greenProgram->addShader(vShader);
greenProgram->addShader(fGreenShader);
normalProgram->addShader(vShader);
normalProgram->addShader(fNormalShader);
}
bool
ShaderSwitch::handle(const GUIEventAdapter& ea, GUIActionAdapter&)
{
if (!_node)
return false;
if (ea.getEventType() != GUIEventAdapter::KEYUP)
return false;
if (ea.getKey() == GUIEventAdapter::KEY_Up && !_activated)
{
std::cout << "set overriding normal shader program" <<
std::endl;
_node->getOrCreateStateSet()->setAttribute(normalProgram.get(),
StateAttribute::ON | StateAttribute::OVERRIDE);
//_node->getOrCreateStateSet()->setAttributeAndModes(normalProgram.get(),
StateAttribute::ON | StateAttribute::OVERRIDE); // same result
_activated = true;
return true;
}
else if (ea.getKey() == GUIEventAdapter::KEY_Down && _activated)
{
std::cout << "unset overriding normal shader program" <<
std::endl;
_node->getOrCreateStateSet()->removeAttribute(normalProgram);
//_node->getOrCreateStateSet()->removeAttribute(StateAttribute::PROGRAM, 0); //
same result
_activated = false;
return true;
}
return false;
}_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org