In which you learn about the fractured landscape of graphics development, set up your local computing environment for writing graphics code, and render a compelling orange rectangle.
Entering the graphics scene today is awkward. 30 years ago, there was no scene. You would write a renderer from scratch, which was a lot of work. Or you could license John Carmack's engine from id Software. 20 years ago, the industry was converging on two graphics libraries: Microsoft's Direct3D and the open standard OpenGL. 10 years ago the market started to fracture. Apple stopped updating OpenGL. They wanted everyone to use their propietary low-level graphics toolkit named Metal. The open standard Vulkan appeared as a competitor to Metal. At the same time, game engines like Unity and Unreal Engine became free for non-commercial users. These game engines handle more than just graphics, including physics, sound, and user interfaces. Today, there is no clear starting point for someone wanting to learn computer graphics.
Complicating things further is C++, which has been the language of choice for many years in game development and graphics research. Unlike many its younger competitors, C++ code compiles down to the native machine code of the processor. It doesn't need to be translated to machine code at runtime like Java or C#. Additionally, it doesn't run an intermittent garbage collection routine to reclaim unused memory. Graphics developers need speed and predictability to render complex 3D scenes at interactive framerates, and C++ serves them well. However, C++ is also a complex language and is en route to becoming more so. If this course used C++, you'd have to spend a non-trivial amount of time learning it. Even worse, the graphical applications you develop would only run on the platform for which you compile them.
In this class, you will use WebGL, an open library for writing graphical applications that run in a web browser. Unlike Direct3D, which runs on Windows, and unlike OpenGL, which has been crippled on macOS, WebGL runs on all major operating systems, including mobile. Because WebGL runs in a web browser, JavaScript is a fitting language in which to write your graphics applications. Even if JavaScript is not your favorite language, it is objectively less complex than C++.
Your graphics applications will run in your web browser, which is almost certainly already capable of rendering WebGL applications. Test your browser to make sure. If that doesn't work, update your browser to the latest version of Chrome, Firefox, Safari, or Edge.
To ease writing WebGL applications, install Visual Studio Code, a light-weight development environment. It has several features that you will use in this course, including support for version control and collaborative editing.
Later on in the course, you will need to read in 3D models and other files in your project. Browsers don't generally allow JavaScript code to read in files from the local file system. To get around this limitation, you will run a local web server out of your project folder. Whenever you need to read in a file, you'll make an HTTP request and the web server will return it. There are many ways to run a local web server. In this course you will use the Node.js platform and the Vite build tool. The advantage of using these tools is that you can grab helper libraries easily and build optimized and portable versions of your applications. Install Node.js.
Once both Visual Studio Code and Node.js are installed, test your installation. Open Visual Studio Code. If it was open as you installed Node.js, close it and open it again. Open Code's integrated terminal by clicking View / Terminal. At the prompt, enter node
. An interactive JavaScript interpreter should appear. Enter an expression like 5 % 3
. If the interpreter does not appear. Something went wrong. Either sleuth it out or seek assistance.
Your code in this course will be under version control. You will store it in a Git repository that both you and your instructor can access. To see if you have it installed, try running this command in your terminal:
git --version
If Git isn't found, install it. Restart Visual Studio Code after the installation finishes.
Your instructor has created a single Git repository for you to use for the entire course. Each of your programming assignments will be organized in a subfolder in this single repository. The repository is initially only stored on GitHub. You want to clone it to your local computer and add a test project to it. First, copy its URL. Then open Visual Studio Code and select View / Command Palette. Enter the command Git: Clone and paste in the URL. Then select a folder that will hold your cloned repository. After the clone completes, you will see in the folder a single file named README.md
.
Now it's time to build your first application. Make sure your course folder is open in Visual Studio Code. If you've opened the right folder, only README.md
will be visible in the file explorer. Each project that you create this semester will have its own subfolder.
In this top-level folder that sits above all projects, create a file named .gitignore
and add these lines:
.DS_Store
Thumbs.db
node_modules
These are the names of files that should never be added to version control. The first two are files created by your operating system to cache thumbnail versions of any image files. These thumbnails are shown in your operation system's file explorer. The folder node_modules
will hold all of your project's dependencies on other projects. Since it is generally very large and can be regenerated at any time, it should be ignored by Git.
Create a new subfolder named hello-orange
. Open the terminal and enter this command so that your commands will be run in the context of your project folder instead of the course folder:
cd hello-orange
In your subfolder, create a file named index.html
and add this HTML code:
<!DOCTYPE html>
<html>
<head>
<title>...</title>
<link rel="icon" href="data:,">
<link rel="stylesheet" href="/style.css">
<script type="module" src="./main.js"></script>
</head>
<body>
<canvas id="canvas"></canvas>
</body>
</html>
The canvas
element is the rectangle that will get filled with pixels. The script
element will load in your JavaScript code.
Create a file named style.css
and add this CSS code:
body {
margin: 0;
}
#canvas {
position: fixed;
left: 0;
right: 0;
width: 100%;
height: 100vh;
}
This stylesheet removes the whitespace margin around the page's body
element and makes the canvas
element fill the browser window.
Create a file named main.js
and add this JavaScript:
let canvas;
function render() {
gl.viewport(0, 0, canvas.width, canvas.height);
gl.clearColor(1, 0.5, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
}
function onResizeWindow() {
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
render();
}
async function initialize() {
canvas = document.getElementById('canvas');
window.gl = canvas.getContext('webgl2');
// Event listeners
window.addEventListener('resize', onResizeWindow);
onResizeWindow();
}
window.addEventListener('load', initialize);
This script grabs a reference to the page's canvas
element and gives it a WebGL context, an environment for executing WebGL commands. The function initialize
contains one-time setup code. The function render
will run once per frame. Currently render
clears the canvas to the color orange. The onResizeWindow
function is called whenever the window changes size. It resizes the canvas so that it matches the window and re-renders the scene.
Create a new file named package.json
and add this configuration:
{
"name": "hello-orange",
"version": "0.0.0",
"type": "module",
"scripts": {
"start": "vite --open",
"build": "vite build",
"preview": "vite preview"
}
}
All Node.js projects have a file named package.json
that describes the project, its dependencies, and custom commands that may be run. This configuration provides three commands. The start
command is the most important one for this course. It will start up your local web server and open your index.html
file in your default browser.
Your project's source code is now complete. To run it, you must first install Vite by executing this command in your terminal:
npm install vite
Inspect package.json
. You will see that Vite has been added as a dependency. The node_modules
folder has also been created. So has package-lock.json
, which tracks the version numbers of the dependencies you are currently using.
Run your local web server with this command:
npm run start
By default, your application is available at http://localhost:3000
. Visit this URL in your browser. Do you see a big orange rectangle? If not, check that your files match those listed above. Seek assistance as needed.
Your files are only in your local clone of your repository. You need to commit your changes and then push them up to GitHub. You should do this after every work session, not just when everything is working. That way your work is backed up regularly and your instructor can see your code if you have a question.
Open the source control management panel in Visual Studio Code by selecting View / SCM. The panel lists all the files that are new to the repository or that have changes since your last commit. Hover your mouse over each file and click the + button to add the changed file to your commit. To add all changes, hover over the the Changes heading and click the + button. Add a short statement that describes the changes in the message box. For example, you might write Add orange renderer.
or Fix missing triangles.
or Refactor particle system.
Click the check button. The changes are committed only to your local repository. To get them on your remote repository, click Sync Changes. Or click the ellipsis button and select Pull, Push / Push.
Visit your repository at GitHub and make sure your changed files were pushed.