Hi Ekaterina:
Hello,

after checking more the forum, I have found another topic
http://forum.openscenegraph.org/viewtopic.php?t=9182&highlight=jotschi

with the following code, which I have slightly modified.

I would be very grateful, if someone can explain to me why the basic model is 
black and how to avoid it?

Because the shader is written to only project the texture. If you need to blend it on top, you will need to either explicitly use the original texture information or do a multipass rendering with this code blending additively over your current scene.

Cheers
Sebastian

Or maybe, someone has a very simple example with any texture projection on the 
terrain.

#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");
int spotTUnit = 3;



const char* VertexShader = {
        "uniform mat4 ViewMatInv;\n"
        "void main()\n"
        "{\n"
        "vec4 posEye = gl_ModelViewMatrix * gl_Vertex;\n"
        "gl_TexCoord[3].s = dot( posEye, gl_EyePlaneS[3]);\n"
        "gl_TexCoord[3].t = dot( posEye, gl_EyePlaneT[3]);\n"
        "gl_TexCoord[3].p = dot( posEye, gl_EyePlaneR[3]);\n"
        "gl_TexCoord[3].q = dot( posEye, gl_EyePlaneQ[3]);\n"
        "gl_Position = gl_ProjectionMatrix * posEye;\n"
        "}\n"
};

const char* FragmentShader = {
        "uniform sampler2D projectionMap;\n"
        "varying vec4 projCoord;\n"
     "void main()\n"
        "{\n"
        "gl_FragColor = texture2DProj(projectionMap, gl_TexCoord[3]);\n"
        //"#if TEST_FOR_REVERSE_PROJECTION\n"
        //"if (gl_TexCoord[3].q > 0.0)\n"
        //"gl_FragColor = texture2DProj(projectionMap, gl_TexCoord[3]);\n"
        //"else\n"
        //"gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
  //   "#endif\n"
        "}\n"
};


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());

        projProg->addShader(new osg::Shader(osg::Shader::VERTEX, VertexShader));
        projProg->addShader(new osg::Shader(osg::Shader::FRAGMENT, 
FragmentShader));

        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, "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("cessna.osg");

        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;
}

Thank you!

Cheers,
Ekaterina

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=69752#69752





_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to