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?

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

Reply via email to