顶点着色器的 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 引入的新 in
和 out
语法。这意味着在顶点着色器中,输入 (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 程序。
我目前通过以下方式为我的顶点着色器加载一些属性:
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 引入的新 in
和 out
语法。这意味着在顶点着色器中,输入 (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 程序。