To add more to this: I've adapted this to where the camera is the projector (ie the image is projected from the viewpoint, well, at least that is the idea):
http://www.jotschi.de/?p=378 and I would like to say I'm close, but I'm still a ways away from a solution. I do see the "clock" projected onto my model, but the movement is not properly coordinated with my camera, and I'm quite sure I see the reverse projection at times. I'm including my source below hoping someone can find what I've done wrong. // #include <osg/Version> #include <osg/Camera> #include <osg/NodeVisitor> #include <osg/TexGenNode> #include <osg/TexMat> #include <osgSim/MultiSwitch> #include <osgDB/ReadFile> #include <osgDB/FileUtils> #include <osgDB/FileNameUtils> #include <osgDB/DatabasePager> #include <osgViewer/ViewerEventHandlers> #include <osgGA/TrackballManipulator> #include <osgGA/FlightManipulator> #include <osgGA/DriveManipulator> #include <osgGA/KeySwitchMatrixManipulator> #include <osgGA/StateSetManipulator> #include <osgGA/AnimationPathManipulator> #include <osgGA/TerrainManipulator> #include <osgGA/CameraManipulator> #include <iostream> #include <osg/Notify> #include <osg/MatrixTransform> #include <osg/ShapeDrawable> #include <osg/PositionAttitudeTransform> #include <osg/Geometry> #include <osgGA/TrackballManipulator> #include <osg/Texture2D> #include <osg/Geode> #include <osg/LightSource> #include <osg/TexGenNode> #include <osg/TexMat> #include <osgDB/WriteFile> #include <osgUtil/Optimizer> #include <osgDB/Registry> #include <osgDB/ReadFile> #include <osgViewer/Viewer> #include <osgViewer/CompositeViewer> using namespace std; osgViewer::View* viewA = new osgViewer::View; osg::TexMat* texMat = new osg::TexMat; osg::Uniform* ViewMatInv = new osg::Uniform( osg::Uniform::FLOAT_MAT4, "ViewMatInv" ); osg::ref_ptr<osg::Program> addShader() { osg::ref_ptr<osg::Program> projProg(new osg::Program); osg::ref_ptr<osg::Shader> projvertexShader(osg::Shader::readShaderFile( osg::Shader::VERTEX, "surface.main.vert.glsl")); osg::ref_ptr<osg::Shader> projfragShader(osg::Shader::readShaderFile( osg::Shader::FRAGMENT, "surface.main.frag.glsl")); projProg->addShader(projvertexShader.get()); projProg->addShader(projfragShader.get()); return projProg; } void addProjectionInfoToState(osg::StateSet* stateset, string fn) { osg::Vec4 centerColour(1.0f,1.0f,1.0f,1.0f); osg::Vec4 ambientColour(0.05f,0.05f,0.05f,1.0f); /* 1. Load the texture that will be projected */ osg::Texture2D* texture = new osg::Texture2D(); texture->setImage( osgDB::readImageFile(fn) );//VTB::createSpotLightImage(centerColour, ambientColour, 64, 1.0)); texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_BORDER); texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_BORDER); texture->setWrap(osg::Texture::WRAP_R, osg::Texture::CLAMP_TO_BORDER); stateset->setTextureAttributeAndModes( (int)spotTUnit, texture, osg::StateAttribute::ON); // set up tex gens stateset->setTextureMode((int)spotTUnit, GL_TEXTURE_GEN_S, osg::StateAttribute::ON); stateset->setTextureMode((int)spotTUnit, GL_TEXTURE_GEN_T, osg::StateAttribute::ON); stateset->setTextureMode((int)spotTUnit, GL_TEXTURE_GEN_R, osg::StateAttribute::ON); stateset->setTextureMode((int)spotTUnit, GL_TEXTURE_GEN_Q, osg::StateAttribute::ON); /* 3. Handover the texture to the fragment shader via uniform */ osg::Uniform* texUniform = new osg::Uniform(osg::Uniform::SAMPLER_2D, "projectionMap"); texUniform->set( (int)spotTUnit ); stateset->addUniform(texUniform); /* 4. set Texture matrix*/ //If you want to create the texture matrix by yourself you can do this like this way: //osg::Vec3 projectorPos = osg::Vec3(0.0f, 0.0f, 324.0f); //osg::Vec3 projectorDirection = osg::Vec3(osg::inDegrees(dirX),osg::inDegrees(dirY), osg::inDegrees(dirZ)); //osg::Vec3 up(0.0f, 1.0f, 0.0f); //osg::Vec3 target = osg::Vec3(0.0f, 0.0f,0.0f); //float projectorAngle = 80.f; //FOV //mat = osg::Matrixd::lookAt(projectorPos, projectorPos*target ,up) * osg::Matrixd::perspective(projectorAngle, 1.0, 1.0, 10); osg::Matrix mat = viewA->getCamera()->getViewMatrix() * viewA->getCamera()->getProjectionMatrix(); texMat->setMatrix(mat); stateset->setTextureAttributeAndModes((int)spotTUnit, texMat, osg::StateAttribute::ON); stateset->addUniform( ViewMatInv ); } osg::StateSet* createProjectorState() { osg::StateSet* stateset = new osg::StateSet; osg::ref_ptr<osg::Program> prog = addShader(); addProjectionInfoToState(stateset, "C:\\Users\\bcolbert\\Desktop\\Work\\OpenSceneGraph-Data-3.0.0\\Images\\clockface.JPG"); stateset->setAttribute(prog.get()); return stateset; } /** * Load some model, scale it and apply the shader */ osg::Node* createModel() { osg::Group* root = new osg::Group; /* Load the terrain which will be the receiver of out projection */ osg::Node* terr = osgDB::readNodeFile("C:\\Users\\bcolbert\\Documents\\JOSHVILLE_new2.ive"); root->addChild( terr ); /* Enable projective texturing for all objects of this node */ root->setStateSet( createProjectorState() ); return root; } int main( int argc, char* argv[] ) { // Set the output level osg::setNotifyLevel( osg::WARN ); osg::ArgumentParser arguments(&argc, argv); osg::ref_ptr<osg::Group> sceneA = new osg::Group; osg::ref_ptr<osg::Group> sceneB = new osg::Group; osg::ref_ptr<osg::Group> sceneC = new osg::Group; sceneA->addChild(createModel()); osgViewer::CompositeViewer viewer(arguments); viewer.addView(viewA); viewA->setUpViewInWindow(10, 10, 640, 480); viewA->setSceneData(sceneA.get()); //Add this to move the projector by mouse - you need to disable the set //of the viewmatrix in the while loop below. osgGA::TrackballManipulator* aManipulator = new osgGA::TrackballManipulator; viewA->setCameraManipulator(aManipulator); // Create a TexGenNode to automatically update the // planes. osg::TexGenNode* texgenNode = new osg::TexGenNode; texgenNode->setTextureUnit( (int)spotTUnit ); osg::TexGen* texgen = texgenNode->getTexGen(); texgen->setMode( osg::TexGen::EYE_LINEAR ); osg::MatrixTransform* posTexGen = new osg::MatrixTransform; posTexGen->addChild( texgenNode ); osg::Vec3 position(0.0f,0.0f,0.0f); osg::Vec3 direction(0.0f,1.0f,0.0f); osg::Vec3 up(0.0f,0.0f,1.0f); up = (direction ^ up) ^ direction; up.normalize(); texgen->setPlanesFromMatrix( osg::Matrixd::lookAt(position, position+direction, up)* viewA->getCamera()->getProjectionMatrix() ); // osg::Matrixd::perspective(45.f,1.0,0.1,100)); sceneA->addChild( posTexGen ); while ( !viewer.done() ) { osg::Matrixd viewMatInv( viewA->getCamera()->getInverseViewMatrix() ); ViewMatInv->set( viewMatInv ); // Position the TexGenNode in the world with the camera; posTexGen->setMatrix( aManipulator->getInverseMatrix() ); viewer.frame(); } return 0; } Vertex shader: uniform mat4 ViewMatInv; void main() { vec4 posEye = gl_ModelViewMatrix * gl_Vertex; // vec4 posWorld = ViewMatInv * posEye; gl_TexCoord[3].s = dot( posEye, gl_EyePlaneS[3] ); gl_TexCoord[3].t = dot( posEye, gl_EyePlaneT[3] ); gl_TexCoord[3].p = dot( posEye, gl_EyePlaneR[3] ); gl_TexCoord[3].q = dot( posEye, gl_EyePlaneQ[3] ); gl_Position = gl_ProjectionMatrix * posEye; } Fragment shader: uniform sampler2D projectionMap; varying vec4 projCoord; void main() { gl_FragColor = texture2DProj( projectionMap, gl_TexCoord[3] ); #if TEST_FOR_REVERSE_PROJECTION if ( gl_TexCoord[3].q > 0.0 ) gl_FragColor = texture2DProj( projectionMap, gl_TexCoord[3] ); else gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); #endif } -B -----Original Message----- From: [email protected] [mailto:[email protected]] On Behalf Of Brad Colbert Sent: Tuesday, September 27, 2011 1:16 PM To: '[email protected]' Subject: [osg-users] GLSL shaders and projective texturing Hi folks, I'm looking for a complete example showing projective texturing with GLSL shaders in OSG. I'm simply trying to implement a spotlight just like the osgspotlight example. What I've found doesn't quite paint the whole picture for me. Anything would be helpful. Cheers, Brad --- Brad Colbert Renaissance Sciences Corporation (480) 374-5073 _______________________________________________ osg-users mailing list [email protected] http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org _______________________________________________ osg-users mailing list [email protected] http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

