PDA

View Full Version : Compute shader doesnt update buffer



Kedriik
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);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

// 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" );
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);

// 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"
"{\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"
"{\n"
"pos.xyz = -pos.xyz * 0.01;\n"
"vel.xyz *= 0.01;\n"
"pos.w += 1.0f;\n"
"}\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"
"}\n"
};
shader = glCreateShader(GL_COMPUTE_SHADER);
glShaderSource(shader, 1, source, NULL);
glCompileShader(shader);

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



//glUseProgram(program);
//glUseProgram(renderProgram);



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

int PARTICLE_COUNT=100000,PARTICLE_GROUP_COUNT=128;

// Generate two buffers, bind them and initialize their data stores
glGenBuffers(1, &position_buffer);
glBindBuffer(GL_ARRAY_BUFFER, position_buffer);
glBufferData(GL_ARRAY_BUFFER,PARTICLE_COUNT * sizeof(vec4),NULL,GL_DYNAMIC_COPY);
// 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);
}
glUnmapBuffer(GL_ARRAY_BUFFER);
// Initialization of the velocity buffer - also filled with random vectors
glGenBuffers(1, &velocity_buffer);
glBindBuffer(GL_ARRAY_BUFFER, velocity_buffer);
glBufferData(GL_ARRAY_BUFFER,PARTICLE_COUNT * sizeof(vec4),NULL,GL_DYNAMIC_COPY);
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);
}
glUnmapBuffer(GL_ARRAY_BUFFER);


/////////////////////////////////////////////////////////////////////////////







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

// Clear the screen
glClear( GL_COLOR_BUFFER_BIT );



// Activate the compute program and bind the position
// and velocity buffers
glUseProgram(program);
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
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT );


///////////////////////////////////////////////////////////////
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
///////////////////////////////////


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

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


glEnableVertexAttribArray(3);
glBindBuffer(GL_ARRAY_BUFFER, position_buffer);
glVertexAttribPointer(
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
);
glDrawArrays(GL_POINTS, 0, PARTICLE_COUNT);


// Swap buffers
glfwSwapBuffers(window);
glfwPollEvents();

} // 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
glfwTerminate();

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:

1517

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

Thnaks