您的位置:首页 > 其它

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();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