2013-11-20 50 views
-1

我想渲染一個VBO數組,但結果不正確。當我第一次使用GLPaint(OpenGLES v2)設置繪製它們時,我將它們保存到一個數組中。如果你想幫助我,這裏是我有的示例項目。 https://drive.google.com/file/d/0B0pG5vRVzBTzUTZPYWNoenhkcWs/edit?usp=sharing渲染頂點緩衝區陣列OenGL ES2

////// Store VBOs when drawing this is done in renderLineFromPoint (from GLPaint) 
- (void) renderLineFromPoint:(CGPoint)start toPoint:(CGPoint)end 
{ 

static GLfloat*  vertexBuffer = NULL; 
static NSUInteger vertexMax = 64; 
NSUInteger   vertexCount = 0, 
count, 
i; 

[EAGLContext setCurrentContext:context]; 
glBindFramebuffer(GL_FRAMEBUFFER, viewFramebuffer); 

// Convert locations from Points to Pixels 
CGFloat scale = self.contentScaleFactor; 
start.x *= scale; 
start.y *= scale; 
end.x *= scale; 
end.y *= scale; 

// Allocate vertex array buffer 
if(vertexBuffer == NULL) 
    vertexBuffer = malloc(vertexMax * 2 * sizeof(GLfloat)); 

// Add points to the buffer so there are drawing points every X pixels 
count = MAX(ceilf(sqrtf((end.x - start.x) * (end.x - start.x) + (end.y - start.y) * (end.y - start.y))/kBrushPixelStep), 1); 

for(i = 0; i < count; ++i) 
{ 
    if(vertexCount == vertexMax) 
    { 
     vertexMax = 2 * vertexMax; 
     vertexBuffer = realloc(vertexBuffer, vertexMax * 2 * sizeof(GLfloat)); 
    } 

    vertexBuffer[2 * vertexCount + 0] = start.x + (end.x - start.x) * ((GLfloat)i/(GLfloat)count); 
    vertexBuffer[2 * vertexCount + 1] = start.y + (end.y - start.y) * ((GLfloat)i/(GLfloat)count); 
    vertexCount += 1; 
} 

glBindBuffer(GL_ARRAY_BUFFER, vboId); 
glBufferData(GL_ARRAY_BUFFER, vertexCount*2*sizeof(GLfloat), vertexBuffer, GL_DYNAMIC_DRAW); 

glEnableVertexAttribArray(ATTRIB_VERTEX); 
glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, 0); 

// Render the vertex array 
glVertexPointer(2, GL_FLOAT, 0, vertexBuffer); 
glDrawArrays(GL_POINTS, 0, vertexCount); 

// Display the buffer 
glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer); 
[context presentRenderbuffer:GL_RENDERBUFFER]; 

// Store VBO for undo 
VBOHolder *vboHolder = [[VBOHolder alloc]init]; 
vboHolder.vertexCount = vertexCount; 
vboHolder.vbo = vertexBuffer; 
[vboHolderArray addObject:vboHolder]; 

} 

////// Here is the problem: I clear the screen and then try to re-render the VBOs 
-(void)renderSavedVertexBufferes 
{ 

    for (VBOHolderModel *vboh in vboHolderArray) 
    { 
    if (vboh.vertexCount == 0) 
    { 
     continue; 
    } 

    NSUInteger vertexCount = vboh.vertexCount; 

    glBindBuffer(GL_ARRAY_BUFFER, vboId); 
    glBufferData(GL_ARRAY_BUFFER, vertexCount*2*sizeof(GLfloat), vboh.vbo, GL_DYNAMIC_DRAW); 

    glEnableVertexAttribArray(ATTRIB_VERTEX); 
    glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, 0); 

    // Render the vertex array 
    glVertexPointer(2, GL_FLOAT, 0, vboh.vbo); 
    glDrawArrays(GL_POINTS, 0, vertexCount); 

    // Display the buffer 
    glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer); 
    [context presentRenderbuffer:GL_RENDERBUFFER]; 

    } 
} 


////// VBOHolderModel looks like this, it wraps the vbo so it can be put in NSMutableArray 
@interface VBOHolderModel : NSObject 
{ 
    GLfloat *vbo; 
    NSUInteger vertexCount; 

} 

它基本上是一個撤消...當按下撤消它應該只刪除3,因爲這是最後一搏,但刪除了一切,並繪製第二圖像中顯示的點。

enter image description here

enter image description here

+0

撤銷應該使用智能設計模式來處理,而不是任何API特定的功能。如果我是你,我會研究這個備忘錄設計模式,這將允許您將文檔存儲爲一系列命令,其中每個命令都存儲以前的狀態。當需要渲染文檔時,您可以像所有命令一樣重播。當需要撤銷命令時,您可以使用先前狀態的副本(快速但內存不足),也可以按順序重播命令。 –

+0

這是迴應你之前的問題;關於* this *問題,我不得不想知道爲什麼一個名爲'SavedVertexBufferes'的函數在每次被調用時都會向VBO發送新數據?如果情況確實如此,它確實不會保存任何東西。我會考慮使用頂點數組對象,因爲這是iOS特定的 - 並不是所有的GL ES 2.0實現都支持它們,但iOS可以。 –

+0

你指的是renderSavedVertexBufferes函數嗎?如果是這樣,那就是我正在試圖重繪已經繪製並存儲在數組中的頂點緩衝區。然後我在該數組中創建一個標誌,讓我知道最後一行的繪製時間,然後我可以刪除頂點緩衝區,然後重繪剩餘的緩衝區,這基本上是一個「撤消」。但我仍然不贊成維也納國際中心的工作方式或OpenGL ES。我需要一個很好的圖解來解釋所有部分之間的關​​系。 –

回答

1

我找到了這個問題的答案在下面的行

// Allocate vertex array buffer
if(vertexBuffer == NULL)
vertexBuffer = malloc(vertexMax * 2 * sizeof(GLfloat));

的問題是,存儲頂點數組都是一樣的!當vertexBuffer爲null時,它僅在init上分配一次內存。其他一些代碼有所改變,如果你想更新,請告訴我。

+0

你能幫我關於如何在GLPaint中使用VBOHolder。我仍然在使用GLPaint應用程序中的撤消操作。 – Madhavan

相關問題