Marcel
Marcel

Reputation: 131

OpenGL c++ Transform Feedback values do not update

We are currently working on a GPU Particle System. Something on my implementation is wrong, it seems the Buffers do not get updated or drawn to.

I would be very grateful for any help!

Particle system init:

Particle Particles[MaxParticles];

Particles[0].Type = 0;
Particles[0].Pos = glm::vec3(12.f, 14.f, 17.f);// getCamPos();
Particles[0].Vel = glm::vec3(0.0f, 0.0341f, 0.0f);
Particles[0].LifetimeMillis = 0.0f;

currTransFeedBuffer = 1;
currVertBuffer = 0;

glGenTransformFeedbacks(2, transFeedBackBuffers);
glGenBuffers(2, particleBuffers);

for (unsigned int i = 0; i < 2; i++) {
    glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transFeedBackBuffers[i]);
    glBindBuffer(GL_ARRAY_BUFFER, particleBuffers[i]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Particles), Particles, GL_DYNAMIC_DRAW);
    glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, particleBuffers[i]);
}

particle system update:

particleShader.useShader();


auto m_deltaTimeMillisLocation      = glGetUniformLocation(particleShader.programHandle, "gDeltaTimeMillis");
auto m_timeLocation                     = glGetUniformLocation(particleShader.programHandle, "gTime");
auto m_launcherLifetimeLocation         = glGetUniformLocation(particleShader.programHandle, "gLauncherLifetime");
auto m_shellLifetimeLocation                = glGetUniformLocation(particleShader.programHandle, "gShellLifetime");
auto m_secondaryShellLifetimeLocation   = glGetUniformLocation(particleShader.programHandle, "gSecondaryShellLifetime");

glUniform1f(m_deltaTimeMillisLocation, (float)delta);
glUniform1f(m_timeLocation, (float)glfwGetTime());
glUniform1f(m_launcherLifetimeLocation, 10.f);
glUniform1f(m_shellLifetimeLocation, 3.f);
glUniform1f(m_secondaryShellLifetimeLocation, 1.5f);

glEnable(GL_RASTERIZER_DISCARD);

glBindBuffer(GL_ARRAY_BUFFER, particleBuffers[currVertBuffer]);
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transFeedBackBuffers[currTransFeedBuffer]);

cout << "update bind buffer " << "particleBuffers" << " -> " << currVertBuffer << endl;
cout << "update bind TF " << "transFeedBackBuffers" << " -> " << currTransFeedBuffer << endl;

glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(3);

glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, sizeof(Particle), 0);                          // type
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Particle), (const GLvoid*)4);         // position
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Particle), (const GLvoid*)16);        // velocity
glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, sizeof(Particle), (const GLvoid*)28);          // lifetime

glBeginTransformFeedback(GL_POINTS);

if (firstParticles) {
    glDrawArrays(GL_POINTS, 0, 1);

    firstParticles = false;
}
else {
    glDrawTransformFeedback(GL_POINTS, transFeedBackBuffers[currVertBuffer]);
}

glEndTransformFeedback();

glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glDisableVertexAttribArray(3);

glDisable(GL_RASTERIZER_DISCARD);

I did not spent much time on the Draw call. My Initial plan was to draw instanced, need more research for this, thats why i tried to get the particle simulation to run first.

    shader->useShader();
    glBindBuffer(GL_ARRAY_BUFFER, particleBuffers[currTransFeedBuffer]);
glDrawTransformFeedback(GL_POINTS,transFeedBackBuffers[currTransFeedBuffer]);

    GLuint temp = currVertBuffer;
    currVertBuffer = currTransFeedBuffer;
    currTransFeedBuffer = temp;

I have also have troubles debugging this code, i used

glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transFeedBackBuffers[currTransFeedBuffer]); 
GLfloat feedback[20];
glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(feedback), feedback);
cout << currTransFeedBuffer << "-------------"<< endl;
for (int i = 0; i < 20; i++) {
    cout << feedback[i] << " - ";
}
cout << endl;

to check the buffer data, it seems to be always just the one element i set in the init, not changing.

Shader class:

Shader::Shader(const string& vertexShader, const string& geoShader, const string& fragmentShader)
: programHandle(0){
programHandle = glCreateProgram();

if (programHandle == 0) {
    cerr << "ERROR: Failed to create programm" << endl;
    system("PAUSE");
    exit(EXIT_FAILURE);
}

GLuint vertexHandle;
GLuint fragmentHandle;
GLuint geoHandle;

loadShader(vertexShader, GL_VERTEX_SHADER, vertexHandle);
loadShader(geoShader, GL_GEOMETRY_SHADER, geoHandle);
loadShader(fragmentShader, GL_FRAGMENT_SHADER, fragmentHandle);

glAttachShader(programHandle, vertexHandle);
glAttachShader(programHandle, fragmentHandle);
glAttachShader(programHandle, geoHandle);

const GLchar* Varyings[4];
Varyings[0] = "Type1";
Varyings[1] = "Position1";
Varyings[2] = "Velocity1";
Varyings[3] = "Age1";

glTransformFeedbackVaryings(programHandle, 4, Varyings, GL_INTERLEAVED_ATTRIBS);

glLinkProgram(programHandle);

}

vert shader:

#version 330                                                                        

layout (location = 0) in float Type;                                                
layout (location = 1) in vec3 Position;                                             
layout (location = 2) in vec3 Velocity;                                             
layout (location = 3) in float Age;                                                 

out float Type0;                                                                    
out vec3 Position0;                                                                 
out vec3 Velocity0;                                                                 
out float Age0;                                                                     

void main()                                                                         
{                                                                                   
    Type0 = Type;                                                                   
    Position0 = Position;                                                           
    Velocity0 = Velocity;                                                           
    Age0 = Age;                                                                     
}

GeometryShader:

#version 330                                                                        

layout(points) in;                                                                  
layout(points) out;                                                                 
layout(max_vertices = 30) out;                                                      

in float Type0[];                                                                   
in vec3 Position0[];                                                                
in vec3 Velocity0[];                                                                
in float Age0[];                                                                    

out float Type1;                                                                    
out vec3 Position1;                                                                 
out vec3 Velocity1;                                                                 
out float Age1;                                                                     

#define PARTICLE_TYPE_LAUNCHER 0.0f                                                 

vec3 GetRandomDir(float TexCoord)                                                   
{                                                                                   
     return vec3(0.5, 0.5, 0.5);                                                                     
}                                

void main() {

        float Age = Age0[0] + gDeltaTimeMillis;

        Type1       = PARTICLE_TYPE_LAUNCHER;                                             
        Position1   = Position0[0];                                                   
        Velocity1   = Velocity0[0];                                                   
        Age1        = Age;                                                                 
        EmitVertex();                                                               
        EndPrimitive(); 

}   

Maybe my tunnel Vision is to strong already, but i worked myself to a lot of tuts, threads and examples, i don't get whats wrong! I hope someone can help me out, greetings!

Upvotes: 2

Views: 157

Answers (0)

Related Questions