我最近尝试使用固定功能opengl对3D多边形网格进行体素化。
void VoxelizeWithOpenGL(const Mesh &in, uint32_t width, uint32_t height,
uint32_t depth, uint8_t *out)
{
GLuint texture_id, fbo_id;
glGenTextures(1, &texture_id);
glEnable(GL_TEXTURE_3D);
glBindTexture(GL_TEXTURE_3D, texture_id);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB8, width, height, depth, 0, GL_RGB,
GL_UNSIGNED_BYTE, (void *)0);
glGenFramebuffers(1, &fbo_id);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_id);
glFramebufferTexture3D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_3D, texture_id, 0, 0);
GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers( 1, drawBuffers );
GLenum status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
throw std::runtime_error("Cannot create 3D framebuffer.");
glViewport(0, 0, width, height);
const AABB &aabb = FindAABB(in);
const glm::mat4 &proj = glm::ortho(aabb.min_x, aabb.max_x, aabb.min_y, aabb.max_y,
aabb.min_z, aabb.max_z);
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(glm::value_ptr(proj));
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
/*glBegin(GL_TRIANGLES);
for(const Face &c: in.faces)
{
const glm::vec3 &o=c.o.pos;
const glm::vec3 &a=c.a.pos;
const glm::vec3 &b=c.b.pos;
glVertex3fv(glm::value_ptr(o));
glVertex3fv(glm::value_ptr(a));
glVertex3fv(glm::value_ptr(b));
}
glEnd();*/
//Read from GPU to RAM
glBindTexture(GL_TEXTURE_3D, texture_id);
glGetTexImage(GL_TEXTURE_3D, 0, GL_RGB, GL_UNSIGNED_BYTE, out);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glDeleteFramebuffers(1, &fbo_id);
glDeleteTextures(1, &texture_id);
}
我很确定FindAABB和网格加载器是正确的,但是即使我评论绘图部分,它仍然给我一些奇怪的结果。(请忽略随机立方体颜色)
答案 0 :(得分:1)
你想在那里做什么,它并没有那样工作。将3D纹理绑定为FBO的颜色附件时,实际上只绑定了纹理的单个图层。要做到这一点,你还必须切断"切断"网格的所有部分都在该层的某个深度跨度之外。然而,三角网格不是实心的,它们只是一个轮廓。所以这不适用于应用剪裁平面。你必须"巩固"你的网格。通过将网格数据放入空间细分结构(如八叉树),没有OpenGL就可以轻松完成。网格必须是可定向的;如果满足此约束,则可以直接从空间细分结构中读出体素。
如果您真的坚持使用OpenGL使用基于图像的方法来做到这一点,那么通过两个剪裁平面剪切网格的结果将是一组轮廓;然后,您可以将洪水填充应用于"巩固"它们,然后是3D纹理。