Created
June 9, 2020 01:37
-
-
Save Strilanc/368b18bfcc5471f71deb5d33af39caa2 to your computer and use it in GitHub Desktop.
Chopped down webgl cube example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<body> | |
<script> | |
let canvas = document.createElement('canvas'); | |
document.body.appendChild(canvas); | |
let gl = canvas.getContext('webgl'); | |
if (!gl) { | |
throw new Error("!gl") | |
} | |
let vsSource = ` | |
attribute vec4 aVertexPosition; | |
attribute vec4 aVertexColor; | |
uniform mat4 uModelViewMatrix; | |
uniform mat4 uProjectionMatrix; | |
varying lowp vec4 vColor; | |
void main(void) { | |
gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition; | |
vColor = aVertexColor; | |
} | |
`; | |
// Fragment shader program | |
let fsSource = ` | |
varying lowp vec4 vColor; | |
void main(void) { | |
gl_FragColor = vColor; | |
}`; | |
let shaderProgram = createProgram(vsSource, fsSource); | |
let programInfo = { | |
program: shaderProgram, | |
attribLocations: { | |
vertexPosition: gl.getAttribLocation(shaderProgram, 'aVertexPosition'), | |
vertexColor: gl.getAttribLocation(shaderProgram, 'aVertexColor'), | |
}, | |
uniformLocations: { | |
projectionMatrix: gl.getUniformLocation(shaderProgram, 'uProjectionMatrix'), | |
modelViewMatrix: gl.getUniformLocation(shaderProgram, 'uModelViewMatrix'), | |
}, | |
}; | |
let buffers = initBuffers(gl); | |
function render() { | |
drawScene(gl, programInfo, buffers); | |
requestAnimationFrame(render); | |
} | |
requestAnimationFrame(render); | |
function initBuffers(gl) { | |
let positionBuffer = gl.createBuffer(); | |
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); | |
let positions = [ | |
// Front face | |
-1.0, -1.0, 1.0, | |
1.0, -1.0, 1.0, | |
1.0, 1.0, 1.0, | |
-1.0, 1.0, 1.0, | |
// Back face | |
-1.0, -1.0, -1.0, | |
-1.0, 1.0, -1.0, | |
1.0, 1.0, -1.0, | |
1.0, -1.0, -1.0, | |
// Top face | |
-1.0, 1.0, -1.0, | |
-1.0, 1.0, 1.0, | |
1.0, 1.0, 1.0, | |
1.0, 1.0, -1.0, | |
// Bottom face | |
-1.0, -1.0, -1.0, | |
1.0, -1.0, -1.0, | |
1.0, -1.0, 1.0, | |
-1.0, -1.0, 1.0, | |
// Right face | |
1.0, -1.0, -1.0, | |
1.0, 1.0, -1.0, | |
1.0, 1.0, 1.0, | |
1.0, -1.0, 1.0, | |
// Left face | |
-1.0, -1.0, -1.0, | |
-1.0, -1.0, 1.0, | |
-1.0, 1.0, 1.0, | |
-1.0, 1.0, -1.0, | |
]; | |
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW); | |
let faceColors = [ | |
[1.0, 1.0, 1.0, 1.0], // Front face: white | |
[1.0, 0.0, 0.0, 1.0], // Back face: red | |
[0.0, 1.0, 0.0, 1.0], // Top face: green | |
[0.0, 0.0, 1.0, 1.0], // Bottom face: blue | |
[1.0, 1.0, 0.0, 1.0], // Right face: yellow | |
[1.0, 0.0, 1.0, 1.0], // Left face: purple | |
]; | |
let colors = []; | |
for (let j = 0; j < faceColors.length; ++j) { | |
let c = faceColors[j]; | |
colors = colors.concat(c, c, c, c); | |
} | |
let colorBuffer = gl.createBuffer(); | |
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); | |
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW); | |
let indexBuffer = gl.createBuffer(); | |
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); | |
let indices = [ | |
0, 1, 2, 0, 2, 3, // front | |
4, 5, 6, 4, 6, 7, // back | |
8, 9, 10, 8, 10, 11, // top | |
12, 13, 14, 12, 14, 15, // bottom | |
16, 17, 18, 16, 18, 19, // right | |
20, 21, 22, 20, 22, 23, // left | |
]; | |
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, | |
new Uint16Array(indices), gl.STATIC_DRAW); | |
return { | |
position: positionBuffer, | |
color: colorBuffer, | |
indices: indexBuffer, | |
}; | |
} | |
function drawScene(gl, programInfo, buffers) { | |
gl.clearColor(0.0, 0.0, 0.0, 1.0); | |
gl.clearDepth(1.0); | |
gl.enable(gl.DEPTH_TEST); | |
gl.depthFunc(gl.LEQUAL); | |
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); | |
let projectionMatrix = perspective( | |
45 * Math.PI / 180, | |
gl.canvas.clientWidth / gl.canvas.clientHeight, | |
0.1, | |
100); | |
let modelViewMatrix = translate(-0.0, 0, -6.0); | |
gl.bindBuffer(gl.ARRAY_BUFFER, buffers.position); | |
gl.vertexAttribPointer( | |
programInfo.attribLocations.vertexPosition, | |
3, | |
gl.FLOAT, | |
false, | |
0, | |
0); | |
gl.enableVertexAttribArray( | |
programInfo.attribLocations.vertexPosition); | |
gl.bindBuffer(gl.ARRAY_BUFFER, buffers.color); | |
gl.vertexAttribPointer( | |
programInfo.attribLocations.vertexColor, | |
4, | |
gl.FLOAT, | |
false, | |
0, | |
0); | |
gl.enableVertexAttribArray( | |
programInfo.attribLocations.vertexColor); | |
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffers.indices); | |
gl.useProgram(programInfo.program); | |
gl.uniformMatrix4fv( | |
programInfo.uniformLocations.projectionMatrix, | |
false, | |
projectionMatrix); | |
gl.uniformMatrix4fv( | |
programInfo.uniformLocations.modelViewMatrix, | |
false, | |
modelViewMatrix); | |
gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_SHORT, 0); | |
} | |
function createProgram(vsSource, fsSource) { | |
let vertexShader = createCompiledShader(gl.VERTEX_SHADER, vsSource); | |
let fragmentShader = createCompiledShader(gl.FRAGMENT_SHADER, fsSource); | |
let shaderProgram = gl.createProgram(); | |
gl.attachShader(shaderProgram, vertexShader); | |
gl.attachShader(shaderProgram, fragmentShader); | |
gl.linkProgram(shaderProgram); | |
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { | |
throw new Error("Shader linking failed.\n" + gl.getProgramInfoLog(shaderProgram)); | |
} | |
return shaderProgram; | |
} | |
function createCompiledShader(type, source) { | |
let shader = gl.createShader(type); | |
gl.shaderSource(shader, source); | |
gl.compileShader(shader); | |
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { | |
throw new Error("Shader compiling failed.\n" + gl.getShaderInfoLog(shader)); | |
} | |
return shader; | |
} | |
function translate(x, y, z) { | |
return new Float32Array([ | |
1, 0, 0, 0, | |
0, 1, 0, 0, | |
0, 0, 1, 0, | |
x, y, z, 1]); | |
} | |
function perspective(fovy, aspect, near, far) { | |
var f = 1.0 / Math.tan(fovy / 2); | |
var nf = 1 / (near - far); | |
return new Float32Array([ | |
f / aspect, 0, 0, 0, | |
0, f, 0, 0, | |
0, 0, (far + near) * nf, -1, | |
0, 0, 2 * far * near * nf, 0, | |
]); | |
} | |
</script></body></html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment