最近剛剛開始研究圖形方面的東西,如果理解有誤請務必指正。在OpenGL 4.5已經有更好的解法了,奈何我辣雞I卡只支持4.4。
UBO是OpenGL 3.1 Core中引入的概念。通過到緩存的通信,修改Uniform變量(=運行時常量)造成的開銷更低,不同的Shader間還可以共享同一UBO的內容。具體就不扯那么多了,有興趣可以閱讀ARB原文了解更多。
因為OpenGL的狀態機模型,有的時候調用相關API會發生意料之外的結果。一般也就是畫不出東西,再慘就是報錯了。這里記錄一下UBO的緩沖區生成與綁定流程:
GLuint buf;
glGenBuffers(1, &buf); // 創建緩存,此時僅僅創建了緩存句柄(name、handle、id,就那個意思),對象並沒有被創建。
auto index = glGetUniformBlockIndex(prog, "UBOName"); // 通過UBO名查詢索引。
glUniformBlockBinding(prog, index, bindingPoint); // 綁定着色器程序$prog的UBO到$bindingPoint。bindingPoint不和同一程序其他UBO重復即可。
glBindBuffer(GL_UNIFORM_BUFFER, buf); // 在首次綁定時會通過句柄構造對象。
glBufferData(GL_UNIFORM_BUFFER, GetUniformBlockSize(index), nullptr, GL_STATIC_DRAW); // 注意顯存中內容是未定義的,在指定數據前不可使用。
glBindBuffer(GL_UNIFORM_BUFFER, 0); // 為了安全解除綁定。
這里通過buf就可以修改相應UBO的內容了。
繪圖時再完成另一半的綁定:
glBindBufferBase(GL_UNIFORM_BUFFER, bindingPoint, buf); // 綁定緩存$buf到$bindingPoint。也可以使用glBindBufferRange()。
需要注意的地方: