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

Reply via email to