Full JavaScript code on this page: (or you can View Page Source)
var gl, canvas, vertices = []
// UPDATE: Changed to drawRectangle. Draws 2 triangles to make a rectangle.
function drawRectangle(x, y, width, height, r, g, b, a) {
var x2 = x+width
var y2 = y+height
vertices.push(
x, y, r, g, b, a,
x, y2, r, g, b, a,
x2, y2, r, g, b, a
)
vertices.push(
x, y, r, g, b, a,
x2, y, r, g, b, a,
x2, y2, r, g, b, a
)
}
function gameLoop() {
window.requestAnimationFrame(gameLoop)
// Clear the screen.
gl.clear(gl.COLOR_BUFFER_BIT)
// UPDATE: Draw the moving rectangle.
var x = 250+Math.sin(Date.now()*.004)*250
var y = 200
var blue = 128 + Math.floor(Math.sin(Date.now()*.01) * 127)
drawRectangle(
x, y,
100, 200,
0, 255, blue, 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)
// Call onresize to set the initial canvas size.
window.onresize()
}
window.onresize = function() {
// 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)
// 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: