Hello,
in the last few day's i posted in the Issue on sharing shaders between
objects thread, that i've trouble in sharing shaders and unfiorms. If
i create two shaders (dot3) and two objects i got the same shader
result on each object.
Now i figured out, that the failure occurs if i use the same code for
the geometry generation of the objects and transform them with
osg::PositionAttitudeTransform on differend positions. It seems too
me, that this transformations are ignored on shader execution. If i
create (simple plane) the transformed object with transformation
values on geometry generation all seems to handled correct ...
Is this a possible bug? Or is this intend and i have to consider
something else?
Best regards,
Chrisitan
P.S.: I've added the manipulated shadertest source where the 2nd quad
has a generated geometry regarding the transformation...
// Copyright (C) 2007 Binary Revolution - http://www.binary-revolution.org
//
// This file is part of ##NAME##.
//
// ##NAME## is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// ##NAME## is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <osg/GraphicsContext>
#include <osg/GLExtensions>
#include <osg/Geometry>
#include <osgGA/GUIEventHandler>
#include <osgGA/TrackballManipulator>
#include <osgDB/WriteFile>
#include <osgDB/ReadFile>
#include "OSGView.h"
#include "OSGCompositeViewer.h"
#include <osgPPU/UnitBypass.h>
#include <osgPPU/UnitText.h>
#include <osgPPU/UnitOut.h>
#include <osg/PositionAttitudeTransform>
#include <osg/Light>
#include <osg/LightSource>
#include <osg/ShapeDrawable>
osg::Light* light;
osg::ref_ptr<osg::PositionAttitudeTransform> sphereXForm;
enum keyCode{KEY_UP = 0xFF52, KEY_DOWN=0xFF54, KEY_LEFT=0xFF51 ,
KEY_RIGHT=0xFF53, KEY_PAGE_DOWN = 0xFF56, KEY_PAGE_UP = 0xFF55};
const float MOVE_VALUE = 0.5f;
/** Update-Callback for light source updates */
class updateLightSource : public osg::Uniform::Callback
{
public:
virtual void operator()
( osg::Uniform* uniform, osg::NodeVisitor* nv )
{
osg::Vec4 pos = light->getPosition();
uniform->set(osg::Vec4(pos.x(), pos.y(), pos.z(), 1.0f));
}
};
/** Update-Callback for light source updates */
class updateCamera : public osg::Uniform::Callback
{
public:
updateCamera(osg::ref_ptr<osg::Camera> camera):m_camera(camera){}
virtual void operator()
( osg::Uniform* uniform, osg::NodeVisitor* nv )
{
osg::Vec3 eye, up, center;
m_camera->getViewMatrixAsLookAt(eye,up,center);
uniform->set(eye);
}
private:
osg::ref_ptr<osg::Camera> m_camera;
};
/** Simple key event handler to move light source */
class myKeyboardEventHandler : public osgGA::GUIEventHandler
{
public:
virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&);
virtual void accept(osgGA::GUIEventHandlerVisitor& v) { v.visit(*this); };
};
bool myKeyboardEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa)
{
switch(ea.getEventType())
{
case(osgGA::GUIEventAdapter::KEYDOWN):
{
switch(ea.getKey())
{
case KEY_UP:
{
osg::Vec4 pos = light->getPosition();
light->setPosition(osg::Vec4(pos.x(), pos.y(), pos.z()+ MOVE_VALUE, pos.w()));
sphereXForm->setPosition(osg::Vec3(pos.x(), pos.y(), pos.z()+ MOVE_VALUE));
return false;
break;
}
case KEY_DOWN:
{
osg::Vec4 pos = light->getPosition();
light->setPosition(osg::Vec4(pos.x(), pos.y(), pos.z()- MOVE_VALUE, pos.w()));
sphereXForm->setPosition(osg::Vec3(pos.x(), pos.y(), pos.z()- MOVE_VALUE));
return false;
break;
}
case KEY_LEFT:
{
osg::Vec4 pos = light->getPosition();
light->setPosition(osg::Vec4(pos.x() - MOVE_VALUE, pos.y(), pos.z(), pos.w()));
sphereXForm->setPosition(osg::Vec3(pos.x()- MOVE_VALUE, pos.y(), pos.z()));
return false;
break;
}
case KEY_RIGHT:
{
osg::Vec4 pos = light->getPosition();
light->setPosition(osg::Vec4(pos.x() + MOVE_VALUE, pos.y(), pos.z(), pos.w()));
sphereXForm->setPosition(osg::Vec3(pos.x()+ MOVE_VALUE, pos.y(), pos.z()));
return false;
break;
}
case KEY_PAGE_UP:
{
osg::Vec4 pos = light->getPosition();
light->setPosition(osg::Vec4(pos.x(), pos.y() + MOVE_VALUE , pos.z(), pos.w()));
sphereXForm->setPosition(osg::Vec3(pos.x(), pos.y()+ MOVE_VALUE, pos.z()));
return false;
break;
}
case KEY_PAGE_DOWN:
{
osg::Vec4 pos = light->getPosition();
light->setPosition(osg::Vec4(pos.x(), pos.y() - MOVE_VALUE , pos.z(), pos.w()));
sphereXForm->setPosition(osg::Vec3(pos.x(), pos.y()- MOVE_VALUE, pos.z()));
return false;
break;
}
default:
return false;
}
}
default:
return false;
}
}
// create a simple quad
osg::Geode* createQuad(const osg::Vec3& centerPos, float radius)
{
printf("Create Quad ...\n");
osg::Geode* geode = new osg::Geode;
osg::Geometry* geom = new osg::Geometry;
osg::ref_ptr<osg::Vec3Array> vertices;
osg::ref_ptr<osg::Vec3Array> normals;
osg::ref_ptr<osg::Vec2Array> texCoords;
osg::ref_ptr<osg::Vec3Array> tangents;
osg::ref_ptr<osg::Vec3Array> binormals;
vertices = new osg::Vec3Array();
vertices->push_back(osg::Vec3(centerPos.x() - radius, centerPos.z(), centerPos.y() - radius));
vertices->push_back(osg::Vec3(centerPos.x() + radius, centerPos.z(), centerPos.y() - radius));
vertices->push_back(osg::Vec3(centerPos.x() + radius, centerPos.z(), centerPos.y() + radius));
vertices->push_back(osg::Vec3(centerPos.x() - radius, centerPos.z(), centerPos.y() + radius));
geom->setVertexArray(vertices.get());
normals = new osg::Vec3Array();
normals->push_back (osg::Vec3 (0.0f, -1.0f, 0.0f));
normals->push_back (osg::Vec3 (0.0f, -1.0f, 0.0f));
normals->push_back (osg::Vec3 (0.0f, -1.0f, 0.0f));
normals->push_back (osg::Vec3 (0.0f, -1.0f, 0.0f));
geom->setNormalArray (normals.get());
geom->setNormalBinding (osg::Geometry::BIND_PER_VERTEX);
texCoords = new osg::Vec2Array();
texCoords->push_back(osg::Vec2(0.0f,0.0f));
texCoords->push_back(osg::Vec2(1.0f,0.0f));
texCoords->push_back(osg::Vec2(1.0f,1.0f));
texCoords->push_back(osg::Vec2(0.0f,1.0f));
geom->setTexCoordArray(0,texCoords.get());
tangents = new osg::Vec3Array();
tangents->push_back (osg::Vec3 (1.0f, 0.0f, 0.0f));
tangents->push_back (osg::Vec3 (1.0f, 0.0f, 0.0f));
tangents->push_back (osg::Vec3 (1.0f, 0.0f, 0.0f));
tangents->push_back (osg::Vec3 (1.0f, 0.0f, 0.0f));
binormals = new osg::Vec3Array();
binormals->push_back (osg::Vec3 (0.0f, 0.0f, 1.0f));
binormals->push_back (osg::Vec3 (0.0f, 0.0f, 1.0f));
binormals->push_back (osg::Vec3 (0.0f, 0.0f, 1.0f));
binormals->push_back (osg::Vec3 (0.0f, 0.0f, 1.0f));
// bind binormal and tangents
geom->setVertexAttribArray (osg::Drawable::ATTRIBUTE_6, tangents.get());
geom->setVertexAttribBinding (osg::Drawable::ATTRIBUTE_6, osg::Geometry::BIND_PER_VERTEX);
geom->setVertexAttribArray (osg::Drawable::ATTRIBUTE_7, binormals.get());
geom->setVertexAttribBinding (osg::Drawable::ATTRIBUTE_7, osg::Geometry::BIND_PER_VERTEX);
geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));
geode->addDrawable(geom);
// add a decal map
osg::Image* image = osgDB::readImageFile("../../../../gfx/tga/rockwall.tga");
if (image)
{
osg::Texture2D* texture = new osg::Texture2D;
texture->setImage(image);
osg::StateSet* stateset = geode->getOrCreateStateSet();
stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
}
// add a normal map
osg::Image* image2 = osgDB::readImageFile("../../../../gfx/tga/rockwall_normal.tga");
if (image2)
{
osg::Texture2D* texture = new osg::Texture2D;
texture->setImage(image2);
osg::StateSet* stateset = geode->getOrCreateStateSet();
stateset->setTextureAttributeAndModes(1,texture,osg::StateAttribute::ON);
}
return geode;
}
// create a single light
osg::LightSource* createLight(osg::StateSet* rootState)
{
light = new osg::Light();
light->setLightNum(0);
light->setAmbient(osg::Vec4( 0.0f, 0.0f, 0.0f, 1.0f));
light->setDiffuse(osg::Vec4( 0.8f, 0.8f, 0.8f, 1.0f));
light->setSpecular(osg::Vec4(0.8f, 0.8f, 0.8f, 1.0f));
light->setPosition(osg::Vec4(0.0,-2.0,0.0,1.0f));
light->setDirection(osg::Vec3(0.0f,1.0f,0.0f));
osg::LightSource* lightS1 = new osg::LightSource;
lightS1->setLight(light);
lightS1->setLocalStateSetModes(osg::StateAttribute::ON);
lightS1->setStateSetModes(*rootState,osg::StateAttribute::ON);
rootState->setMode(GL_LIGHTING,osg::StateAttribute::ON);
rootState->setMode(GL_LIGHT0 + light->getLightNum(),osg::StateAttribute::ON);
return lightS1;
}
// Create a sphere centered at the origin
osg::ref_ptr<osg::Geode> createSphere()
{
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
osg::Sphere* unitSphere = new osg::Sphere( osg::Vec3(0,0,0), 1.0);
osg::ShapeDrawable* unitSphereDrawable = new osg::ShapeDrawable(unitSphere);
geode->addDrawable(unitSphereDrawable);
return geode;
}
int main( int argc, char **argv )
{
// parse arguments
osg::ArgumentParser arguments(&argc,argv);
// create the rendering context for the views
osg::ref_ptr<osg::GraphicsContext::WindowingSystemInterface> wsi = osg::GraphicsContext::getWindowingSystemInterface();
if(wsi.valid()==false){
printf("OSG WindowsSystemInterface is not available!\n");
exit(1);
}
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits();
if(traits.valid()==false){
printf("OSG Traits are not available!\n");
exit(1);
}
traits->doubleBuffer = true;
traits->mipMapGeneration = false;
traits->sharedContext = 0;
traits->windowDecoration = true;
traits->supportsResize = true;
traits->width = 1024;
traits->height = 768;
osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
if(gc.valid()==false){
printf("OSG GraphicsContext are not available!\n");
exit(1);
}
// set up the scene root
osg::ref_ptr<osg::Group> rootNode = new osg::Group();
osg::StateSet* rootState = rootNode->getOrCreateStateSet();
rootState->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
// Lichtquelle erzeugen
rootNode->addChild(createLight(rootState));
// set up a standard view
OSGView* stdView = new OSGView();
stdView->setGraphicsContext(gc.get());
stdView->setViewPort(0, 0, 1024, 768); // using the upper right area of the window
stdView->setSceneData(rootNode.get());
stdView->getView()->addEventHandler(new myKeyboardEventHandler());
// set up the scene
osg::Node* model = 0;
osg::Node* model2 = 0;
// create 1st model
if (!model) model = createQuad(osg::Vec3(0.0f, 0.0f, 0.0f), 10.0f); ;
osg::PositionAttitudeTransform* pos1 = new osg::PositionAttitudeTransform();
pos1->setPosition(osg::Vec3(0,0,0));
pos1->addChild(model);
rootNode->addChild(pos1);
// create 2nd model
if (!model2) model2 = createQuad(osg::Vec3(25.0f, 0.0f, 0.0f), 10.0f); ;
osg::PositionAttitudeTransform* pos2 = new osg::PositionAttitudeTransform();
pos2->setPosition(osg::Vec3(0,0,0));
pos2->addChild(model2);
rootNode->addChild(pos2);
// create light source and representing sphere
osg::LightSource* lightSource = createLight(rootState);
rootNode->addChild(lightSource);
sphereXForm = new osg::PositionAttitudeTransform();
osg::Vec4 pos = light->getPosition();
sphereXForm->setPosition(osg::Vec3(pos.x(),pos.y(),pos.z()));
sphereXForm->addChild(createSphere().get());
rootNode->addChild(sphereXForm.get());
// grab model state sets
osg::ref_ptr<osg::StateSet> state = model->getOrCreateStateSet();
osg::ref_ptr<osg::StateSet> state2 = model2->getOrCreateStateSet();
if(state.valid()==false || state2.valid()==false){
printf("Invalid osg::StateSet!\n");
exit(1);
}
// Set up the shared Program
osg::ref_ptr<osg::Program> prg = new osg::Program;
prg->addBindAttribLocation("tangent", osg::Drawable::ATTRIBUTE_6);
prg->addBindAttribLocation("binromal", osg::Drawable::ATTRIBUTE_7);
osg::ref_ptr<osg::Program> prg2 = new osg::Program;
prg2->addBindAttribLocation("tangent", osg::Drawable::ATTRIBUTE_6);
prg2->addBindAttribLocation("binromal", osg::Drawable::ATTRIBUTE_7);
// Set up the shared Shaders
osg::ref_ptr<osg::Shader> vert = osg::Shader::readShaderFile(osg::Shader::VERTEX, "../../../shaders/glsl/dot3.vert");
if (!vert.valid()) return 1;
osg::ref_ptr<osg::Shader> frag = osg::Shader::readShaderFile(osg::Shader::FRAGMENT, "../../../shaders/glsl/dot3.frag");
if (!frag.valid()) return 1;
osg::ref_ptr<osg::Shader> vert2 = osg::Shader::readShaderFile(osg::Shader::VERTEX, "../../../shaders/glsl/dot3.vert");
if (!vert2.valid()) return 1;
osg::ref_ptr<osg::Shader> frag2 = osg::Shader::readShaderFile(osg::Shader::FRAGMENT, "../../../shaders/glsl/dot3.frag");
if (!frag2.valid()) return 1;
// Set up the uniforms on each StateSet
osg::Uniform* lightPosU = new osg::Uniform("LIGHT_POSITION", pos);
lightPosU->setUpdateCallback(new updateLightSource());
osg::Uniform* lightPosU2 = new osg::Uniform("LIGHT_POSITION", pos);
lightPosU2->setUpdateCallback(new updateLightSource());
state->addUniform(lightPosU, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);
state2->addUniform(lightPosU2, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);
osg::Vec3 eye, up, center;
stdView->getCamera()->getViewMatrixAsLookAt(eye,up,center);
osg::Uniform* cameraPosU = new osg::Uniform("CAMERA_POSITION", eye);
osg::Uniform* cameraPosU2 = new osg::Uniform("CAMERA_POSITION", eye);
state->addUniform(cameraPosU, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);
state2->addUniform(cameraPosU2, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);
cameraPosU->setUpdateCallback(new updateCamera(stdView->getCamera()));
cameraPosU2->setUpdateCallback(new updateCamera(stdView->getCamera()));
osg::Uniform* lightRadius = new osg::Uniform("lightRadius", 10.0f);
osg::Uniform* lightRadius2 = new osg::Uniform("lightRadius", 10.0f);
state->addUniform(lightRadius, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);
state2->addUniform(lightRadius2, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);
osg::Uniform* normalMapU = new osg::Uniform("normalMap",1);
osg::Uniform* normalMapU2 = new osg::Uniform("normalMap",1);
state->addUniform(normalMapU, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);
state2->addUniform(normalMapU2, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);
osg::Uniform* baseTextureU = new osg::Uniform("decalMap",0);
osg::Uniform* baseTextureU2 = new osg::Uniform("decalMap",0);
state->addUniform(baseTextureU, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);
state2->addUniform(baseTextureU2, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);
osg::Uniform* ambientU = new osg::Uniform("matAmbient", osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
osg::Uniform* ambientU2 = new osg::Uniform("matAmbient", osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
state->addUniform(ambientU, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);
state2->addUniform(ambientU2, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);
osg::Uniform* diffuseU = new osg::Uniform("matDiffuse", osg::Vec4(0.8f, 0.8f, 0.8f, 1.0f));
osg::Uniform* diffuseU2 = new osg::Uniform("matDiffuse", osg::Vec4(0.8f, 0.8f, 0.8f, 1.0f));
state->addUniform(diffuseU, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);
state2->addUniform(diffuseU2, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);
osg::Uniform* specularU = new osg::Uniform("matSpecular", osg::Vec4(0.8f, 0.8f, 0.8f, 1.0f));
osg::Uniform* specularU2 = new osg::Uniform("matSpecular", osg::Vec4(0.8f, 0.8f, 0.8f, 1.0f));
state->addUniform(specularU, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);
state2->addUniform(specularU, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);
prg->addShader(vert.get());
prg->addShader(frag.get());
prg2->addShader(vert2.get());
prg2->addShader(frag2.get());
// Bind shaders
state->setAttributeAndModes(prg.get(), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);
state2->setAttributeAndModes(prg2.get(), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);
// set up the composite viewer
OSGCompositeViewer compViewer = OSGCompositeViewer();
compViewer.addView(stdView);
return compViewer.run();
}
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org