未用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 ; }