Osg-OsgShader着色器(Qt5.14.2+osgE3.6.5+win10)-No16-OsgShader
.pro
1 QT += core gui widgets 2 TARGET = TestOsgQt 3 TEMPLATE = app 4 DEFINES += QT_DEPRECATED_WARNINGS 5 CONFIG += c++11 6 7 QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO 8 QMAKE_LFLAGS_RELEASE = $$QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO 9 10 SOURCES += \ 11 main.cpp 12 13 HEADERS += 14 15 OsgDir = D:\\Gitee\\osg365R 16 CONFIG(release, debug|release) { 17 LIBS += -L$${OsgDir}/lib/ -losgDB -losgViewer -lOpenThreads -losgAnimation -losg \ 18 -losgEarth -losgEarthAnnotation -losgEarthFeatures -losgEarthSymbology -losgEarthUtil \ 19 -losgQOpenGL -losgUtil -losgText -losgTerrain -losgSim \ 20 -losgShadow -losgParticle -losgManipulator -losgGA -losgFX \ 21 -losgWidget 22 } else { 23 LIBS += -L$${OsgDir}/debug/lib/ -losgDBd -losgViewerd -lOpenThreadsd -losgAnimationd -losgd \ 24 -losgEarthd -losgEarthAnnotationd -losgEarthFeaturesd -losgEarthSymbologyd -losgEarthUtild \ 25 -losgQOpenGLd -losgUtild -losgTextd -losgTerraind -losgSimd \ 26 -losgShadowd -losgParticled -losgManipulatord -losgGAd -losgFXd \ 27 } 28 29 30 INCLUDEPATH += $${OsgDir}/include 31 DEPENDPATH += $${OsgDir}/include
main.cpp
1 #include <osg/Program> 2 #include <osgDB/ReadFile> 3 #include <osgViewer/Viewer> 4 5 static const char* vertSource = { 6 "varying vec3 normal;"//易变量 用于着色器之间的传值 7 "void main()" 8 "{" 9 " normal = normalize(gl_NormalMatrix * gl_Normal);" //把法线向量从物体空间转化到视觉空间。 10 " gl_Position = ftransform();" //相当于 gl_Position = ModelViewProjectionMatrix * gl_Vertex, 11 //模型视图投影矩阵与空间顶点位置相乘,得到裁剪空间顶点位置。 12 "}" 13 }; 14 15 static const char* fragSource = { 16 "uniform vec4 mainColor;" //外面程序输入的颜色 17 "varying vec3 normal;" //上面的顶点着色器传的法线 18 "void main()" 19 "{" 20 " float intensity = dot(vec3(gl_LightSource[0].position), normal);" //计算光照位置与法线的点积,为什么这么做,知道的朋友不吝赐教下。 21 //按照我的理解就是计算了一下亮度值。 22 //给输出的颜色赋值 23 " if (intensity > 0.95) gl_FragColor = mainColor;" //如果这个值大于0.95,则输出颜色为mainColor,而uniform回调中每帧在来回改这个值,所 24 //以这一部分会出现闪烁的效果。 25 " else if (intensity > 0.5) gl_FragColor = vec4(0.6,0.3,0.3,1.0);" 26 " else if (intensity > 0.25) gl_FragColor = vec4(0.4,0.2,0.2,1.0);" 27 " else gl_FragColor = vec4(0.2,0.1,0.1,1.0);" 28 "}" 29 }; 30 31 32 /* 一直变量uniform回调类,主要用于每帧更新着色器中的用户数据,从而改变渲染的行为和输出结果。 */ 33 34 35 class ColorCallback : public osg::Uniform::Callback 36 { 37 public: 38 ColorCallback() : _incRed(false) {} 39 40 virtual void operator()( osg::Uniform* uniform, osg::NodeVisitor* nv ) 41 { 42 if ( !uniform ) return; 43 44 osg::Vec4 color; 45 uniform->get( color );//获取通过uniform 设置进去的值mainColor 46 47 if ( _incRed==true )//3、如果r减到0呢,就给他一直加。 48 { 49 if ( color.x()<1.0 ) color.x() += 0.1; 50 else _incRed = false;//4、如果加到1就给他再减。 51 } 52 else 53 { 54 if ( color.x()>0.0 ) color.x() -= 0.1;//1、如果RGB中的r分量大于0,则一直减小。 55 else _incRed = true;// 2、r减到0了。 56 } 57 uniform->set( color ); 58 } 59 60 protected: 61 bool _incRed; 62 }; 63 64 void createShaders( osg::StateSet& ss ) 65 { 66 osg::ref_ptr<osg::Shader> vertShader = new osg::Shader( osg::Shader::VERTEX, vertSource ); 67 osg::ref_ptr<osg::Shader> fragShader = new osg::Shader( osg::Shader::FRAGMENT, fragSource ); 68 69 osg::ref_ptr<osg::Program> program = new osg::Program; 70 program->addShader( vertShader.get() ); 71 program->addShader( fragShader.get() ); 72 73 osg::ref_ptr<osg::Uniform> mainColor = new osg::Uniform( "mainColor", osg::Vec4(0.5,0.5,0.5,1.0) );//这个部分的颜色是闪烁部分的颜色值。 74 mainColor->setUpdateCallback( new ColorCallback ); 75 76 ss.addUniform( mainColor.get() ); 77 ss.setAttributeAndModes( program.get() ); 78 } 79 80 int main( int argc, char** argv ) 81 { 82 osg::ArgumentParser arguments( &argc, argv ); 83 osg::Node* model = osgDB::readNodeFiles( arguments ); 84 if ( !model ) model = osgDB::readNodeFile( "D:\\Gitee\\data\\cow.osg" ); 85 86 createShaders( *(model->getOrCreateStateSet()) ); 87 88 osgViewer::Viewer viewer; 89 viewer.setSceneData( model ); 90 viewer.setUpViewInWindow(20,20,600,600); 91 return viewer.run(); 92 }
作者:疯狂Delphi
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
欢迎关注我,一起进步!扫描下方二维码即可加我