I'm using instancing to draw the same quad multiple times, for the floor in a game engine. Each floor has different texture co-ordinates depending on it's size and my problem is that all instances are using the texture co-ordinates of the first instance.
This is how I am buffering the data.
public static void UploadTextureCooridnates()
{
// Construct texture co-ordinate array
List<Vector2> textureCoords = new List<Vector2>();
foreach (Floor floor in Floor.collection)
{
float xCoordLeft = 0;
float yCoordBottom = 0;
float yCoordTop = floor.scale.X;
float xCoordRight = floor.scale.Z;
textureCoords.Add(new Vector2(xCoordLeft, yCoordBottom));
textureCoords.Add(new Vector2(xCoordRight, yCoordBottom));
textureCoords.Add(new Vector2(xCoordRight, yCoordTop));
textureCoords.Add(new Vector2(xCoordLeft, yCoordBottom));
textureCoords.Add(new Vector2(xCoordRight, yCoordTop));
textureCoords.Add(new Vector2(xCoordLeft, yCoordTop));
}
Vector2[] texCoords = textureCoords.ToArray();
// Buffer data
GL.BindBuffer(BufferTarget.ArrayBuffer, VBOtexcoordsInstanced);
GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(texCoords.Length * Vector2.SizeInBytes), texCoords, BufferUsageHint.StaticDraw);
GL.EnableVertexAttribArray(1);
GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 0, 0);
GL.VertexAttribDivisor(1, 0);
}
If you really are using instancing to draw multiple quads, then clearly you must have:
Your problem is your expectation. You're instancing with quads. That means your render call only uses 4-6 vertices. This will be just as true for your texture coordinates as your positions.
Your problem is that you're treating per-instance data as though it were per-vertex data. Texture coordinates change with each instance; therefore, they are per-instance data. But you don't have them use instancing, so they're treated as per-vertex data. So only the texture coordinates from the first 6 vertices will be used.
Of course, you can't really make them per-instance data either. Each vertex+instance pair has a separate texture coordinate value. And instancing doesn't provide a way to do that directly. Instead, you would have to use gl_VertexID
and gl_InstanceID
to fetch data directly from a buffer object; either an SSBO or a buffer texture.
And therefore, your problem really is this:
I'm using instancing to draw the same quad multiple times
Stop doing that. It's not worthwhile. Just put the positions in the CPU buffer data. Use proper buffer streaming techniques, and your performance will be reasonable.