5.4 - A Simple Model

Rendering a model is not a simple process. It will be easier to understand how things work if we start with the simplest example possible and gradually add complexity. When you render complex models you will want to design those models in Blender (or some other modeling tool). For our purposes here, let’s manually define a very simple 3D model to work with.

A Simple 3D Model

Examine the code in the ‘simple_model_01.js’ file below. Note the following big ideas:

  • The Triangle function (line 37) is a class definition that contains no functionality. It will hold the data that defines one triangle. To start off simple, a Triangle object will hold an array of three vertices.
  • The SimpleModel function (line 48) is a class definition that contains no functionality. It will hold a “name” for a model and an array of triangle objects. A model, in its simplest form, is just a collection of triangles.
  • The CreatePyramid function (line 59) creates an instance of the SimpleModel class called model, gives it a name called ‘simple’, and sets its array of triangles to the 4 triangles of a pyramid.

Note: You can edit the JavaScript code and “re-start” the rendering if you want to experiment. If you introduce errors in the code you might have to reload the page to get a fresh, error-free version of the code.

Show: Code Canvas Run Info
 
1
/**
2
 * simple_model_01.js, By Wayne Brown, Spring 2016
3
 */
4
5
/**
6
 * The MIT License (MIT)
7
 *
8
 * Copyright (c) 2015 C. Wayne Brown
9
 *
10
 * Permission is hereby granted, free of charge, to any person obtaining a copy
11
 * of this software and associated documentation files (the "Software"), to deal
12
 * in the Software without restriction, including without limitation the rights
13
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
 * copies of the Software, and to permit persons to whom the Software is
15
 * furnished to do so, subject to the following conditions:
16
 *
17
 * The above copyright notice and this permission notice shall be included in all
18
 * copies or substantial portions of the Software.
19
20
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
 * SOFTWARE.
27
 */
28
29
"use strict";
30
31
//-------------------------------------------------------------------------
32
/**
33
 * A simple triangle composed of 3 vertices.
34
 * @param vertices Array An array of 3 vertices.
35
 * @constructor
36
  */
37
window.Triangle = function (vertices) {
38
  var self = this;
39
  self.vertices = vertices;
40
};
41
42
//-------------------------------------------------------------------------
43
/**
44
 * A simple model composed of an array of triangles.
45
 * @param name String The name of the model.
46
 * @constructor
47
 */
48
window.SimpleModel = function (name) {
49
  var self = this;
50
  self.name = name;
51
  self.triangles = [];
52
};
53
54
//-------------------------------------------------------------------------
55
/**
56
 * Create a Simple_model of 4 triangles that forms a pyramid.
57
 * @return SimpleModel
58
 */
59
window.CreatePyramid = function () {
60
  var vertices, triangle1, triangle2, triangle3, triangle4;
61
62
  // Vertex data
63
  vertices = [  [ 0.0, -0.25, -0.50],
64
                [ 0.0,  0.25,  0.00],
65
                [ 0.5, -0.25,  0.25],
66
                [-0.5, -0.25,  0.25] ];
67
68
  // Create 4 triangles
69
  triangle1 = new Triangle([vertices[2], vertices[1], vertices[3]]);
70
  triangle2 = new Triangle([vertices[3], vertices[1], vertices[0]]);
71
  triangle3 = new Triangle([vertices[0], vertices[1], vertices[2]]);
72
  triangle4 = new Triangle([vertices[0], vertices[2], vertices[3]]);
73
74
  // Create a model that is composed of 4 triangles
75
  var model = new SimpleModel("simple");
76
  model.triangles = [ triangle1, triangle2, triangle3, triangle4 ];
77
78
  return model;
79
};
80
81
./simple_pyramid/simple_pyramid.html

A simple, manually defined 3D model. You can spin the model with your mouse.

Please use a browser that supports "canvas"
Animate
Open this webgl program in a new tab or window

In the following sequence of lessons we will use this simple model to do the following:

  • Render the pyramid using a single color for the entire model.
  • Render the pyramid using a different color for each face.
  • Render the pyramid using a different color for each vertex.
  • Render the pyramid using texture coordinates for each vertex.

What you will discover as you go through these various examples is that your shader programs, buffer objects, and JavaScript rendering code is very interdependent. As you change one of them, they all must change!

A Side Note about JavaScript Functions

In order for the demo code to be editable in the web page, the functions have to defined using a non-standard syntax that makes them changeable “after the fact”. Functions are added to the JavaScript environment when a web page is loaded. But the demo code needs to redefine them. This is tricky JavaScript stuff that I would like to not explain, but you will be confused if it is not explained, so here goes...

Global JavaScript scope is defined by a special object named window. If you would like to examine this object, type window into the JavaScript console pane in the Developer Tools and hit enter. You can then expand the object to see its properties by clicking on the right arrow in front of the object. (The global environment has a lot of stuff in it!!!!)

When you define a function you are creating an object. Objects can be assigned to a variable, passed as a parameter, or modified like any variable. When you create a function at global scope a new property of the window object is added using the name of the function as the property name. This new property is a reference to the new function object. However, JavaScript adds extra properties to the function object that makes the object non-modifiable. Let’s look at an example:

// Create a global function
function example1(a,b,c) {
 ...
}

// Create a function and store it in a global variable
var example2 = function (a,b,c) {
  ...
}

You now have two new function objects and two new properties of the window object: window.example1 and window.example2. Both properties hold a reference to a function object. However, the objects have been modified with secret properties that make the functions unchangeable.

If we define a property of the window object directly, no secret properties are added to the function definition or the window property. Therefore, if we define a global function like this:

// Create a global property that references a function
window.example3 = function (a,b,c) {
 ...
}

no secret changes to the new property are performed and we can redefine the window.example3 property to anything we want, including a different version of the function code!

Next Section - 5.5 - Example 1: One Color per Model