如果我想在同一程序的不同着色器阶段中使用制服,如何指定显式统一位置?
使用自动分配时,不同阶段的制服在标识符匹配时分配到同一位置。但是如何使用
在着色器中定义位置layout (location = ...)
语法?
以下引用: https://www.opengl.org/wiki/Uniform_(GLSL)/Explicit_Uniform_Location
将相同的统一位置分配给同一着色器或同一程序中的两个制服是违法的。即使这两个制服具有相同的名称和类型,并且在不同的着色器阶段中定义,但明确地为它们分配相同的统一位置是不合法的。将发生链接器错误。
以下引用GLSL规范:
程序中没有两个默认块统一变量可以具有相同的位置, 即使它们未被使用,否则将产生编译时或链接时错误。
我正在使用OpenGL 4.3。
由于阅读了很多代码,我发现,制服没用了。 这导致以下情况:在 GTX 780 上,以下代码运行没有问题(虽然它似乎不应该)。在 Intel HD 5500 板载图形芯片上,根据 GL_ARB_DEBUG_OUTPUT 扩展,代码在链接时产生 SHADER_ID_LINK 错误。它指出,统一的位置与另一个制服重叠。
顶点着色器:
#version 430 core
layout(location = 0) in vec4 vPosition;
layout(location = 2) in vec4 vTexCoord;
layout(location = 0) uniform mat4 WorldMatrix; // <-- unused in both stages
out vec4 fPosition;
out vec4 fTexCoord;
void main() { ... }
Fragment Shader:
#version 430 core
in vec4 fPosition;
in vec4 fTexCoord;
layout(location = 0) out vec4 Albedo;
layout(location = 1) out vec4 Normal;
layout(location = 0) uniform mat4 WorldMatrix; // <-- unused in both stages
layout(location = 1) uniform mat4 InverseViewProjectionMatrix;
layout(location = 2) uniform samplerCube Cubemap;
void main() { ... }
但是,使用制服时,不会出现问题。假设我正确地解释了GLSL Spec,这似乎并不像它所假设的那样。虽然,这正是我希望它发挥作用的方式。
当没有使用制服时,仍存在重叠制服的问题。
答案 0 :(得分:2)
请参阅complete GL+VAO/VBO+GLSL+shaders example in C++
在GPU方面:
#version 400 core
layout(location = 0) in vec3 pos;
不确定从哪个位置添加布局位置,但对于400+
,它肯定会起作用
VBO pos
设置为位置0
在CPU端:
// globals
GLuint vbo[4]={-1,-1,-1,-1};
GLuint vao[4]={-1,-1,-1,-1};
const GLfloat vao_pos[]=
{
// x y z //ix
-1.0,-1.0,-1.0, //0
+1.0,-1.0,-1.0, //1
+1.0,+1.0,-1.0, //2
-1.0,+1.0,-1.0, //3
-1.0,-1.0,+1.0, //4
+1.0,-1.0,+1.0, //5
+1.0,+1.0,+1.0, //6
-1.0,+1.0,+1.0, //7
};
// init
GLuint i;
glGenVertexArrays(4,vao);
glGenBuffers(4,vbo);
glBindVertexArray(vao[0]);
i=0; // VBO location
glBindBuffer(GL_ARRAY_BUFFER,vbo[i]);
glBufferData(GL_ARRAY_BUFFER,sizeof(vao_pos),vao_pos,GL_STATIC_DRAW);
glEnableVertexAttribArray(i);
glVertexAttribPointer(i,3,GL_FLOAT,GL_FALSE,0,0);
将data
附加到location
时
然后你需要在单个阶段内使用它的所有着色器中为它设置 单个阶段是指单个/一组 通过单阶段开始,您可以假设每次 [edit2]以下是非nVidia驱动程序的制服 顶点着色器: 片段着色器: 这些是来自链接示例的重写着色器,其中布局位置用于制服。你必须添加: 用于 在CPU端像往常一样使用 或定义的位置: 看起来 nVidia 编译器以不同方式处理位置。如果它无法正常运行,请尝试解决有缺陷的驱动程序的解决方法,以设置每种数据类型具有不同步骤的位置:layout location
。您不能同时将同一位置分配给多个 VBO (这是您复制的所有状态)。glDrawArrays/glDrawElements
个调用而不更改着色器设置。如果您有更多着色器程序阶段(多个片段/顶点/几何体......),则可以为每个阶段设置不同的位置,但在每个阶段内,其所有着色器程序必须具有相同的位置设置。glUseProgram(prog_id);
来电,并以glUseProgram(0);
或其他阶段开始结束...... // Vertex
#version 400 core
#extension GL_ARB_explicit_uniform_location : enable
layout(location = 0) in vec3 pos;
layout(location = 2) in vec3 nor;
layout(location = 3) in vec3 col;
layout(location = 0) uniform mat4 m_model; // model matrix
layout(location =16) uniform mat4 m_normal; // model matrix with origin=(0,0,0)
layout(location =32) uniform mat4 m_view; // inverse of camera matrix
layout(location =48) uniform mat4 m_proj; // projection matrix
out vec3 pixel_pos; // fragment position [GCS]
out vec3 pixel_col; // fragment surface color
out vec3 pixel_nor; // fragment surface normal [GCS]
void main()
{
pixel_col=col;
pixel_pos=(m_model*vec4(pos,1)).xyz;
pixel_nor=(m_normal*vec4(nor,1)).xyz;
gl_Position=m_proj*m_view*m_model*vec4(pos,1);
}
// Fragment
#version 400 core
#extension GL_ARB_explicit_uniform_location : enable
layout(location =64) uniform vec3 lt_pnt_pos;// point light source position [GCS]
layout(location =67) uniform vec3 lt_pnt_col;// point light source color&strength
layout(location =70) uniform vec3 lt_amb_col;// ambient light source color&strength
in vec3 pixel_pos; // fragment position [GCS]
in vec3 pixel_col; // fragment surface color
in vec3 pixel_nor; // fragment surface normal [GCS]
out vec4 col;
void main()
{
float li;
vec3 c,lt_dir;
lt_dir=normalize(lt_pnt_pos-pixel_pos); // vector from fragment to point light source in [GCS]
li=dot(pixel_nor,lt_dir);
if (li<0.0) li=0.0;
c=pixel_col*(lt_amb_col+(lt_pnt_col*li));
col=vec4(c,1.0);
}
#extension GL_ARB_explicit_uniform_location : enable
400
个人资料以使其有效glGetUniformLocation
id=glGetUniformLocation(prog_id,"lt_pnt_pos"); glUniform3fv(id,1,lt_pnt_pos);
id=glGetUniformLocation(prog_id,"lt_pnt_col"); glUniform3fv(id,1,lt_pnt_col);
id=glGetUniformLocation(prog_id,"lt_amb_col"); glUniform3fv(id,1,lt_amb_col);
glGetFloatv(GL_MODELVIEW_MATRIX,m);
id=glGetUniformLocation(prog_id,"m_model" ); glUniformMatrix4fv(id,1,GL_FALSE,m);
m[12]=0.0; m[13]=0.0; m[14]=0.0;
id=glGetUniformLocation(prog_id,"m_normal" ); glUniformMatrix4fv(id,1,GL_FALSE,m);
for (i=0;i<16;i++) m[i]=0.0; m[0]=1.0; m[5]=1.0; m[10]=1.0; m[15]=1.0;
id=glGetUniformLocation(prog_id,"m_view" ); glUniformMatrix4fv(id,1,GL_FALSE,m);
glGetFloatv(GL_PROJECTION_MATRIX,m);
id=glGetUniformLocation(prog_id,"m_proj" ); glUniformMatrix4fv(id,1,GL_FALSE,m);
id=64; glUniform3fv(id,1,lt_pnt_pos);
id=67; glUniform3fv(id,1,lt_pnt_col);
id=70; glUniform3fv(id,1,lt_amb_col);
glGetFloatv(GL_MODELVIEW_MATRIX,m);
id= 0; glUniformMatrix4fv(id,1,GL_FALSE,m);
m[12]=0.0; m[13]=0.0; m[14]=0.0;
id=16; glUniformMatrix4fv(id,1,GL_FALSE,m);
for (i=0;i<16;i++) m[i]=0.0; m[0]=1.0; m[5]=1.0; m[10]=1.0; m[15]=1.0;
id=32; glUniformMatrix4fv(id,1,GL_FALSE,m);
glGetFloatv(GL_PROJECTION_MATRIX,m);
id=48; glUniformMatrix4fv(id,1,GL_FALSE,m);
float,int,bool
double
vec3
vec4
dvec3
dvec4
mat3
mat4