iOS OpenGL ES偶尔会渲染错误的顶点

时间:2017-03-17 14:59:02

标签: ios opengl-es

我正在尝试使用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并自己设置上下文,上下文设置如下所示:


var SplitByPathPlugin = require('webpack-split-by-path');
module.exports = {
  entry: {
    app: 'app.js'
  },
  output: {
    path: __dirname + '/public',
    filename: "[name]-[chunkhash].js",
    chunkFilename: "[name]-[chunkhash].js"
  },
  plugins: [
    new SplitByPathPlugin([
      {
        name: 'vendor',
        path: path.join(__dirname, 'node_modules')
      }
    ], {
      manifest: 'app-entry'
    })
  ]
};

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

// [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;

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

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

在致电- (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); } 之前,我更新了VBO:

glDrawElements

最后,我画了它们:

- (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); 打印每个顶点和索引时,它们似乎正确设置。

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

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

谢谢!

1 个答案:

答案 0 :(得分:0)

韦尔普!发现出了什么问题。它与我发布的任何片段无关。为了我的治疗方式的理智,我将详细解释答案。

在我的着色器中,我绑定一个4x4矩阵以应用转换来映射屏幕坐标。为了方便起见,我将它分配到一个指针数组中,并将其映射到另一个3x3矩阵,这是一组2D变换,然后我只用1&#39; s填充对角线,其余用0&#39; s填充。

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.

这解决了所有问题,现在网格一直工作!

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