1
\$\begingroup\$

I want to draw a textured quad but there is nothing drawn and the setup should be right. This is my vertex shader:

#version 330

in vec2 position;
in vec2 texel;

out vec2 texCoord;

void main() {
    texCoord = texel;
    gl_Position = vec4(position, 0.0, 1.0);
}

This code is producing no output on screen. Now comes the crazy stuff. If I add the following,

#version 330

in vec2 position;
in vec2 texel;
in vec2 foo;

out vec2 texCoord;

void main() {
    texCoord = texel;
    gl_Position = vec4(position + foo, 0.0, 1.0);
}

everything is as it should be.

I am pretty sure that my setup is correct. I have checked the values of the vertex attributes by passing them as texCoord instead of the uv coordinates, and assigning them to my fragment color output in the fragment shader. In both cases this produces the expected color gradient. The extra uninitialized attribute foo must be zero, because its rendered as the vertex color.

So the thing is, nothing is drawn unless I add an vertex attribute to position. It doesn't matter if I add texel or the mysterious, uninitialized vertex attribute. The output is the same.

update:

glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), sizeof(glm::vec2);

This is my vertex struct:

struct Vertex {
    glm::vec3 pos;
    glm::vec2 tex;
    glm::vec3 normal;
    Vertex(const glm::vec3& _pos,const glm::vec2& _tex,const glm::vec3& _normal):
    pos(_pos),tex(_tex),normal(_normal){}
    Vertex(const Vertex&)=default;
    Vertex& operator=(const Vertex&)=default;
};

The buffer is correct. I have mapped the vertex buffer and put it on the standard output. All numbers are correct.

\$\endgroup\$
  • \$\begingroup\$ Have you made sure everything is done correctly on the CPU side of things? Like setting vertex attribute pointers and attribute locations etc. I assume that you checked your setup (i.e. the vertex attribute values) via fragment output for the second version only, since the original version doesn't draw anything? At the very least the problem sounds a bit like a messed up index, offset or stride value. And I don't see any obvious problem with the vertex shader. \$\endgroup\$ – Invor Oct 1 '14 at 15:44
  • \$\begingroup\$ I am sure everything is done right on the CPU side, but I will add the necessary code in a few minutes. I have tested something else that shouldn't work. I have add an extra, not initialized vec2 as input and replaced the last line with "gl_Position = vec4(foo + foo2, 0.0, 1.0);" And again, everything is drawn correctly. So the actual vertex position is never used in the shader. That sounds like a driver issue. \$\endgroup\$ – Georg Schäfer Oct 1 '14 at 15:55
2
\$\begingroup\$

Your shader, vertex structure, and glVertexAttribPointer calls do not agree. This tends to cause unusual behavior because you're mapping unexpected values to the GPU pipeline.

Your vertex structure says you have a 3-vector for position, a 2-vector for for texture coordinates, and a 3-vector for the normal (a total of eight floats per vertex).

Your glVertexAttribPointer calls say that attribute 0 is nonexistant (which means it defaults to a four-component float that is tightly-packed; this is obviously very wrong in your case). It also says that attribute 1 is a 2-vector (okay) and that attribute 2 is a 2-vector (but your structure has a 3-vector). I'm unclear what exactly the result of saying attribute 0 is tightly-packed but the other two aren't is, in this case, but almost certainly it's going to lead you to getting totally bogus values in the shader by the time it gets run.

Your shader takes 2-vectors for everything, which agrees with neither your Vertex structure or what you've mapped to the pipeline via glVertexAttribPointer. Even if you ignore the problems you have with your attribute mapping, this would smear the values of your vertex buffer into various mismatched components of your shader inputs depending on how far along in the stream you were reading (because the stride of a vertex defined in the shader is six floats and the size of one in the buffer is eight).

You should make all three of those agree. If you choose to do so based on the Vertex structure, that might mean:

// in your shader:
in vec3 position;
in vec2 texel;
in vec3 normal;

// in your C++ code:
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(glm::vec3));
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(glm::vec3) + sizeof(vec2));
\$\endgroup\$
  • \$\begingroup\$ I'm sorry. I have posted the wrong vertex struct. The used struct contains only two vec2. Anyway, I have fixed the problem. A friend has written the wrapper classes for the OpenGL stuff and I have bound the attribute location for the shader after linking the shader. But thank you very much for your effort. \$\endgroup\$ – Georg Schäfer Oct 1 '14 at 17:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.