未用shader的效果:
使用shader后的效果:
注意这些颜色的值在0.0~1.0之间。遵循openGL的方式。
./data/myFrag.frag
uniform sampler2D texUnit0; void main(){ //texUnit0由外面调用程序传进来,gl_TexCoord[]输入纹理坐标数组;这句话的意思 从纹理采样器texUnit0中取得纹理坐标对应的纹理像素值。 vec4 color = texture2D(texUnit0,gl_TexCoord[0].xy); //简单的将这三个颜色值相加。 float gcolor = color.r+color.g+color.b; //灰度值输出(gl_FragColor是每个片元着色器必须设置的输出) gl_FragColor = vec4(gcolor,gcolor,gcolor,color.a); }
main.cpp
#include <osgViewer/Viewer> #include <osg/Node> #include <osg/Geode> #include <osg/Group> #include <osg/ShapeDrawable> #include <osgDB/ReadFile> #include <osgDB/WriteFile> #include <osgUtil/Optimizer> //绘制多个预定义的几何体 osg::ref_ptr<osg::Geode> createShape() { //创建一个叶节点 osg::ref_ptr<osg::Geode> geode = new osg::Geode(); //设置半径和高度 float radius = 0.8f; float height = 1.0f; //创建精细度对象,精细度越高,细分就越多 osg::ref_ptr<osg::TessellationHints> hints = new osg::TessellationHints; //设置精细度为0.5f hints->setDetailRatio(0.5f); //添加一个球体,第一个参数是预定义几何体对象,第二个是精细度,默认为0 geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0f,0.0f,0.0f),radius),hints.get())); //添加一个正方体 geode->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(2.0f,0.0f,0.0f),2*radius),hints.get())); return geode.get() ; } int main() { //创建Viewer对象,场景浏览器 osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer(); osg::ref_ptr<osg::Group> root = new osg::Group(); //添加到场景 osg::ref_ptr<osg::Group> myGroup = new osg::Group; myGroup->addChild(createShape()); myGroup->getOrCreateStateSet()->setTextureAttribute( 0,new osg::Texture2D(osgDB::readImageFile("C:\55.jpg"))); myGroup->getOrCreateStateSet()->setTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::ON); /************************使用片元着色器************************************/ osg::ref_ptr<osg::StateSet> ss = myGroup->getOrCreateStateSet(); //new一个属性类,用于添加属性, osg::ref_ptr<osg::Program> texProgram = new osg::Program; //new一个片元着色器 osg::ref_ptr<osg::Shader> texFragObj = new osg::Shader(osg::Shader::FRAGMENT); texFragObj->loadShaderSourceFromFile("./data/myFrag.frag"); texProgram->addShader(texFragObj); //传参 形参是texUnit0 0作为实参 osg::ref_ptr<osg::Uniform> texUniform = new osg::Uniform("texUnit0",0); ss->setAttributeAndModes(texProgram); ss->addUniform(texUniform); root->addChild(myGroup.get()); /************************使用片元着色器************************************/ //优化场景数据 osgUtil::Optimizer optimizer ; optimizer.optimize(root.get()) ; viewer->setSceneData(root.get()); viewer->setUpViewInWindow(20,20,600,600); viewer->realize(); viewer->run(); return 0 ; }