zoukankan      html  css  js  c++  java
  • osg使用shader动态修改纹理坐标

    #include <osg/Node>
    #include <osg/Geometry>
    #include <osg/Notify>
    #include <osg/MatrixTransform>
    #include <osg/Texture2D>
    #include <osg/DrawPixels>
    #include <osg/PolygonOffset>
    #include <osg/Geode>
    
    #include <osgDB/Registry>
    #include <osgDB/ReadFile>
    
    #include <osgText/Text>
    
    #include <osgViewer/Viewer>
    
    #include <osg/ShapeDrawable>
    
    #ifdef _DEBUG
    #pragma comment(lib,"osgd.lib")
    #pragma comment(lib,"osgDBd.lib")
    #pragma comment(lib,"osgTextd.lib")
    #pragma comment(lib,"osgViewerd.lib")
    #endif
    
    class TextureCoordUpdateCallback : public osg::NodeCallback
    {
    public:
    
        TextureCoordUpdateCallback(double delay = 1.0) :
            _delay(delay),
            _prevTime(0.0)
        {
        }
    
        virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
        {
            if (nv->getFrameStamp())
            {
                double currTime = nv->getFrameStamp()->getSimulationTime();
                if (currTime - _prevTime > _delay)
                {
                    osg::Geode* geode = node->asGeode();
                    osg::Geometry* geom = geode->getDrawable(0)->asGeometry();
                    // 获取纹理坐标数组
                    osg::Array* tmp = geom->getTexCoordArray(0);
                    osg::Vec2Array* coorArray = (osg::Vec2Array*) tmp;
                    auto it = coorArray->begin();
                    for (; it < coorArray->end(); it++)
                    {
                        // 动起来
                        it->x() += 0.001;
                    }
                    // 更新纹理坐标数组
                    geom->setTexCoordArray(0, coorArray);
    
                    // record time
                    _prevTime = currTime;
                }
            }
        }
    
    
    protected:
        double                          _delay;
        double                          _prevTime;
    
    };
    
    
    osg::Node* createPyramidModel()
    {
        // create the root node which will hold the model.
        osg::Group* root = new osg::Group();
    
        // turn off lighting
        root->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
    
        osg::Geode* pyramidGeode = new osg::Geode();
        osg::Geometry* pyramidGeometry = new osg::Geometry();
        pyramidGeode->setUpdateCallback(new TextureCoordUpdateCallback(0.01));
        pyramidGeode->setDataVariance(osg::Object::DYNAMIC);
        pyramidGeode->addDrawable(pyramidGeometry);
        root->addChild(pyramidGeode);
    
        osg::Vec3Array* pyramidVertices = new osg::Vec3Array;
        pyramidVertices->push_back(osg::Vec3(0, 0, 0)); // 左前 
        pyramidVertices->push_back(osg::Vec3(10, 0, 0)); // 右前 
        pyramidVertices->push_back(osg::Vec3(10, 10, 0)); // 右后 
        pyramidVertices->push_back(osg::Vec3(0, 10, 0)); // 左后 
        pyramidVertices->push_back(osg::Vec3(5, 5, 10)); // 塔尖
        pyramidGeometry->setVertexArray(pyramidVertices);
        osg::DrawElementsUInt* pyramidBase = new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);
        pyramidBase->push_back(3);
        pyramidBase->push_back(2);
        pyramidBase->push_back(1);
        pyramidBase->push_back(0);
        pyramidGeometry->addPrimitiveSet(pyramidBase);
        osg::DrawElementsUInt* pyramidFaceOne = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
        pyramidFaceOne->push_back(0);
        pyramidFaceOne->push_back(1);
        pyramidFaceOne->push_back(4);
        pyramidGeometry->addPrimitiveSet(pyramidFaceOne);
        osg::DrawElementsUInt* pyramidFaceTwo = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
        pyramidFaceTwo->push_back(1);
        pyramidFaceTwo->push_back(2);
        pyramidFaceTwo->push_back(4);
        pyramidGeometry->addPrimitiveSet(pyramidFaceTwo);
        osg::DrawElementsUInt* pyramidFaceThree = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
        pyramidFaceThree->push_back(2);
        pyramidFaceThree->push_back(3);
        pyramidFaceThree->push_back(4);
        pyramidGeometry->addPrimitiveSet(pyramidFaceThree);
        osg::DrawElementsUInt* pyramidFaceFour = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
        pyramidFaceFour->push_back(3);
        pyramidFaceFour->push_back(0);
        pyramidFaceFour->push_back(4);
        pyramidGeometry->addPrimitiveSet(pyramidFaceFour);
    
        osg::Vec4Array* colors = new osg::Vec4Array;
        colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); //红色    
        colors->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f)); //绿色    
        colors->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f)); //蓝色    
        colors->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f)); //白色
        pyramidGeometry->setColorArray(colors);
        pyramidGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
    
        osg::Vec3Array* normals = new osg::Vec3Array(1);
        (*normals)[0].set(0.0f, -1.0f, 0.0f);
        pyramidGeometry->setNormalArray(normals, osg::Array::BIND_OVERALL);
    
        osg::Vec2Array* texcoords = new osg::Vec2Array(5);
        (*texcoords)[0].set(0.00f, 0.0f);
        (*texcoords)[1].set(0.25f, 0.0f);
        (*texcoords)[2].set(0.50f, 0.0f);
        (*texcoords)[3].set(0.75f, 0.0f);
        (*texcoords)[4].set(0.50f, 1.0f);
        pyramidGeometry->setTexCoordArray(0, texcoords);
    
        // set up the texture state.
        osg::Texture2D* texture = new osg::Texture2D;
        texture->setDataVariance(osg::Object::DYNAMIC); // protect from being optimized away as static state.
        texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR);
        texture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR);
        texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::REPEAT);
        texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::REPEAT);
        texture->setImage(osgDB::readImageFile("Images/road.png"));
        osg::StateSet* stateset = pyramidGeometry->getOrCreateStateSet();
        stateset->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
    
        return root;
    }
    
    static char * fragShader = {
        "varying vec4 color;
    "
        "uniform sampler2D baseTex;
    "
        "uniform int osg_FrameNumber;
    "//当前OSG程序运行的帧数;
        "uniform float osg_FrameTime;
    "//当前OSG程序的运行总时间;
        "uniform float osg_DeltaFrameTime;
    "//当前OSG程序运行每帧的间隔时间;
        "uniform mat4 osg_ViewMatrix;
    "//当前OSG摄像机的观察矩阵;
        "uniform mat4 osg_ViewMatrixInverse;
    "// 当前OSG摄像机观察矩阵的逆矩阵。
        "void main(void){
    "
        "vec2 coord = gl_TexCoord[0].xy+vec2(0,osg_FrameTime*0.8);"
        "   gl_FragColor = texture2D(baseTex, coord);
    "
        "}
    "
    };
    osg::Node* createCone()
    {
        osg::ref_ptr<osg::Geode> geode = new osg::Geode;
        osg::ref_ptr<osg::Cone> cone = new osg::Cone(osg::Vec3(0, 0, 0), 1.0f, 5);
        osg::ref_ptr<osg::ShapeDrawable> shapeDrawable = new osg::ShapeDrawable(cone.get());
        geode->addDrawable(shapeDrawable.get());
    
        // set up the texture state.
        osg::Texture2D* texture = new osg::Texture2D;
        //texture->setDataVariance(osg::Object::DYNAMIC); // protect from being optimized away as static state.
        texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR);
        texture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR);
        texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::REPEAT);
        texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::REPEAT);
        texture->setImage(osgDB::readImageFile("Images/test.jpg"));
    
        osg::StateSet* stateset = shapeDrawable->getOrCreateStateSet();
        stateset->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
        osg::Program * program = new osg::Program;
        program->addShader(new osg::Shader(osg::Shader::FRAGMENT, fragShader));
        stateset->addUniform(new osg::Uniform("baseTex", 0));
        stateset->setAttributeAndModes(program, osg::StateAttribute::ON);
    
        return geode.release();
    }
    int main(int, char **)
    {
        // construct the viewer.
        osgViewer::Viewer viewer;
    
        // add model to viewer.
        //viewer.setSceneData(createPyramidModel());
        viewer.setSceneData(createCone());
    
        return viewer.run();
    }
  • 相关阅读:
    JZOJ 3034. 【NOIP2012模拟10.17】独立集
    JZOJ 3035. 【NOIP2012模拟10.17】铁轨
    JZOJ 1259. 牛棚安排
    数位DP JZOJ 3316. 非回文数字
    JZOJ 3046. 游戏
    JZOJ 3013. 填充棋盘
    debian 安装oracle提供的java8
    java 汉字转拼音 PinYin4j
    debian ssh设置root权限登陆 Permission denied, please try again
    java并发下订单生成策略
  • 原文地址:https://www.cnblogs.com/coolbear/p/7662899.html
Copyright © 2011-2022 走看看