2013-07-23 61 views
7

我假設這將是「未定義」的那些東西之一,但我似乎無法從Google中找到具體的答案。使用佈局限定符時,未緩衝頂點屬性的OpenGL默認值

讓我們在我的頂點着色器說我有:

layout(location = 0) in vec3 vPosition; 
layout(location = 1) in vec3 vNormal; 
layout(location = 2) in vec4 vColour; 

但並沒有什麼緩衝,以地點2 glEnableVertexAttribArray()或glVertexAttribPointer()。我能期望價值是什麼特別的嗎?

我假設一個vec4它將沿{0,0,0,0},{0,0,0,1}或{1,1,1,1}行,但在我的情況是{0,0,1,1}。

當我先前使用glBindAttribLocation()來指定的位置,它默認爲{1,1,1,1},用3個不同的操作系統4臺不同的機器(Ubuntu的12.04,窗口7,和Ubuntu 10.04)。

跨機器假設值爲{0,0,1,1}是否安全?或者這只是一個巧合?

回答

5

我可以期待值是什麼特別的嗎?

是的,這是一個特定的值。

假設你正確關掉屬性陣列(即:與glDisableVertexAttribArray該屬性索引),將得到的值來自in-context vertex attribute,如由glVertexAttrib套件的功能設定。這些是全局上下文狀態,不存儲在VAO中。

默認情況下,它們都從(0,0,0,1)開始。但是,如果您已使用該屬性索引中的數組以特定屬性進行渲染,則上下文值將被有效銷燬。所以你應該重置上下文值,如果你想使用它。

+0

所以我已經爲特定的位置編號設置了glDisableVertexAttribArray(),但它仍然在着色器中被讀爲{0,0,1,1}。我正在使用VAO,所以我只撥打一次電話。我應該在我的glDrawElements()調用之前禁用它們嗎? – kbirk

+0

@Pondwater:如果VAO禁用它,則禁用它。您不必再次禁用它。另外,我做了一個補充答案。 –

+0

啊,這是有道理的!謝謝你的澄清! – kbirk

1

他們在這裏沒有定義,但這可能不是問題。 GL狀態由CURRENT_VERTEX_ATTRIB值組成。最初,他們是(0,0,0,1)。您可以通過glVertexAttrib()系列函數明確地設置那些沒有啓用數組的屬性值。

唯一要擔心的是當在繪圖期間實際啓用屬性數組時,當前值會發生什麼情況。引述Spec (Version 3.3),2.8.3節頂點數組 - 繪製命令:

如果未啓用對應於由頂點着色器 所需的通用屬性的陣列,則對應的元素是從當前通用 採取屬性狀態(參見2.7節)。

如果對應於由頂點着色器所需要的通用屬性的陣列是 使能時,相應的電流通用屬性值是 執行的DrawArraysOneInstance後未定義的。

所以你必須指定一個有用的值,然後你爲該特定屬性啓用了一個數組。

UPDATE

此行爲已實際改變開始與OpenGL 4.2

如果未啓用對應於由頂點着色器所需要的通用屬性陣列 ,則相應的元件被取從當前通用屬性 狀態(請參閱第2.7節)。否則,如果啓用了陣列,則通過執行DrawArraysOneInstance,相應的當前通用屬性值不受影響

所以現在,glDraw*()調用將永遠不會修改當前設置的屬性值。

+0

「*它們在這裏沒有定義,但這可能不成問題,GL狀態由CURRENT_VERTEX_ATTRIB值組成。*」那麼這怎麼會使它們變成「未定義的」?如果spec *定義它們,則不是不確定的。 –

+1

@NicolBolas:我指的事實,你啓用了ATTRIB陣列渲染後(由SPEC)的值是不確定的,這是我承擔OP在做,因爲否則他們會一直在默認值,如果他甚至不知道有關'glVertexAttrib'。 – derhass