You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
252 lines
6.3 KiB
252 lines
6.3 KiB
var projectionMatrix, modelViewMatrix;
|
|
var rotationAxis;
|
|
var shaderProgram, shaderVertexPositionAttribute
|
|
var shaderVertexColorAttribute;
|
|
var shaderProjectionMatrixUniform, shaderModelViewMatrixUniform;
|
|
|
|
var duration = 5000; // ms
|
|
var currentTime = Date.now();
|
|
|
|
function initWebGL(canvas) {
|
|
var gl = null;
|
|
var msg = "Your browser does not support WebGL, " +
|
|
"or it is not enabled by default.";
|
|
try {
|
|
gl = canvas.getContext("experimental-webgl");
|
|
}
|
|
catch (e) {
|
|
msg = "Error creating WebGL Context!: " + e.toString();
|
|
}
|
|
if (!gl) {
|
|
alert(msg);
|
|
throw new Error(msg);
|
|
}
|
|
|
|
return gl;
|
|
}
|
|
|
|
function initViewport(gl, canvas) {
|
|
gl.viewport(0, 0, canvas.width, canvas.height);
|
|
}
|
|
|
|
// Create the vertex, color, and index data for a
|
|
// multicolored cube
|
|
function createCube(gl) {
|
|
// Vertex Data
|
|
var vertexBuffer;
|
|
vertexBuffer = gl.createBuffer();
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
|
|
var verts = [
|
|
// 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(verts),
|
|
gl.STATIC_DRAW);
|
|
// Color data
|
|
var colorBuffer = gl.createBuffer();
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
|
|
var faceColors = [
|
|
[1.0, 0.0, 0.0, 1.0], // Front face
|
|
[0.0, 1.0, 0.0, 1.0], // Back face
|
|
[0.0, 0.0, 1.0, 1.0], // Top face
|
|
[1.0, 1.0, 0.0, 1.0], // Bottom face
|
|
[1.0, 0.0, 1.0, 1.0], // Right face
|
|
[0.0, 1.0, 1.0, 1.0] // Left face
|
|
];
|
|
var vertexColors = [];
|
|
for (var i in faceColors) {
|
|
var color = faceColors[i];
|
|
for (var j=0; j < 4; j++) {
|
|
vertexColors = vertexColors.concat(color);
|
|
}
|
|
}
|
|
gl.bufferData(
|
|
gl.ARRAY_BUFFER,
|
|
new Float32Array(vertexColors),
|
|
gl.STATIC_DRAW);
|
|
// Index data (defines the triangles to be drawn)
|
|
var cubeIndexBuffer = gl.createBuffer();
|
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeIndexBuffer);
|
|
var cubeIndices = [
|
|
0, 1, 2, 0, 2, 3, // Front face
|
|
4, 5, 6, 4, 6, 7, // Back face
|
|
8, 9, 10, 8, 10, 11, // Top face
|
|
12, 13, 14, 12, 14, 15, // Bottom face
|
|
16, 17, 18, 16, 18, 19, // Right face
|
|
20, 21, 22, 20, 22, 23 // Left face
|
|
];
|
|
gl.bufferData(
|
|
gl.ELEMENT_ARRAY_BUFFER,
|
|
new Uint16Array(cubeIndices),
|
|
gl.STATIC_DRAW);
|
|
var cube = {
|
|
buffer:vertexBuffer,
|
|
colorBuffer:colorBuffer,
|
|
indices:cubeIndexBuffer,
|
|
vertSize:3,
|
|
nVerts:24,
|
|
colorSize:4,
|
|
nColors: 24,
|
|
nIndices:36,
|
|
primtype:gl.TRIANGLES};
|
|
|
|
return cube;
|
|
}
|
|
|
|
function initMatrices(canvas) {
|
|
modelViewMatrix = mat4.create();
|
|
mat4.translate(
|
|
modelViewMatrix, modelViewMatrix, [0, 0, -4.6]);
|
|
|
|
// Create a project matrix with 45 degree field of view
|
|
projectionMatrix = mat4.create();
|
|
mat4.perspective(projectionMatrix, Math.PI / 4,
|
|
canvas.width / canvas.height, 1, 10000);
|
|
|
|
rotationAxis = vec3.create();
|
|
vec3.normalize(rotationAxis, [1, 1, 1]);
|
|
}
|
|
|
|
function createShader(gl, id, type) {
|
|
var shader;
|
|
var str = document.getElementById(id).text;
|
|
if (type == "fragment") {
|
|
shader = gl.createShader(gl.FRAGMENT_SHADER);
|
|
} else if (type == "vertex") {
|
|
shader = gl.createShader(gl.VERTEX_SHADER);
|
|
} else {
|
|
return null;
|
|
}
|
|
|
|
gl.shaderSource(shader, str);
|
|
gl.compileShader(shader);
|
|
|
|
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
|
alert(gl.getShaderInfoLog(shader));
|
|
return null;
|
|
}
|
|
|
|
return shader;
|
|
}
|
|
|
|
function initShader(gl, vertex, fragment) {
|
|
// load and compile the fragment and vertex shader
|
|
var fragmentShader = createShader(gl, fragment, "fragment");
|
|
var vertexShader = createShader(gl, vertex, "vertex");
|
|
|
|
// link them together into a new program
|
|
shaderProgram = gl.createProgram();
|
|
gl.attachShader(shaderProgram, vertexShader);
|
|
gl.attachShader(shaderProgram, fragmentShader);
|
|
gl.linkProgram(shaderProgram);
|
|
|
|
// get pointers to the shader params
|
|
shaderVertexPositionAttribute = gl.getAttribLocation(
|
|
shaderProgram, "vertexPos");
|
|
gl.enableVertexAttribArray(shaderVertexPositionAttribute);
|
|
shaderVertexColorAttribute = gl.getAttribLocation(
|
|
shaderProgram, "vertexColor");
|
|
gl.enableVertexAttribArray(shaderVertexColorAttribute);
|
|
|
|
shaderProjectionMatrixUniform = gl.getUniformLocation(
|
|
shaderProgram, "projectionMatrix");
|
|
shaderModelViewMatrixUniform = gl.getUniformLocation(
|
|
shaderProgram, "modelViewMatrix");
|
|
|
|
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
|
|
alert("Could not initialise shaders");
|
|
}
|
|
}
|
|
|
|
function draw(gl, obj) {
|
|
// clear the background (transparent)
|
|
gl.clearColor(0.0, 0.0, 0.0, 0.0);
|
|
// // clear the background (black)
|
|
// gl.clearColor(0.0, 0.0, 0.0, 1.0);
|
|
gl.enable(gl.DEPTH_TEST);
|
|
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
|
|
|
// set the shader to use
|
|
gl.useProgram(shaderProgram);
|
|
|
|
// connect up the shader parameters: vertex position,
|
|
// color, and projection/model matrices
|
|
// set up the buffers
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, obj.buffer);
|
|
gl.vertexAttribPointer(shaderVertexPositionAttribute,
|
|
obj.vertSize, gl.FLOAT, false, 0, 0);
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, obj.colorBuffer);
|
|
gl.vertexAttribPointer(shaderVertexColorAttribute,
|
|
obj.colorSize, gl.FLOAT, false, 0, 0);
|
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, obj.indices);
|
|
gl.uniformMatrix4fv(shaderProjectionMatrixUniform, false,
|
|
projectionMatrix);
|
|
gl.uniformMatrix4fv(shaderModelViewMatrixUniform, false,
|
|
modelViewMatrix);
|
|
|
|
// draw the object
|
|
gl.drawElements(
|
|
obj.primtype, obj.nIndices, gl.UNSIGNED_SHORT, 0);
|
|
}
|
|
|
|
function animate() {
|
|
var now = Date.now();
|
|
var deltat = now - currentTime;
|
|
currentTime = now;
|
|
var fract = deltat / duration;
|
|
var angle = Math.PI * 2 * fract;
|
|
mat4.rotate(
|
|
modelViewMatrix, modelViewMatrix, angle, rotationAxis);
|
|
}
|
|
|
|
function run(gl, cube) {
|
|
requestAnimationFrame(function() { run(gl, cube); });
|
|
draw(gl, cube);
|
|
animate();
|
|
}
|
|
|
|
function startGl() {
|
|
// Get A WebGL context
|
|
var canvas = document.getElementById("cube");
|
|
var gl = initWebGL(canvas);
|
|
var obj = createCube(gl);
|
|
|
|
initViewport(gl, canvas);
|
|
initMatrices(canvas);
|
|
initShader(
|
|
gl,
|
|
"cube-vertex-shader",
|
|
"cube-fragment-shader");
|
|
run(gl, obj);
|
|
}
|
|
/* vim: set ts=4 sw=4: */
|