2.5 - Canvas and GL Context¶
Graphics generated in real-time on a web page (as opposed to the display of a picture) are always drawn into a rectangular HTML canvas element. A canvas element has a context. The context defines how the graphics are created. There is an API for creating 2D graphics which we won’t take time to discuss here. (See w3schools tutorial for more information.) For WebGL programming, you need to get a WebGL context. The context is a JavaScript object that stores all of the state and behavior of the graphics displayed in a canvas.
Getting the Canvas Element¶
Using JavaScript, you need to get the canvas element you want to draw into.
If there is only one canvas element on the web page, you could get the element
by its type. But a more general scheme, which supports multiple canvas
elements on a single web page, is to use a unique id
for the canvas.
The standard HTML code for defining a canvas element is shown below. If
a browser does not support canvas elements, it will display the message inside
the <canvas> tag. Otherwise it will display a rectangular region on the page.
Notice that the canvas element is assigned a unique ID.
<canvas id="W1_canvas">
Please use a browser that supports "canvas"
</canvas>
In JavaScript, after a web page has been loaded, you can get a canvas
element using the document.getElementById(id)
function. You should
handle errors appropriately, so a function like this would be typical.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | /**
* Get a canvas element given its unique id
*
* @param canvas_id {string} The HTML id of the canvas to render to.
* @return the matching canvas element
*/
function getCanvas(canvas_id) {
let canvas;
canvas = document.getElementById(canvas_id);
if (!canvas || canvas.nodeName !== "CANVAS") {
console.log('Fatal error: Canvas "' + canvas_id + '" not found');
}
return canvas;
}
|
Getting the WebGL Context¶
Now that we have an object that represents the canvas element, we use a
method of the object called getContext('webgl')
to get a WebGL object
that represents the 3D graphics state and behavior of the canvas. Again we
should handle errors appropriately. (We will discuss WebGL environment
options in later lessons.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | /**----------------------------------------------------------------------
* Get a WebGL context from a canvas
* @param canvas {canvas} The DOM element that represents the canvas.
* @param options {object} options to set in the WebGL environment.
* @return The WebGL context for the canvas.
*/
self.getWebglContext = function (canvas, options = {}) {
let context;
context = canvas.getContext('webgl', options );
if (!context) {
out.displayError("No WebGL context could be found.");
}
return context;
};
|
The WebGL Context¶
The WebGL context is a JavaScript object that stores the current state of the graphics library. WebGL is a state machine, which means that if you set a WebGL variable to a specific value, that value will not change until you change it. For example, you can set the color used to clear the canvas background once. You don’t need to set the color value every time you want to clear the window.
The WebGL context object also defines methods for the entire WebGL API.
All WebGL functionality is accessed through the context object. The
convention is to name the context object gl
. Below is a typical
start to a WebGL program.
// Get the rendering context for the canvas
gl = getWebglContext( getCanvas(canvas_id) );
if (!gl) {
return;
}
// Initialize the state of the WebGL context
gl.useProgram(program);
gl.enable(gl.DEPTH_TEST);
gl.clearColor(0.9, 0.9, 0.9, 1.0);
Notice that all WebGL functionality is accessed through the gl
object.
Each canvas has its own WebGL context. If you have 4 canvas elements on a web page, you will have to store 4 separate WebGL contexts. And regrettably for WebGL 1.0, context’s can’t share data or shader programs. Supposedly future versions of WebGL will allow sharing of resources between contexts.
Canvas Size vs. WebGL Context Size¶
An HTML canvas element has a size that determines how much area it takes up
on a web page. Two properties of a canvas element store its dimensions:
clientWidth
and clientHeight
. These values are always in pixels.
A WebGL context has a size which determines the dimensions of the draw buffer
it renders. Two properties of a canvas element store its draw buffer size:
width
and height
. These values are always in pixels.
For example, the following HTML code will create a canvas whose physical size on the screen is 400-by-400 pixels, but whose WebGL context is only 100-by-100. Every pixel rendered to the WebGL draw buffer will be displayed in 16 pixels on the screen (in a 4-by-4 block) which will make the image appear blurry.
<canvas id="W1" width="100" height="100" style="width: 400px; height: 400px;">
Please use a browser that supports "canvas"
</canvas>
If you want the highest resolution renderings possible, the dimensions of a canvas element should be the same size as its physical size on the screen. That is,
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
Glossary¶
- canvas
- an HTML element which defines a rectangular area in a web page on which graphics can be displayed.
- context
- the environment in which something happens.
- WebGL context
- a JavaScript object that stores the state of WebGL for a specific canvas and provides an interface to all WebGL API functions.
Self-Assessments¶
- It creates a rectangular area which can contain graphics.
- Correct.
- It defines an error message.
- Incorrect, though the text inside the element is displayed as an error message if the browser does not support the canvas element.
- It defines a surface to paint on, such as an "oil canvas."
- Incorrect, HTML does not do oil paintings.
- It defines a pop-up window that can contain graphics.
- Incorrect, pop-up windows are created with the alert() function.
Q-48: What does this HTML code do?
<canvas id="W1_canvas">
Please use a browser that supports "canvas"
</canvas>
Q-50: Q-49: Please correctly order the following steps when creating a 3D rendering in a canvas element.Get the canvas DOM element.
---
Get a WebGL context for the canvas element.
---
Call WebGL functions to produce a 3D rendering.
---
Re-render the 3D rendering when events happen.
---
-
Q-51: What does it mean that “WebGL is a state machine?”
- WebGL remains in the same state it is in until it is told to change.
- Correct. If you set the color to red, it stays red until it is changed to something else.
- WebGL is used to render maps of geographic states.
- Incorrect, though WebGL could be used to draw maps.
- WebGL is always in a state of change.
- Incorrect, WebGL only changes its "context" when WebGL commands are called.
- WebGL commands must be issued over and over again for each new rendering.
- Incorrect. In fact, to make rendering as fast as possible, you should not make unnecessary WebGL function calls.
-
Q-52: The physical size of a canvas element on the screen and the size of its associated WebGL context can be different.
- True.
- Correct. And if the canvas is bigger than the WebGL context, the displayed image will be "blurry."
- False.
- Incorrect.