Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
普通OpenGL着色器存储缓冲区对象(SSBO)不工作_Opengl_Glsl_Buffer_Shader_Opengl 4 - Fatal编程技术网

普通OpenGL着色器存储缓冲区对象(SSBO)不工作

普通OpenGL着色器存储缓冲区对象(SSBO)不工作,opengl,glsl,buffer,shader,opengl-4,Opengl,Glsl,Buffer,Shader,Opengl 4,我试图用一个非常基本的例子来说明SSBO是如何工作的。顶点着色器: #version 430 layout(location = 0) in vec2 Vertex; void main() { gl_Position = vec4(Vertex, 0.0, 1.0); } 和片段着色器: #version 430 layout(std430, binding = 2) buffer ColorSSBO { vec3 color; }; void main() {

我试图用一个非常基本的例子来说明SSBO是如何工作的。顶点着色器:

#version 430

layout(location = 0) in vec2 Vertex;

void main() {
    gl_Position = vec4(Vertex, 0.0, 1.0);
}
和片段着色器:

#version 430

layout(std430, binding = 2) buffer ColorSSBO {
    vec3 color;
};

void main() {
    gl_FragColor = vec4(color, 1.0);
}
我知道它们是有效的,因为如果我将
vec4(颜色,1.0)
替换为
vec4(1.0,1.0,1.0,1.0)
我会在屏幕中央看到一个白色三角形

我使用以下代码初始化并绑定SSBO:

GLuint ssbo;
glGenBuffers(1, &ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
float color[] = {1.f, 1.f, 1.f};
glBufferData(GL_SHADER_STORAGE_BUFFER, 3*sizeof(float), color, GL_DYNAMIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);

这里有什么问题?

绘制三角形时,需要三个点,每个点需要三组单独的红-绿-蓝值。您只将一个集放入着色器缓冲区。对于其他两个点,颜色的值下降到默认值,即黑色(0.0,0.0,0.0)。如果未启用“混合”,则三角形很可能被绘制为完全黑色,因为其两个顶点为黑色


尝试将另外两组红-绿-蓝值放入存储缓冲区,以查看它是否会将它们作为其他两点的颜色值加载。

我猜您在渲染之前缺少SSBO绑定。在您的示例中,您正在复制内容,然后立即绑定它,这对于声明是不必要的。换句话说,示例中的以下行:

...
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, ssbo);
...
必须在渲染之前放置,例如:

...
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, ssbo);

/*
 Your render calls and other bindings here.
*/

glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
...
如果没有此选项,着色器(理论上)将无法看到内容

此外,正如前面所建议的,在声明数组时必须对元素使用填充(例如,使用vec4而不是vec3)。如果你不这样做,它显然会起作用,但由于这个事实会产生奇怪的结果

以下两个链接帮助我理解SSBO的含义以及如何在代码中处理它们:

我希望这对任何面临类似问题的人都有帮助


附言:我知道这篇文章很老了,但我想有所贡献。

你的使用标志让我觉得有点奇怪,尽管我从未对它们有过任何信心。您已经告诉德国劳埃德船级社,这个缓冲区将填充您从其他缓冲区复制的数据,但是。。。当您分配缓冲区时,您正在用客户机本身的数据填充它。我一直认为这些提示是安慰剂,但你永远不知道——这可能是世界上第一个真正接受这些提示的司机?:)您是否尝试过更具逻辑性的
GL\u DYNAMIC\u DRAW
用法提示?如果您尝试将此SSBO扩展到阵列中,您将遇到对齐问题。您需要将
color
更改为
vec4
或在其后面立即放置一个
float
。不过我相信你知道这一点。其想法是使用该缓冲区实现链表顺序独立透明,因此它将被片段着色器写入然后只读,但同时我正在用主机数据测试它。我尝试了你的两个建议,但我看到的仍然是一个黑屏:(非常令人沮丧。着色器编译器/链接器是否向您提供了任何错误日志信息?我可以很容易地想象片段着色器在使用恒定颜色时工作,但在SSBO声明出现问题时使用
color
时不工作。不会引发任何错误。我使用标准代码t检查编译和链接从官方教程上看,然后我用assert(glGetError()==GL_NO_ERROR)进行了双重检查。我已经更改了清晰的颜色,现在使用SSBO时,我看到一个黑色三角形。似乎由于一个神秘的原因,数据没有上传。我想知道这是否是驱动程序问题。代码非常简单,我找不到任何滥用API的情况。