2017-03-17 89 views
0

我試圖使我已經使用OpenGL來提高性能的應用程序的部分內容。目前,我正試圖在矩形上繪製簡單的水平和垂直線條。iOS的OpenGL ES的渲染偶爾錯頂點

這工作的大部分時間,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; 

所有的作品好,然後我繼續生成維也納組織。下面是我的頂點對象的樣子:

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之前,我更新了維也納組織:

- (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打印每個頂點和索引時,它們似乎被正確設置。

也許有人已經收到了這個問題,或者可以點我到正確的方向?

如果需要,也可以共享更多來源。

謝謝!

回答

0

Welp!發現什麼是錯的。它與我發佈的任何片段無關。爲了我的理智,我會詳細解釋答案。

在我的着色器,我綁定一個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. 

這解決了所有問題,現在網格一直工作!

課程:在使用它之前將你的記憶歸零,夥計們。