Hasan Al-Baghdadi
Hasan Al-Baghdadi

Reputation: 442

glGetUniformLocation returning -1 during transform feedback when it is used

The function returns -1, even though Uniform is defined and used within the vertex shader, I suspect the cause may be that the out attributes might not be properly bound with the target buffer (not sure if that is the case). Without this one Uniform, most of my values will stay the same.

Drawing the Transform Feedback

/*code included in update*/
glUseProgram(feedbackShader->GetProgram());

glEnable(GL_RASTERIZER_DISCARD);
/*end of code included in update*/

glBindBuffer(GL_ARRAY_BUFFER, particleBuffer[isEvenBuffer]);
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformBuffer[!isEvenBuffer]);

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

glVertexAttribPointer(5, 3, GL_FLOAT, GL_FALSE, sizeof(Particle), 0); //Location
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Particle), (const GLvoid*)12); //Velocity
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Particle), (const GLvoid*)24); //InitLocation
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Particle), (const GLvoid*)36); //InitVelocity
glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, sizeof(Particle), (const GLvoid*)48); //Lifetime
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(Particle), (const GLvoid*)52); //InitLifetime

GLint uniformLocation = glGetUniformLocation(feedbackShader->GetProgram(), "time");

glUniform1f(uniformLocation, msec);

glBeginTransformFeedback(GL_POINTS);

glDrawTransformFeedback(GL_POINTS, transformBuffer[isEvenBuffer]);

glEndTransformFeedback();

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

The Vertex Shader

#version 410

in vec3 inLocation;
in vec3 inVelocity;
in vec3 inInitLocation;
in vec3 inInitVelocity;
in float inLifeTime;
in float inInitlifeTime;

out vec3 outLocation;
out vec3 outVelocity;
out vec3 outInitLocation;
out vec3 outInitVelocity;
out float outLifeTime;
out float outInitlifeTime;

uniform float time;

vec3 Gravity = vec3(0.0f,-0.98f,0.0f);
float dampeningFactor = 0.5;

void main()
{

  outLifeTime = inLifeTime - time;

  if(outLifeTime > 0.0f){
    outVelocity = (inVelocity + Gravity * time) * dampeningFactor;
    outLocation = inLocation + inVelocity * time;
  }else{
    outVelocity = inInitVelocity;
    outLocation = inInitLocation;
    outLifeTime = inInitlifeTime;
  }
  outInitVelocity = inInitVelocity;
  outInitLocation = inInitLocation;
  outInitlifeTime = inInitlifeTime;
}

UPDATE There were a few extra bits of information you all asked for.

The Vertex Shader

#version 410

in vec3 inLocation;
in vec3 inVelocity;
in vec3 inInitLocation;
in vec3 inInitVelocity;
in float inLifeTime;
in float inInitlifeTime;

out vec3 outLocation;
out vec3 outVelocity;
out vec3 outInitLocation;
out vec3 outInitVelocity;
out float outLifeTime;
out float outInitlifeTime;

uniform float time;

vec3 Gravity = vec3(0.0f,-0.98f,0.0f);
float dampeningFactor = 0.5;

void main()
{

  outLifeTime = inLifeTime - time;

  if(outLifeTime > 0.0f){
    outVelocity = (inVelocity + Gravity * time) * dampeningFactor;
    outLocation = inLocation + inVelocity * time;
  }else{
    outVelocity = inInitVelocity;
    outLocation = inInitLocation;
    outLifeTime = inInitlifeTime;
  }
  outInitVelocity = inInitVelocity;
  outInitLocation = inInitLocation;
  outInitlifeTime = inInitlifeTime;
}

The Feedback Varyings (I was stupid and didn't have this at first, though the same issue remains in my code)

const GLchar* feedbackVaryings[] = {
    "outLocation",
    "outVelocity",
    "outInitLocation",
    "outInitVelocity",
    "outLifeTime",
    "outInitlifeTime"
};
glTransformFeedbackVaryings(feedbackShader->LinkProgram(), 6, feedbackVaryings, GL_INTERLEAVED_ATTRIBS);

I also added the gluseProgram in the "Drawing the Transform Feedback section".

Upvotes: 1

Views: 178

Answers (1)

Rabbid76
Rabbid76

Reputation: 210878

I assume that the instruction

feedbackShader->LinkProgram()

linkes the program. But the varying transform feedback variables have to be specified before linking the program.

See OpenGL 4.6 API Core Profile Specification; 7.3.1.1 Naming Active Resources; page 104

The order of the active resource list is implementation-dependent for all interfaces except for TRANSFORM_FEEDBACK_VARYING. If variables in the TRANSFORM_FEEDBACK_VARYING interface were specified using the TransformFeedbackVaryings command, the active resource list will be arranged in the variable order specified in the most recent call to TransformFeedbackVaryings before the last call to LinkProgram.

This means, first you have to attach the compiled vertex shader object to the program object (glAttachShader). Then you have to specify the transform feedback varying (glTransformFeedbackVaryings). Finally you have to link the program (glLinkProgram):

GLuint shader_obj;
GLuint program_obj;

.....

glAttachShader(program_obj, shader_obj);

const GLchar* feedbackVaryings[] = {
    "outLocation",
    "outVelocity",
    "outInitLocation",
    "outInitVelocity",
    "outLifeTime",
    "outInitlifeTime"
};
glTransformFeedbackVaryings(program_obj, 6, feedbackVaryings, GL_INTERLEAVED_ATTRIBS);

glLinkProgram(program_obj);



Further I recommend to use Layout Qualifier to define the attribute indices of the vertex shaser inpout variables.

e.g.

layout (location = 0) in vec3 inLocation;
layout (location = 1) in vec3 inVelocity;
layout (location = 2) in vec3 inInitLocation;
layout (location = 3) in vec3 inInitVelocity;
layout (location = 4) in float inLifeTime;
layout (location = 5) in float inInitlifeTime;

As an alternative the attribute index can be determined by glGetAttribLocation after linking the program or set by glBindAttribLocation before linking the program.

Upvotes: 1

Related Questions