打开 GL ES 2.0 多个 drawElements 和绘制顺序
Open GL ES 2.0 multiple drawElements and draw order
我实现了简单的 OBJ 解析器并使用平行六面体作为示例模型。我添加了基于四元数的旋转功能。下一个目标 - 添加光。我分析了法线并决定将法线绘制为 "debug" 特征(以进一步更好地理解光)。但在那之后我坚持了下来:
这是我的小旋转平行六面体。
再看右下角的顶点和法线。我不明白为什么它会通过我的平行六面体呈现。它应该被隐藏起来。
我使用深度缓冲区(因为没有它,平行六面体在我旋转时看起来很奇怪)。所以我初始化它:
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 顺序。我不敢相信复杂的场景(例如天空、土地和建筑物)是通过一次绘制调用绘制的。
所以,我缺少什么?
提前致谢。
如果要渲染到 window 表面,则需要将深度请求作为 EGL 配置请求的一部分。您分配的深度渲染缓冲区仅在将其附加到帧缓冲区对象 (FBO) 以进行离屏渲染时才有用。
我实现了简单的 OBJ 解析器并使用平行六面体作为示例模型。我添加了基于四元数的旋转功能。下一个目标 - 添加光。我分析了法线并决定将法线绘制为 "debug" 特征(以进一步更好地理解光)。但在那之后我坚持了下来:
这是我的小旋转平行六面体。 再看右下角的顶点和法线。我不明白为什么它会通过我的平行六面体呈现。它应该被隐藏起来。
我使用深度缓冲区(因为没有它,平行六面体在我旋转时看起来很奇怪)。所以我初始化它:
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 顺序。我不敢相信复杂的场景(例如天空、土地和建筑物)是通过一次绘制调用绘制的。
所以,我缺少什么?
提前致谢。
如果要渲染到 window 表面,则需要将深度请求作为 EGL 配置请求的一部分。您分配的深度渲染缓冲区仅在将其附加到帧缓冲区对象 (FBO) 以进行离屏渲染时才有用。