2

For a few days now, I've been struggling with compute shaders and buffers. I've looked through multiple examples of their usage, such as in "The OpenGL redbook 8th edition" and on the threads "OpenGL vertices in shader storage buffer" and "OpenGL Compute Shader SSBO," but I can't seem to get this working.

I'm trying to make, for now, a simple program that can generate vertices by invoking a compute shader, store those generated vertices in an SSBO, pass those vertices to a vertex shader, and then go through the rest of the pipeline to make a single, stationary image, which, in this case, is just a line. However, after compiling the program, only a dot at (0,0) is shown.

The compute shader:

#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;
  }
} 

Program:

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();

Vertex Shader:

#version 430 core

layout(location = 0) in vec4 vPosition;

void main()
{
  gl_Position = vPosition;
}

In this sample, I try to use an SSBO to hold the 2 endpoints of a line segment (-.5, -.5) (.5, .5). The shader storage buffer holds this segment 100 times instead of just once; I thought there was a dispatch minimum I wasn't meeting.

If I call glGetError(program) or glGetError(computeShaderProgram), it returns GL_NO_ERROR. Also, the shaders compile successfully and both programs link without error. It does, however, warn me that extension 420pack is required in the compute shader for some reason. When I used #extension ARB_420pack (not my exact writing), it didn't get rid of the warning. My drivers are up-to-date and I have a Radeon R9 270x (OpenGL 4.4). I'm using MinGW and C to create this program, but I do know some C++.

Does anyone have any ideas on what I'm doing wrong?

Community
  • 1
  • 1

1 Answers1

3

Does this seem right in your CS:

  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;
  }

look carefully at the indices you assign to. It's always [x][0]. Clearly you want at least one index to vary.

datenwolf
  • 159,371
  • 13
  • 185
  • 298