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

Reply via email to