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();
    }
  • 相关阅读:
    locate和grep命令
    内存管理(30天自制操作系统--读书笔记)
    单字节的FIFO缓存(30天自制操作系统--读书笔记)
    STM32 DMA中断只进入一次的解决办法
    Linux Linker
    Linux Linker Script
    java学习-- equals和hashCode的关系
    java学习--"==”和 equals
    java学习--equals
    POI richText和html的转换案例
  • 原文地址:https://www.cnblogs.com/coolbear/p/7662899.html
Copyright © 2011-2022 走看看