WebGL Simple 2D Example 7

Support canvas/screen resize.

Full JavaScript code on this page: (or you can View Page Source)

var gl, canvas, vertices = [], shaderProgram

function drawTriangle(x1, y1, x2, y2, x3, y3, r, g, b, a) {
	// All 3 points of the triangle get the same rgb.
	vertices.push(
		x1, y1, r, g, b, a,
		x2, y2, r, g, b, a,
		x3, y3, r, g, b, a
	)
}

function gameLoop() {
	window.requestAnimationFrame(gameLoop)

	// Clear the screen.
	gl.clear(gl.COLOR_BUFFER_BIT)

	// Draw the moving triangle.
	drawTriangle(
		250+Math.sin(Date.now()*.004)*250, 100,
		150, 400,
		350, 400,
		0, 255, 128 + Math.floor(Math.sin(Date.now()*.01) * 127), 1
	)
	
	// Tell webGL to draw these triangle this frame.
	gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW)

	// Draw all the triangles.
	gl.drawArrays(gl.TRIANGLES, 0, vertices.length/6)
	
	// Clear vertices. We will fill it every frame.
	// This way you don't need to delete objects from the screen. You just stop drawing them.
	vertices = []
}

function glSetup() {
	gl = myCanvas.getContext("experimental-webgl")

	// Set the background color to sky blue.
	gl.clearColor(.5, .7, 1, 1)

	// Tell webGL that we aren't doing anything special with the vertex buffer, just use a default one.
	gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer())

	// Vertex shader source code.
	var vertCode =
	"attribute vec2 coordinates;" +
	"attribute vec4 rgba;" +
	"varying highp vec4 rgbaForFrag;" +
	" uniform vec2 canvasSize;" +
	
	"void main(void) {" +
		" vec2 drawPos;" +
		// Divide the position by our current canvas size.
		" drawPos = coordinates / canvasSize * 2.0;" +
		// We are passing in only 2D coordinates. Then Z is always 0.0 and the divisor is always 1.0
		" gl_Position = vec4(drawPos.x - 1.0, 1.0 - drawPos.y, 0.0, 1.0);" +
		// Pass the color and transparency to the fragment shader.
		" rgbaForFrag = vec4(rgba.xyz / 255.0, rgba.w);" +
	"}"

	// Create a vertex shader object.
	var vertShader = gl.createShader(gl.VERTEX_SHADER)
	gl.shaderSource(vertShader, vertCode)
	gl.compileShader(vertShader)

	// Fragment shader source code.
	var fragCode =
	"varying highp vec4 rgbaForFrag;" +
	"void main(void) {" +
		" gl_FragColor = rgbaForFrag;" +
	"}"

	// Create fragment shader object.
	var fragShader = gl.createShader(gl.FRAGMENT_SHADER)
	gl.shaderSource(fragShader, fragCode)
	gl.compileShader(fragShader)

	// Tell webGL to use both my shaders.
	shaderProgram = gl.createProgram()
	gl.attachShader(shaderProgram, vertShader)
	gl.attachShader(shaderProgram, fragShader)
	gl.linkProgram(shaderProgram)
	gl.useProgram(shaderProgram)

	// Tell webGL to read 2 floats from the vertex array for each vertex
	// and store them in my vec2 shader variable I've named "coordinates"
	// We need to tell it that each vertex takes 24 bytes now (6 floats)
	var attribute = gl.getAttribLocation(shaderProgram, "coordinates")
	gl.vertexAttribPointer(attribute, 2, gl.FLOAT, false, 24, 0)
	gl.enableVertexAttribArray(attribute)

	// Tell webGL to read 4 floats from the vertex array for each vertex
	// and store them in my vec4 shader variable I've named "rgba"
	// Start after 8 bytes. (After the 2 floats for x and y)
	var attribute = gl.getAttribLocation(shaderProgram, "rgba")
	gl.vertexAttribPointer(attribute, 4, gl.FLOAT, false, 24, 8)
	gl.enableVertexAttribArray(attribute)
	
	// Tell webGL that when we set the opacity, it should be semi transparent above what was already drawn.
	gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
	gl.enable(gl.BLEND)
	
// UPDATE: Call onresize to set the initial canvas size. window.onresize() } window.onresize = function() { // UPDATE: To test we'll make the canvas be 1/3 the browser width. Try resizing your browser. var width = Math.floor(innerWidth/3) var height = 500 myCanvas.style.width = width+"px" myCanvas.style.height = height+"px" myCanvas.setAttribute("width", width) myCanvas.setAttribute("height", height)
// UPDATE: Moved this code so it updates webGL every time we change the canvas size. // Set the viewport size to be the whole canvas. gl.viewport(0, 0, width, height) // Set our shader variable for canvas size. It's a vec2 that holds both width and height. gl.uniform2f(gl.getUniformLocation(shaderProgram, "canvasSize"), width, height)
} window.onload = function() { glSetup() gameLoop() }
HTML:
					
Step 8 - Draw Rectangles »