簡體   English   中英

OpenGL 統一緩沖區混淆

[英]OpenGL Uniform Buffer confusion

有人能告訴我關於看似不必要的復雜 Uniform Buffers 嗎? 我已經閱讀了 OpenGL Superbible 5 中的部分,我查看了博客上的一些示例,我閱讀了官方規范,但我仍然不明白。

具體來說,所有示例似乎都需要一個着色器程序來開始,以便最初使用 glGetActiveUniformsiv 設置統一緩沖區。 我不明白這個。 為什么接口不允許您在不參考着色器程序的情況下定義結構,在鏈接時根據程序驗證緩沖區格式?

其次,如果我從一個程序中獲取結構布局,假設所有使用這組制服的程序的結構布局都相同,那么該結構是否保證具有相同的偏移量、數據大小等? 我會這么認為。

第三,我不明白綁定點。 我必須使用索引調用 glBindBufferBase,然后使用塊索引和傳遞給 glBindBufferBase 的索引調用 glUniformBlockBinding。 我無法准確地想象這里發生了什么。 Superbible 缺乏清晰度,規格和我見過的樣品也是如此。

  1. 你究竟為什么想要? 就個人而言,除非您有嚴重的數據短缺問題並且需要每個字節,否則我認為沒有理由使用std140以外的任何其他std140 這使得代碼清爽多了。

    但是,如果您對避免使用std140 ,請繼續閱讀。

  2. 規范徹底解釋了這一點:一切都在布局限定符中。

    恰好有 3 個布局限定符: packedsharedstd140 packed意味着實現可以隨意安排一切。 這包括刪除當前程序不使用的制服。 因此布局是實現定義的,並且該布局中的某些制服可能已被優化掉。

    shared意味着實現可以像packed一樣自由排列數據。 但是,它必須為每件制服提供存儲空間。 這使得在程序之間共享統一布局成為可能,因此得名。 shared還要求實現將為跨程序的一致定義提供一致的布局。 因此,您只需要對一種布局進行查詢。

    要回答你的第一個問題,如果你願意的話,你可以創建一個shared布局的假程序。 您可以僅使用它來查詢統一塊的布局。 然后,只要布局在其他程序中保持一致(使用shared布局),所有布局都將相同。 所以它不需要特殊的 API。

    然而, std140意味着統一塊的布局由 OpenGL 實現逐字節明確定義。 這隱含地允許共享,因為本規范下的兩個相同的統一塊將具有相同的布局。 由於該實現無法優化std140布局塊中的制服,所以一切都很完美。

    同樣,幾乎沒有理由避免std140 除非您處於非常非常嚴重的內存限制下。

  3. 這與紋理的機制完全相同 唯一的區別是統一塊名稱本身並不是統一的。

    紋理對象綁定到紋理圖像單元,使用glActiveTexture(GL_TEXTURE0 + i);glBindTexture() ,其中i是紋理圖像單元索引。 您現在需要告訴着色器哪個采樣器使用該圖像單元。 但是,OpenGL 不允許您直接與名稱進行關聯; 您必須將采樣器名稱轉換為索引位置。 因此,您可以使用glGetUniformLocation獲得特定采樣器的統一位置。 獲得統一位置后,您可以通過調用glUniform1i(loc, i)將紋理圖像單元與該位置相關聯,其中i也是您將紋理綁定到的紋理圖像單元。

    統一緩沖區對象綁定到統一緩沖區綁定點,使用glBindBufferRange(GL_UNIFORM_BUFFER, i, ...) ,其中i是統一緩沖區綁定點。 您現在需要告訴着色器哪個統一塊使用該綁定點。 但是,OpenGL 不允許您直接與名稱進行關聯; 您必須將統一塊轉換為索引位置。 因此,您可以使用glGetUniformBlockIndex獲得特定統一塊的glGetUniformBlockIndex 獲得索引后,您可以通過調用glUniformBlockBinding(program, index, i)將統一緩沖區綁定點與該索引相關聯,其中i也是統一緩沖區綁定到的統一緩沖區綁定點。

    看? 完全相同的。 它們使用不同的術語,但在結構上,它們是相同的。 如果您需要圖片,那么您可以在此處找到包含圖表更詳盡的討論

暫無
暫無

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

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