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
View Code

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 }
View Code

 

posted on 2022-07-13 13:51  疯狂delphi  阅读(61)  评论(0编辑  收藏  举报

导航