OSG 砖块 shader 例子 GLSL

来源:互联网 发布:淘宝网下雪纺女短袖 编辑:程序博客网 时间:2024/05/17 02:41

按键 x y z 可以调节灯光位置

#include <osgViewer/Viewer>#include <osgDB/ReadFile>#include <osg/Shape>#include <osg/Shapedrawable>#include <osg/MatrixTransform>static char * vertexShader = {"#version 140\n""in vec4 MCvertex; \n""in vec3 MCnormal;\n""in vec3 osg_SimulationTime;\n""uniform mat4 osg_ModelViewMatrix;\n""uniform mat4 osg_ModelViewProjectionMatrix;\n""uniform mat3 osg_NormalMatrix;\n""uniform vec3 LightPosition ;\n""const float SpecularContribution = 0.3;\n""const float DiffuseContribution = 1.0 - SpecularContribution;\n""out float LightIntensity;\n""out vec2 MCposition;\n""void main()\n""{\n""  vec3 ecPosition = vec3(osg_ModelViewMatrix * MCvertex);\n""  vec3 tnorm = normalize(osg_NormalMatrix * MCnormal);\n""  vec3 lightVec = normalize(vec3(LightPosition[0],LightPosition[1],LightPosition[2]*osg_SimulationTime) - ecPosition);\n""  vec3 reflectVec = reflect(-lightVec, tnorm);\n""  vec3 viewVec = normalize(-ecPosition);\n""  float diffuse = max(dot(lightVec, tnorm), 0.0);\n""  float spec = 0.0;\n""  if (diffuse > 0.0)\n""   {\n""  spec = max(dot(reflectVec, viewVec), 0.0);\n""  spec = pow(spec, 16.0);\n"" }\n""  LightIntensity = DiffuseContribution * diffuse + SpecularContribution * spec;\n""  MCposition = MCvertex.xy;\n""  gl_Position = osg_ModelViewProjectionMatrix * MCvertex;\n""} \n"};static char * fragShader = {" #version 140 \n"" uniform vec3 BrickColor = vec3(0,1,1), MortarColor = vec3(1,0,1);\n"" uniform vec2 BrickSize = vec2(0.3,0.15);\n"" uniform vec2 BrickPct = vec2(0.9,0.85);\n"" in vec2 MCposition;\n"" in float LightIntensity;\n"" out vec4 FragColor;\n"" void main()\n"" {\n"" vec3 color;\n"" vec2 position, useBrick;\n""position = MCposition / BrickSize;\n""  if (fract(position.y * 0.5) > 0.5)\n""position.x += 0.5;\n""position = fract(position);\n""useBrick = step(position, BrickPct);\n""color = mix(MortarColor, BrickColor, useBrick.x * useBrick.y);\n""color *= LightIntensity;\n""FragColor = vec4(color, 1.0);\n""}\n"};osg::Node *  CreateNode(){osg::Geode * geode = new osg::Geode;osg::Geometry* polyGeom = new osg::Geometry();osg::Vec3Array* vertices = new osg::Vec3Array();vertices->push_back(osg::Vec3(-10, 0, 0));vertices->push_back(osg::Vec3(10, 0, 0));vertices->push_back(osg::Vec3(0, 10, 10));polyGeom->setVertexArray(vertices);osg::ref_ptr<osg::Vec4Array> colorsArray = new osg::Vec4Array;colorsArray->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f));colorsArray->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f));colorsArray->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f));polyGeom->setColorArray(colorsArray.get());polyGeom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);osg::Vec3Array* normals = new osg::Vec3Array;normals->push_back(osg::Vec3(0.0f, 1.0f, 0.0f));normals->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));normals->push_back(osg::Vec3(1.0f, 0.0f, 0.0f));polyGeom->setNormalArray(normals);polyGeom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);polyGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES, 0, 3));polyGeom->setVertexAttribArray(0, vertices);polyGeom->setVertexAttribBinding(0, osg::Geometry::BIND_PER_VERTEX);polyGeom->setVertexAttribArray(1, colorsArray.get());polyGeom->setVertexAttribBinding(1, osg::Geometry::BIND_PER_VERTEX);polyGeom->setVertexAttribArray(2, normals);polyGeom->setVertexAttribBinding(2, osg::Geometry::BIND_PER_VERTEX);geode->addDrawable(polyGeom);return geode;}osg::MatrixTransform * lightPos;class MyNodeVisitor : public osg::NodeVisitor{public:MyNodeVisitor() :osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN){}virtual void apply(osg::Geode& node){for (int i = 0; i < node.getNumParents(); ++i){osg::Geometry * polyGeom = dynamic_cast<osg::Geometry*>(node.getDrawable(i));if (!polyGeom)return;polyGeom->setVertexAttribArray(0, polyGeom->getVertexArray());polyGeom->setVertexAttribBinding(0, osg::Geometry::BIND_PER_VERTEX);polyGeom->setVertexAttribArray(1, polyGeom->getColorArray());polyGeom->setVertexAttribBinding(1, osg::Geometry::BIND_PER_VERTEX);polyGeom->setVertexAttribArray(2, polyGeom->getNormalArray());polyGeom->setVertexAttribBinding(2, polyGeom->getNormalBinding());}}};class LightPosCallback : public osg::Uniform::Callback{public:LightPosCallback(){}virtual void operator()(osg::Uniform* uniform, osg::NodeVisitor* nv){osg::Matrix m = lightPos->getMatrix();uniform->set(m.getTrans());}};osg::Node * createlight(){osg::ShapeDrawable *sun_sd = new osg::ShapeDrawable;osg::Sphere* sun_sphere = new osg::Sphere;sun_sphere->setName("SunSphere");sun_sphere->setRadius(0.5);sun_sd->setShape(sun_sphere);sun_sd->setColor(osg::Vec4(1.0, 0.0, 0.0, 1.0));osg::Geode* sun_geode = new osg::Geode;sun_geode->setName("SunGeode");sun_geode->addDrawable(sun_sd);return sun_geode;}class KeyboardEventHandler : public osgGA::GUIEventHandler{public:KeyboardEventHandler(){}virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter&){switch (ea.getEventType()){case(osgGA::GUIEventAdapter::KEYDOWN) :{  if (ea.getKey() == 'x')//绕x轴旋转  {  osg::Matrix trans = lightPos->getMatrix();  trans = trans * osg::Matrix::rotate(osg::PI_2 / 10, osg::X_AXIS);  lightPos->setMatrix(trans);  }  if (ea.getKey() == 'y')//绕y轴旋转  {  osg::Matrix trans = lightPos->getMatrix();  trans = trans * osg::Matrix::rotate(osg::PI_2 / 10, osg::Y_AXIS);  lightPos->setMatrix(trans);  }  if (ea.getKey() == 'z')//绕z轴旋转  {  osg::Matrix trans = lightPos->getMatrix();  trans = trans * osg::Matrix::rotate(osg::PI_2 / 10, osg::Z_AXIS);  lightPos->setMatrix(trans);  }}}return false;}};int main(){osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;osg::ref_ptr<osg::Node> geode = osgDB::readNodeFile("cow.osg");//CreateNode();MyNodeVisitor visitor;geode->accept(visitor);osg::ref_ptr<osg::StateSet> stateSet = geode->getOrCreateStateSet();osg::ref_ptr<osg::Shader> vShader = new osg::Shader(osg::Shader::VERTEX, vertexShader);osg::ref_ptr<osg::Shader> fShader = new osg::Shader(osg::Shader::FRAGMENT, fragShader);osg::ref_ptr<osg::Program> program = new osg::Program;program->addShader(vShader.get());program->addShader(fShader.get());program->addBindAttribLocation("MCvertex", 0);program->addBindAttribLocation("MCnormal", 2);osg::ref_ptr<osg::Uniform> M4 = new osg::Uniform("LightPosition", osg::Vec3d(2, 0, 0));M4->setUpdateCallback(new LightPosCallback());stateSet->addUniform(M4.get());stateSet->setAttributeAndModes(program.get(), osg::StateAttribute::ON);lightPos = new osg::MatrixTransform;lightPos->setMatrix(osg::Matrix::translate(0, 0, 5));lightPos->addChild(createlight());osg::Group * root = new osg::Group;//root->addChild(osgDB::readNodeFile("d:/ah64_apache.3ds"));root->addChild(lightPos);root->addChild(geode);viewer->addEventHandler(new KeyboardEventHandler());viewer->setSceneData(root);viewer->setUpViewInWindow(35, 35, 1024, 800);viewer->realize();osg::State* state = viewer->getCamera()->getGraphicsContext()->getState();state->setUseModelViewAndProjectionUniforms(true);return viewer->run();}





 




2 0
原创粉丝点击