osg使用shader动态修改纹理坐标
2017-10-13 19:39
453 查看
#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;\n" "uniform sampler2D baseTex;\n" "uniform int osg_FrameNumber;\n"//当前OSG程序运行的帧数; "uniform float osg_FrameTime;\n"//当前OSG程序的运行总时间; "uniform float osg_DeltaFrameTime;\n"//当前OSG程序运行每帧的间隔时间; "uniform mat4 osg_ViewMatrix;\n"//当前OSG摄像机的观察矩阵; "uniform mat4 osg_ViewMatrixInverse;\n"// 当前OSG摄像机观察矩阵的逆矩阵。 "void main(void){\n" "vec2 coord = gl_TexCoord[0].xy+vec2(0,osg_FrameTime*0.8);" " gl_FragColor = texture2D(baseTex, coord);\n" "}\n" }; 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(); }
相关文章推荐
- OSG Shader GLSL 4.3 使用纹理 例子
- UnityShader之纹理贴图滚动实现(修改UV坐标)
- 以员工号和工资为参数,修改指定员工的工资。使用不带占位符的动态dml语句实现
- [cocos2dx笔记013]一个使用CCRenderTexture创建动态纹理显示数字的类
- 火云开发课堂 - 《Shader从入门到精通》系列 第十六节:在Shader中对3D模型使用纹理
- WPF 定时器DispatcherTimer+GetCursorPos 的使用,动态查看屏幕上任一点坐标
- PreferenceActivity的使用 程序动态添加修改Preference
- Shader学习笔记(六)_Time的使用,会动的纹理
- PCL Save VTK File With Texture Coordinates 使用PCL库来保存带纹理坐标的VTK文件
- 动态修改PE文件图标(使用UpdateResource API函数)
- Android使用Gradle命令动态修改BASE_URL(测试/正式环境地址)完成打包,不需要修改代码
- 使用js动态的修改div和span标记中…
- (译)如何使用CCRenderTexture来创建动态纹理
- java中如何使用asm动态的生成或修改一个class文件以及asm的架构思想
- 使用SetWindowPos API函数移动窗口后,还需修改Delphi的属性值,以备下次使用,否则就会出问题(不是API不起作用,而是使用了错误的坐标值)
- 在 cocos2d-x 3.x中使用shader实现精灵色相(Hue)的修改
- (译)如何使用CCRenderTexture来创建动态纹理
- 使用lightProbe来模拟动态物体的照明shader
- java使用dbcp连接池实现jdbc动态新增,修改,删除,切换数据库源
- “error PRJ0050: 未能注册输出。请确保您有修改注册表的相应权限。” 上网找了一下次问题的解决方案 工程设置的问题,VS2005建的STL工程中默认的设置是: ALT的使用:动态链接到 A