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
" );
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.
" );
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
// Initialize GLEW
glewExperimental = true; // Needed for core profile
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW
");
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
"
"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 +=100;// vel.xyz * dt;
"
"pos.w -= 0.0001 * dt 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);
"
"}
"
};
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_COUNT * 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_COUNT * 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:
[ATTACH=CONFIG]808[/ATTACH]
I can move around this cube of points so i assume that vertex shader and my own function from Camera class work OK
Thnaks