【问题标题】:Opengl shader bitwise operation not working in WindowsOpengl着色器按位操作在Windows中不起作用
【发布时间】:2021-11-15 13:32:36
【问题描述】:

我使用整数作为“过滤器”并将其传递给几何着色器并使用按位运算来获取位值。它适用于 macOS,但不适用于 Windows。为了说明我的观点,我使用并修改了 learnopengl.com 中几何着色器部分的教程代码,位于

https://learnopengl.com/Advanced-OpenGL/Geometry-Shader

根据教程代码,我在main.cpp中添加了如下代码。 (我添加了 enabledFaces[] 和 VFO,并将它们传递给着色器。)为简单起见,我只为每个 enableFaces[] 整数设置一位。

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 中不起作用以及如何解决它?谢谢。

【问题讨论】:

  • 我猜测了一下(如果我错了,我相信 OpenGL 专家之一会纠正我)但是如果你使用 glVertexAttribPointer 你的整数数据将被转换为浮点数并传递给顶点着色器,然后它将被转换回整数——所以你受这些转换和浮点表示的支配。尝试改用glVertexAttribIPointer
  • @G.M.伟大的!就是这样!我模糊地想到了类型转换,但它在 Mac 上工作的事实让我感到困惑。而且我不知道 glVertexAttribIPointer!
  • 现在,作为 StackOverflow 的新手,我不知道如何结束这个问题。也许,@G.M.可以发表您的评论作为答案然后我可以接受它作为答案?

标签: c++ opengl glsl shader bitwise-operators


【解决方案1】:

按照 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++ 和着色器中)都是整数类型。奇怪,但它有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    相关资源
    最近更新 更多