【问题标题】:iOS OpenGL ES occasionally rendering wrong verticesiOS OpenGL ES 偶尔会渲染错误的顶点
【发布时间】:2017-03-18 02:13:19
【问题描述】:

我正在尝试渲染我使用 OpenGL 来提高性能的应用程序的一些内容。目前,我正在尝试在矩形上绘制简单的水平线和垂直线。

这在大多数情况下都有效,and this is how the proper render looks。

但偶尔,看似随机的,它会以一种奇怪的方式从屏幕的原点开始绘制顶点:This is the same view controller, I just reopened it, and now it looks weirdly weird.

我正在使用 GLKView 并自己设置上下文,上下文设置如下所示:

// [CustomView initWithFrame:] calls [OpenGLContext init]>

<OpenGLContext.m>

self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
[EAGLContext setCurrentContext:self.context];
<compile shaders, etc.>

<[CustomView initWithFrame:]>
self.context = self.openGlContext.context;
self.drawableDepthFormat = GLKViewDrawableDepthFormat24;
self.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888;
self.drawableStencilFormat = GLKViewDrawableStencilFormatNone;
self.drawableMultisample = GLKViewDrawableMultisample4X;
self.layer.opaque = YES;
self.opaque = NO;

一切正常,然后我继续生成 VBO。这是我的顶点对象的样子:

typedef struct {
    vector_float3 position;
    packed_float4 color;
} VertexObject;

为了管理顶点/索引数据,我使用 malloc/realloc 和使用自定义 VertexArrayBuffer Objective-C 类的指针来封装它。在开始渲染之前,我创建了一个像这样的 VAO:

- (void)createVAO:(VertexArrayBuffer*)vao // vao has the pointers and stuff
{
    // Re-generate
    glGenVertexArraysOES(1, &vao->vao);
    glBindVertexArrayOES(vao->vao);

    glGenBuffers(1, &vao->vertexBuffer); // VertexObject *vertexBuffer
    glBindBuffer(GL_ARRAY_BUFFER, vao->vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, vao.vertexCount * sizeof(VertexObject), vao.vertices, GL_STATIC_DRAW);

    glEnableVertexAttribArray(positionSlot);
    glVertexAttribPointer(positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(VertexObject), NULL);

    glEnableVertexAttribArray(colorSlot);
    glVertexAttribPointer(colorSlot, 4, GL_FLOAT, GL_FALSE, sizeof(VertexObject), (GLvoid*)sizeof(vector_float3));

    glGenBuffers(1, &vao->indexBuffer); // GLuint *indexBuffer
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vao->indexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, vao.indexCount * sizeof(GLuint), vao.indices, GL_STATIC_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArrayOES(0);
}

在致电glDrawElements 之前,我会更新 VBO:

- (void)updateVAO:(VertexArrayBuffer*)vao
{
    glBindVertexArrayOES(vao->vao);

    glBindBuffer(GL_ARRAY_BUFFER, vao->vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, vao.vertexCount * sizeof(VertexObject), vao.vertices, GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vao->indexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, vao.indexCount * sizeof(GLuint), vao.indices, GL_STATIC_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArrayOES(0);
}

最后,我画了它们:

glDrawElements(GL_LINES, (GLsizei)vao.indexCount, GL_UNSIGNED_INT, NULL);

我在视图控制器中同时运行了其中的两个,一个用于需要网格效果的每个甘特视图。它可能只有一个或两个同时出现故障。有时网格根本不会出现!

我已尝试检查我的对齐方式并寻找有类似问题的任何人,但我找不到任何人发生过类似的事情。当我使用po vao.vertices[0].position 打印每个顶点和索引时,它们似乎设置正确。

也许有人以前遇到过这个问题,或者可以指出我正确的方向吗?

如果需要,也可以分享更多资源。

谢谢!

【问题讨论】:

    标签: ios opengl-es


    【解决方案1】:

    哎呀!发现出了什么问题。它也与我发布的任何 sn-ps 无关。为了我在治疗方面的理智,我将详细解释答案。

    在我的着色器中,我绑定了一个 4x4 矩阵以应用转换来映射屏幕坐标。为了使事情更容易,我将它分配到一个指针数组中,并从另一个 3x3 矩阵映射它,该矩阵是一组 2D 转换,然后我只用 1 填充对角线,其余用 0 填充。

    Welp,至少我 打算 用 0 填充它。这是罪魁祸首:

    // GLfloat *renderMatrix
    renderMatrix = malloc(sizeof(GLfloat) * 4 * 4); // 4x4 matrix
    

    在渲染过程中,我将其放入着色器中:

    GLint matrixSlot = self.openGlContext->transformMatrixSlot;
    glUniformMatrix4fv(matrixSlot, 1, 0, renderMatrix);
    

    您可能会注意到它缺少一些东西。是的,我没有在使用之前准备内存。

    size_t matrixL = sizeof(GLfloat) * 4 * 4;
    renderMatrix = malloc(matrixL);
    memset(renderMatrix, 0, matrixL); // this is needed.
    

    这解决了所有问题,现在网格可以始终如一地工作!

    课程:在使用之前将记忆归零,伙计们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多