Leif Andersen
Leif Andersen

Reputation: 22332

OpenGL Vertex Shader Runtime Issues (not using VBOs or textures)

I have the following vertex shader:

uniform mat4 uMVP;
attribute vec4 aPosition;
attribute vec4 aNormal;
attribute vec2 aTexCoord;
varying vec2 vTexCoord;
varying vec4 vPrimaryColor;
void main() {
  gl_Position = uMVP * aPosition;
  vPrimaryColor = vec4(1.0, 1.0, 1.0, 1.0);
  vTexCoord = aTexCoord;
}

And the following fragment shader:

uniform sampler2D sTex;
varying vec2 vTexCoord;
varying vec4 vPrimaryColor;
void main() {
  gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
}

Note that while I have a vTexCoord and vPrimaryColor, neither of which are used in the fragment shader. (The reason why they are there is because they eventually will be).

Now, I also set uMVP to be the identity matrix for now, and draw using the following code:

// Load the matrix
glUniformMatrix4fv(gvMVPHandle, 1, false, &mvPMatrix.matrix[0][0]);

// Draw the square to be textured
glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gFullScreenQuad);
glEnableVertexAttribArray(gvPositionHandle);
glVertexAttribPointer(gvTexCoordHandle, 2, GL_FLOAT, GL_FALSE, 0, gFullScreenQuad);
glDrawArrays(GL_QUADS, 0, 4);

where the square is:

const GLfloat PlotWidget::gFullScreenQuad[] = { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f};

So, when I run this program, I get a black screen. Which does not seem like you would expect. However, when I change the line in the shade:

vTexCoord = aTexCoord;

To

vTexCoord = vec2(1.0, 1.0);

It works perfectly. So I would assume the problem with the code is with that line of code, but I can't think of anything in opengl that would cause this. Also, I'm using Qt for this project, which means this class is using the QGLWidget. I've never had this issue with OpenGL ES 2.0.

Any suggestions?

I'm sorry for the vague title, but I don't even know what class of problem this would be.

Upvotes: 1

Views: 346

Answers (3)

g466a
g466a

Reputation: 1

Same problem, different cause.

For some devices the automatic variable linking in glLinkProgram does not work as specified.

Make sure things are done in the following order:

  1. glCreateProgram

  2. glCreateShader && glCompileShader for both shaders

  3. glBindAttribLocation for all attributes

  4. glLinkProgram

Step 3 can be repeated later at any time to rebind variables to different buffer slots - however changes only become effective after another call to glLinkgProgram.

or short: whenever you call glBindAttribLocation make sure a glLinkProgram calls comes after.

Upvotes: 0

Leif Andersen
Leif Andersen

Reputation: 22332

Apparently you need to actually use the whole use glEnableVertexAttribArray if it's getting passed into the fragment shader. I have no idea why though. But changing the drawing code to this:

glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gFullScreenQuad);
glEnableVertexAttribArray(gvPositionHandle);
glVertexAttribPointer(gvTexCoordHandle, 2, GL_FLOAT, GL_FALSE, 0, gFullScreenQuad);
glEnableVertexAttribArray(gvTexCoordHandle);
glDrawArrays(GL_QUADS, 0, 4);

made it work.

Upvotes: 0

Pike65
Pike65

Reputation: 572

Are you checking glGetShaderInfoLog and glGetProgramInfoLog during your shader compilation? If not then I would recommend that as the first port of call.

Next thing to check would be your the binding for the texture coordinates. Are the attributes are being set up correctly? Is the data valid?

Finally, start stepping through your code with liberal spraying of glGetError calls. It wil almost certainly fail on glDrawArrays which won't help you much, but that's usually when the desparation sets in for me!

OR

You could try gDEBugger. I use it mainly to look for bottlenecks and to make sure I'm releasing OpenGL resources properly so can't vouch for the debugger, but it's worth a shot.

Upvotes: 2

Related Questions