欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

OSG使用OpenGL3.3 几何着色器例子

程序员文章站 2024-03-25 16:45:34
...
#include <osgViewer/Viewer>
#include <osg/Geometry>
#include <osg/Material>
#include <osgDB/ReadFile>
#include <osg/Image>
#include <osg/Texture2D>
#include <osg/Texture1D>

void configureShaders(osg::StateSet* stateSet)
{
    const std::string vertexSource =
        "#version 330\n"
        "\n"
        "layout (location = 0) in vec4 Position;\n"
        "layout (location = 1) in vec4 color;\n"
        "layout (location = 2) in vec3 Normal;\n"
        "layout (location = 3) in vec2 Texcoord;\n"
        "uniform mat3 osg_NormalMatrix;\n"
        "out vec4 vcolor;\n"
        "out vec3 Norm;\n"
        "out vec2 texcoord;\n"
        "void main()\n"
        "{\n"
        "    gl_Position = Position;\n"
        "    vcolor = color;\n"
        "    Norm = osg_NormalMatrix * Normal; \n"
        "    texcoord = Texcoord;  \n"
        "} \n";
    osg::Shader* vShader = new osg::Shader(osg::Shader::VERTEX, vertexSource);

    const std::string geomSource =
        "#version 330                                                                       \n"
        "layout(triangles) in;                                                                  \n"
        "layout(triangle_strip) out;                                                        \n"
        "layout(max_vertices = 9) out;                                                        \n"
        "uniform mat4 osg_ModelViewProjectionMatrix;                                     \n"
        /*<数组大小为3,,下标索引为0,1,2>*/
        "in vec4 vcolor[];\n"
        "in vec3 Norm[]; \n"
        "in  vec2 texcoord[];  \n "/*<数组大小为3,下标索引为0,1,2>*/
        "out vec2 tex; \n"
        "out vec4 fcolor;                                                                   \n"
        "out vec3 norm;   \n"
        "uniform sampler2D Tex;\n"
        "uniform sampler1D Tex1D;\n"
        "void main(void)                                                                    \n"
        "{                                                                                    \n"
        /*<绘制四边形>*/
        "    for (int i = 0; i < gl_in.length(); i++)                                        \n"
        "    {                                                                                \n"
        "        gl_Position = osg_ModelViewProjectionMatrix*gl_in[i].gl_Position;            \n"
        "       tex=texcoord[i];   \n"
        "       fcolor=vcolor[i];                                                       \n"/*<设置每个顶点颜色都不一样>*/
        "       norm=Norm[i]; \n"
        "        EmitVertex();                                                                \n"
        "    }                                                                                \n"
        "    EndPrimitive();                                                                    \n"
        "        gl_Position = osg_ModelViewProjectionMatrix*gl_in[0].gl_Position;            \n"
        "       tex=texcoord[0];   \n"
        "       fcolor=vcolor[0];                                                       \n"/*<设置每个顶点颜色都不一样>*/
        "       norm=Norm[0]; \n"
        "        EmitVertex();                                                                \n"
        "        gl_Position = osg_ModelViewProjectionMatrix*gl_in[2].gl_Position;            \n"
        "       tex=texcoord[2];   \n"
        "       fcolor=vcolor[2];                                                       \n"/*<设置每个顶点颜色都不一样>*/
        "       norm=Norm[2]; \n"
        "        EmitVertex();                                                                \n"
        "        gl_Position = osg_ModelViewProjectionMatrix*vec4(1.0,0.0,0.0,1.0);            \n"/*<TempVertex[0]不是原点>*/
        "       tex=texcoord[1];   \n"
        "       fcolor=vcolor[2];                                                       \n"/*<设置每个顶点颜色都不一样>*/
        "       norm=Norm[0]; \n"
        "        EmitVertex();                                                                \n"
        "    EndPrimitive();                                                                    \n"

"} \n";

osg::Shader* gShader = new osg::Shader(osg::Shader::GEOMETRY, geomSource);

    const std::string fragmentSource =
        "#version 330 \n"
        " \n"
        "layout (location = 0) out vec4 fragData; \n"
        " \n"
        "uniform sampler2D Texture;\n"
        "in vec4 fcolor;                           \n"
        "in vec3 norm;   \n"
        "in vec2 tex; \n"
        "void main() \n"
        "{ \n"
        "vec4 textureColor=texture(Texture,tex) * fcolor;\n"
        "  fragData = textureColor; \n"
        "} \n";
    osg::Shader* fShader = new osg::Shader(osg::Shader::FRAGMENT, fragmentSource);

    osg::Program* program = new osg::Program;

    program->addShader(vShader);
    program->addShader(gShader);
    program->addShader(fShader);

    stateSet->setAttribute(program);
}

