查看: 828|回复: 0

利用GeometryShader绘制一个立方体

[复制链接]

该用户从未签到

发表于 2017-8-16 21:24:55 | 显示全部楼层 |阅读模式
本帖最后由 张利维 于 2017-8-16 21:29 编辑

我想用几何着色器画一个立方体,大致思路是从osg传入一个顶点的坐标,然后再在几何着色器中进行偏移。于是我首先想以绘制一个正方形测试一下这个思路是否可行。(在几何着色器中通过绘制4个顶点的triangle_strip实现绘制一个正方形的效果)。

但结果发现当使用一个顶点作为输入时,没有任何内容显示出来,而传入两个顶点时却可以显示出两个正方形(但也存在一些问题,比如正方形在漫游过程中会被奇怪的裁剪掉一部分)。这让我很是纠结,为什么传入一个顶点的时候不行呢?

下面是我通过传入一个顶点,在几何着色器中绘制正方形的代码,不知道为啥就是显示不出来-->_<--。求大神指点迷津
另外,我看英文版的论坛上也有一个和我一样的问题,但是没有解决问题地址


  1. #include <osg/Geode>
  2. #include <osg/Geometry>
  3. #include <osgViewer/Viewer>
  4. #include <osg/MatrixTransform>
  5. #include <osgDB/ReadFile>
  6. #include <osgDB/WriteFile>
  7. #include <osg/ShapeDrawable>
  8. #include <osg\PolygonMode>
  9. #include <osg\LineWidth>
  10. #include <osg/ComputeBoundsVisitor>
  11. #include <osgUtil\Optimizer>
  12. #include <osg/CullFace>
  13. #include <osgViewer/ViewerEventHandlers>
  14. #include <osgGA/TrackballManipulator>

  15. #include "Voxelization.h"
  16. #include "DataAcquireNodeVisitor.h"
  17. #include "DrawUtils.h"

  18. #include <iostream>
  19. #include <fstream>

  20. const int OSG_WIDTH = 1280;
  21. const int OSG_HEIGHT = 960;
  22. const osg::Vec4f FOG_COLOR = osg::Vec4f(0.6f, 0.6f, 0.7f, 1.f);

  23. int main() {

  24.         osgViewer::Viewer viewer;
  25.         osg::ref_ptr<osg::Group> root = new osg::Group;
  26.         root->addChild(createVoxel(viewer.getCamera()));
  27.         viewer.setSceneData(root.get());
  28.         viewer.setUpViewInWindow(100, 100, OSG_WIDTH, OSG_HEIGHT);

  29.         //viewer.getCamera()->setClearColor(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
  30.         /* depth settings */
  31.         osg::StateSet* state = root->getOrCreateStateSet();
  32.         state->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);

  33.         osg::Camera* camera = viewer.getCamera();
  34.         camera->setClearColor(FOG_COLOR);
  35.         camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  36.         viewer.setCameraManipulator(new osgGA::TrackballManipulator);
  37.         viewer.realize();
  38.         while (!viewer.done()) {
  39.                 camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  40.                 viewer.frame();
  41.         }

  42.         return 0;
  43. }
复制代码


