WebGL - Partial textures

This was something that took me a bit to understand when working with WebGL. When you draw a texture, you're going to be mapping coordinates of the texture to the coordinates you specify in your vertices array.

Example:

var x1 = object.pos.x;
var y1 = object.pos.y;
var x2 = object.pos.x + object.width;
var y2 = object.pos.y + object.height;

We have 4 variables, each for the different coordinates of a game object.

var vertices = [
  x1, y1,
  x2, y1,
  x1, y2,
  x1, y2,
  x2, y1,
  x2, y2
];

So we setup the two triangles to draw the square.

Top Left -> Top Right -> Bottom Left

Bottom Left -> Top Right -> Bottom Right

In 2d games, I typically prefer to have the Y value go up as you go down the screen, as supposed to the default. So I flip the coordinate in with a uniform matrix in a shader. This sit here shows how to set this up: http://webglfundamentals.org/webgl/lessons/webgl-2d-matrices.html. Because of this, the texture coordinates get a little weird.

The texture i have below is 128x128. Be sure to always have them power of 2 and square.

What i want to draw is the 0, 0 32x32 of the image. My object that I showed earlier has the proper width & height values. So we just need to tell webgl where to start with the texture, and use those width & height properties.

WebGL texture coordinates and OpenGL for that matter always specify between 0 and 1. For x, 0 is the furthest left coordinate, 1 is the furthest right. 0.5 is in the middle. So we basically work this as a percentage:

player.png
var dw = (object.width / object.texture.image.width);
var dh = 1.0 - (object.height / object.texture.image.height);

The texture property is the created texture for actual drawing. The image property on that is the raw image data. I use that to get the true size of the image.

Though why am I taking a 1.0 value and subtracting the height? It's because of the Y flip. This is what got me for a bit when trying to get this to work. Because we have the Y flip in the uniform matrix, and not before the texture coords are all said & done, we need to use opposite Y values. So from there, I simply draw out what I need:

var textureCoords = [
  0.0, 1.0,
  dw, 1.0,
  0.0, dh,
  0.0, dh,
  dw, 1.0,
  dw, dh
];

As I said, each coordinate there is in order and maps to the coordinates in the vertices.

[0.0, 1.0] => [x1, y1]
[dw, 1.0] => [x2, y1]
[0.0, dh] => [x1, y2]
[0.0, dh] => [x1, y2]
[dw, 1.0] => [x2, y1]
[dw, dh] => [x2, y2]

We map the bottom left corner to the top left corner, the bottom corner, 32 pixels in to the top right corner, and so forth. The x position always stays the same, but I flipped the Y.

I hope this post helps.