Osg-OsgShader着色器(Qt5.14.2+osgE3.6.5+win10)-No20-OsgShader
相关资料:
https://www.freesion.com/article/1874284521/ 原文
实例代码:
.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 // 原文 2 // https://www.freesion.com/article/1874284521/ 3 #include <osgViewer/Viewer> 4 #include <osgDB/ReadFile> 5 #include <osg/Shape> 6 #include <osg/ShapeDrawable> 7 #include <osg/MatrixTransform> 8 9 static const char * vertexShader = { 10 "#version 140 \n" 11 "in vec4 MCvertex; \n" 12 "in vec3 MCnormal; \n" 13 "in vec3 osg_SimulationTime; \n" 14 "uniform mat4 osg_ModelViewMatrix; \n" 15 "uniform mat4 osg_ModelViewProjectionMatrix;\n" 16 "uniform mat3 osg_NormalMatrix;\n" 17 "uniform vec3 LightPosition ;\n" 18 "const float SpecularContribution = 0.3;\n" 19 "const float DiffuseContribution = 1.0 - SpecularContribution;\n" 20 "out float LightIntensity;\n" 21 "out vec2 MCposition;\n" 22 "void main()\n" 23 "{\n" 24 " vec3 ecPosition = vec3(osg_ModelViewMatrix * MCvertex); \n" 25 " vec3 tnorm = normalize(osg_NormalMatrix * MCnormal); \n" 26 " vec3 lightVec = normalize(vec3(LightPosition[0],LightPosition[1],LightPosition[2]*osg_SimulationTime) - ecPosition); \n" 27 " vec3 reflectVec = reflect(-lightVec, tnorm); \n" 28 " vec3 viewVec = normalize(-ecPosition); \n" 29 " float diffuse = max(dot(lightVec, tnorm), 0.0); \n" 30 " float spec = 0.0; \n" 31 " if (diffuse > 0.0) \n" 32 " {\n" 33 " spec = max(dot(reflectVec, viewVec), 0.0);\n" 34 " spec = pow(spec, 16.0);\n" 35 " }\n" 36 " LightIntensity = DiffuseContribution * diffuse + SpecularContribution * spec;\n" 37 " MCposition = MCvertex.xy;\n" 38 " gl_Position = osg_ModelViewProjectionMatrix * MCvertex;\n" 39 "} \n" 40 }; 41 42 43 static const char * fragShader = { 44 " #version 140 \n" 45 " uniform vec3 BrickColor = vec3(0,1,1), MortarColor = vec3(1,0,1);\n" 46 " uniform vec2 BrickSize = vec2(0.3,0.15);\n" 47 " uniform vec2 BrickPct = vec2(0.9,0.85);\n" 48 " in vec2 MCposition;\n" 49 " in float LightIntensity;\n" 50 " out vec4 FragColor;\n" 51 " void main()\n" 52 " {\n" 53 " vec3 color;\n" 54 " vec2 position, useBrick;\n" 55 " position = MCposition / BrickSize;\n" 56 " if (fract(position.y * 0.5) > 0.5)\n" 57 " position.x += 0.5;\n" 58 " position = fract(position);\n" 59 " useBrick = step(position, BrickPct);\n" 60 " color = mix(MortarColor, BrickColor, useBrick.x * useBrick.y);\n" 61 " color *= LightIntensity;\n" 62 " FragColor = vec4(color, 1.0);\n" 63 "}\n" 64 }; 65 osg::Node * CreateNode() 66 { 67 osg::Geode * geode = new osg::Geode; 68 osg::Geometry* polyGeom = new osg::Geometry(); 69 osg::Vec3Array* vertices = new osg::Vec3Array(); 70 vertices->push_back(osg::Vec3(-10, 0, 0)); 71 vertices->push_back(osg::Vec3(10, 0, 0)); 72 vertices->push_back(osg::Vec3(0, 10, 10)); 73 polyGeom->setVertexArray(vertices); 74 75 76 osg::ref_ptr<osg::Vec4Array> colorsArray = new osg::Vec4Array; 77 colorsArray->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); 78 colorsArray->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f)); 79 colorsArray->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f)); 80 polyGeom->setColorArray(colorsArray.get()); 81 polyGeom->setColorBinding(osg::Geometry::BIND_PER_VERTEX); 82 83 osg::Vec3Array* normals = new osg::Vec3Array; 84 normals->push_back(osg::Vec3(0.0f, 1.0f, 0.0f)); 85 normals->push_back(osg::Vec3(0.0f, 0.0f, 1.0f)); 86 normals->push_back(osg::Vec3(1.0f, 0.0f, 0.0f)); 87 polyGeom->setNormalArray(normals); 88 polyGeom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); 89 90 91 polyGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES, 0, 3)); 92 93 polyGeom->setVertexAttribArray(0, vertices); 94 polyGeom->setVertexAttribBinding(0, osg::Geometry::BIND_PER_VERTEX); 95 polyGeom->setVertexAttribArray(1, colorsArray.get()); 96 polyGeom->setVertexAttribBinding(1, osg::Geometry::BIND_PER_VERTEX); 97 polyGeom->setVertexAttribArray(2, normals); 98 polyGeom->setVertexAttribBinding(2, osg::Geometry::BIND_PER_VERTEX); 99 100 geode->addDrawable(polyGeom); 101 return geode; 102 } 103 104 105 osg::MatrixTransform * lightPos; 106 107 class MyNodeVisitor : public osg::NodeVisitor 108 { 109 public: 110 MyNodeVisitor() :osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN){} 111 112 virtual void apply(osg::Geode& node) 113 { 114 for (int i = 0; i < node.getNumParents(); ++i) 115 { 116 osg::Geometry * polyGeom = dynamic_cast<osg::Geometry*>(node.getDrawable(i)); 117 118 if (!polyGeom)return; 119 120 polyGeom->setVertexAttribArray(0, polyGeom->getVertexArray()); 121 polyGeom->setVertexAttribBinding(0, osg::Geometry::BIND_PER_VERTEX); 122 polyGeom->setVertexAttribArray(1, polyGeom->getColorArray()); 123 polyGeom->setVertexAttribBinding(1, osg::Geometry::BIND_PER_VERTEX); 124 polyGeom->setVertexAttribArray(2, polyGeom->getNormalArray()); 125 polyGeom->setVertexAttribBinding(2, polyGeom->getNormalBinding()); 126 } 127 } 128 }; 129 130 131 class LightPosCallback : public osg::Uniform::Callback 132 { 133 public: 134 LightPosCallback() 135 { 136 } 137 virtual void operator()(osg::Uniform* uniform, osg::NodeVisitor* nv) 138 { 139 osg::Matrix m = lightPos->getMatrix(); 140 uniform->set(m.getTrans()); 141 } 142 }; 143 144 osg::Node * createlight() 145 { 146 osg::ShapeDrawable *sun_sd = new osg::ShapeDrawable; 147 osg::Sphere* sun_sphere = new osg::Sphere; 148 sun_sphere->setName("SunSphere"); 149 sun_sphere->setRadius(0.5); 150 sun_sd->setShape(sun_sphere); 151 sun_sd->setColor(osg::Vec4(1.0, 0.0, 0.0, 1.0)); 152 153 osg::Geode* sun_geode = new osg::Geode; 154 sun_geode->setName("SunGeode"); 155 sun_geode->addDrawable(sun_sd); 156 157 return sun_geode; 158 } 159 160 161 class KeyboardEventHandler : public osgGA::GUIEventHandler 162 { 163 public: 164 165 KeyboardEventHandler(){} 166 167 virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter&) 168 { 169 switch (ea.getEventType()) 170 { 171 case(osgGA::GUIEventAdapter::KEYDOWN) : 172 { 173 if (ea.getKey() == 'x')//绕x轴旋转 174 { 175 osg::Matrix trans = lightPos->getMatrix(); 176 trans = trans * osg::Matrix::rotate(osg::PI_2 / 10, osg::X_AXIS); 177 lightPos->setMatrix(trans); 178 } 179 if (ea.getKey() == 'y')//绕y轴旋转 180 { 181 osg::Matrix trans = lightPos->getMatrix(); 182 trans = trans * osg::Matrix::rotate(osg::PI_2 / 10, osg::Y_AXIS); 183 lightPos->setMatrix(trans); 184 } 185 if (ea.getKey() == 'z')//绕z轴旋转 186 { 187 osg::Matrix trans = lightPos->getMatrix(); 188 trans = trans * osg::Matrix::rotate(osg::PI_2 / 10, osg::Z_AXIS); 189 lightPos->setMatrix(trans); 190 } 191 } 192 } 193 194 return false; 195 } 196 }; 197 int main() 198 { 199 osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer; 200 osg::ref_ptr<osg::Node> geode = osgDB::readNodeFile("D:/Gitee/OsgTestQt/src/No20-OsgShader/cow.osg");//CreateNode(); 201 202 MyNodeVisitor visitor; 203 geode->accept(visitor); 204 205 206 osg::ref_ptr<osg::StateSet> stateSet = geode->getOrCreateStateSet(); 207 208 osg::ref_ptr<osg::Shader> vShader = new osg::Shader(osg::Shader::VERTEX, vertexShader); 209 osg::ref_ptr<osg::Shader> fShader = new osg::Shader(osg::Shader::FRAGMENT, fragShader); 210 osg::ref_ptr<osg::Program> program = new osg::Program; 211 program->addShader(vShader.get()); 212 program->addShader(fShader.get()); 213 214 program->addBindAttribLocation("MCvertex", 0); 215 program->addBindAttribLocation("MCnormal", 2); 216 217 218 219 osg::ref_ptr<osg::Uniform> M4 = new osg::Uniform("LightPosition", osg::Vec3d(2, 0, 0)); 220 M4->setUpdateCallback(new LightPosCallback()); 221 stateSet->addUniform(M4.get()); 222 223 stateSet->setAttributeAndModes(program.get(), osg::StateAttribute::ON); 224 225 lightPos = new osg::MatrixTransform; 226 lightPos->setMatrix(osg::Matrix::translate(0, 0, 5)); 227 lightPos->addChild(createlight()); 228 229 osg::Group * root = new osg::Group; 230 //root->addChild(osgDB::readNodeFile("d:/ah64_apache.3ds")); 231 root->addChild(lightPos); 232 root->addChild(geode); 233 234 235 viewer->addEventHandler(new KeyboardEventHandler()); 236 viewer->setSceneData(root); 237 viewer->setUpViewInWindow(35, 35, 500, 500); 238 239 viewer->realize(); 240 osg::State* state = viewer->getCamera()->getGraphicsContext()->getState(); 241 state->setUseModelViewAndProjectionUniforms(true); 242 243 244 return viewer->run(); 245 }
作者:疯狂Delphi
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
欢迎关注我,一起进步!扫描下方二维码即可加我