顶点着色器的 OpenGL 属性名称

Names of OpenGL attributes for the vertex shader

我目前通过以下方式为我的顶点着色器加载一些属性:

glBindBuffer(GL_ARRAY_BUFFER, MeshVBs[eyeNum]->GLBuffer);
UINT stride = sizeof(ovrDistortionVertex);
const VertexAttribDesc VertexDesc[] =
//Name, Size, Type, Normalized, Offset
{   {"Position",    2, GL_FLOAT, false, offsetof(ovrDistortionVertex, ScreenPosNDC)},
    {"inV", 1, GL_FLOAT, false, offsetof(ovrDistortionVertex, VignetteFactor)},
    {"inTexCoord0", 2, GL_FLOAT, false, offsetof(ovrDistortionVertex, TanEyeAnglesR)},
    {"inTexCoord1", 2, GL_FLOAT, false, offsetof(ovrDistortionVertex, TanEyeAnglesG)},
    {"inTexCoord2", 2, GL_FLOAT, false, offsetof(ovrDistortionVertex, TanEyeAnglesB)}    };
for (size_t i = 0; i < 5; i++)
{
    VertexAttribDesc vad = VertexDesc[i];
    glEnableVertexAttribArray((GLuint)i);   
    glVertexAttribPointer((GLuint)i, vad.Size, vad.Type, vad.Normalized, stride, reinterpret_cast<char*>(vad.Offset));
}

也就是使用的vertex shader

#version 330 core
uniform vec2 EyeToSourceUVScale;
uniform vec2 EyeToSourceUVOffset;
attribute vec2 Position;        
attribute float inT;                
attribute vec2 inTexCoord0; 
attribute vec2 inTexCoord1; 
attribute vec2 inTexCoord2;
varying vec4 oPosition;     
varying vec2 oTexCoord0;        
varying vec2 oTexCoord1;        
varying vec2 oTexCoord2;
varying float oVignette;
vec2 TexCoord0 = vec2((inTexCoord0.x), (-inTexCoord0.y));
vec2 TexCoord1 = vec2((inTexCoord1.x), (-inTexCoord1.y));
vec2 TexCoord2 = vec2((inTexCoord2.x), (-inTexCoord2.y));
float Vignette = inT;

vec2 normalizeTexCoord( in vec2 TexCoord )
{   
   return ( EyeToSourceUVScale*TexCoord) + EyeToSourceUVOffset;
}       

void main(){
    oTexCoord0 = normalizeTexCoord( TexCoord0);     
    oTexCoord1 = normalizeTexCoord( TexCoord1);     
    oTexCoord2 = normalizeTexCoord( TexCoord2); 
    oVignette = Vignette;
    gl_Position.xyzw = vec4( Position.xy , 0.500000, 1.00000);
}

行得通!但是,如果我将顶点着色器中的 "inT" 重命名为 "inV",则一切都不再有效。知道为什么它不起作用吗?

如果您需要有关上下文的更多信息来给出答案,请告诉我。

----解决方案----

在主循环之前:

UINT stride = sizeof(ovrDistortionVertex);
   const VertexAttribDesc VertexDesc[] =
       //Name, Size, Type, Normalized, Offset
   {   {"Position", 2, GL_FLOAT, false, offsetof(ovrDistortionVertex, ScreenPosNDC)},
   {"inVignette",   1, GL_FLOAT, false, offsetof(ovrDistortionVertex, VignetteFactor)},
   {"inTexCoord0", 2, GL_FLOAT, false, offsetof(ovrDistortionVertex, TanEyeAnglesR)},
   {"inTexCoord1", 2, GL_FLOAT, false, offsetof(ovrDistortionVertex, TanEyeAnglesG)},
   {"inTexCoord2", 2, GL_FLOAT, false, offsetof(ovrDistortionVertex, TanEyeAnglesB)}    };
   for (int i = 0;i<5;i++)
   {
       VertexAttribDesc vad = VertexDesc[i];
       glBindAttribLocation (shader_programm, i, vad.Name);
   }
   glLinkProgram(shader_programm);

在主循环中保留:

glBindBuffer(GL_ARRAY_BUFFER, MeshVBs[eyeNum]->GLBuffer);
for (size_t i = 0; i < 5; i++)
{
    VertexAttribDesc vad = VertexDesc[i];
    glEnableVertexAttribArray((GLuint)i);   
    glVertexAttribPointer((GLuint)i, vad.Size, vad.Type, vad.Normalized, stride, reinterpret_cast<char*>(vad.Offset));
}

和新的顶点着色器(片段着色器也改变了 varying -> in)

#version 330 core
uniform vec2 EyeToSourceUVScale;
uniform vec2 EyeToSourceUVOffset;
in vec2 Position;       
in float inVignette;                
in vec2 inTexCoord0;    
in vec2 inTexCoord1;    
in vec2 inTexCoord2;
out vec4 oPosition;     
out vec2 oTexCoord0;        
out vec2 oTexCoord1;        
out vec2 oTexCoord2;
out float oVignette;
vec2 TexCoord0 = vec2((inTexCoord0.x), (-inTexCoord0.y));
vec2 TexCoord1 = vec2((inTexCoord1.x), (-inTexCoord1.y));
vec2 TexCoord2 = vec2((inTexCoord2.x), (-inTexCoord2.y));
float Vignette = inVignette;

vec2 normalizeTexCoord( in vec2 TexCoord )
{   
   return ( EyeToSourceUVScale*TexCoord) + EyeToSourceUVOffset;
}       

void main(){
 oTexCoord0 = normalizeTexCoord( TexCoord0);        
 oTexCoord1 = normalizeTexCoord( TexCoord1);        
 oTexCoord2 = normalizeTexCoord( TexCoord2);    

    oVignette = Vignette;
    gl_Position.xyzw = vec4( Position.xy , 0.500000, 1.00000);
}

该语法对 330 core 着色器无效。您需要使用 GLSL 130 引入的新 inout 语法。这意味着在顶点着色器中,输入 (attribute) 全部变为 in,输出 (varying) 全部变为 out。在匹配的片段着色器中,顶点着色器的输出 (varying) 是输入,因此使用 in.

声明

综上所述,我没有看到您实际查询顶点属性的位置。许多驱动程序会自动按字母顺序分配属性位置,因此将 inT 更改为 inV 将更改其位置在 inTexCoord2.

之后

由于这是一个 GLSL 3.30 着色器,您可以选择在着色器中显式绑定属性位置,在 linking 之前从 API 绑定它们,或者在事后查询它们.

为了尽可能简单地完成这项工作,我会这样做:

const VertexAttribDesc VertexDesc[] =
//Name, Size, Type, Normalized, Offset
{   {"Position",    2, GL_FLOAT, false, offsetof(ovrDistortionVertex, ScreenPosNDC)},
    {"inV", 1, GL_FLOAT, false, offsetof(ovrDistortionVertex, VignetteFactor)},
    {"inTexCoord0", 2, GL_FLOAT, false, offsetof(ovrDistortionVertex, TanEyeAnglesR)},
    {"inTexCoord1", 2, GL_FLOAT, false, offsetof(ovrDistortionVertex, TanEyeAnglesG)},
    {"inTexCoord2", 2, GL_FLOAT, false, offsetof(ovrDistortionVertex, TanEyeAnglesB)}    };

for (size_t i = 0; i < 5; i++)
{
    VertexAttribDesc vad = VertexDesc[i];
    glBindAttribLocation (prog, i, vad.Name);
}

请记住,必须在 link GLSL 程序之前完成。在 link 操作期间分配属性位置。您可以稍后更改它们,但您必须重新link 程序。