CS 4722 - Computer Graphics and Multimedia
Module #7, Assignment #1Exercise #1You will continue to modify the ObjManager application shown below so that it can show texture materials on the OBJ files, as well as showing their mesh lines. Below the program is shown with the modifications you made in Module 6. Below is the next version of the program with the option for showing texture materials and mesh lines. Note that not all OBJ files have textures or smooth shading normals, so options for those only show up for the user to manipulate when the OBJ file includes that information: The partial HTML code is given here: ObjManager2.html. The partial JavaScript code is given here: ObjManager2.js. Your first OBJ files which have been converted to ".js" files (most of which were from Module 6) are below, and they all go inside of an "Objs" folder in your Visual Studio Project: Polyhedron.js
The last one above (Generic_Female_01) is an OBJ file (converted to a ".js" file) with texture material information inside it, so it will be drawn with those textures as shown above. The old OBJ files from Module 6 did not have texture material information in them. The following are a set of new OBJ files with texture materials that you will be using for this Module, and they are given below: Annie: annie.obj When an OBJ file includes texture materials, it is paired with an ".mtl" file, and the ".mtl" file has all of the information about the texture materials inside of it. The following are the ".mtl" files that go with the new OBJ files, and you will need to place these files inside of a "Textures" folder inside your Visual Studio Project: Annie: annie.mtl And additionally, each of the ".mtl" files identifies image files that are used as the actual textures for the objects when they are drawn. Some OBJ files use more than one image file for its various textures. For example, the "Harleen Quinzel" OBJ file uses 7 image files. All of the image files for the new OBJ files need to also go inside of a "Textures" folder inside your Visual Studio Project along with your ".mtl" files, and they are all listed below: Annie:
After loading your HTML and your Javascript files, you need to put these other files into their proper folders. OBJ files that have texture materials have ".mtl" files which point to any number of image files that make up the textures. However, JavaScript code can't search a user's drive for the other files, so you must pre-load these files into pre-defined folders in your Visual Studio Project where they will be found. Place all the ".js" files and ".obj" files into an "Objs" folder you create in your project. Then change the ".obj" part of any of those files to ".js". Next, place all of the ".mtl" and ".png" and ".jpg" files into a "Textures" folder you create in your project. Then change the ".mtl" part of any of those files to ".js". Don't change the file types on the image files (i.e. leave the ".png" and ".jpg" extensions alone). Next, go into your HTML file and find the following line: <script type="text/javascript" src="Objs/generic_female_01.js"></script>
Replace that one line with the following six line: <script type="text/javascript" src="Objs/annie.js"></script>
<script type="text/javascript" src="Objs/batman.js"></script>
<script type="text/javascript" src="Objs/clock.js"></script>
<script type="text/javascript" src="Objs/generic_female_01.js"></script>
<script type="text/javascript" src="Objs/generic_male_01.js"></script>
<script type="text/javascript" src="Objs/harleen_quinzel.js"></script>
Next, while still in your HTML file, find the following line: <option value="8">Female With Material</option>
Replace that one line with the following six line: <option value="8">Annie With Textures</option>
<option value="9">Batman With Textures</option>
<option value="10">Clock With Textures</option>
<option value="11">Female With Textures</option>
<option value="12">Male With Textures</option>
<option value="13">Harleen Quinzel With Textures</option>
Next, while still in your HTML file, find the following three lines: <br />
Rotate Light:
<input id="rotatelight" type="checkbox" checked="checked" />
Do not remove these lines, but below them add the following three lines: <br />
Show Mesh:
<input id="showmesh" type="checkbox" />
Next, while still in your HTML file, find the following three lines: <br />
Remove ADS:
<input id="removeads" type="checkbox" checked="checked" />
Do not remove these lines, but below them add the following three lines: <br />
Remove Texture:
<input id="removetexture" type="checkbox" />
Now, go into your "Objs" folder find the following six files that should have ".js" as their file types: annie.js
batman.js
clock.js
generic_female_01.js
generic_male_01.js
harleen_quinzel.js
You need to edit each of these files and add at the top of the file the following text with the backtick (`) character (where the # is a number that goes from 8 to 13): var filedata# = `
If you keep things in order, then in "annie.js" the # will be an '8', and in "batman.js" the # will be a '9', and so on up to where in "harleen_quinzel.js" the # will be a '13'. Note that because "generic_female_01.js" was already modified initially, it has "filedata8" in it already, but that should be changed to "filedata11". And remember that at the end of each of those files you need to add the following as the new last line of the file with another backtick (`) character (except for in "generic_female_01.js" which already has it): `;
The `(backtick) character begins and ends a template literal in JavaScript, making anything between them a text block of whatever we want, which in this case is the source code for the OBJ file. The above additions load the OBJ file's content into a JavaScript variable that is accessible to our program after being loaded. Each variable must have a separate name, which is why the # sign is there and the variable names will actually be filedata8, filedata9, filedata10, and so on. Now go into your JavaScript code, and find the following line in the initializations at the top: var gotTexture = false;
Do not remove that line, but below it add the following two lines: var hideTexture = false;
var showMesh = false;
Then below there find the following line inside the fileinput handler: document.getElementById("selObject").value = "";
Do not remove that line, but below it add the following lines: showMesh = false;
document.getElementById("showmesh").checked = false;
hideTexture = false;
document.getElementById("removetexture").checked = false;
Then below there find the following line from your keydown handler: document.addEventListener("keydown",
Do not remove that line, but ABOVE it this time add the following lines: document.getElementById("showmesh").onchange =
function (event) {
showMesh = event.target.checked;
};
document.getElementById("removetexture").onchange =
function (event) {
hideTexture = event.target.checked;
if (hideTexture) {
resetLighting();
}
};
Next, go above these lines and find the following lines inside your selObject handler: else if (fileselected == "8") {
objfile = filedata8;
}
Do not remove these lines, but BELOW them this time add the following lines: else if (fileselected == "9") {
objfile = filedata9;
}
else if (fileselected == "10") {
objfile = filedata10;
}
else if (fileselected == "11") {
objfile = filedata11;
}
else if (fileselected == "12") {
objfile = filedata12;
}
else if (fileselected == "13") {
objfile = filedata13;
}
Next find the following two lines below that start off the resetLighting() method: function resetLighting() {
if (!hasTextures) {
Replace these two lines with the following lines: function resetLighting() {
if (!hasTextures || hideTexture) {
Then below there find the following line from inside the makemesh() method: y = document.getElementById("adscontrol");
Do not remove that line, but ABOVE it add the following lines: showMesh = false;
document.getElementById("showmesh").checked = false;
hideTexture = false;
document.getElementById("removetexture").checked = false;
Then below there find the following line from inside the render() method: else if (hasTextures) {
REPLACE that line with the following lines: else if (showMesh) {
for (var h1 = 0; h1 < mtlindcode.length; ++h1) {
if (skip.indexOf(h1) > -1)
continue;
var start = Number(mtlindval[h1]);
var len = ((h1 == mtlindcode.length - 1) ?
points.length : Number(mtlindval[h1 + 1])) - start;
if (len > 0) {
for (var i = start; i < start + len; i += 3)
gl.drawArrays(gl.LINE_LOOP, i, 3);
}
}
} else if (hasTextures && !hideTexture) {
After all of these changes to your program you should be all done, unless you have the CORS error. If you do not have the CORS error, you should now have the new functionality which shows textures if the texture information is available, and you can also hide the textures if they are showing, and you can also show mesh lines for objects with or without textures. If you do have the CORS error, you will have to make a number of changes to get your program working. The first thing you need to do is add the backtick (`) comment to the following files in your Textures folder (NOT the ones in your Objs folder): annie.js
batman.js
clock.js
generic_female_01.js
generic_male_01.js
harleen_quinzel.js
These files must be read in by your program as JavaScript library files if you have the CORS error, but they will not have the same "filedata#" variable names as the files in your Objs folder, since these are completely different types of files. Instead this time, the variable name will be the same as the file's name, without the ".js" part. So, inside the annie.js file the first line will be: var annie = `
And inside of the batman.js file the first line will be: var batman = `
And so on up to where in harleen_quinzel.js you will have: var harleen_quinzel = `
And remember that at the end of each of those files you need to add the following as the new last line of the file with another backtick (`) character: `;
Be sure that you are only modifying the above files if you have are dealing with the CORS error. The next thing to do if you have the CORS error is add the following <script> tag lines below your other <script> tags in your HTML file: <script type="text/javascript" src="Textures/annie.js"></script>
<script type="text/javascript" src="Textures/batman.js"></script>
<script type="text/javascript" src="Textures/clock.js"></script>
<script type="text/javascript" src="Textures/generic_female_01.js"></script>
<script type="text/javascript" src="Textures/generic_male_01.js"></script>
<script type="text/javascript" src="Textures/harleen_quinzel.js"></script>
<script type="text/javascript"
src="https://ksuweb.kennesaw.edu/~ashaw8/cs4722/materials/ann000_buki.js">
</script>
<script type="text/javascript"
src="https://ksuweb.kennesaw.edu/~ashaw8/cs4722/materials/ann000_eye00.js">
</script>
<script type="text/javascript"
src="https://ksuweb.kennesaw.edu/~ashaw8/cs4722/materials/ann000_mouth00.js">
</script>
<script type="text/javascript"
src="https://ksuweb.kennesaw.edu/~ashaw8/cs4722/materials/ann000_skin00.js">
</script>
<script type="text/javascript"
src="https://ksuweb.kennesaw.edu/~ashaw8/cs4722/materials/ann000_skin01.js">
</script>
<script type="text/javascript"
src="https://ksuweb.kennesaw.edu/~ashaw8/cs4722/materials/Batman_V3_Eye_High_D.js">
</script>
<script type="text/javascript"
src="https://ksuweb.kennesaw.edu/~ashaw8/cs4722/materials/Batman_Torso_D.js">
</script>
<script type="text/javascript"
src="https://ksuweb.kennesaw.edu/~ashaw8/cs4722/materials/Batman_Legs_D.js">
</script>
<script type="text/javascript"
src="https://ksuweb.kennesaw.edu/~ashaw8/cs4722/materials/batman_head_D.js">
</script>
<script type="text/javascript"
src="https://ksuweb.kennesaw.edu/~ashaw8/cs4722/materials/Batman_Cape_D.js">
</script>
<script type="text/javascript"
src="https://ksuweb.kennesaw.edu/~ashaw8/cs4722/materials/Uhr_ohne_Zeiger.js">
</script>
<script type="text/javascript"
src="https://ksuweb.kennesaw.edu/~ashaw8/cs4722/materials/steel.js">
</script>
<script type="text/javascript"
src="https://ksuweb.kennesaw.edu/~ashaw8/cs4722/materials/generic_female01_d.js">
</script>
<script type="text/javascript"
src="https://ksuweb.kennesaw.edu/~ashaw8/cs4722/materials/generic_male01_d.js">
</script>
<script type="text/javascript"
src="https://ksuweb.kennesaw.edu/~ashaw8/cs4722/materials/Harleen_Quinzel_Eye_D.js">
</script>
<script type="text/javascript"
src="https://ksuweb.kennesaw.edu/~ashaw8/cs4722/materials/Harleen_Quinzel_Hair_D.js">
</script>
<script type="text/javascript"
src="https://ksuweb.kennesaw.edu/~ashaw8/cs4722/materials/Harleen_Quinzel_HairHelmet_D.js">
</script>
<script type="text/javascript"
src="https://ksuweb.kennesaw.edu/~ashaw8/cs4722/materials/Harleen_Quinzel_Head_D.js">
</script>
<script type="text/javascript"
src="https://ksuweb.kennesaw.edu/~ashaw8/cs4722/materials/Harleen_Quinzel_Glass_D.js">
</script>
<script type="text/javascript"
src="https://ksuweb.kennesaw.edu/~ashaw8/cs4722/materials/Harleen_Quinzel_Legs_D.js">
</script>
<script type="text/javascript"
src="https://ksuweb.kennesaw.edu/~ashaw8/cs4722/materials/Harleen_Quinzel_Torso_D.js">
</script>
The above lines load the .mtl files and each of the image files into your program as JavaScript libraries. Next, if you have the CORS error, go inside of your ObjManager2.js file and replace the "loadmtl()" function definition with the following: function loadmtl(filenm) {
var mmm = filenm.indexOf(texdirname);
if (mmm > -1) {
filenm = filenm.substring(mmm + texdirname.length);
}
mmm = filenm.lastIndexOf(".js");
if (mmm > -1) {
filenm = filenm.substring(0, mmm);
}
if (typeof window[filenm] !== 'undefined') {
var filecontent = window[filenm];
filecontent = filecontent.replace(/map_Kd textures/ig,"map_Kd ");
loadmtlkeypairs(filecontent);
}
}
And lastly, if you have the CORS error, inside of your ObjManager2.js file replace the "loadNextTexture()" function definition with the following: function loadNextTexture() {
var texturenm = texturePending[0];
var ttt = texturenm.indexOf(texdirname);
if (ttt > -1) {
texturenm = texturenm.substring(ttt + texdirname.length);
}
ttt = texturenm.lastIndexOf(".");
if (ttt > -1) {
texturenm = texturenm.substring(0, ttt);
}
if (typeof window[texturenm] !== 'undefined') {
imagesPending.push(true);
textureArray.push("");
var img = new Image();
img.onload = function () {
imagesPending.pop();
configureTexture(img, texturePending[0]);
};
img.src = window[texturenm];
}
}
Now the CORS error should be gone, and you should be all set. By the way, it is possible to modify FireFox's settings on a Mac or a PC so that it does not generate the "Cross Origin Request Security (CORS) error". You can read about how to do this in the following file: Cross Origin Fix For Firefox Exercise #2Finish the SkyBoxDemo application so that it shows a scene in a park in which the user can look in all directions. Directly in front of viewer in the scene will be a sphere that is reflecting what is behind the camera eye in the scene. A SkyBox will be used so that as the user pans around the scene, they will be able to see the entire park. And a regular Cube Map will be used so that the reflective sphere will reflect whatever is behind the camera as it pans around: Your scene should zoom in toward to the sphere when the Page-Down arrow is pressed or the Mouse Wheel is scrolled forward, getting no closer than a radius of 3. Your scene should zoom out away from the sphere when the Page-Up arrow is pressed or the Mouse Wheel is scrolled backward, getting no further away than a radius of 30. And dragging the cursor (while holding the mouse down) to the left, right, up or down should pan the scene in the appropriate direction. Initially your code only shows a green sphere and nothing else in the scene. The partial HTML code is given here: SkyBoxDemo.html. The partial Javascript code is given here: SkyBoxDemo.js. To accomplish these tasks you first need to modify your Vertex Shader and your Fragment Shader so that they use a Cube Map instead of the way the scene is rendered now. The same Cube Map will be used to create both the SkyBox and the reflective sphere. Go into your Vertex Shader and add the following declaration: varying vec3 fTexCubeCoord;
Next, in the main() method of the Vertex Shader add the following declaration: fTexCubeCoord = normalize(vPosition.xyz);
Then, in the Fragment Shader add the following declaration: varying vec3 fTexCubeCoord;
uniform samplerCube texMap;
Then, in the main() method of the Fragment Shader REPLACE the line that is there with the following line: gl_FragColor = textureCube(texMap, fTexCubeCoord);
You will use the following six images as your SkyBox images, so create an "Images" folder in your project and add them to it:
Then below the canvas tags in your HTML file, add the following code: <img id="cubefront" src="Images/park_front.jpg" hidden />
<img id="cubeback" src="Images/park_back.jpg" hidden />
<img id="cubetop" src="Images/park_top.jpg" hidden />
<img id="cubebottom" src="Images/park_bottom.jpg" hidden />
<img id="cubeleft" src="Images/park_left.jpg" hidden />
<img id="cuberight" src="Images/park_right.jpg" hidden />
NOTE: If you are experiencing the CORS error so that your images don't load, then add the following <script> tags below your other <script> tags in your HTML file: <script type="text/javascript"
src="https://ksuweb.kennesaw.edu/~ashaw8/cs4722/assignments/park_front.js">
</script>
<script type="text/javascript"
src="https://ksuweb.kennesaw.edu/~ashaw8/cs4722/assignments/park_back.js">
</script>
<script type="text/javascript"
src="https://ksuweb.kennesaw.edu/~ashaw8/cs4722/assignments/park_top.js">
</script>
<script type="text/javascript"
src="https://ksuweb.kennesaw.edu/~ashaw8/cs4722/assignments/park_bottom.js">
</script>
<script type="text/javascript"
src="https://ksuweb.kennesaw.edu/~ashaw8/cs4722/assignments/park_left.js">
</script>
<script type="text/javascript"
src="https://ksuweb.kennesaw.edu/~ashaw8/cs4722/assignments/park_right.js">
</script>
Next, whether or not you are experiencing the CORS error, go into your Javascript file and add the following declaration:
var vertices = [
vec4(-0.5, -0.5, 0.5, 1.0),
vec4(-0.5, 0.5, 0.5, 1.0),
vec4(0.5, 0.5, 0.5, 1.0),
vec4(0.5, -0.5, 0.5, 1.0),
vec4(-0.5, -0.5, -0.5, 1.0),
vec4(-0.5, 0.5, -0.5, 1.0),
vec4(0.5, 0.5, -0.5, 1.0),
vec4(0.5, -0.5, -0.5, 1.0)
];
var fovy = 37;
var near = 0.1;
var far = 100;
var radius = 10;
var skyboxScale = 60;
var theta = 0.0;
var phi = 0.0;
var cubeMap;
var cubeFrontImage;
var cubeBackImage;
var cubeTopImage;
var cubeBottomImage;
var cubeLeftImage;
var cubeRightImage;
var spherePoints = 0;
var cubePoints = 0;
var trackingMouse = false;
var curx = 0;
var cury = 0;
Next, in your init() method in your Javascript file, find the following line: tetrahedron(va, vb, vc, vd, 5);
Below that line, add the following lines: spherePoints = pointsArray.length;
cube();
cubePoints = pointsArray.length - spherePoints;
Next, only if you DO NOT HAVE the CORS error, go to the bottom of your init() method, ABOVE your render() call, add the following lines: cubeFrontImage = document.getElementById("cubefront");
cubeBackImage = document.getElementById("cubeback");
cubeTopImage = document.getElementById("cubetop");
cubeBottomImage = document.getElementById("cubebottom");
cubeLeftImage = document.getElementById("cubeleft");
cubeRightImage = document.getElementById("cuberight");
If you DO HAVE the CORS error, don't add the above lines. Instead of the above lines, add the following lines: cubeFrontImage = new Image();
cubeFrontImage.src = filepark_frontdata;
cubeBackImage = new Image();
cubeBackImage.src = filepark_backdata;
cubeTopImage = new Image();
cubeTopImage.src = filepark_topdata;
cubeBottomImage = new Image();
cubeBottomImage.src = filepark_bottomdata;
cubeRightImage = new Image();
cubeRightImage.src = filepark_rightdata;
cubeLeftImage = new Image();
cubeLeftImage.src = filepark_leftdata;
// Reloads the window after 1 second to give the
// script-tag loaded images time to finish loading
setTimeout(function () {
if (window.location.hash != '#r') {
window.location.hash = 'r';
window.location.reload();
}
}, 1000);
Next, whether or not you have the CORS error, below the code you just added (which means still above the "render();" call), add the following code:
configureCubeMap(cubeFrontImage, cubeBackImage, cubeTopImage,
cubeBottomImage, cubeRightImage, cubeLeftImage);
gl.activeTexture(gl.TEXTURE0);
gl.uniform1i(gl.getUniformLocation(program, "texMap"), 0);
canvas.addEventListener("mousedown", function (event) {
var x = 2 * event.clientX / canvas.width - 1;
var y = 2 * (canvas.height - event.clientY) / canvas.height - 1;
startMotion(x, y);
});
canvas.addEventListener("mouseup", function (event) {
var x = 2 * event.clientX / canvas.width - 1;
var y = 2 * (canvas.height - event.clientY) / canvas.height - 1;
stopMotion(x, y);
});
canvas.addEventListener("mousemove", function (event) {
var x = 2 * event.clientX / canvas.width - 1;
var y = 2 * (canvas.height - event.clientY) / canvas.height - 1;
mouseMotion(x, y);
});
document.addEventListener("keydown",
function (event) {
if (event.keyCode == 65 || event.keyCode == 37) { // A or Left
theta += 0.01;
}
if (event.keyCode == 68 || event.keyCode == 39) { // D or Right
theta -= 0.01;
}
if (event.keyCode == 87 || event.keyCode == 38) { // W or Up
phi += 0.01;
}
if (event.keyCode == 83 || event.keyCode == 40) { // S or Down
phi -= 0.01;
}
if (event.keyCode == 33) { // Page Up
if (radius < 30) {
++radius;
}
}
if (event.keyCode == 34) { // Page Down
if (radius > 3) {
--radius;
}
}
}, false);
document.addEventListener("wheel",
function (event) {
var delta = Math.sign(event.deltaY);
if (radius < 29 && delta > 0) {
radius += 2;
}
if (radius == 29 && delta > 0) {
radius += 1;
}
else if (radius > 4 && delta < 0) {
radius -= 2;
}
else if (radius == 4 && delta < 0) {
radius -= 1;
}
});
Next, in your JavaScript code below the init() method, add the following new methods:
function mouseMotion(x, y) {
if (trackingMouse) {
theta += (x - curx);
curx = x;
phi += (cury - y);
cury = y;
}
}
function startMotion(x, y) {
trackingMouse = true;
curx = x;
cury = y;
}
function stopMotion(x, y) {
trackingMouse = false;
}
function configureCubeMap(frontImg, backImg, topImg, bottomImg, rightImg, leftImg) {
cubeMap = gl.createTexture();
gl.bindTexture(gl.TEXTURE_CUBE_MAP, cubeMap);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGBA,
gl.RGBA, gl.UNSIGNED_BYTE, rightImg);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGBA,
gl.RGBA, gl.UNSIGNED_BYTE, leftImg);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGBA,
gl.RGBA, gl.UNSIGNED_BYTE, topImg);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGBA,
gl.RGBA, gl.UNSIGNED_BYTE, bottomImg);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGBA,
gl.RGBA, gl.UNSIGNED_BYTE, frontImg);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGBA,
gl.RGBA, gl.UNSIGNED_BYTE, backImg);
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
}
function cube() {
quad(1, 0, 3, 2);
quad(2, 3, 7, 6);
quad(3, 0, 4, 7);
quad(5, 1, 2, 6);
quad(4, 5, 6, 7);
quad(5, 4, 0, 1);
}
function quad(a, b, c, d) {
pointsArray.push(vertices[a]);
pointsArray.push(vertices[b]);
pointsArray.push(vertices[c]);
pointsArray.push(vertices[a]);
pointsArray.push(vertices[c]);
pointsArray.push(vertices[d]);
}
Next, in your render() method find the following line: modelViewMatrix = lookAt(eye, at, up);
ABOVE that line, add the following lines: if (phi < 0)
phi += 2 * Math.PI;
if (phi > 2 * Math.PI)
phi -= 2 * Math.PI;
if (phi > Math.PI / 2 && phi < 3 * Math.PI / 2) {
up = vec3(0.0, -1.0, 0.0);
}
else {
up = vec3(0.0, 1.0, 0.0);
}
eye = vec3(radius * Math.cos(theta) * Math.cos(phi),
radius * Math.sin(phi),
radius * Math.sin(theta) * Math.cos(phi));
Next, while still in your render() method, find the following line: gl.drawArrays(gl.TRIANGLES, 0, pointsArray.length);
REPLACE that line with the following lines that draw the sphere first, and then the Skybox around it: gl.drawArrays(gl.TRIANGLES, 0, spherePoints);
modelViewMatrix = mult(modelViewMatrix,
scalem(skyboxScale, skyboxScale, skyboxScale));
gl.uniformMatrix4fv(modelViewMatrixLoc, false, flatten(modelViewMatrix));
gl.drawArrays(gl.TRIANGLES, spherePoints, cubePoints);
Now you should be all done. Add a Comment block section to the top of your Javascript program in this assignment with the following information filled in using the following format: /*
* Course: CS 4722
* Section: .....
* Name: ......
* Professor: ......
* Assignment #: ......
*/
Be sure your program runs without error. DeliverablesTurn in the files:
Do this by uploading the file as an attachment to this Module's assignment drop box in D2L Brightspace. |