Skip to content

Instantly share code, notes, and snippets.

@reccanti
Last active February 9, 2019 06:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save reccanti/d4345f868487c6388ddc1c9b4d1684ed to your computer and use it in GitHub Desktop.
Save reccanti/d4345f868487c6388ddc1c9b4d1684ed to your computer and use it in GitHub Desktop.
Example from the first tutorial on WebGL Fundamentals https://webglfundamentals.org/webgl/lessons/webgl-fundamentals.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>WebGL Source</title>
<style>
html {
height: 100%;
}
body {
background-color: #DDD;
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
canvas {
width: 500px;
height: 500px;
background-color: white;
}
</style>
</head>
<body>
<canvas id="webgl" width="500" height="500"></canvas>
<script src="./webglFundamentals1.js"></script>
</body>
</html>
"use strict";
const glsl = x => x;
function createShader(gl, type, source) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
if (success) {
return shader;
}
console.log(gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
}
function createProgram(gl, vertexShader, fragmentShader) {
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
const success = gl.getProgramParameter(program, gl.LINK_STATUS);
if (success) {
return program;
}
console.log(gl.getProgramInfoLog(program));
gl.deleteProgram(program);
}
function main() {
// Get A WebGL context
const canvas = document.getElementById("webgl");
const gl = canvas.getContext("webgl");
if (!gl) {
return;
}
// Define the shader source
const vertexShaderSource = glsl`
attribute vec2 a_position;
uniform vec2 u_resolution;
void main() {
// convert the position from pixels 0.0 to 1.0
vec2 zeroToOne = a_position / u_resolution;
// convert from 0->1 to 0->2
vec2 zeroToTwo = zeroToOne * 2.0;
// convert from 0->2 to -1->+1 (clipspace)
vec2 clipSpace = zeroToTwo - 1.0;
gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);
}
`;
const fragmentShaderSource = glsl`
// fragment shaders don't have a default precision
// so we need to pick one. mediump is a good default
precision mediump float;
uniform vec4 u_color;
void main() {
// gl_FragColor is a special variable a fragment
// shader is responsible for setting
gl_FragColor = u_color;
}
`;
// create GLSL shaders, upload the GLSL source, compile the shaders
const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
// Link the two shaders into a program
const program = createProgram(gl, vertexShader, fragmentShader);
// look up where the vertex data needs to go.
const positionAttributeLocation = gl.getAttribLocation(program, "a_position");
const resolutionUniformLocation = gl.getUniformLocation(program, "u_resolution");
const colorUniformLocation = gl.getUniformLocation(program, "u_color");
// Create a buffer and put three 2d clip space points in it
const positionBuffer = gl.createBuffer();
// Bind it to ARRAY_BUFFER (think of it as ARRAY_BUFFER = positionBuffer)
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
var positions = [
10, 20,
80, 20,
10, 30,
10, 30,
80, 20,
80, 30
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
// CODE ABOVE THIS LINE IS INITIALIZATION CODE
// CODE BELOW THIS LINE IS RENDERING CODE
// webglUtils.resizeCanvasToDisplaySize(gl.canvas);
// Tell WebGL how to convert from clip space to pixels
// gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
// Clear the canvas
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
// Tell it to use our program (pair of shaders)
gl.useProgram(program);
// Turn on the attribute
gl.enableVertexAttribArray(positionAttributeLocation);
gl.uniform2f(resolutionUniformLocation, gl.canvas.width, gl.canvas.height);
// Bind the position buffer.
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
function randomInt(range) {
return Math.floor(Math.random() * range);
}
function setRectangle(gl, x, y, width, height) {
const x1 = x;
const x2 = x + width;
const y1 = y;
const y2 = y + height;
// NOTE: gl.bufferData(gl.ARRAY_BUFFER, ...) will affect
// whatever buffer is bound to the `ARRAY_BUFFER` bind point
// but so far we only have one buffer. If we had more than one
// buffer we'd want to bind that buffer to `ARRAY_BUFFER` first.
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
x1, y1,
x2, y1,
x1, y2,
x1, y2,
x2, y1,
x2, y2
]), gl.STATIC_DRAW);
}
// Tell the attribute how to get data out of positionBuffer (ARRAY_BUFFER)
const size = 2; // 2 components per iteration
const type = gl.FLOAT; // the data is 32bit floats
const normalize = false; // don't normalize the data
const stride = 0; // 0 = move forward size * sizeof(type) each iteration to get the next position
const offset = 0; // start at the beginning of the buffer
gl.vertexAttribPointer(
positionAttributeLocation, size, type, normalize, stride, offset);
for (let ii = 0; ii < 50; ++ii) {
// Setup a random rectangle
// This will write to positionBuffer because
// its the last thing we bound on the ARRAY_BUFFER
// bind point
setRectangle(gl, randomInt(gl.canvas.width), randomInt(gl.canvas.width), randomInt(gl.canvas.height), randomInt(gl.canvas.height));
// set a random color
gl.uniform4f(colorUniformLocation, Math.random(), Math.random(), Math.random(), 1);
// draw the rectangle
gl.drawArrays(gl.TRIANGLES, 0, 6);
}
console.log(gl.canvas.width);
// // draw
// const primitiveType = gl.TRIANGLES;
// const drawoffset = 0;
// const count = 6;
// gl.drawArrays(primitiveType, drawoffset, count);
}
window.addEventListener("load", main);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment