PDA

View Full Version : Transform feedback problem



chachacha
03-02-2016, 01:16 PM
Greetings:
I am trying to write a particle system using transform feedback starting as simply as possible: one particle which moves straight until it hits a boundary to be replaced by two with application of pingpong buffering. The relevant part of the code is below.

Everything works fine except when I destroy the initial particle and try to create two new ones. Only the first one seems to update the transform feedback buffer, not the second. Please see the geometry shader down below where I explain the problem in comments.

Thanks,
Cha



static Particle testSet[1] = // Initial coordinates, velocity of one particle.
{
vec4(0.0, 0.0, 0.0, 1.0), vec3(1.0, 0.0, 0.0)
};
static const char * varyings[] = {"newCoords", "newVel"};
// Initialization
void initialize(void)
{
...
glTransformFeedbackVaryings(programId, 2, varyings, GL_INTERLEAVED_ATTRIBS);
...
// Pingpong buffers.
glBindVertexArray(vao[0]);
glBindBuffer(GL_ARRAY_BUFFER, buffer[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(testSet), testSet, GL_DYNAMIC_COPY);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(testSet[0]), 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(testSet[0]), (void*)sizeof(testSet[0].coords));
glEnableVertexAttribArray(1);

glBindVertexArray(vao[1]);
glBindBuffer(GL_ARRAY_BUFFER, buffer[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(testSet), NULL, GL_DYNAMIC_COPY);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(testSet[0]), 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(testSet[0]), (void*)sizeof(testSet[0].coords));
glEnableVertexAttribArray(1);
...
}


//Drawing
void draw(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

if (frameParity == 0)
{
glBindVertexArray(vao[0]);
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedback[0]);
glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buffer[1]);
glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(testSet), NULL, GL_DYNAMIC_COPY);
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buffer[1]);
glBeginTransformFeedback(GL_POINTS);
if (firstFrame == 1)
{
glDrawArrays(GL_POINTS, 0, 2);
firstFrame = 0;
}
else
glDrawTransformFeedback(GL_POINTS, transformFeedback[1]);
glEndTransformFeedback();
}

else
{
glBindVertexArray(vao[1]);
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedback[1]);
glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buffer[0]);
glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(testSet), NULL, GL_DYNAMIC_COPY);
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buffer[0]);
glBeginTransformFeedback(GL_POINTS);
glDrawTransformFeedback(GL_POINTS, transformFeedback[0]);
glEndTransformFeedback();
}

glutSwapBuffers();
}


// Pass-through vertex shader
#version 430 core

layout(location=0) in vec4 particleCoords;
layout(location=1) in vec3 particleVel;

out vec4 coords;
out vec3 vel;

void main(void)
{
coords = particleCoords;
vel = particleVel;
}


// Geometry shader
#version 430 core

layout(points) in;
layout(points, max_vertices=3) out;

uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;

in vec4 coords[];
in vec3 vel[];

out vec4 newCoords;
out vec3 newVel;

void main(void)
{
if (coords[0].x < 90.0 && coords[0].x > -90.0 && coords[0].y < 90.0 && coords[0].y > -90.0) // Within boundary.
// THIS IF PART WORKS FINE - INITIAL PARTICLE MOVING AS IT'S SUPPOSED TO WITHIN THE BOUNDARY.
{
newCoords = coords[0] + vec4(vel[0], 0.0);
newVel = vel[0];
gl_Position = projectionMatrix * modelViewMatrix * coords[0];
EmitVertex( );
EndPrimitive( );
}
else
// THIS IS WHERE THE PROBLEM IS. WHEN THE INITIAL PARTICLE HITS THE BOUNDARY I WANT TO
// GENERATE TWO PARTICLES AS BELOW. HOWEVER, ONLY THE FIRST PARTICLE IS DRAWN MOVING
// AS ITS SUPPOSED. THE SECOND PARTICLE IS NOT DRAWN AT ALL. WHICH MEANS newCoords/newVal
// BELOW AREN'T WRITING INTO THE TRANSFORM FEEDBACK BUFFER. WHY?
{
newCoords = vec4(50.0, 0.0, 0.0, 1.0);
newVel = vec3(-1.0, 0.0, 0.0);
EmitVertex( );
EndPrimitive( );

newCoords = vec4(-50.0, 0.0, 0.0, 1.0);
newVel = vec3(1.0, 0.0, 0.0);
EmitVertex( );
EndPrimitive( );

}
}

mamannon
03-03-2016, 02:05 AM
[/CODE]

void main(void)
{
if (coords[0].x < 90.0 && coords[0].x > -90.0 && coords[0].y < 90.0 && coords[0].y > -90.0) // Within boundary.
// THIS IF PART WORKS FINE - INITIAL PARTICLE MOVING AS IT'S SUPPOSED TO WITHIN THE BOUNDARY.
{
newCoords = coords[0] + vec4(vel[0], 0.0);
newVel = vel[0];
gl_Position = projectionMatrix * modelViewMatrix * coords[0];
EmitVertex( );
EndPrimitive( );
}
else
// THIS IS WHERE THE PROBLEM IS. WHEN THE INITIAL PARTICLE HITS THE BOUNDARY I WANT TO
// GENERATE TWO PARTICLES AS BELOW. HOWEVER, ONLY THE FIRST PARTICLE IS DRAWN MOVING
// AS ITS SUPPOSED. THE SECOND PARTICLE IS NOT DRAWN AT ALL. WHICH MEANS newCoords/newVal
// BELOW AREN'T WRITING INTO THE TRANSFORM FEEDBACK BUFFER. WHY?
{
newCoords = vec4(50.0, 0.0, 0.0, 1.0);
newVel = vec3(-1.0, 0.0, 0.0);
EmitVertex( );
EndPrimitive( );

newCoords = vec4(-50.0, 0.0, 0.0, 1.0);
newVel = vec3(1.0, 0.0, 0.0);
EmitVertex( );
EndPrimitive( );

}
}[/CODE]

You're using OpenGL 4.3 and I am using 3.3, but I am quite sure, that your problem is due to the double using EndPrimitive() function. Use it only once.

chachacha
03-04-2016, 02:42 AM
You're using OpenGL 4.3 and I am using 3.3, but I am quite sure, that your problem is due to the double using EndPrimitive() function. Use it only once.

Thanks, mamannon. Sorry for the late reply, had to take off for a day.

Actually, that's one of the first things I tried. Didn't work. Not sure what to do.