void main()
{
    osg::ref_ptr<osg::Group> root = new osg::Group;
    /*<顶点坐标>*/
    osgViewer::Viewer viewer;
    osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
    vertices->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));
    vertices->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));
    vertices->push_back(osg::Vec3(1.0f, 0.0f, 1.0f));
    /*<顶点颜色>*/
    osg::ref_ptr<osg::Vec4Array> V_C = new osg::Vec4Array;
    V_C->push_back(osg::Vec4(0.0, 1.0, 1.0, 1.0));
    V_C->push_back(osg::Vec4(0.0, 0.0, 1.0, 1.0));
    V_C->push_back(osg::Vec4(1.0, 1.0, 1.0, 1.0));
    V_C->push_back(osg::Vec4(0.0, 1.0, 0.0, 1.0));
    /*<顶点法线>*/
    osg::ref_ptr<osg::Vec3Array> V_N = new osg::Vec3Array;
    V_N->push_back(osg::Vec3(0.0, 1.0, 0.0));
    /*<顶点纹理坐标>*/
    osg::ref_ptr<osg::Vec2Array> V_T = new osg::Vec2Array;
    V_T->push_back(osg::Vec2(0.0, 0.0));
    V_T->push_back(osg::Vec2(1.0, 0.0));
    V_T->push_back(osg::Vec2(1.0, 1.0));
    V_T->push_back(osg::Vec2(0.0, 1.0));

    osg::ref_ptr<osg::Geometry> geom = new osg::Geometry();
    /*<设置顶点>*/
    geom->setVertexArray(vertices);
    /*<顶点颜色>*/
    geom->setVertexAttribArray(1, V_C);
    geom->setVertexAttribBinding(1, osg::Geometry::BIND_PER_VERTEX);
    /*<顶点法线>*/
    geom->setVertexAttribArray(2, V_N);
    geom->setVertexAttribBinding(2, osg::Geometry::BIND_OVERALL);
    /*<顶点纹理坐标>*/
    geom->setTexCoordArray(0, V_T);

    /*<纹理载入>*/
    osg::ref_ptr<osg::Image> image1 = osgDB::readImageFile("Images/brick.jpg");
    if (!image1)
    {
        std::cout << " cannot Open image !!" << std::endl;
    }

osg::ref_ptr<osg::Texture2D> texture1 = new osg::Texture2D();
    texture1->setDataVariance(osg::Object::DYNAMIC);
    texture1->setImage(image1.get());
    geom->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture1.get(), osg::StateAttribute::ON);
    geom->getOrCreateStateSet()->addUniform(new osg::Uniform("Texture", 0));
    geom->getOrCreateStateSet()->addUniform(new osg::Uniform("Tex", 0));

geom->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLES, 0, 3));
    configureShaders(geom->getOrCreateStateSet());
    root->addChild(geom);

    /*<版本指定>*/
    const int width(800), height(450);
    const std::string version("3.1");
    osg::ref_ptr< osg::GraphicsContext::Traits > traits = new osg::GraphicsContext::Traits();
    traits->x = 50; traits->y = 30;
    traits->width = width; traits->height = height;
    traits->windowDecoration = true;
    traits->doubleBuffer = true;
    traits->glContextVersion = version;
    osg::ref_ptr< osg::GraphicsContext > gc = osg::GraphicsContext::createGraphicsContext(traits.get());
    if (!gc.valid())
    {
        osg::notify(osg::FATAL) << "Unable to create OpenGL v" << version << " context." << std::endl;
        return;
    }
    // Create a Camera that uses the above OpenGL context.
    osg::Camera* cam = viewer.getCamera();
    cam->setGraphicsContext(gc.get());
    // Must set perspective projection for fovy and aspect.
    cam->setProjectionMatrix(osg::Matrix::perspective(30., (double)width / (double)height, 1., 100.));
    // Unlike OpenGL, OSG viewport does *not* default to window dimensions.
    cam->setViewport(new osg::Viewport(0, 0, width, height));
    // for non GL3/GL4 and non GLES2 platforms we need enable the osg_ uniforms that the shaders will use,
    // you don't need thse two lines on GL3/GL4 and GLES2 specific builds as these will be enable by default.
    gc->getState()->setUseModelViewAndProjectionUniforms(true);
    gc->getState()->setUseVertexAttributeAliasing(true);

    viewer.setSceneData(root.get());
    viewer.run();
    return;
}
相关标签: OSG着色器