OSG使用GLSL各个版本例子

GLSL版本以opengl3.3为分界线,opengl3.3及以上使用的是高版本着色器,以下则是低版本着色器。OSG是兼容OpenGL的所以着色器语言既能用OGL低版本也可以用高版本的。如下使用的两个例子


1.使用OpenGL高版本着色器(OpenGL4.3)
2.使用OpenGL低级版本着色器(OpenGL2.X)


使用OpenGL高版本着色器(OpenGL4.3)

#include <dtABC/application.h>
#include <dtUtil/nodeprintout.h>

#include <dtCore/object.h>
#include <dtCore/orbitmotionmodel.h>

#include <osg/shader>
#include <osg/Node>
#include <osgDB/ReadFile>
#include <osgDB/fileutils>
#include <osg/Geometry>
#include <osgViewer/viewer>

static char * vertexShader= {
        "#version 430 \n"
        "layout (location=0) in vec3 VertexPosition;\n"
        "layout (location=1) in vec4 VertexColor;\n"
        "uniform mat4 MVP;"
        "out vec4 Color;\n"
        "void main()\n"
        "{\n"
            "   Color = VertexColor;\n"
            "   gl_Position = MVP * vec4(VertexPosition,1.0);\n"
    "   }\n"
};

static char * fragShader ={
        "#version 430 \n"
        "in vec4 Color;\n"
        "layout (location=0) out vec4 FragColor;\n"
        "void main() {\n"
        "   FragColor = Color;//vec4(0.5,0.5,0.5,0.4);\n"
        "}\n"
};
osg::Node *  CreateNode()
{
        osg::Geode * geode = new osg::Geode;
         osg::Geometry* polyGeom = new osg::Geometry();
        osg::Vec3Array* vertices = new osg::Vec3Array();
        vertices->push_back(osg::Vec3(-5,0,0));
        vertices->push_back(osg::Vec3(5,0,0));
        vertices->push_back(osg::Vec3(0,0,5));
        //polyGeom->setVertexArray(vertices);


        osg::ref_ptr<osg::Vec4Array> colorsArray = new osg::Vec4Array;
        colorsArray->push_back(osg::Vec4(1.0f,0.0f,0.0f,1.0f));
        colorsArray->push_back(osg::Vec4(0.0f,0.0f,1.0f,1.0f));
        colorsArray->push_back(osg::Vec4(0.0f,1.0f,0.0f,1.0f));
    //  polyGeom->setColorArray(colorsArray.get());
        //polyGeom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);

        polyGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES,0,3));

        /*
        The osg::Geometry class uses the setVertexAttribArray() and
        setVertexAttribBinding() methods to bind vertex attributes to shaders. They should
        be provided per vertex. GLSL's built-in vertex attributes include the gl_Position, gl_
        Normal, and gl_MultiTexCoord* variables. However, you may still specify your own
        vertex attributes, such as tangents or vertex weights.
        Try declaring an attribute in the vertex shader and make use of the osg::Geometry's vertex
        attribute arrays. Another important task that you need to perform is to bind the external
        attribute array and the GLSL attribute, with the help of the addBindAttribLocation()
        method of osg::Program. It has a name and an index parameter, the first of which
        indicates the attribute name in the shader source code, and the second should correspond
        to the input index value of setVertexAttribArray().
        */
        polyGeom->setVertexAttribArray(0,vertices);
        polyGeom->setVertexAttribBinding(0, osg::Geometry::BIND_PER_VERTEX);
        polyGeom->setVertexAttribArray(1,colorsArray.get());    
        polyGeom->setVertexAttribBinding(1, osg::Geometry::BIND_PER_VERTEX);

        geode->addDrawable(polyGeom);
        return geode; 
}

class MVPCallback: public osg::Uniform::Callback
{
public:
        MVPCallback(osg::Camera * camera):mCamera(camera){
        }
         virtual void operator()( osg::Uniform* uniform, osg::NodeVisitor* nv){
                 osg::Matrix modelView = mCamera->getViewMatrix();
                 osg::Matrix projectM = mCamera->getProjectionMatrix();
                 uniform->set(modelView * projectM);
         }

private:
        osg::Camera * mCamera;
};
int main(int argc, char *argv[]) {   

        osgViewer::Viewer viewer;

        osg::Group * root = new osg::Group;
        osg::ref_ptrnode = CreateNode();

        osg::StateSet * ss = node->getOrCreateStateSet();
        osg::Program * program = new osg::Program;
        program->addBindFragDataLocation("VertexPosition",0);
        program->addBindFragDataLocation("VertexColor",1);

        osg::Shader * vS = new osg::Shader(osg::Shader::FRAGMENT,fragShader); 
        osg::Shader * fS = new osg::Shader(osg::Shader::VERTEX,vertexShader); 
        osg::Uniform* MVPUniform = new osg::Uniform( "MVP",osg::Matrix());
        MVPUniform->setUpdateCallback(new MVPCallback(viewer.getCamera()));
        ss->addUniform(MVPUniform);//对应的Program和Uniform要加到同一个Node下的StateSet中
        program->addShader(vS);
        program->addShader(fS);
        ss->setAttributeAndModes(program,osg::StateAttribute::ON);

        root->addChild(node); 
        viewer.setSceneData(root);

        viewer.run();

        return 0;
}

使用OpenGL低级版本着色器(OpenGL2.X)


#include <osg/Node>
#include <osgViewer/Viewer>
#include <osg/Program>
#include <osgDB/ReadFile>
#include <osg/Shader>
#include <osgViewer/ViewerEventHandlers>


static char * vertexShader = {
    "varying vec4 color;\n"
    "void main(void ){\n"
        "color = gl_Vertex;\n"
        "gl_Position = gl_ModelViewProjectionMatrix*gl_Vertex;\n"
    "}\n"
};
static char * fragShader = {
    "varying vec4 color;\n"
    "void main(void){\n"
    "   gl_FragColor = clamp(color,0.0,1.0);\n"
    "}\n"
};
int main()
{
    osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
    osg::ref_ptr<osg::Node>node = osgDB::readNodeFile("glider.osg");


    osg::StateSet * ss = node->getOrCreateStateSet();
    osg::Program * program = new osg::Program;
    program->addShader(new osg::Shader(osg::Shader::FRAGMENT,fragShader));
    program->addShader(new osg::Shader(osg::Shader::VERTEX,vertexShader));
    ss->setAttributeAndModes(program,osg::StateAttribute::ON);

    viewer->addEventHandler(new osgViewer:: WindowSizeHandler);
    viewer->setSceneData(node.get());
    return viewer->run();
}

你可能感兴趣的:(OSG)