Getting started with WebGL – Part 3

Introduction

 

Our program is ready. We will feed this program from JS with our coordinates and launch the program.

 

Sending static JS coordinates to the program

Loading the static JS coordinates into a buffer

The WebGL API works with strongly typed data. In our vertex shader, we defined  the “position” attribute with type vec3, meaning a vector of 3 floats, so in Javascript, let’s write our 3D-coordinates in a Float32Array (32-bit floating point numbers).

photo2-article3

To transfer the newly created data from Javascript to the GPU/graphics card, we need to explicitly create a buffer of type WebGLBuffer. This buffer corresponds to a region of physical memory storage used to temporarily store data while it is being moved from Javascript to the GPU/graphics card.

 

WebGL functions don’t directly refer to a buffer. Instead, they use a state machine, with internal global variables as references to the buffers. Here, we bind (or associate) our squareVerticesBuffer to the gl.ARRAY_BUFFER variable, so that we can fill it with the bufferData function.

 

In our square example, the coordinates are static, so we specify the usage pattern of the data store with gl.STATIC_DRAW.

Send coordinates to the program

In our GLSL vertex shader, the coordinates of the vertices correspond to the attribute we named “position”. We need somewhat to say that our bugger squareVerticesBuffer actually contains what is called position in GLSL. As any other buffer, it needs to be bound before being manipulated.

 

We can retrieve a descriptor of an attribute by using the method getAttribLocation.

 

This descriptor doesn’t contain any value per se. It is just an address representing the attribute itself.

We need to turn on the attribute:

 

Finally we associate our currently bound buffer with the attribute “position”:

 

photo3-article3

One could notice that this WebGL API allows us to put in several attributes in a single buffer. Or create several buffers, one per attribute. It is left at the discretion of the developer.

 

Drawing the square

Let’s launch the program now. We will use the technique called triangle strip to draw.

The triangle strip technique will draw faces out of vertices: 1,2,3; 2,3,4; 3,4,5; 4,5,6, … and so on.

In our case, we have only 4 vertices, so it will draw: 1,2,3; 2,3,4. Two triangles for one square.

 

Be careful about orientation:

A triangle has two faces: a front-face, and a back-face. By default in WebGL, clockwise vertices describe a front-face. Counterclockwise vertices describe a back-face. So the vertices order matters. Drawing a back face is like drawing nothing.

photo4-article3

Finally, let’s wrap the drawing in a function:

 

Done ! We can now checkout:

 

Open index.html, to see the same square we had before.

photo5-article3

 

Opening

For a dynamic square in Javascript, we can checkout again:

photo6-article3

When a button is clicked, we update the buffer with the new coordinates, using the function.

 

We also changed the draw function. Instead of drawing once and for all or only when needed, we will redraw at each frame. A frame is one image. A movie usually is a succession of 24 frames per second. Your computer usually displays 60 frames per second.

Javascript has the convenient requestAnimationFrame function to callback a function just before the next frame. The monitor has to display.

 

We have finally rendered a moving orange square, in WebGL.