View Full Version : Compute shader doesnt update buffer

11-27-2014, 09:48 AM
Hello, its my first post : )

So the problem is that compute shader probably doesnt update vertex buffer. I followed the example from book OpenGL Programming Guide Eighth Edition. Chapter 12. After assing some random values to vectors in position_buffer (which is my vertexbuffer aswell) points appear random in the space but no motion which should comes from compute shader. So i belive that something is wrong with it. Here are the codes:

main c++ file:

#include "cube.h" //here are all libraries, will post if needed

#include <string>
//#include <glfw3.h>
GLFWwindow* window;
//#include <vector>
#include <iostream>
#include <AntTweakBar.h>
#include "camera.h"
#include "ship.h"
#include <iomanip>

using namespace std;

glm::mat4 cameraPosition(double);
Camera camera(glm::vec3(1,1,1)); //my own class Camera but works just fine

glm::vec3 vec1=glm::vec3(1,1,1);
int main( void )

srand (time(NULL));

int q2, q1,q3=1;

float w=1920,h=1080;

glm:: mat4 initProjectionMatrix = glm::perspective(45.0f,w /h, 0.1f, 1000000.0f);

// Initialise GLFW
if( !glfwInit() )
fprintf( stderr, "Failed to initialize GLFW\n" );
return -1;

glfwWindowHint(GLFW_SAMPLES, 4);

// Open a window and create its OpenGL context

window = glfwCreateWindow( w, h, "Kedrowski Dream", NULL, NULL);

if( window == NULL ){
fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n" );
return -1;

// Initialize GLEW
glewExperimental = true; // Needed for core profile
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
return -1;

// Ensure we can capture the escape key being pressed below
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);

glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT);

// Dark blue background
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

GLuint shader, program, renderProgram;
renderProgram=LoadShaders ( "SimpleVertexShaderOPT.txt", "SimpleFragmentShaderOPT.txt" );
GLuint MatrixID = glGetUniformLocation(renderProgram, "MVP");
GLuint dtID = glGetUniformLocation(program, "dt");

static const GLchar* source[] = //compute shader
"#version 430 core\n"
"layout (local_size_x = 128) in;\n"
"layout (rgba32f, binding = 0) uniform imageBuffer velocity_buffer;\n"
"layout (rgba32f, binding = 1) uniform imageBuffer position_buffer;\n"
"uniform float dt;\n"
"void main(void)\n"
"vec4 vel = imageLoad(velocity_buffer, int(gl_GlobalInvocationID.x));\n"
"vec4 pos = imageLoad(position_buffer, int(gl_GlobalInvocationID.x));\n"
"int i;\n"
"pos.xyz +=100;// vel.xyz * dt;\n"
"pos.w -= 0.0001 * dt expires, reset it\n"
"if (pos.w <= 0.0)\n"
"pos.xyz = -pos.xyz * 0.01;\n"
"vel.xyz *= 0.01;\n"
"pos.w += 1.0f;\n"
"// Store the new position and velocity back into the buffers\n"
"imageStore(position_buffer, int(gl_GlobalInvocationID.x), pos);\n"
"imageStore(velocity_buffer, int(gl_GlobalInvocationID.x), vel);\n"
shader = glCreateShader(GL_COMPUTE_SHADER);
glShaderSource(shader, 1, source, NULL);

program = glCreateProgram();
glAttachShader(program, shader);


// Generate two buffers, bind them and initialize their data stores
GLuint buffers, position_buffer, velocity_buffer, attractors_buffer;


// Generate two buffers, bind them and initialize their data stores
glGenBuffers(1, &position_buffer);
glBindBuffer(GL_ARRAY_BUFFER, position_buffer);
// Map the position buffer and fill it with random vectors
vec4 * positions = (vec4 *)glMapBufferRange(GL_ARRAY_BUFFER,0,PARTICLE_COUN T * sizeof(vec4),GL_MAP_WRITE_BIT |GL_MAP_INVALIDATE_BUFFER_BIT);
for (int i = 0; i < PARTICLE_COUNT; i++)
positions[i] = vec4(rand()%10, rand()%10, rand()%10,10);
// Initialization of the velocity buffer - also filled with random vectors
glGenBuffers(1, &velocity_buffer);
glBindBuffer(GL_ARRAY_BUFFER, velocity_buffer);
vec4 * velocities = (vec4 *)glMapBufferRange(GL_ARRAY_BUFFER,0,PARTICLE_COUN T * sizeof(vec4),GL_MAP_WRITE_BIT |GL_MAP_INVALIDATE_BUFFER_BIT);
for (int i = 0; i < PARTICLE_COUNT; i++)
velocities[i] = vec4(10.0f, 0.0f, 0.0f,0.0f);


do{ //start pętli wykonywującej
static double lastTime = glfwGetTime();
double currentTime = glfwGetTime();
double deltaTime = double(currentTime - lastTime);

// Clear the screen

// Activate the compute program and bind the position
// and velocity buffers
glBindImageTexture(0, velocity_buffer, 0,GL_FALSE, 0,GL_READ_WRITE, GL_RGBA32F);
glBindImageTexture(1, position_buffer, 0,GL_FALSE, 0,GL_READ_WRITE, GL_RGBA32F);

// Set delta time

glUniform1f(dtID, (float)deltaTime);

// Dispatch the compute shader
glDispatchCompute(PARTICLE_GROUP_COUNT, 1, 1);
// Ensure that writes by the compute shader have completed

glm::mat4 Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 1000000000000000.0f);

mat4 mvp=Projection *camera.cameraPositionFree(deltaTime); //my function, works ok

glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &mvp[0][0]);

// glBindVertexArray(position_buffer);
//glBlendFunc(GL_ONE, GL_ONE);

glBindBuffer(GL_ARRAY_BUFFER, position_buffer);
3, // attribute. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset

// Swap buffers

} // Check if the ESC key was pressed or the window was closed
while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
glfwWindowShouldClose(window) == 0 );

// Close OpenGL window and terminate GLFW

return 0;

Vertex Shader:

#version 330 core

// Input vertex data, different for all executions of this shader.
layout(location = 3) in vec3 vertexPosition_modelspace;

// Values that stay constant for the whole mesh.
uniform mat4 MVP;

void main(){

// Output position of the vertex, in clip space : MVP * position
gl_Position = MVP * vec4(vertexPosition_modelspace,1);


Fragment Shader:

#version 330 core

// Ouput data
out vec3 color;

void main()

// Output color = red
color = vec3(1,0,0);


Compute Shader:

#version 430 core
layout (local_size_x = 128) in;
layout (rgba32f, binding = 0) uniform imageBuffer velocity_buffer;
layout (rgba32f, binding = 1) uniform imageBuffer position_buffer;
uniform float dt;
void main(void)
vec4 vel = imageLoad(velocity_buffer, int(gl_GlobalInvocationID.x));
vec4 pos = imageLoad(position_buffer, int(gl_GlobalInvocationID.x));
int i;
pos.xyz += vel.xyz * dt; //even if i change dt or vel or both to some values it still doesnt change position_buffer anyhow
pos.w -= 0.0001 * dt;

// If the particle expires, reset it
if (pos.w <= 0.0)
pos.xyz = -pos.xyz * 0.01;
vel.xyz *= 0.01;
pos.w += 1.0f;
// Store the new position and velocity back into the buffers
imageStore(position_buffer, int(gl_GlobalInvocationID.x), pos);
imageStore(velocity_buffer, int(gl_GlobalInvocationID.x), vel);

The output of program is:


I can move around this cube of points so i assume that vertex shader and my own function from Camera class work OK