Hands-On Game Development with WebAssembly
上QQ阅读APP看书,第一时间看更新

The return of vertex and texture data

Would you be upset if I told you we had some more variables to discuss? Well, the next one is a variable we discussed earlier, but I will mention it again because it is important. The vertex_texture_data array is an array that stores all of the vertex geometry and UV texture coordinate data that are used for rendering:

var vertex_texture_data = new Float32Array([
// x, y, u, v
0.16, 0.213, 1.0, 1.0,
-0.16, 0.213, 0.0, 1.0,
0.16, -0.213, 1.0, 0.0,
-0.16, -0.213, 0.0, 0.0,
-0.16, 0.213, 0.0, 1.0,
0.16, -0.213, 1.0, 0.0
]);

One thing I did not mention earlier is why the x and y values range from -0.16 to 0.16 on the x-axis and -0.213 to 0.213 on the y-axis. Because we are rendering a single image, we do not need to scale the geometry to fit the image dynamically. The spaceship image we are using is 128 x 128 pixels. The canvas size we are using is 800 x 600 pixels. As we discussed earlier, no matter what size we use for the canvas, WebGL fits both axes into a range from -1 to +1. This makes the coordinate (0, 0) the center of the canvas element. It also means that the canvas width is always 2 and the canvas height is always 2, no matter how many pixels wide or high the canvas element is. So, if we want to figure out how wide we want our geometry to be to have it match the width of the image, we have to do some calculations. First, we need to figure out how many units of WebGL clip space width corresponds to one pixel. The WebGL clip space has a width of 2.0, and the actual canvas has a width of 800 pixels, so the width of a single pixel in WebGL space is 2.0 / 800 = 0.0025. We need to know how wide our image is in WebGL clip space, so we will multiply the 128 pixels by 0.0025 and get a WebGL clip space width of 0.32. Because we would like to have the x value at the center of our geometry to be 0, we have our x geometry range from -0.16 to +0.16.

Now that we have done the width, let's tackle the height. The height of the canvas is 600 pixels, but in WebGL clip space, the height of the canvas is always 2.0 (-1.0 Y to +1.0 Y). So, how many WebGL units are in a single pixel? 2.0 / 600 = 0.00333333…repeating. Obviously, this is an instance where floating-point precision is unable to match a real-world value. We are going to lop off some of those trailing 3s and hope that the precision is enough. Going back to figuring out the height of the image in WebGL clip space, it is 128-pixels high, so we need to multiply 128 by 0.0033333…repeating. The result is 0.4266666…repeating, which we will truncate to 0.426. So, our y geometry must go from -0.213 to +0.213.

I am doing my best to ignore the complexity of the WebGL clip space. This is a 3D volume and not a simple 2D drawing area like the 2D canvas context. For more information on this topic, please consult the Mozilla developer docs for clip space: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_model_view_projection#Clip_space.

As I said earlier, a lot of this will be managed for us by SDL when we work on our game, but in the future, you may wish to work with OpenGL in WebAssembly. The OpenGL ES 2.0 and OpenGL ES 3.0 libraries have been ported to WebAssembly, and those libraries more or less have direct analogs with WebGL. WebGL 1.0 is a modified version of OpenGL ES 2.0, which was a version of OpenGL that was designed to run on mobile hardware. WebGL 2.0 is a modified version of OpenGL ES 3.0. Understanding what WebGL is doing through calls to SDL can make us better game developers, even if SDL is doing a lot of the heavy lifting for us.