4
$\begingroup$

I want to draw a string of text with a single draw call (Instancing). I am reading a bitmap for each character texture. I want to pass the texture coordinates for each vertex of a quad (a single character). Now these texture coordinates are supposed to be updated for each vertex processed by the vertex shader because I set the glVertexAttribDivisor() to 0 which means it should be. But it's not happening.

Here's the source code where I am sending the data to the GPU...

//TEXTURE COORDS
glBindBuffer(GL_ARRAY_BUFFER, mVBOTexCoords);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2)*mTexCoords.size(), mTexCoords.data(), GL_STATIC_DRAW);

glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, 0, 0);

glVertexAttribDivisor(3,0);

and the vertex shader...

#version 400 

out vec2 tex_coords;

layout(location = 0) in vec2 pos;
layout(location = 1) in vec2 offset;
layout(location = 2) in vec2 scale;
layout(location = 3) in vec2 tex;

uniform mat4 projection;

void main()
{
    tex_coords = tex;

 vec4 position = vec4(pos,0.0f,1.0f);
     position.xy*=scale;
     position.xy+=offset;

     gl_Position = projection*position;

}

Sorry for the mess. I hope you get it. I am not getting why its not updating the texture coordninates for each vertex.

$\endgroup$
  • 1
    $\begingroup$ First step in any GL debugging problem: have you tried setting up KHR_debug, and/or sprinkling your code with glGetError calls, to see if the driver reports any issues? $\endgroup$ – Nathan Reed Dec 25 '16 at 18:58
  • $\begingroup$ Thanks for commenting. Yes i am using debug output extension and it didnt report any problem. I have also checked each iteration of vertex shader with RenderDoc. Everything is updating according to their vertex divisor settings besides texture coordinates. This is weird. $\endgroup$ – Ankit singh kushwah Dec 25 '16 at 19:02
  • 1
    $\begingroup$ Hmm, what are you getting for the texture coordinates in RenderDoc? When you say they're not updating correctly, what are they doing instead? $\endgroup$ – Nathan Reed Dec 25 '16 at 19:14
  • $\begingroup$ I mean its showing texture coordinates of the first instance for all instances. I checked all the data before sending it to the gpu memory. I will put the whole code and check it one more time later. $\endgroup$ – Ankit singh kushwah Dec 25 '16 at 19:24
5
$\begingroup$

Now this texture coordinates supposed to be updated for each vertex processed by vertex shader because i set the glVertexAttribDivisor() to 0 which means it should be.

No, it doesn't.

A divisor of 0 means that the texture coordinate work exactly as if you hadn't called glVertexAttribDivisor for that attribute at all. 0 is not a special case; it's the default.

That means that the texture coordinate will be updated at the same rate as the position. So it will get the same value for each instance, exactly like it does for the positions.

There is no way to use instancing to get an attribute to always increase. It either is a per-instance attribute (changing more-or-less based on gl_InstanceID) or it is a per-vertex attribute (changing based on gl_VertexID). To get the per-instance behavior, you use a divisor 1 or greater. To get the per-vertex behavior, you use a divisor of 0.

$\endgroup$
  • 1
    $\begingroup$ Worth noting also that he could get the behavior he wants using a texture buffer or SSBO, and manually indexing it with gl_InstanceID * vertex_count + gl_VertexID in the shader. $\endgroup$ – Nathan Reed Dec 25 '16 at 23:40
  • $\begingroup$ @NathanReed: Heh heh heh, no you can't. Instance arrays and gl_InstanceID have different interactions with base instance rendering. And by "different interactions", I mean gl_InstanceID completely ignores the base instance. Now, if this were Vulkan, gl_InstanceIndex could do that. But if you want to do this in GL, you have to use an extension... for some reason. $\endgroup$ – Nicol Bolas Dec 26 '16 at 1:29
  • 2
    $\begingroup$ OK, but "no you can't" is a bit too pessimistic—that's only a problem if you're using nonzero base instances to begin with; and if you are, you could also store the base instance in a uniform and account for it in the shader. :) $\endgroup$ – Nathan Reed Dec 27 '16 at 0:40

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.