0
votes

I am working on a Project to create Geometry by using a Geometry Shader and Transform Feedback.

I am currently trying to have the Geometry Shader return its input (1 triangle) without changing/adding anything, but its not working.

I would appreciate any help/advice I can get. Here are parts of my code:

The creation of the Program for Transform Feedback:

//==========================================
// Create the Transform Program
//==========================================

int check = LoadShader("Shaders//transformVS.glsl", GL_VERTEX_SHADER, transformVS);

//TODO: check for fail

check = LoadShader("Shaders//transformGS.glsl", GL_GEOMETRY_SHADER, transformGS);

//TODO: check for fail

transformProgram = glCreateProgram();

glAttachShader(transformProgram, transformVS);
glAttachShader(transformProgram, transformGS);

glBindAttribLocation(transformProgram, 0, "position_in");
glBindAttribLocation(transformProgram, 1, "normal_in");
glBindAttribLocation(transformProgram, 2, "length_in");

static const char* varyings[] = { "position_out", "normal_out", "length_out" };
glTransformFeedbackVaryings(transformProgram, 3, varyings, GL_INTERLEAVED_ATTRIBS);

glLinkProgram(transformProgram);

if (CheckProgram(transformProgram) == -1){
    glDetachShader(transformProgram, transformVS);
    glDetachShader(transformProgram, transformGS);
    glDeleteShader(transformVS);
    transformVS = 0;
    glDeleteShader(transformGS);
    transformGS = 0;
    glDeleteProgram(transformProgram);
    transformProgram = 0;

    return -1;
}

error = glGetError();

The Creation of the VBOs, VAOs and TFOs:

//=====================================
// Create VBOs
//=====================================

glGenBuffers(2, VBOID);

glBindBuffer(GL_ARRAY_BUFFER, VBOID[0]);
glBufferData(GL_ARRAY_BUFFER, 3 * sizeof(TVertex_VNL), vertices, GL_DYNAMIC_COPY);
glBindBuffer(GL_ARRAY_BUFFER, 0);

error = glGetError();

glBindBuffer(GL_ARRAY_BUFFER, VBOID[1]);
glBufferData(GL_ARRAY_BUFFER, 3 * sizeof(TVertex_VNL), NULL, GL_DYNAMIC_COPY);
glBindBuffer(GL_ARRAY_BUFFER, 0);

error = glGetError();

//=====================================
// Create VAOs
//=====================================

glGenVertexArrays(2, VAOID);

glBindVertexArray(VAOID[0]);
    glBindBuffer(GL_ARRAY_BUFFER, VBOID[0]);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(TVertex_VNL), BUFFER_OFFSET(0)); //position
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(TVertex_VNL), BUFFER_OFFSET(sizeof(float) * 3)); //normal
    glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(TVertex_VNL), BUFFER_OFFSET(sizeof(float) * 6)); //length
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glEnableVertexAttribArray(2);
glBindVertexArray(0);

error = glGetError();

glBindVertexArray(VAOID[1]);
    glBindBuffer(GL_ARRAY_BUFFER, VBOID[1]);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(TVertex_VNL), BUFFER_OFFSET(0)); //position
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(TVertex_VNL), BUFFER_OFFSET(sizeof(float) * 3)); //normal
    glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(TVertex_VNL), BUFFER_OFFSET(sizeof(float) * 6)); //length
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glEnableVertexAttribArray(2);
glBindVertexArray(0);

error = glGetError();



//=====================================
// Create TFOs
//=====================================

glGenTransformFeedbacks(2, TFOID);

glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, TFOID[0]);
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, VBOID[0]);
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);

error = glGetError();

glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, TFOID[1]);
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, VBOID[1]);
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);

error = glGetError();

The render Method:

//=========================================
// Clear Screen
//=========================================

//Clear all the buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

//========================================
// Transform Feedback
//========================================

glEnable(GL_RASTERIZER_DISCARD);

glUseProgram(transformProgram);

glBindVertexArray(VAOID[0]);
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, TFOID[1]);

glBeginTransformFeedback(GL_TRIANGLES);

glDrawArrays(GL_TRIANGLES, 0, 3);

glEndTransformFeedback();

glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);

glDisable(GL_RASTERIZER_DISCARD);

//========================================
// Draw Triangle
//========================================

//Bind the shader that we want to use
glUseProgram(renderProgram);

//Setup all uniforms for your shader
glUniformMatrix4fv(renderMVP, 1, FALSE, &MVP[0][0]);

//Bind the VAO
glBindVertexArray(VAOID[1]);
glDrawArrays(GL_TRIANGLES, 0, 3);

//glDrawTransformFeedback(GL_TRIANGLES, TFOID[1]);

//========================================
// Swap Buffers
//========================================

glutSwapBuffers();

The Vertex Shader:

#version 330

in vec3 position_in;
in vec3 normal_in;
in float length_in;

out vec3 vs_position;
out vec3 vs_normal;
out float vs_length;

void main()
{
    vs_position = position_in;
    vs_normal = normal_in;
    vs_length = length_in;
}

The Geometry Shader:

#version 330

layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;

in vec3 vs_position[];
in vec3 vs_normal[];
in float vs_length[];

out vec3 position_out;
out vec3 normal_out;
out float length_out;

void main()
{
    for(int i = 0; i < 3; i++){
        position_out = vs_position[i];
        normal_out = vs_normal[i];
        length_out = vs_length[i];

        EmitVertex();
    }

    EndPrimitive();
}
1
during intialization, you create two TFOs, buit initialize the first one twice. During rendering, you only use the second.derhass
@derhass thanks again for the answer. I fixed that one too but its still not working. Could there be something missing in the TFO initialisation, like telling opengl were to write the different output variables?Omanidos
Since you use interleaved output, all outputs will be written to the same buffer (unless you use separators, but that is a completely differen thing which should not be relevant here). I'm not sure about not using a fragment shader at all. Since you use RASTERIZER_DISACRD, it probably shouldn't be necessary, but I haven't looked that up in the spec. I think it can't hurt to add some error checks to the render method, though.derhass

1 Answers

2
votes

Your geometry shader is not emitting any vertices because the for loop body is never entered:

for(int i = 0; i >= 3; i++){