index previous next

Shading program

  1. Create shading program from vertex and fragment shader
    1. create program object
    2. attach vertex and fragment shader to the program
    3. link them
    4. use program

Recap

This is our plan

  1. Get webgl context from canvas
  2. Create vertex data
  3. Put data into GPU buffer
  4. Create vertex shader
  5. Create fragment shader
  6. Create shading program from vertex and fragment shader
  7. Plug in buffer into shading program
  8. Draw

and points 1-5 are done. Time to create our shading program from shaders.

create program object

Another very simple object creation. It is just


var program = gl.createProgram()

attach vertex and fragment shader to the program

After our shading program is created, time to put something inside. That something are our shaders.


gl.attachShader(program, vertexShader)
gl.attachShader(program, fragmentShader)

link them

Vertex and fragment shader that are attached to the program, must be linked together. Their output (from vertex shader) and input (from fragment shader) variables must match each other plus some of the variables may be exposed as input variables for shading program. This checking and exposing is done at this stage. We also definitely want to check if there are some errors.


gl.linkProgram(program)
if(gl.getProgramParameter(program, gl.LINK_STATUS) != true)
{
	throw "Program linking failed!\n" + gl.getProgramInfoLog(program)
}

You will fully understand why this stage is here, when you will start passing values from vertex shader to fragment shader.

use program

When program is created and shaders are linked, program is ready to be used. By using program I mean pluggin it in into graphics pipeline for data processing. The code is simply


gl.useProgram(program)

From now on, when something is sent to be drawn, our shading program will get it.

Summary

We have created shading program, attached vertex and fragment shader into it. They were linked together and shading program is plugged into graphics pipeline waiting to be used.

Full code goes below.


<!DOCTYPE html> 

<html>
<head>
<meta charset="UTF-8">
<title>noniwoo webgl tutorial</title>
</head>
<body>
<canvas id="canvas1" width="640" height="480"></canvas>

<script type="unknown" id="vertexShader">
attribute vec3 vertexPos;

void main(void)
{
	gl_Position = vec4(vertexPos, 1.0);
}
</script>


<script type="unknown" id="fragmentShader">
void main(void)
{
	gl_FragColor = vec4(0.2, 0.6, 0.2, 1.0);
}
</script>


<script>
var canvas = document.getElementById('canvas1')
if( canvas == null )
{
	throw "Could not get canvas element!"
}

var gl = canvas.getContext('webgl')
if( gl == null )
{
	gl = canvas.getContext('experimental-webgl')
	if( gl == null )
	{
		throw "Could not get webgl context"
	}
}

gl.clearColor(1.0, 1.0, 0.0, 1.0)
gl.clear(gl.COLOR_BUFFER_BIT)

var triangleVertices = new Float32Array([
	 0.0,  1.0,  0.0,  // top
	 1.0, -1.0,  0.0,  // right
	-1.0, -1.0,  0.0   // left
])

var triangleBuffer = gl.createBuffer()
gl.bindBuffer( gl.ARRAY_BUFFER, triangleBuffer )
gl.bufferData( gl.ARRAY_BUFFER, triangleVertices, gl.STATIC_DRAW )

var vertexShaderTag = document.getElementById('vertexShader')
var vertexShaderSource = vertexShaderTag.innerHTML
var vertexShader = gl.createShader(gl.VERTEX_SHADER)

gl.shaderSource(vertexShader, vertexShaderSource)
gl.compileShader(vertexShader)
if(gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS) != true)
{
	throw "Vertex shader compilation failed!\n" + gl.getShaderInfoLog(vertexShader)
}


var fragmentShaderTag = document.getElementById('fragmentShader')
var fragmentShaderSource = fragmentShaderTag.innerHTML
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER)

gl.shaderSource(fragmentShader, fragmentShaderSource)
gl.compileShader(fragmentShader)
if(gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS) != true)
{
	throw "Fragment shader compilation failed!\n" + gl.getShaderInfoLog(fragmentShader)
}


var program = gl.createProgram()
gl.attachShader(program, vertexShader)
gl.attachShader(program, fragmentShader)

gl.linkProgram(program)
if(gl.getProgramParameter(program, gl.LINK_STATUS) != true)
{
	throw "Program linking failed!\n" + gl.getProgramInfoLog(program)
}

gl.useProgram(program)

</script>

</body>
</html>

index previous next