# Tutorials

### Sidebar

#### Node.js in WebStorm

 RT @snebiker: #PlayGameLieschtel - brilliant event by Kantonsbibliothek Baselland #KBL to get kids into libraries, including family #gamede… About 2 days, 14 hours ago by: Martin Christen (@MartinChristen) Only a handful tickets left for @PyConDE in Karlsruhe (October 24-28, 2018) - The schedule is now available at… https://t.co/Og4fp3DsoA About 5 days, 7 hours ago by: Martin Christen (@MartinChristen) IAMCP & @swissmade_sw Augmented Reality event just started https://t.co/bdREI6lJM4 #ar #AugmentedReality #Basel… https://t.co/9KpsdU3fvM About 6 days, 13 hours ago by: Martin Christen (@MartinChristen)
webgl:tutorial02

## WebGL Tutorial 2: Draw a Triangle

(unfinished: work in progress)

At first, drawing ta triangle using WebGL seems to be complicated, as we need to understand several things like vertex and fragment shaders, projections, vertex buffers, and so on.

So let's start with a very simple application and draw a 2D triangle like this:

#### Normalized Device Coordinates

We will draw the triangle in normalized device coordinates (NDC). This is a left handed coordinate system with range [-1,1] for all components x,y, and z:

WebGL draws triangles, lines and points in normalized device coordinates. Whatever you want to draw your coordinates must be in the range from (-1,-1,-1) to (1,1,1). WebGL will clip all primitives to this range. This means triangles, lines, and points are clipped if not in this range.

There are several famous transformations which result in NDC, like the perspective or orthographic/orthogonal projection. These transformations are not part of this tutorial: in this tutorial we don't do any transformations we create our geometries directly in normalized device coordinates.

The operation is completed by WebGL by transforming the normalized device coordinates to Window Coordinates, sometimes also called “Pixel Coordinates” or “Screen Coordinates”.

#### Shaders: Processing Vertices and Fragments

In WebGL you have to implement two types of so called “shaders”. The first is the vertex shader. This is a program running on the GPU which is called for each vertex. In this shader you can do operations related to vertices. In many cases this involves transforming vertices. The second is the fragment shader. This is a program which is called for each fragment. Usually the output color of the fragment is calculated here.

#### The Application

Now lets start implementing this application: The onload event start with the main function. In last tutorial we learned how to initialize WebGL, this is done here again.

```var gl = initWebGL();
```

Now we get the vertex and the fragment shader source code from the DOM:

```         var v = document.getElementById("vertexshader").firstChild.nodeValue;
```

```         var vs = gl.createShader(gl.VERTEX_SHADER);

program = gl.createProgram();
```

The whole program looks like this:

```<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="keywords" content="WebGL">
<meta name="author" content="Martin Christen, martin.christen@gmail.com">
attribute vec2 aVertexPosition;

void main() {
gl_Position = vec4(aVertexPosition, 0.0, 1.0);
}
</script>
#ifdef GL_ES
precision highp float;
#endif

uniform vec4 uColor;

void main() {
gl_FragColor = uColor;
}
</script>
<script type="text/javascript">

function initWebGL()
{
var canvas = document.getElementById("canvas");
var gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
if (!gl) return null; // can't initialize WebGL
return gl;
}

function main()
{
var gl = initWebGL();

program = gl.createProgram();

// Setup Geometry
var vertices = new Float32Array([
-0.5,-0.5,0.5,-0.5,0.0,0.5  // Triangle-Coordinates
]);

vbuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vbuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

itemSize = 2; // we have 2 coordinates (x,y)
numItems = vertices.length / itemSize; // number of triangles

// Viewport
gl.viewport(0, 0, canvas.width, canvas.height);
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

// Setup Geometry:
gl.useProgram(program);

program.uColor = gl.getUniformLocation(program, "uColor");
gl.uniform4fv(program.uColor, [0.5, 0.0, 0.0, 1.0]);

program.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition");
gl.enableVertexAttribArray(program.aVertexPosition);
gl.vertexAttribPointer(program.aVertexPosition, itemSize, gl.FLOAT, false, 0, 0);

// Draw:
gl.drawArrays(gl.TRIANGLES, 0, numItems);
}
</script>