誤區一:
給 VBO 賦予數據時,即 調用
glBindBuffer(GL_ARRAY_BUFFER,vbo)
glBufferData(GL_ARRAY_BUFFER,sizeof(data),GL_STATIC_DRAW)
這兩個函數時,需要事先 通過glBindVertexArray() 綁定到一個 VAO 上。
勘誤:
實際上,glBufferData(),把 數組數據 寫入 一個 vbo 時,完全沒有必要綁定 glBindVertexArray() 一個 VAO.
道理也很簡單:我要給一個 vbo 寫入數據,其實並不關心 vao是哪個,跟我要寫數據這件事完全沒有關係!
只有在 把 vbo 的數據,真正傳遞到 shader 時候,也就是 調用 glVertexAttribPointer() 等針對 shader 的操作時(比如 glUseProgram,glEnableVertexAttribArray )時,才必須明確指定綁定到哪個 VAO 上.
在 glBufferData() 時,只是簡答的給一個 vbo 傳數據,跟 shader 無關,完全沒有必要 bind 任何 VAO.
誤區二:
關於 glVertexAttribPointer() 調用時,給 shader 傳遞數據時的 stride 參數的問題。
比如有這樣的數據:
GLfloat vertexData[18] = {
-1,-1,0,//p1 pos
1,0,0,//p1 color red
1,-1,0,//p2 pos
0,1,0,//p2 color green
0,1,0,//p3 pos
0,0,1.//p3 color blue
};
前3個float表示頂點位置,後3個float表示頂點顏色時。
在給 shader 裏的 pos 傳遞數據時,這個 stride 我本來以爲 是 ,位置數據之間 ,隔着 一個 color 數據,即 3個 sizeof(GL_FLOAT), 所以 stride 要傳3.
其實結果是 錯誤的,這個 stride 的含義是,前一個頂點的 第一個位置數據,與後一個頂點的 第一個位置數據,數據之間內存地址的差距。這個差距,應該是 1個 pos 的數據(3 * sizeof(GL_FLOAT)) 和 一個 (3 * sizeof(GL_FLOAT)),結果是 3 + 3 = 6. 所以這個 stride 需要傳 6.
但是具體 有些教程裏面, 只有 pos 或者 color 等一種數據,這時數據之間相聯,沒有間隔時,stride 竟然會傳0,讓我有些困惑。難道不應該傳 當前 這1個 頂點 所佔用的數據 的 跨度嗎 ?比如 對只有3個 GL_FLOAT 組成 pos 數據的 VBO 來說,這時候 stride 不應該傳 3*sizeof(GL_FLOAT) 嗎?
經過實驗, 這種情況stride 傳 3*sizeof(GL_FLOAT) 完全沒有問題(這個我理解),但是傳0 也沒有問題,讓我很困惑,不太明白其中與原理 。
誤區三:
opengl 我記得在固定管線的時候,需要開啓/關閉 饒向剔除功能,否則很可能你設置的所有參數都沒有問題,僅僅是因爲 opengl默認會 不顯示某一種頂點繞向(順時針 逆時針 我忘記了) ,導致你的 GL 程序畫不出來東西。
但是,目前測試來看,在自定義渲染管線的 新時代 OpenGL 裏面,已經拋棄了 這一設定,只要 fragment shader 裏給了顏色,就會正常顯示,而不必關心 VBO 裏 頂點數據 頂點 位置之間的繞序問題了。
以上3個誤區,是今天重新再系統縷了一遍 VAO VBO 的基礎用法得出來的。在此記錄備忘。