Skip to content

Instantly share code, notes, and snippets.

@davepagurek
Created October 20, 2017 17:01
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 davepagurek/94f7863cc8f9675a1eac2b1abba885d7 to your computer and use it in GitHub Desktop.
Save davepagurek/94f7863cc8f9675a1eac2b1abba885d7 to your computer and use it in GitHub Desktop.
<html>
<head>
</head>
<body>
<canvas id="glCanvas" width="640" height="480"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.4.0/gl-matrix-min.js"></script>
<script type="text/javascript" src="script.js"></script>
</body>
</html>
main();
const center = {};
const mouseInfo = {};
(window.onresize = function () {
center.x = window.innerWidth / 2;
center.y = window.innerHeight / 2;
})();
function main() {
const canvas = document.getElementById('glCanvas');
const gl = canvas.getContext('webgl');
if (!gl) {
alert('No webgl support :(');
return;
}
const vsSource = `
attribute vec4 aVertexPosition;
attribute vec4 aVertexColor;
uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;
varying lowp vec4 vColor;
void main() {
gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;
vColor = aVertexColor;
}
`;
const fsSource = `
varying lowp vec4 vColor;
void main() {
gl_FragColor = vColor;
}
`;
const shaderProgram = initShaderProgram(gl, vsSource, fsSource);
const 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')
}
}
const buffers = initBuffers(gl);
function render() {
drawScene(gl, programInfo, buffers, mouseInfo);
}
document.body.addEventListener('mousemove', function(e) {
mouseInfo.x = e.clientX - center.x;
mouseInfo.y = e.clientY - center.y;
mouseInfo.rx = 0 - mouseInfo.y;
mouseInfo.ry = mouseInfo.x;
['rx', 'ry'].forEach(function (r) {
mouseInfo[r] *= 0.1;
mouseInfo[r] = Math.max(-60, mouseInfo[r]);
mouseInfo[r] = Math.min(60, mouseInfo[r]);
mouseInfo[r] *= Math.PI/180;
});
if (window.requestAnimationFrame) {
window.requestAnimationFrame(render);
}
});
var then = 0;
requestAnimationFrame(render);
}
function initShaderProgram(gl, vsSource, fsSource) {
const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);
const shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert(`Unable to initialize the shader program: ${gl.getProgramInfoLog(shaderProgram)}`);
return null;
}
return shaderProgram;
}
function loadShader(gl, type, source) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert(`An error occurred compiling the shaders: ${gl.getShaderInfoLog(shader)}`);
gl.deleteShader(shader);
return null;
}
return shader;
}
function initBuffers(gl) {
const positionBuffer = gl.createBuffer();
const positions = [
1.0, 1.0,
-1.0, 1.0,
1.0, -1.0,
-1.0, -1.0
];
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
const colorBuffer = gl.createBuffer();
const colors = [
1.0, 1.0, 1.0, 1.0, // white
1.0, 0.0, 0.0, 1.0, // red
0.0, 1.0, 0.0, 1.0, // green
0.0, 0.0, 1.0, 1.0, // blue
];
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
return {position: positionBuffer, color: colorBuffer};
}
function drawScene(gl, programInfo, buffers, mouseInfo) {
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);
const fieldOfView = 45 * Math.PI / 180;
const aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
const zNear = 0.1;
const zFar = 100.0;
const projectionMatrix = mat4.create();
mat4.perspective(projectionMatrix, fieldOfView, aspect, zNear, zFar);
const modelViewMatrix = mat4.create();
mat4.translate(modelViewMatrix, modelViewMatrix, [-0.0, 0.0, -6.0]);
mat4.rotate(modelViewMatrix, modelViewMatrix, Math.PI-mouseInfo.rx, [1, 0, 0]);
mat4.rotate(modelViewMatrix, modelViewMatrix, Math.PI-mouseInfo.ry, [0, 1, 0]);
{
const numComponents = 2;
const type = gl.FLOAT;
const normalize = false;
const stride = 0;
const offset = 0;
gl.bindBuffer(gl.ARRAY_BUFFER, buffers.position);
gl.vertexAttribPointer(
programInfo.attribLocations.vertexPosition,
numComponents,
type,
normalize,
stride,
offset
);
gl.enableVertexAttribArray(programInfo.attribLocations.vertexPosition);
}
{
const numComponents = 4;
const type = gl.FLOAT;
const normalize = false;
const stride = 0;
const offset = 0;
gl.bindBuffer(gl.ARRAY_BUFFER, buffers.color);
gl.vertexAttribPointer(
programInfo.attribLocations.vertexColor,
numComponents,
type,
normalize,
stride,
offset
);
gl.enableVertexAttribArray(programInfo.attribLocations.vertexColor);
}
gl.useProgram(programInfo.program);
gl.uniformMatrix4fv(
programInfo.uniformLocations.projectionMatrix,
false,
projectionMatrix
);
gl.uniformMatrix4fv(
programInfo.uniformLocations.modelViewMatrix,
false,
modelViewMatrix
);
{
const offset = 0;
const vertexCount = 4;
gl.drawArrays(gl.TRIANGLE_STRIP, offset, vertexCount);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment