Answered step by step
Verified Expert Solution
Question
1 Approved Answer
Write a WebGL program that displays a cube with colored faces using an orthographic projection. Allow an interactive user to rotate the cube 15 degrees
Write a WebGL program that displays a cube with colored faces using an orthographic projection. Allow an interactive user to rotate the cube 15 degrees about the x and y axes. Use ColoredCube from matsuda/ch07 as a template, and make the following modifications. 1) Replace the cuon-matrix.js functions setPerspective and lookAt by functions setOrtho, translate, and rotate. The viewing volume defined by setOrtho should be chosen so that the cube occupies most of the volume but no clipping occurs. 2) Add buttons labeled 'Rotate x' and 'Rotate y', along with callback functions that redraw the cube with the modified rotation angles. This requires a drawing function that creates the modelview-projection matrix mvpMatrix, passes it to the shader variable u_MvpMatrix, clears the color and depth buffers, and calls gl.drawElements. Also, since this drawing function is called by main() and the button callbacks, several variables must be converted from local to global.
Colored Cube Code:
// ColoredCube.js (c) 2012 matsuda | |
// Vertex shader program | |
var VSHADER_SOURCE = | |
'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; ' + | |
'} '; | |
// Fragment shader program | |
var FSHADER_SOURCE = | |
'#ifdef GL_ES ' + | |
'precision mediump float; ' + | |
'#endif ' + | |
'varying vec4 v_Color; ' + | |
'void main() { ' + | |
' gl_FragColor = v_Color; ' + | |
'} '; | |
function main() { | |
// Retrieve | |
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, 1.0); | |
gl.enable(gl.DEPTH_TEST); | |
// Get the storage location of u_MvpMatrix | |
var u_MvpMatrix = gl.getUniformLocation(gl.program, 'u_MvpMatrix'); | |
if (!u_MvpMatrix) { | |
console.log('Failed to get the storage location of u_MvpMatrix'); | |
return; | |
} | |
// Set the eye point and the viewing volume | |
var mvpMatrix = new Matrix4(); | |
mvpMatrix.setPerspective(30, 1, 1, 100); | |
mvpMatrix.lookAt(3, 3, 7, 0, 0, 0, 0, 1, 0); | |
// 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); | |
} | |
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.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 | |
]); | |
var indices = new Uint8Array([ // Indices of the vertices | |
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 | |
]); | |
// 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; | |
} | |
function initArrayBuffer(gl, data, num, type, attribute) { | |
var buffer = gl.createBuffer(); // Create a buffer object | |
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); | |
return true; | |
} |
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started