I use an integer to use as a "filter" and pass it to a geometric shader and use a bitwise operation to get the bit values. It works in macOS, but not in Windows. To show my point, I used and modified the tutorial code in the geometric shader part in the learnopengl.com found at
https://learnopengl.com/Advanced-OpenGL/Geometry-Shader
Based on the tutorial code, I added the following code in the main.cpp. (I added enabledFaces[] and VFO, and passed them to the shaders.) I only set one bit to each enabledFaces[] integer for simplicity.
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);
In the vertex shader as a pass-through:
#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;
}
And the geometric shader (added the if statement with the gEnabledFaces):
##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);
}
No change in the fragment shader:
#version 330 core
out vec4 FragColor;
in vec3 fColor;
void main()
{
FragColor = vec4(fColor, 1.0);
}
Due to the if statement in the main() in the geometric shader, two houses (the first and the third polygons) out of the 4 polygons should be displayed. It works correctly on Mac, but nothing is displayed in Windows. If I remove the if statement in Windows, all polygons display correctly. Would someone please explain why this does not work in Windows and how to fix it? Thank you.
As suggested by G.M., the use of glVertexAttribIPointer solves the problem.
But I use Qt and unfortunately, it seems that glVertexAttribIPointer is not available. So I changed the glVertexAttribPointer to float type instead of an integer type. So,
Changing from glVertexAttribPointer(2, 1, GL_INT, GL_FALSE, sizeof(int), 0);
to glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(float), 0);
Then it works in Windows, in spite of the fact that the passing variables (in the C++ and also in shaders) are all integer type. Strange but it works.