【发布时间】:2016-09-19 23:19:54
【问题描述】:
几天来,我一直在为计算着色器和缓冲区苦苦挣扎。我查看了它们使用的多个示例,例如“The OpenGL redbook 8th edition”和线程“OpenGL vertices in shader storage buffer”和“OpenGL Compute Shader SSBO”,但我似乎无法让它工作。
目前,我正在尝试制作一个简单的程序,该程序可以通过调用计算着色器来生成顶点,将这些生成的顶点存储在 SSBO 中,将这些顶点传递给顶点着色器,然后执行其余部分管道来制作一个单一的、静止的图像,在这种情况下,它只是一条线。但是,编译程序后,仅显示 (0,0) 处的一个点。
计算着色器:
#version 430 core
layout(std430, binding = 0) buffer data
{
float coordinate_array[200][3];
};
layout(local_size_x=20, local_size_y=1, local_size_z=1) in;
void main(void)
{
uint x = gl_GlobalInvocationID.x;
if(x%2 == 0)
{
coordinate_array[x][0] = -.5;
coordinate_array[x][0] = -.5;
coordinate_array[x][0] = 0;
}
else
{
coordinate_array[x][0] = .5;
coordinate_array[x][0] = .5;
coordinate_array[x][0] = 0;
}
}
程序:
char *source;
GLuint vertexShader, fragmentShader, computeShader;
GLuint program, computeShaderProgram;
GLuint computeShaderBuffer;
numVertices = 200;
dimension = 3;
size = sizeof(float**)*numVertices*dimension;
//Create the buffer the compute shader will write to
glGenBuffers(1, &computeShaderBuffer);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, computeShaderBuffer);
glBufferData(GL_SHADER_STORAGE_BUFFER, size, NULL, GL_STATIC_DRAW);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, computeShaderBuffer);
//Create the compute shader
computeShader = glCreateShader(GL_COMPUTE_SHADER);
source = getSource(computeShaderSrc);
glShaderSource(computeShader, 1, &source, NULL);
glCompileShader(computeShader);
//Create and dispatch the compute shader program
computeShaderProgram = glCreateProgram();
glAttachShader(computeShaderProgram, computeShader);
glLinkProgram(computeShaderProgram);
glUseProgram(computeShaderProgram);
glDispatchCompute(numVertices/20, 1, 1);
//Generate the vertex array object
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
//Use buffer as a set of vertices
glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT);
glBindBuffer(GL_ARRAY_BUFFER, computeShaderBuffer);
//Create the vertex shader
vertexShader = glCreateShader(GL_VERTEX_SHADER);
source = getSource(vertexShaderSource);
glShaderSource(vertexShader, 1, &source, NULL);
//Create the fragment shader
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
source = getSource(fragmentShaderSource);
glShaderSource(fragmentShader, 1, &source, NULL);
glCompileShader(fragmentShader);
//Create the program to draw
program = glCreateProgram();
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);
glUseProgram(program);
//Enable the vertex array
glVertexAttribPointer(0, dimension, GL_FLOAT, 0, 0, (void*)0);
glEnableVertexAttribArray(0);
//Draw it
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(VAO);
glDrawArrays(GL_POINTS, 0, numVertices);
glFlush();
顶点着色器:
#version 430 core
layout(location = 0) in vec4 vPosition;
void main()
{
gl_Position = vPosition;
}
在此示例中,我尝试使用 SSBO 来保存线段的 2 个端点 (-.5, -.5) (.5, .5)。着色器存储缓冲区保存此段 100 次,而不是仅一次;我以为我没有达到最低调度要求。
如果我调用 glGetError(program) 或 glGetError(computeShaderProgram),它会返回 GL_NO_ERROR。此外,着色器编译成功,两个程序链接没有错误。但是,它确实警告我,由于某种原因,计算着色器中需要扩展 420pack。当我使用#extension ARB_420pack(不是我的确切写作)时,它并没有消除警告。我的驱动程序是最新的,我有一个 Radeon R9 270x (OpenGL 4.4)。我正在使用 MinGW 和 C 来创建这个程序,但我确实知道一些 C++。
有人对我做错了什么有任何想法吗?
【问题讨论】: