2017-05-24 19 views
0

我在本教程在這裏實現永久性的映射緩衝區的渲染我寫的,很像: persistent-mapped-buffers-in-openglPeristent映射的緩衝器(glBufferStorage GL_MAP_PERSISTENT_BIT)具有非常小的塊

爲了簡化,其工作是這樣的:

glGenBuffers(1, &vboID); 
glBindBuffer(GL_ARRAY_BUFFER, vboID); 
flags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT; 
glBufferStorage(GL_ARRAY_BUFFER, MY_BUFFER_SIZE, 0, flags); 

映射(僅創造一次後...):

flags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT; 
myPointer = glMapBufferRange(GL_ARRAY_BUFFER, 0, MY_BUFFER_SIZE, flags); 

更新:

// wait for the buffer 
glClientWaitSync(Buffer.Sync[Index], GL_SYNC_FLUSH_COMMANDS_BIT, WaitDuration); 

// modify underlying data... 

鎖定緩衝區:

glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); 

我理解的想法後,我能實現它沒有進一步的問題,也獲得由於它頗有些性能。 但是由於我正在使用的遊戲引擎,我無法避免的是,我有時會用很小的塊,只是幾個垂直進行很多drawcalls。如果發生這種情況,我會看到視覺扭曲,清楚地表明出現了問題。

我所嘗試的是在更新緩衝區之前和之後添加更多的等待。雖然這不會有任何意義,但只是爲了測試,我試圖刪除GL_MAP_COHERENT_BIT並使用glFlushMappedBufferRange,我試着用一個緩衝區而不是多個緩衝區。

對我來說,它看起來像籬笆不會正常工作,但我不明白這會發生。 不應該避免像這樣的麻煩,即使這意味着犧牲性能? 但是,如果我使用glBufferData,或者已經說過,如果塊是幾百個vert而不是drawcalls,那麼同樣的情況可以毫無困難地工作。
任何暗示這可能是由什麼引起的,或者我如何獲得關於失敗的更多信息會是非常有用的。 根本沒有OpenGL錯誤。

+1

我們需要看到更多的代碼。例如,什麼導致緩衝區變爲「鎖定」?也就是說,您何時發送柵欄同步以及您何時等待?你是否緩衝你的頂點數據傳輸?等等。 –

+0

我嘗試提供任何需要:) 如果我使用1個緩衝區,3個或更多,這似乎並不重要。關於本教程,鎖定是通過刪除以前的同步並使用glFenceSync完成的。我不確定這是否合適,但這就是本教程中描述的方式。本教程的完整代碼如下: https://github.com/fenbf/GLSamples/blob/master/src/PersistentMappedBuffer.cpp我也可以在這裏添加更多的代碼,但它應該完全相同(除非我已經監督了一些東西) – Gnampf

+0

我剛剛添加了測試,但還有更多的柵欄和同步,無論它是否有意義。即使在各個地方添加glFinish()也沒有「修復」這個問題。 – Gnampf

回答

1

事實證明,問題出在一個完全不同的地方和事物的組合。

對於多個緩衝器它代替在

glVertexAttribPointer(VERTEX_COORD_ATTRIB, 3, GL_FLOAT, GL_FALSE, StrideSize, (void*) BeginOffset)); 

設置索引在

glDrawArrays(GL_TRIANGLES, 0, VertSize); 

必要設置用於所述多個緩衝器的偏移和用於單個緩衝器失真問題的來到由於如果只有一個,就會錯過等待或錯誤的「if」。

我希望這對於遇到這樣的問題的其他人知道這對持久性映射緩衝區來說不是一個普遍問題是有用的。

相關問題