簡體   English   中英

在 iOS 中使用 Metal 進行渲染時更新每幀的索引緩沖區

[英]Update the index buffer each frame when rending using Metal in iOS

我有非常動態的數據,每幀都會改變。 數據本身比較小所以我用

[commandEncoder setVertexBytes:_vertices.buffer() length:_vertices.size() * sizeof(float) atIndex:0];

設置頂點數據。

但是,在使用以下方法繪制時,我還需要設置索引數據:

[commandEncoder drawIndexedPrimitives: ...];

如何更新所提供的MTLBuffer用於索引數據drawIndexedPrimitives方法? 我需要能夠有效地更新索引緩沖區。

本文包含使用多個緩沖區在 CPU 和 GPU 之間同步數據而不強制它們以鎖步方式工作的深入解釋。 你應該仔細閱讀它。 我將總結下面的方法。

  1. 為您的索引緩沖區選擇一個足夠大的大小,以容納您可能需要繪制的最大索引數。
  2. 分配幾個(2-3)個這種大小的緩沖區並將它們放在一個數組中(類型為NSArray<id<MTLBuffer>> )。 這是您的重用池; 我將在下面將其稱為indexBufferPool
  3. 初始化渲染器時, 創建一個調度信號量,其值等於您放入重用池中的緩沖區數。 我將在下面將其稱為bufferSemaphore
  4. 創建緩沖區索引成員變量並將其初始化為 0。下面我將其稱為bufferIndex
  5. 每次繪制時,通過調用dispatch_semaphore_wait(bufferSemaphore, DISPATCH_TIME_FOREVER)等待信號量。
  6. 當信號量等待函數返回時,將新索引數據復制到當前緩沖區索引處的緩沖區是安全的。 使用memcpy或其他一些復制技術,將索引數據復制到bufferPool[bufferIndex]的內容中。
  7. 使用bufferPool[bufferIndex]作為索引緩沖區繪制基元。
  8. 通過設置bufferIndex = (bufferIndex + 1) % ResourceCount增加bufferIndex ,其中ResourceCount是重用池中的緩沖區數。
  9. 在提交之前,將一個已完成的處理程序添加到當前命令緩沖區。 完成的處理程序應該調用dispatch_semaphore_signal(bufferSemaphore) 這讓任何對 draw 方法的掛起調用都知道在當前緩沖區索引處寫入緩沖區是安全的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM