c++ - Open GL ES 2.0 多个drawElements和绘制顺序

标签 c++ ios opengl-es vbo depth-buffer

我实现了简单的 OBJ 解析器并使用平行六面体作为示例模型。我添加了基于四元数的旋转功能。下一个目标——增加光线。我解析了法线并决定将法线绘制为“调试”功能(为了进一步更好地理解光线)。但之后我就卡住了:

enter image description here

这是我的小旋转的平行六面体。 查看右下角顶点和法线。我不明白为什么它通过我的平行六面体渲染。它应该被隐藏。

我使用深度缓冲区(因为如果没有它,当我旋转它时,平行六面体看起来很奇怪)。所以我初始化它:

glGenRenderbuffers(1, &_depthRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, _frameBufferWidth, _frameBufferHeight);

并启用它:

glEnable(GL_DEPTH_TEST);

我生成 4 个 VBO:平行六面体的顶点和索引缓冲区、线(法线)的顶点和索引缓冲区。 我对两个模型都使用一个简单的着色器(如果需要的话 - 我可以稍后添加代码,但我认为一切都可以)。 首先我画平行六面体,然后画法线。 这是我的代码:

// _field variable - parallelepiped

glClearColor(0.3, 0.3, 0.4, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

int vertexSize = Vertex::size();
int colorSize = Color::size();
int normalSize = Normal::size();
int totalSize = vertexSize + colorSize + normalSize;
GLvoid *offset = (GLvoid *)(sizeof(Vertex));

glBindBuffer(GL_ARRAY_BUFFER, _geomBufferID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indicesBufferID);

glVertexAttribPointer(_shaderAtributePosition, vertexSize, GL_FLOAT, GL_FALSE, sizeof(Vertex::oneElement()) * totalSize, 0);
glVertexAttribPointer(_shaderAttributeColor, colorSize, GL_FLOAT, GL_FALSE, sizeof(Color::oneElement()) * totalSize, offset);

glDrawElements(GL_TRIANGLES, _field->getIndicesCount(), GL_UNSIGNED_SHORT, 0);

#ifdef NORMALS_DEBUG_DRAWING
   glBindBuffer(GL_ARRAY_BUFFER, _normalGeomBufferID);
   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _normalIndexBufferID);

   totalSize = vertexSize + colorSize;
   glVertexAttribPointer(_shaderAtributePosition, vertexSize, GL_FLOAT, GL_FALSE, sizeof(Vertex::oneElement()) * totalSize, 0);
   glVertexAttribPointer(_shaderAttributeColor, colorSize, GL_FLOAT, GL_FALSE, sizeof(Color::oneElement()) * totalSize, offset);
   glDrawElements(GL_LINES, 2 * _field->getVertexCount(), GL_UNSIGNED_SHORT, 0);
#endif

我理解,例如,如果我将这两个绘制调用合并为一个(并对平行六面体和法线使用相同的 VBO - 一切都会好起来)。 但会不舒服,因为我使用直线和三角形。

应该有另一种方法来修复 Z 顺序。我不敢相信复杂的场景(例如天空、土地和建筑物)是通过一次绘制调用绘制的。

那么,我缺少什么?

提前致谢。

最佳答案

如果要渲染到窗口表面,则需要将深度请求作为 EGL 配置请求的一部分。您分配的深度渲染缓冲区仅在将其附加到帧缓冲区对象 (FBO) 进行离屏渲染时才有用。

关于c++ - Open GL ES 2.0 多个drawElements和绘制顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41343408/

相关文章:

同时使用 Java 和 C++ 的 Android OpenGL

c++ - qt 线程与 movetothread

c++ - 无法读取文件进行文件处理,使用boost库获取文件路径

ios - 更改 UIImageView 中 UIImage 的大小和位置(快速)

ios - 如何使用RxSwift取消之前的请求

android - 为什么这个 Android 镜面照明示例没有按预期工作?

c++ - 如何序列化融合::vector ?

c++ - 修改 char 数组时,reintrepret_cast to char* 是否定义明确?

ios - 我使用 NSAttributedString 还是 UIWebView Swift

android - OpenGl fragment 着色器纹理速度