Opengl 着色器按位操作在 Windows 中不起作用
Opengl shader bitwise operation not working in Windows
我使用整数作为“过滤器”并将其传递给几何着色器并使用按位运算来获取位值。它适用于 macOS,但不适用于 Windows。为了表明我的观点,我使用并修改了位于
的 learnopengl.com 中几何着色器部分的教程代码
https://learnopengl.com/Advanced-OpenGL/Geometry-Shader
我在教程代码的基础上,在main.cpp中添加了如下代码。 (我添加了 enabledFaces[] 和 VFO,并将它们传递给着色器。)为了简单起见,我只为每个 enabledFaces[] 整数设置一位。
int enabledFaces[] = {
1 << 0, 1 << 1, 1 << 2, 1 << 3
};
unsigned int VBO, VAO, VFO;
glGenBuffers(1, &VBO);
glGenBuffers(1, &VFO);
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(points), &points, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), 0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(2 * sizeof(float)));
glBindVertexArray(VFO);
glBindBuffer(GL_ARRAY_BUFFER, VFO);
glBufferData(GL_ARRAY_BUFFER, sizeof(enabledFaces), &enabledFaces, GL_STATIC_DRAW);
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 1, GL_INT, GL_FALSE, sizeof(int), 0);
glBindVertexArray(0);
在顶点着色器中作为直通:
#version 330 core
layout (location = 0) in vec2 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in int vEnabledFaces;
out int gEnabledFaces;
out VS_OUT {
vec3 color;
} vs_out;
void main() {
vs_out.color = aColor;
gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0);
gEnabledFaces = vEnabledFaces;
}
和几何着色器(添加带有 gEnabledFaces 的 if 语句):
##version 330 core
layout (points) in;
layout (triangle_strip, max_vertices = 5) out;
in int gEnabledFaces[];
in VS_OUT {
vec3 color;
} gs_in[];
out vec3 fColor;
void build_house(vec4 position)
{
fColor = gs_in[0].color; // gs_in[0] since there's only one input vertex
gl_Position = position + vec4(-0.2, -0.2, 0.0, 0.0); // 1:bottom-left
EmitVertex();
gl_Position = position + vec4( 0.2, -0.2, 0.0, 0.0); // 2:bottom-right
EmitVertex();
gl_Position = position + vec4(-0.2, 0.2, 0.0, 0.0); // 3:top-left
EmitVertex();
gl_Position = position + vec4( 0.2, 0.2, 0.0, 0.0); // 4:top-right
EmitVertex();
gl_Position = position + vec4( 0.0, 0.4, 0.0, 0.0); // 5:top
fColor = vec3(1.0, 1.0, 1.0);
EmitVertex();
EndPrimitive();
}
void main() {
if ( (gEnabledFaces[0] & 0x01) != 0 || (gEnabledFaces[0] & 0x04) != 0)
build_house(gl_in[0].gl_Position);
}
片段着色器没有变化:
#version 330 core
out vec4 FragColor;
in vec3 fColor;
void main()
{
FragColor = vec4(fColor, 1.0);
}
由于几何着色器的 main() 中的 if 语句,应显示 4 个多边形中的两个房屋(第一个和第三个多边形)。它在 Mac 上工作正常,但在 Windows 上没有任何显示。如果我删除 Windows 中的 if 语句,所有多边形都会正确显示。请有人解释为什么这在 Windows 中不起作用以及如何解决它?谢谢。
根据G.M的建议,使用glVertexAttribIPointer解决了问题。
但我使用 Qt,不幸的是,glVertexAttribIPointer 似乎不可用。所以我将 glVertexAttribPointer 更改为浮点类型而不是整数类型。所以,
从
glVertexAttribPointer(2, 1, GL_INT, GL_FALSE, sizeof(int), 0);
到
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(float), 0);
然后它在 Windows 中工作,尽管传递变量(在 C++ 和着色器中)都是整数类型。奇怪,但它有效。
我使用整数作为“过滤器”并将其传递给几何着色器并使用按位运算来获取位值。它适用于 macOS,但不适用于 Windows。为了表明我的观点,我使用并修改了位于
的 learnopengl.com 中几何着色器部分的教程代码https://learnopengl.com/Advanced-OpenGL/Geometry-Shader
我在教程代码的基础上,在main.cpp中添加了如下代码。 (我添加了 enabledFaces[] 和 VFO,并将它们传递给着色器。)为了简单起见,我只为每个 enabledFaces[] 整数设置一位。
int enabledFaces[] = {
1 << 0, 1 << 1, 1 << 2, 1 << 3
};
unsigned int VBO, VAO, VFO;
glGenBuffers(1, &VBO);
glGenBuffers(1, &VFO);
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(points), &points, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), 0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(2 * sizeof(float)));
glBindVertexArray(VFO);
glBindBuffer(GL_ARRAY_BUFFER, VFO);
glBufferData(GL_ARRAY_BUFFER, sizeof(enabledFaces), &enabledFaces, GL_STATIC_DRAW);
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 1, GL_INT, GL_FALSE, sizeof(int), 0);
glBindVertexArray(0);
在顶点着色器中作为直通:
#version 330 core
layout (location = 0) in vec2 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in int vEnabledFaces;
out int gEnabledFaces;
out VS_OUT {
vec3 color;
} vs_out;
void main() {
vs_out.color = aColor;
gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0);
gEnabledFaces = vEnabledFaces;
}
和几何着色器(添加带有 gEnabledFaces 的 if 语句):
##version 330 core
layout (points) in;
layout (triangle_strip, max_vertices = 5) out;
in int gEnabledFaces[];
in VS_OUT {
vec3 color;
} gs_in[];
out vec3 fColor;
void build_house(vec4 position)
{
fColor = gs_in[0].color; // gs_in[0] since there's only one input vertex
gl_Position = position + vec4(-0.2, -0.2, 0.0, 0.0); // 1:bottom-left
EmitVertex();
gl_Position = position + vec4( 0.2, -0.2, 0.0, 0.0); // 2:bottom-right
EmitVertex();
gl_Position = position + vec4(-0.2, 0.2, 0.0, 0.0); // 3:top-left
EmitVertex();
gl_Position = position + vec4( 0.2, 0.2, 0.0, 0.0); // 4:top-right
EmitVertex();
gl_Position = position + vec4( 0.0, 0.4, 0.0, 0.0); // 5:top
fColor = vec3(1.0, 1.0, 1.0);
EmitVertex();
EndPrimitive();
}
void main() {
if ( (gEnabledFaces[0] & 0x01) != 0 || (gEnabledFaces[0] & 0x04) != 0)
build_house(gl_in[0].gl_Position);
}
片段着色器没有变化:
#version 330 core
out vec4 FragColor;
in vec3 fColor;
void main()
{
FragColor = vec4(fColor, 1.0);
}
由于几何着色器的 main() 中的 if 语句,应显示 4 个多边形中的两个房屋(第一个和第三个多边形)。它在 Mac 上工作正常,但在 Windows 上没有任何显示。如果我删除 Windows 中的 if 语句,所有多边形都会正确显示。请有人解释为什么这在 Windows 中不起作用以及如何解决它?谢谢。
根据G.M的建议,使用glVertexAttribIPointer解决了问题。
但我使用 Qt,不幸的是,glVertexAttribIPointer 似乎不可用。所以我将 glVertexAttribPointer 更改为浮点类型而不是整数类型。所以,
从 glVertexAttribPointer(2, 1, GL_INT, GL_FALSE, sizeof(int), 0);
到 glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(float), 0);
然后它在 Windows 中工作,尽管传递变量(在 C++ 和着色器中)都是整数类型。奇怪,但它有效。