簡體   English   中英

GLSL OpenGL 3.x如何指定通用頂點屬性索引和語義之間的映射?

[英]GLSL OpenGL 3.x how to specify the mapping between generic vertex attribute indices and semantics?

我正在從HLSL切換到GLSL

在頂點緩沖區中定義頂點屬性時,必須調用

glVertexAttribPointer(  GLuint      index, 
    GLint   size, 
    GLenum      type, 
    GLboolean   normalized, 
    GLsizei     stride, 
    const GLvoid *      pointer);

並傳遞一個索引。 但是,如何在着色器中指定哪個索引映射到哪個語義呢?

例如gl_Normal 如何在頂點着色器中使用gl_Normal時指定它為索引1的通用頂點屬性?

在GLSL中沒有所謂的“語義”。 只有屬性索引和頂點着色器輸入。

有兩種頂點着色器輸入。 在3.1中刪除的種類(以“ gl_”開頭的種類)和用戶定義的種類。 無法使用glVertexAttribPointer設置移除的種類; 每個變量都有其自己的特殊功能。 gl_Normal具有glNormalPointergl_Color具有glColorPointer等。但是這些功能不再存在於核心OpenGL中。

用戶定義的頂點着色器輸入與屬性索引關聯。 按以下方式之一為每個命名輸入分配索引,從最重載到默認:

  1. 通過使用GLSL 3.30或ARB_explicit_attrib_location擴展語法layout(location = #) ,其中#是屬性索引。 因此,如果我有一個名為position的輸入,我會給它索引3:

     layout(location = 3) in vec4 position; 

    這是我處理此問題的首選方法。 Explicit_attrib_location在幾乎所有仍受支持的硬件上都可用(不是Intel)。

  2. 通過glBindAttribLocation顯式關聯。 鏈接程序之前,請先調用此函數。 為此,我們將執行以下操作:

     GLuint program = glCreateProgram(); glAttachShader(program, some_shader); glBindVertexAttrib(program, 3, "position"); glLinkProgram(program); 

    您可以設置多個屬性。 實際上,您可以將多個屬性名稱設置為同一索引。 這樣做的想法是能夠自動設置一堆映射,並讓OpenGL找出哪個可以與實際的着色器代碼一起使用。 因此,您可以將“位置”和“軸”映射到索引3,並且只要您不將包含兩個輸入的着色器放到該系統中,就可以了。

  3. 讓OpenGL分配它。 如果您沒有通過其他方法之一將屬性索引分配給屬性,則GLSL鏈接器將為您分配該屬性。 您可以使用glGetAttribLocation獲取鏈接后的屬性。

    我真的不建議這樣做,因為OpenGL會任意分配索引。 因此,每個使用名為position的屬性的着色器都可能在不同的索引中具有該位置。 我認為這不是一個好主意。 因此,如果您不能在着色器中顯式設置它,那么至少在鏈接之前在OpenGL代碼中顯式設置它。 這樣,您就可以對索引0的含義,索引1的含義等等有一個約定。

暫無
暫無

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

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