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()->asGeometry();
// 获取纹理坐标数组
osg::Array* tmp = geom->getTexCoordArray();
osg::Vec2Array* coorArray = (osg::Vec2Array*) tmp;
auto it = coorArray->begin();
for (; it < coorArray->end(); it++)
{
// 动起来
it->x() += 0.001;
}
// 更新纹理坐标数组
geom->setTexCoordArray(, 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(, , )); // 左前
pyramidVertices->push_back(osg::Vec3(, , )); // 右前
pyramidVertices->push_back(osg::Vec3(, , )); // 右后
pyramidVertices->push_back(osg::Vec3(, , )); // 左后
pyramidVertices->push_back(osg::Vec3(, , )); // 塔尖
pyramidGeometry->setVertexArray(pyramidVertices);
osg::DrawElementsUInt* pyramidBase = new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, );
pyramidBase->push_back();
pyramidBase->push_back();
pyramidBase->push_back();
pyramidBase->push_back();
pyramidGeometry->addPrimitiveSet(pyramidBase);
osg::DrawElementsUInt* pyramidFaceOne = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, );
pyramidFaceOne->push_back();
pyramidFaceOne->push_back();
pyramidFaceOne->push_back();
pyramidGeometry->addPrimitiveSet(pyramidFaceOne);
osg::DrawElementsUInt* pyramidFaceTwo = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, );
pyramidFaceTwo->push_back();
pyramidFaceTwo->push_back();
pyramidFaceTwo->push_back();
pyramidGeometry->addPrimitiveSet(pyramidFaceTwo);
osg::DrawElementsUInt* pyramidFaceThree = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, );
pyramidFaceThree->push_back();
pyramidFaceThree->push_back();
pyramidFaceThree->push_back();
pyramidGeometry->addPrimitiveSet(pyramidFaceThree);
osg::DrawElementsUInt* pyramidFaceFour = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, );
pyramidFaceFour->push_back();
pyramidFaceFour->push_back();
pyramidFaceFour->push_back();
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();
(*normals)[].set(0.0f, -1.0f, 0.0f);
pyramidGeometry->setNormalArray(normals, osg::Array::BIND_OVERALL); osg::Vec2Array* texcoords = new osg::Vec2Array();
(*texcoords)[].set(0.00f, 0.0f);
(*texcoords)[].set(0.25f, 0.0f);
(*texcoords)[].set(0.50f, 0.0f);
(*texcoords)[].set(0.75f, 0.0f);
(*texcoords)[].set(0.50f, 1.0f);
pyramidGeometry->setTexCoordArray(, 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(, 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(, , ), 1.0f, );
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(, 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", ));
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动态修改纹理坐标的更多相关文章
- OSG绘制金字塔geode+动态纹理坐标
osg::Node* createPyramidModel() { // create the root node which will hold the model. osg::Group* roo ...
- Unity 3D动态修改Shader状态,使物体透明等等
Unity动态改Shader状态透明 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- ...
- OSG学习:计算纹理坐标
在很多时候,直接指定纹理坐标是非常不方便的,如曲面纹理坐标,只有少数的曲面(如圆锥.圆柱等)可以在不产生扭曲的情况下映射到平面上,其他的曲面在映射到表面时都会产生一定程度的扭曲.一般而言,曲面表面的曲 ...
- OSG立体模式下动态修改相机远近裁剪面的实现
1. 非立体模式下动态修改相机远近裁剪面 class GLB_DLLCLASS_EXPORT CGlbGlobeClipHandler : public osg::NodeCallback { ...
- OSG与Shader的结合使用
目录 1. 概述 2. 固定管线着色 3. 纹理着色 4. 参考 1. 概述 以往在OpenGL中学习渲染管线的时候,是依次按照申请数据.传送缓冲区.顶点着色器.片元着色器这几个步骤编程的.OSG是O ...
- OpenMesh 读写网格控制(读取写入纹理坐标,法向等)
OpenMesh读取网格默认是不自动读取obj网格中的法向,纹理坐标等信息的,写入网格同样也是.所以要读取(或写入)这些信息需要修改默认的选项. 先看一下其读写网格的函数 template<cl ...
- 关于Unity中如何代码动态修改天空盒
在Unity中动态修改天空盒有两种方法: 一.为每个Texture建立天空盒材质球,需要更换时直接将对应材质球作为天空盒,缺点是建立的材质球太多 private void ChangeSkybox(M ...
- Unity3D代码动态修改材质球的颜色
代码动态修改材质球的颜色: gameObject.GetComponent<Renderer>().material.color=Color.red;//当材质球的Shader为标准时,可 ...
- ReactNative 根据scrollView/listview滑动距离动态修改NavBar颜色
我们常见某些APP上滑的时候,NavBar颜色会从透明渐变为某种颜色 原理非常简单,根据scrollView的回调动态修改NavBar的透明度即可. 在RN中,尤其是ListView中这个回调不是很好 ...
随机推荐
- T-SQL 错误状态
MS Windows Error Messages Code Error Message 0 操作成功完成. 1 功能错误. 2 系统找不到指定的文件. 3 系统找不到指定的路径. 4 系统无法打开文 ...
- java.sql.SQLException: Value '0000-00-00 00:00:00' can not be represented as java.sql.Date
架构使用jsp+servlet+java+mysql mysql里time字段类型为datetime java实体类中该字段类型为Date 页面中,时间字段类型为空的信息显示不出来,且报错信息如下: ...
- 第三百四十一节,Python分布式爬虫打造搜索引擎Scrapy精讲—编写spiders爬虫文件循环抓取内容—meta属性返回指定值给回调函数—Scrapy内置图片下载器
第三百四十一节,Python分布式爬虫打造搜索引擎Scrapy精讲—编写spiders爬虫文件循环抓取内容—meta属性返回指定值给回调函数—Scrapy内置图片下载器 编写spiders爬虫文件循环 ...
- goldengate一些參数整理
manager參数: AUTOSTART:指定在mgr启动时自己主动启动那些进程. AUTOSTART ER * AUTOSTART extract extsz AUTORESTART:指定在mgr ...
- bioperl 自动化下载genbank 中的序列
当我们想要从genbank 中下载序列的时候,总需要点击右上角的download 按钮,选择对应的格式,然后通过浏览器进行下载,这样反复的点击很费时间了 其实可以通过bioperl 自动化的完成下载: ...
- [mysql] mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in
From: http://www.ttlsa.com/php/deprecated-mysql-connect/ php 5个版本,5.2.5.3.5.4.5.5,怕跟不上时代,新的服务器直接上5.5 ...
- VueJs中 Class 与 Style 绑定
绑定 HTML Class 尽管可以用 Mustache 标签绑定 class,比如 class="{{ className }}",但是我们不推荐这种写法和 v-bind:cla ...
- ubuntu14.04_64位安装tensorflow-gpu
第一步(可直接跳到第二步):安装nvidia显卡驱动 linux用户可以通过官方ppa解决安装GPU驱动的问题.使用如下命令添加Graphic Drivers PPA: sudo add-apt-re ...
- ubuntu安装mongo数据库
安装mongo数据库,在shell下输入 sudo apt-get install mongodb 如果需要在Python中使用mongo数据库,还需要额外安装Python封装库 pip instal ...
- 软件设计模式之工厂模式(JAVA)
什么是工厂模式? 工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式.著名的Jive论坛 ,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见.因为工厂模式就相 ...