传入一个顶点

  1. osg::ref_ptr<osg::Geode> createVoxel(osg::Camera* camera)
  2. {
  3.         osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
  4.         //vertices->push_back(osg::Vec3(0.0f, 1.0f, 0.0f));
  5.         vertices->push_back(osg::Vec3(1.0f, 0.0f, 0.0f));

  6.         // create geometry
  7.         osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
  8.         geom->addPrimitiveSet(new osg::DrawArrays(GL_POINTS, 0, vertices->size()));
  9.         geom->setUseDisplayList(false);
  10.         geom->setVertexArray(vertices);
  11.         // set attributes
  12.         geom->setVertexAttribArray(0, vertices, osg::Array::BIND_PER_VERTEX);
  13.        
  14.         // create shader
  15.         osg::ref_ptr<osg::Program> program = new osg::Program;

  16.         osg::ref_ptr<osg::Shader> vertShader = new osg::Shader(osg::Shader::VERTEX);
  17.         if (!vertShader->loadShaderSourceFromFile("Shaders/voxelDraw.vert"))
  18.                 std::cerr << "Could not read VERTEX shader from file" << std::endl;
  19.         program->addShader(vertShader);

  20.         osg::ref_ptr<osg::Shader> geomShader = new osg::Shader(osg::Shader::GEOMETRY);
  21.         if (!geomShader->loadShaderSourceFromFile("Shaders/voxelDraw.geom"))
  22.                 std::cerr << "Could not read GEOMETRY shader from file" << std::endl;
  23.         program->addShader(geomShader);

  24.         osg::ref_ptr<osg::Shader> fragShader = new osg::Shader(osg::Shader::FRAGMENT);
  25.         if (!fragShader->loadShaderSourceFromFile("Shaders/voxelDraw.frag"))
  26.                 std::cerr << "Could not read FRAGMENT shader from file" << std::endl;
  27.         program->addShader(fragShader);

  28.         // geode
  29.         osg::ref_ptr<osg::Geode> geode = new osg::Geode;
  30.         geode->addDrawable(geom.get());

  31.         osg::StateSet* state = geode->getOrCreateStateSet();
  32.         state->setAttributeAndModes(program.get(), osg::StateAttribute::ON);

  33.         // add uniforms
  34.         osg::Uniform* modelViewProjectionMatrix = new osg::Uniform(osg::Uniform::FLOAT_MAT4, "ModelViewProjectionMatrix");
  35.         modelViewProjectionMatrix->setUpdateCallback(new ModelViewProjectionMatrixCallback(camera));
  36.         state->addUniform(modelViewProjectionMatrix);

  37.         osg::Uniform* viewportVector = new osg::Uniform(osg::Uniform::FLOAT_VEC2, "Viewport");
  38.         viewportVector->setUpdateCallback(new ViewportCallback(camera));
  39.         state->addUniform(viewportVector);

  40.         osg::Uniform* cameraEye = new osg::Uniform(osg::Uniform::FLOAT_VEC4, "CameraEye");
  41.         cameraEye->setUpdateCallback(new CameraEyeCallback(camera));
  42.         state->addUniform(cameraEye);

  43.         // state settings
  44.         osg::LineWidth* lw = new osg::LineWidth;
  45.         lw->setWidth(10.f);
  46.         state->setAttribute(lw, osg::StateAttribute::ON);
  47.         return geode.release();
  48. }
复制代码


顶点着色器

  1. #version 330

  2. uniform mat4 ModelViewProjectionMatrix;

  3. layout(location = 0) in vec4 position;
  4. out mat4 transform;
  5. out vec4 pos;

  6. void main()
  7. {
  8.         gl_Position = ModelViewProjectionMatrix * position;
  9.         transform = ModelViewProjectionMatrix;
  10.         pos = position;
  11.        
  12. }
复制代码


几何着色器

  1. #version 330

  2. layout(points) in;
  3. layout(triangle_strip,max_vertices = 8) out;

  4. uniform vec2 Viewport;
  5. in mat4 transform[];
  6. in vec4 pos[];
  7. out vec4 color;
  8. void main()
  9. {
  10.         //这里我是想在世界坐标系下进行偏移,然后再进行视图变换和投影
  11.         gl_Position = transform[0] * (pos[0] + vec4(0.0,0.0,0.0,1.0));EmitVertex();
  12.         gl_Position = transform[0] * (pos[0] + vec4(0.5,0.0,0.0,1.0));EmitVertex();
  13.         gl_Position = transform[0] * (pos[0] + vec4(0.0,0.0,0.5,1.0));EmitVertex();
  14.         gl_Position = transform[0] * (pos[0] + vec4(0.5,0.0,0.5,1.0));EmitVertex();
  15.         EndPrimitive();

  16.         color = pos[0];
  17. }
复制代码


片段着色器

  1. #version 330
  2. in vec4 color;
  3. void main()
  4. {
  5.         gl_FragColor = vec4(color.xyz,1.0);
  6. }
复制代码

下面是之前提到的,正方形被诡异的裁剪了的情况

QQ截图20170816212256.png
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表