Created
November 25, 2020 14:40
-
-
Save MinaGabriel/27212605bbee801cce2f32c09be0dd73 to your computer and use it in GitHub Desktop.
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
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"/> | |
<title>Translate a Triangle</title> | |
<body onload="main()"> | |
<canvas id="webgl" width="300" height="300" style="position: absolute"> | |
Please use a browser that supports "canvas" | |
</canvas> | |
<div> | |
<h1>19</h1> | |
<h2>Great Designs Come from Great Designers --- Not from Great Design Processes</h2> | |
<p>The basic premise underlying the SEI's [Software | |
Engineering Institute] work on software process maturity | |
is that the quality of a software product is largely | |
determined by the quality of the software development | |
and maintenance processes used to build it.</p> | |
Mark Paulk [1995], "The evolution of the SEI's capability maturity model for software" | |
<p>...[W]hile some may see them as the crazy ones, we see | |
genius, because the ones who are crazy enough to think | |
that they can change the world, are the ones who do.</p> | |
Steve Jobs, Apple commercial (1997) | |
</div> | |
</body> | |
<script src="https://rawgit.com/huningxin/webglbook_examples/master/lib/webgl-utils.js"></script> | |
<script src="https://rawgit.com/huningxin/webglbook_examples/master/lib/webgl-debug.js"></script> | |
<script src="https://rawgit.com/huningxin/webglbook_examples/master/lib/cuon-utils.js"></script> | |
<script src="https://rawgit.com/huningxin/webglbook_examples/master/lib/cuon-matrix.js"></script> | |
<script type="text/javascript"> | |
// 3DoverWeb.js (c) 2012 matsuda | |
// Vertex shader program | |
var VSHADER_SOURCE = | |
'attribute vec4 a_Position;\n' + | |
'attribute vec4 a_Color;\n' + | |
'uniform mat4 u_MvpMatrix;\n' + | |
'uniform bool u_Clicked;\n' + // Mouse is pressed | |
'varying vec4 v_Color;\n' + | |
'void main() {\n' + | |
' gl_Position = u_MvpMatrix * a_Position;\n' + | |
' if (u_Clicked) {\n' + // Draw in red if mouse is pressed | |
' v_Color = vec4(1.0, 0.0, 0.0, 1.0);\n' + | |
' } else {\n' + | |
' v_Color = vec4(a_Color.rgb, 1.0);\n' + | |
' }\n' + | |
'}\n'; | |
// Fragment shader program | |
var FSHADER_SOURCE = | |
'#ifdef GL_ES\n' + | |
'precision mediump float;\n' + | |
'#endif\n' + | |
'varying vec4 v_Color;\n' + | |
'void main() {\n' + | |
' gl_FragColor = v_Color;\n' + | |
'}\n'; | |
var ANGLE_STEP = 20.0; // Rotation angle (degrees/second) | |
function main() { | |
// Retrieve <canvas> element | |
var canvas = document.getElementById('webgl'); | |
// Get the rendering context for WebGL | |
var gl = getWebGLContext(canvas); | |
if (!gl) { | |
console.log('Failed to get the rendering context for WebGL'); | |
return; | |
} | |
// Initialize shaders | |
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) { | |
console.log('Failed to intialize shaders.'); | |
return; | |
} | |
// Set the vertex information | |
var n = initVertexBuffers(gl); | |
if (n < 0) { | |
console.log('Failed to set the vertex information'); | |
return; | |
} | |
// Set the clear color and enable the depth test | |
gl.clearColor(0.0, 0.0, 0.0, 0.0); | |
gl.enable(gl.DEPTH_TEST); | |
// Get the storage locations of uniform variables | |
var u_MvpMatrix = gl.getUniformLocation(gl.program, 'u_MvpMatrix'); | |
var u_Clicked = gl.getUniformLocation(gl.program, 'u_Clicked'); | |
if (!u_MvpMatrix || !u_Clicked) { | |
console.log('Failed to get the storage location'); | |
return; | |
} | |
// Calculate the view projection matrix | |
var viewProjMatrix = new Matrix4(); | |
viewProjMatrix.setPerspective(30.0, canvas.width / canvas.height, 1.0, 100.0); | |
viewProjMatrix.lookAt(0.0, 0.0, 7.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); | |
gl.uniform1i(u_Clicked, 0); // Pass false to u_Clicked | |
var currentAngle = 0.0; // Current rotation angle | |
// Register the event handler | |
canvas.onmousedown = function(ev) { // Mouse is pressed | |
var x = ev.clientX, y = ev.clientY; | |
var rect = ev.target.getBoundingClientRect(); | |
if (rect.left <= x && x < rect.right && rect.top <= y && y < rect.bottom) { | |
// If pressed position is inside <canvas>, check if it is above object | |
var x_in_canvas = x - rect.left, y_in_canvas = rect.bottom - y; | |
check(gl, n, x_in_canvas, y_in_canvas, currentAngle, u_Clicked, viewProjMatrix, u_MvpMatrix); | |
} | |
} | |
var tick = function() { // Start drawing | |
currentAngle = animate(currentAngle); | |
draw(gl, n, currentAngle, viewProjMatrix, u_MvpMatrix); | |
requestAnimationFrame(tick, canvas); | |
}; | |
tick(); | |
} | |
function initVertexBuffers(gl) { | |
// Create a cube | |
// v6----- v5 | |
// /| /| | |
// v1------v0| | |
// | | | | | |
// | |v7---|-|v4 | |
// |/ |/ | |
// v2------v3 | |
var vertices = new Float32Array([ // Vertex coordinates | |
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 | |
]); | |
var colors = new Float32Array([ // Colors | |
0.2, 0.58, 0.82, 0.2, 0.58, 0.82, 0.2, 0.58, 0.82, 0.2, 0.58, 0.82, // v0-v1-v2-v3 front | |
0.5, 0.41, 0.69, 0.5, 0.41, 0.69, 0.5, 0.41, 0.69, 0.5, 0.41, 0.69, // v0-v3-v4-v5 right | |
0.0, 0.32, 0.61, 0.0, 0.32, 0.61, 0.0, 0.32, 0.61, 0.0, 0.32, 0.61, // v0-v5-v6-v1 up | |
0.78, 0.69, 0.84, 0.78, 0.69, 0.84, 0.78, 0.69, 0.84, 0.78, 0.69, 0.84, // v1-v6-v7-v2 left | |
0.32, 0.18, 0.56, 0.32, 0.18, 0.56, 0.32, 0.18, 0.56, 0.32, 0.18, 0.56, // v7-v4-v3-v2 down | |
0.73, 0.82, 0.93, 0.73, 0.82, 0.93, 0.73, 0.82, 0.93, 0.73, 0.82, 0.93, // v4-v7-v6-v5 back | |
]); | |
// Indices of the vertices | |
var indices = new Uint8Array([ | |
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 | |
]); | |
// Write the vertex property to buffers (coordinates and normals) | |
if (!initArrayBuffer(gl, vertices, gl.FLOAT, 3, 'a_Position')) return -1; // Coordinates | |
if (!initArrayBuffer(gl, colors, gl.FLOAT, 3, 'a_Color')) return -1; // Color Information | |
// Create a buffer object | |
var indexBuffer = gl.createBuffer(); | |
if (!indexBuffer) { | |
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; | |
} | |
function check(gl, n, x, y, currentAngle, u_Clicked, viewProjMatrix, u_MvpMatrix) { | |
var picked = false; | |
gl.uniform1i(u_Clicked, 1); // Pass true to u_Clicked(Draw cube with red) | |
draw(gl, n, currentAngle, viewProjMatrix, u_MvpMatrix); | |
// Read pixel at the clicked position | |
var pixels = new Uint8Array(4); // Array for storing the pixel value | |
gl.readPixels(x, y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels); | |
if (pixels[0] == 255) // If red = 255, clicked on cube | |
picked = true; | |
gl.uniform1i(u_Clicked, 0); // Pass false to u_Clicked(Draw cube with specified color) | |
draw(gl, n, currentAngle, viewProjMatrix, u_MvpMatrix); | |
if (picked) alert('The cube was selected! '); | |
} | |
var g_MvpMatrix = new Matrix4(); // Model view projection matrix | |
function draw(gl, n, currentAngle, viewProjMatrix, u_MvpMatrix) { | |
// Caliculate The model view projection matrix and pass it to u_MvpMatrix | |
g_MvpMatrix.set(viewProjMatrix); | |
g_MvpMatrix.rotate(currentAngle, 1.0, 0.0, 0.0); // Rotate appropriately | |
g_MvpMatrix.rotate(currentAngle, 0.0, 1.0, 0.0); | |
g_MvpMatrix.rotate(currentAngle, 0.0, 0.0, 1.0); | |
gl.uniformMatrix4fv(u_MvpMatrix, false, g_MvpMatrix.elements); | |
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); // Clear buffers (color and depth) | |
gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0); // Draw | |
} | |
var last = Date.now(); // Last time that this function was called | |
function animate(angle) { | |
var now = Date.now(); // Calculate the elapsed time | |
var elapsed = now - last; | |
last = now; | |
// Update the current rotation angle (adjusted by the elapsed time) | |
var newAngle = angle + (ANGLE_STEP * elapsed) / 1000.0; | |
return newAngle % 360; | |
} | |
function initArrayBuffer (gl, data, type, num, attribute) { | |
// Create a buffer object | |
var buffer = gl.createBuffer(); | |
if (!buffer) { | |
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); | |
if (a_attribute < 0) { | |
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); | |
// Unbind the buffer object | |
gl.bindBuffer(gl.ARRAY_BUFFER, null); | |
return true; | |
} | |
</script> | |
</head> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment