2012-12-26 49 views
0

任何人都可以告訴我GL_INT_2_10_10_10_REV作爲glVertexAttribPointer()中的類型參數的確切時間嗎? 我想通過使用這種類型的顏色值。這種類型的「REV」後綴的含義是什麼?它是否需要在着色器中進行特殊處理?在glVertexAttribPointer()中使用GL_INT_2_10_10_10_REV()

我的代碼如下:

GLuint red=1023,green=1023,blue=1023,alpha=3; 

GLuint val = 0; 
val = val | (alpha << 30); 
val = val | (blue << 20); 
val = val | (green << 10); 
val = val | (red << 0); 

GLuint test_data[]={val,val,val,val}; 

loadshaders(); 

glBindAttribLocation(ps,0,"tk_position"); 

glBindAttribLocation(ps,1,"color"); 

LinkShader(); 

glUseProgram(ps); 

glEnableVertexAttribArray (0); 

glVertexAttribPointer(0, 4, GL_FLOAT, 0, 0, vertices); 

glEnableVertexAttribArray (1); 

glVertexAttribPointer(1,GL_BGRA,GL_UNSIGNED_INT_2_10_10_10_REV,GL_TRUE,0,test_data); 

glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 

的着色器: 頂點着色器 -

#version 150 

in vec4 tk_position; 
in vec4 color; 

out vec4 v_color; 

void main() 
{ 
    v_color = color; 
    gl_Position = tk_position; 
} 

片段着色器 -

#version 150 

in vec4 v_color; 
out vec4 fragColor; 

void main() 
{ 
    fragColor = v_color; 
} 

該程序對象被確認爲良好。那裏沒有問題。此代碼在AMD卡上正常工作,但在NVidia上失敗。失敗意味着我在glDrawArrays()調用中獲得NULL指針訪問權限。

Access violation 
    Exception Flag: 0x00000000 
    Exception Addr: 0x055f32ce 

回答

3

讓我們打破這種分解成可以理解的部分:

INT意味着該格式將被解讀爲一個整數。

2_10_10_10意味着第一個int和第二個3的10位之間的比特分割。請注意,這些值合計爲32,即4個字節整數中的位數。

REV表示組件的順序相反。

IIRC這種格式最常用於打包頂點法線,以減小頂點數據的大小。還沒有真正看到它用於其他任何事情。

EDIT

另外,我發現this cool page與可視化到底是哪位表示哪些值表。該網站大部分是日文,但表格是英文的。

EDIT 2

鏈接到上述網頁是死的,here是的值是如何制定了一個表的另一頁。

+0

這很有用,謝謝。第二部分仍未得到答覆。如果我使用這種類型讓我們說指定顏色值,我該如何編碼?以下似乎不起作用:GLint data [] = {32767,32767,32767,32767}; glVertexAttribPointer(1,GL_BGRA,GL_INT_2_10_10_10_REV,GL_TRUE,0,數據);你還可以詳細說明「頂點正常包裝」究竟是什麼? – maverick9888

+0

我發佈的表顯示哪些位對應着色器中的哪些值。根據[glVertexAttribPointer的手冊頁](http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribPointer.xml),您將得到一個「GL_INVALID_OPERATION」來將大小設置爲1而不是4。 –

+0

頂點法線填充是指當您獲取頂點的法向量(通常是3d向量或12個字節)並將其壓縮到單個字節時。你會失去一點準確性,但有了法線,這不是一個明顯的區別,但它會顯着減小每個頂點的大小。 –

13

如果您正在傳遞顏色,那麼您想要的更可能是UNSIGNED_ INT_2_10_10_10_REV。所以我會假裝這就是你要求的。

整個字段打包成一個無符號整數。 OpenGL將無符號整數定義爲32位大小,因此您應該使用OpenGL提供的GLuint typedef。

但是,這種格式是包裝,所以你不能只是推入一個數組。這是一種壓縮形式,因此當您認真考慮使頂點屬性數據較小時通常會使用它。

首先,只有使用10/10/10/2的顏色的理由是,如果您要存儲的顏色的值取自顏色深度較深的顏色,而不是常規的每秒8位顏色,通道顏色。畢竟,RGB組件將分別具有10位;如果你的源顏色只有8位,你實際上沒有獲得任何新的信息。

所以我們假設你有一些浮點顏色值和浮點精度。您必須將每個組件標準化至[0,1]範圍。然後,將每個值乘以2,從而擴大到[0,1023]的範圍。然後你將每個組件轉換成整數。

問題出現在包裝到實際領域。名字中的「REV」意味着組件的順序受到尊重。通常在OpenGL中,如果看到類似GL_UNSIGNED_SHORT_5_6_5這樣的格式,那麼這意味着每個無符號短整型被分解成5位模式,接着是6位,接着是5位。最左邊的5位字段是紅色,6位字段是綠色,最右邊的5位字段是藍色。

REV」表示顛倒這一點。所以2_10_10_10_REV意味着兩個最重要的位去阿爾法。接下來的10位將轉到藍色。然後是綠色。然後是紅色。

所以你必須將你的整數捆綁在[0,1023]範圍內,然後將它們推到GLuint值的正確位置。你可以爲數組中的每個這樣的組件做到這一點。

GLuint val = 0; 
val = val | (alpha << 30); 
val = val | (blue << 20); 
val = val | (green << 10); 
val = val | (red << 0); 

此代碼假定alpha僅有2個非零位,和blue,​​,和red各自具有僅10非零比特。

+0

它在AMD上運行良好,但NVidia以某種方式失敗。感謝您的答覆。 – maverick9888

+3

什麼「工作正常」?它是如何成功的,它是如何失敗的?用「某種方式失敗」的代碼增加你的問題。 –

相關問題