2022-07-12 18:18:10 +00:00
|
|
|
// ColoredCube.js (c) 2012 matsuda
|
|
|
|
|
|
|
|
const vertex_shader = `
|
|
|
|
attribute vec4 a_Position;
|
|
|
|
attribute vec4 a_Color;
|
|
|
|
uniform mat4 u_MvpMatrix;
|
|
|
|
varying vec4 v_Color;
|
|
|
|
|
|
|
|
void main()
|
|
|
|
{
|
|
|
|
gl_Position = u_MvpMatrix * a_Position;
|
|
|
|
v_Color = a_Color;
|
|
|
|
} `;
|
|
|
|
|
|
|
|
|
|
|
|
const fragment_shader = `
|
|
|
|
#ifdef GL_ES
|
|
|
|
precision mediump float;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
varying vec4 v_Color;
|
|
|
|
|
|
|
|
void main()
|
|
|
|
{
|
|
|
|
gl_FragColor = v_Color;
|
|
|
|
} `;
|
|
|
|
|
2022-07-12 19:11:19 +00:00
|
|
|
var gl, n;
|
|
|
|
var v_rotate = {x: 0, y:0, z:0};
|
|
|
|
|
|
|
|
function main() {
|
2022-07-12 18:18:10 +00:00
|
|
|
// Retrieve <canvas> element
|
|
|
|
var canvas = document.getElementById('webgl');
|
|
|
|
|
|
|
|
// Get the rendering context for WebGL
|
2022-07-12 19:11:19 +00:00
|
|
|
gl = getWebGLContext(canvas);
|
|
|
|
if (!gl) {
|
2022-07-12 18:18:10 +00:00
|
|
|
console.log('Failed to get the rendering context for WebGL');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Initialize shaders
|
2022-07-12 19:11:19 +00:00
|
|
|
if (!initShaders(gl, vertex_shader, fragment_shader)) {
|
2022-07-12 18:18:10 +00:00
|
|
|
console.log('Failed to intialize shaders.');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the vertex information
|
2022-07-12 19:11:19 +00:00
|
|
|
n = initVertexBuffers(gl);
|
|
|
|
if (n < 0) {
|
2022-07-12 18:18:10 +00:00
|
|
|
console.log('Failed to set the vertex information');
|
|
|
|
return;
|
|
|
|
}
|
2022-07-12 19:11:19 +00:00
|
|
|
draw(gl);
|
|
|
|
}
|
2022-07-12 18:18:10 +00:00
|
|
|
|
2022-07-12 19:11:19 +00:00
|
|
|
function draw(gl) {
|
2022-07-12 18:18:10 +00:00
|
|
|
// Set the clear color and enable the depth test
|
|
|
|
gl.clearColor(0.0, 0.0, 0.0, 1.0);
|
|
|
|
gl.enable(gl.DEPTH_TEST);
|
|
|
|
|
|
|
|
// Get the storage location of u_MvpMatrix
|
|
|
|
var u_MvpMatrix = gl.getUniformLocation(gl.program, 'u_MvpMatrix');
|
2022-07-12 19:11:19 +00:00
|
|
|
if (!u_MvpMatrix) {
|
2022-07-12 18:18:10 +00:00
|
|
|
console.log('Failed to get the storage location of u_MvpMatrix');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the eye point and the viewing volume
|
|
|
|
var mvpMatrix = new Matrix4();
|
2022-07-12 19:11:19 +00:00
|
|
|
// The longest measure of a cube is the furthest corner diagonal, with a size of sqrt(3)
|
|
|
|
// Here, we take the root of 3, and add a little extra, to make sure it doesn't clip
|
|
|
|
const root_three = Math.sqrt(3) + 0.01;
|
|
|
|
// Then, we define the ortho projection to use this value as the coordinate of each clipping plane.
|
|
|
|
mvpMatrix.setOrtho(-root_three, root_three, -root_three, root_three, -root_three, root_three);
|
|
|
|
// From there, we rotate
|
|
|
|
mvpMatrix.rotate(v_rotate.x, 1, 0, 0).rotate(v_rotate.y, 0, 1, 0).rotate(v_rotate.z, 0, 0, 1);
|
|
|
|
|
2022-07-12 18:18:10 +00:00
|
|
|
|
|
|
|
// Pass the model view projection matrix to u_MvpMatrix
|
|
|
|
gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements);
|
|
|
|
|
|
|
|
// Clear color and depth buffer
|
|
|
|
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
|
|
|
|
|
|
|
// Draw the cube
|
|
|
|
gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0);
|
|
|
|
}
|
|
|
|
|
2022-07-12 19:11:19 +00:00
|
|
|
function initVertexBuffers(gl) {
|
2022-07-12 18:18:10 +00:00
|
|
|
// Create a cube
|
|
|
|
// v6----- v5
|
|
|
|
// /| /|
|
|
|
|
// v1------v0|
|
|
|
|
// | | | |
|
|
|
|
// | |v7---|-|v4
|
|
|
|
// |/ |/
|
|
|
|
// v2------v3
|
|
|
|
|
|
|
|
var vertices = new Float32Array([ // Vertex coordinates
|
2022-07-12 19:11:19 +00:00
|
|
|
1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, // v0-v1-v2-v3 front
|
|
|
|
1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, // v0-v3-v4-v5 right
|
|
|
|
1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, // v0-v5-v6-v1 up
|
|
|
|
-1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, // v1-v6-v7-v2 left
|
|
|
|
-1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, // v7-v4-v3-v2 down
|
|
|
|
1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0 // v4-v7-v6-v5 back
|
2022-07-12 18:18:10 +00:00
|
|
|
]);
|
|
|
|
|
|
|
|
var colors = new Float32Array([ // Colors
|
2022-07-12 19:11:19 +00:00
|
|
|
0.4, 0.4, 1.0, 0.4, 0.4, 1.0, 0.4, 0.4, 1.0, 0.4, 0.4, 1.0, // v0-v1-v2-v3 front(blue)
|
|
|
|
0.4, 1.0, 0.4, 0.4, 1.0, 0.4, 0.4, 1.0, 0.4, 0.4, 1.0, 0.4, // v0-v3-v4-v5 right(green)
|
|
|
|
1.0, 0.4, 0.4, 1.0, 0.4, 0.4, 1.0, 0.4, 0.4, 1.0, 0.4, 0.4, // v0-v5-v6-v1 up(red)
|
|
|
|
1.0, 1.0, 0.4, 1.0, 1.0, 0.4, 1.0, 1.0, 0.4, 1.0, 1.0, 0.4, // v1-v6-v7-v2 left
|
|
|
|
1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, // v7-v4-v3-v2 down
|
|
|
|
0.4, 1.0, 1.0, 0.4, 1.0, 1.0, 0.4, 1.0, 1.0, 0.4, 1.0, 1.0 // v4-v7-v6-v5 back
|
2022-07-12 18:18:10 +00:00
|
|
|
]);
|
|
|
|
|
|
|
|
var indices = new Uint8Array([ // Indices of the vertices
|
2022-07-12 19:11:19 +00:00
|
|
|
0, 1, 2, 0, 2, 3, // front
|
|
|
|
4, 5, 6, 4, 6, 7, // right
|
|
|
|
8, 9, 10, 8, 10, 11, // up
|
|
|
|
12, 13, 14, 12, 14, 15, // left
|
|
|
|
16, 17, 18, 16, 18, 19, // down
|
|
|
|
20, 21, 22, 20, 22, 23 // back
|
2022-07-12 18:18:10 +00:00
|
|
|
]);
|
|
|
|
|
|
|
|
// Create a buffer object
|
|
|
|
var indexBuffer = gl.createBuffer();
|
|
|
|
if (!indexBuffer)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
// Write the vertex coordinates and color to the buffer object
|
|
|
|
if (!initArrayBuffer(gl, vertices, 3, gl.FLOAT, 'a_Position'))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (!initArrayBuffer(gl, colors, 3, gl.FLOAT, 'a_Color'))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
// Write the indices to the buffer object
|
|
|
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
|
|
|
|
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
|
|
|
|
|
|
|
|
return indices.length;
|
|
|
|
}
|
|
|
|
|
2022-07-12 19:11:19 +00:00
|
|
|
function initArrayBuffer(gl, data, num, type, attribute) {
|
2022-07-12 18:18:10 +00:00
|
|
|
var buffer = gl.createBuffer(); // Create a buffer object
|
2022-07-12 19:11:19 +00:00
|
|
|
if (!buffer) {
|
2022-07-12 18:18:10 +00:00
|
|
|
console.log('Failed to create the buffer object');
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Write date into the buffer object
|
|
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
|
|
|
gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);
|
|
|
|
|
|
|
|
// Assign the buffer object to the attribute variable
|
|
|
|
var a_attribute = gl.getAttribLocation(gl.program, attribute);
|
2022-07-12 19:11:19 +00:00
|
|
|
if (a_attribute < 0) {
|
2022-07-12 18:18:10 +00:00
|
|
|
console.log('Failed to get the storage location of ' + attribute);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
gl.vertexAttribPointer(a_attribute, num, type, false, 0, 0);
|
|
|
|
|
|
|
|
// Enable the assignment of the buffer object to the attribute variable
|
|
|
|
gl.enableVertexAttribArray(a_attribute);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2022-07-12 19:11:19 +00:00
|
|
|
|
|
|
|
function rotate(axis) {
|
|
|
|
if (axis in v_rotate) {
|
|
|
|
v_rotate[axis] += 15.0;
|
|
|
|
v_rotate[axis] %= 360; // bound to [0, 360)
|
|
|
|
|
|
|
|
console.log(`${axis} = ${v_rotate[axis]}`);
|
|
|
|
}
|
|
|
|
draw(gl);
|
|
|
|
}
|