In theory, let's say I have a vertex shader which knows:
- The dimensions of a 2D texture/tilesheet (in pixels)
- The dimensions of each tile within that texture (in pixels)
- The number of tiles within the texture (not necessarily RowCount * ColumnCount... The final row may fall short X number of tiles)
- A given "TileIndex", representing a desired tile # which increments from left to right, top to bottom (in that order)
Using the built-in gl_VertexID input variable to aid in the creation of proper texture coordinates, what sort of math/algorithm must be used to get this shader to "select" the correct tile index and corresponding texture coordinates (to be passed on to the fragment shader)?
I believe it has something to do with X + Y * Width, or perhaps the use of a modulus operation somewhere, but it becomes complicated when the only given is a single tile index value...
So, I've only gotten as far as the following:
#version 330 core
layout(location=0) in vec3 in_pos; // Vertex Position
layout(location=1) in int in_tileIndex; // Desired Tile Index
out vec2 out_texCoord; // Resulting Texture Coordinates
// (passed on to the frag shader)
void main()
{
// The following variables will eventually be uniforms/attributes, and are only
// used here for more immediate debugging while I figure this algorithm out...
float tileWidth = 32; // In pixels
float tileHeight = 32; // In pixels
float tileCount = 88; // Not always rows * cols
float imgWidth = 255; // In pixels
float imgHeight = 351; // In pixels
float width = 1.0f / tileWidth; // In textels (To be used as a scalar down below?)
float height = 1.0f / tileHeight; // In textels (To be used as a scalar down below?)
///////////////////////////////////////
// NOT SURE WHAT TO PUT HERE...
// (need to find a way to use the
// above info to generate correct
// texture coordinates below...)
///////////////////////////////////////
int vid = gl_VertexID % 4;
switch(vid) {
case 0:
out_texCoord = vec2(0, 1); // Currently set to the entire image (instead of a single tile within it)
break;
case 1:
out_texCoord = vec2(1, 1); // Currently set to the entire image (instead of a single tile within it)
break;
case 2:
out_texCoord = vec2(0, 0); // Currently set to the entire image (instead of a single tile within it)
break;
case 3:
out_texCoord = vec2(1, 0); // Currently set to the entire image (instead of a single tile within it)
break;
}
gl_Position = vec4(in_pos, 1);
}
