Google Code offered in: English - Español - 日本語 - 한국어 - Português - Pусский - 中文(简体) - 中文(繁體)
O3D is an open-source JavaScript API for creating interactive 3D graphics applications that run in a browser window: games, ads, 3D model viewers, product demos, virtual worlds. This Developer's Guide presents a series of examples that illustrate the key concepts and typical programming tasks used in O3D application development.
This chapter introduces you to the general structure of an O3D application. To begin, all you need is the O3D plug-in, a text editor, and a web browser to create and view the HTML document that includes the O3D JavaScript code.
The Hello, Cube sample creates a spinning red cube. (To view the code for Hello, Cube in a new window, click here).
The basic tasks performed in an O3D program are the following:
The following sections discuss how the Hello, Cube sample implements these tasks.
An O3D application is contained in an HTML document. The main code for the O3D JavaScript application is contained in a <script> element inside the <head> element of the HTML document. In this example, when the HTML page is finished loading, the O3D init() function is called. The HTML page also sets up an onunload event, which calls the application's uninit() function to perform necessary cleanup, such as removing callback functions when the HTML page is unloaded..
<script type="text/javascript" src="o3djs/base.js"></script>
<script type="text/javascript">
o3djs.require('o3djs.util');
o3djs.require('o3djs.math');
o3djs.require('o3djs.rendergraph');
window.onload = init;
window.onunload = uninit;
.
.
.
O3D includes a number of utility libraries that simplify the coding of common tasks. If you use functions from one of these libraries, you also need to include that code in <script> tags at the beginning of your program as shown below. (The first <script> element defines the require
<script type="text/javascript" src="o3djs/base.js"></script>
<script type="text/javascript">
o3djs.require('o3djs.util');
o3djs.require('o3djs.math');
o3djs.require('o3djs.rendergraph');
In the code sample, the init() function calls the utility function o3djs.util.makeClients() to make the O3D objects. When this function returns, it invokes the callback function initStep2(). The user's browser must have scripting enabled in order for O3D HTML elements to be created.
function init() {
o3djs.util.makeClients(initStep2)
}
Use the o3djs.util.makeClients() function to create O3D objects in HTML that can be used across platforms. This function finds all <div> elements with an id that starts with the word "o3d" (for example o3d, o3d-element, and so on) and inserts a client area inside. The size of the client area is always set to 100 percent, which means the <div> must have its size set or managed by the browser. For example:
<!-- A div of a specific size --> <div id="o3d" style="width:800px; height:600px" /> <!-- A div that fills its containing element --> <div id="o3d" style="width:100%; height:100%" />
The makeClients() utility takes a callback function as one of its parameters. This callback is triggered once the O3D objects have been created.
This code assigns values to global variables:
var o3dElement = clientElements[0]; g_client = o3dElement.client; g_o3d = o3dElement.o3d; g_math = o3djs.math;
These variables have the following meaning:
o3dElement is the HTML O3D element, which is part of the DOMg_client is the entry point of the O3D applicationg_o3d is the namespace for O3Dg_math is the namespace for the math library
The pack contains all O3D objects and manages their lifetime.
g_pack = g_client.createPack();
This example uses the utility function rendergraph.createBasicView() to create a standard render graph, as described in the Technical Overview. This render graph has two draw lists, one for draw elements with opaque materials (the performance draw list) and one for draw elements with transparent materials (the transparency draw list). A separate draw pass is performed for each draw list.
var viewInfo = o3djs.rendergraph.createBasicView(
g_pack,
g_client.root,
g_client.renderGraphRoot);
The draw context specifies the view projection and the position of a virtual camera that is viewing the scene (the view transformation). The drawContext object is created by the utility function renderGraph.createBasicView(). Here is an example of setting its values:
// Set up a simple perspective view.
viewInfo.drawContext.projection = g_math.matrix4.perspective(
g_math.degToRad(30), // 30 degree fov.
g_client.width / g_client.height,
1, // Near plane.
5000); // Far plane.
// Set up our view transformation to look towards the world origin where the
// cube is located.
viewInfo.drawContext.view = g_math.matrix4.lookAt([0, 1, 5], // eye
[0, 0, 0], // target
[0, 1, 0]); // up
The vertex and pixel shaders are defined in the <textarea> element of the HTML document. The shaders control the calculations for the color of each pixel in each draw element. This code creates the effect (redEffect) and reads in the contents of the shaders:
var redEffect = g_pack.createObject('Effect');
// looks in the HTML document for an element named "effect"
var shaderString = document.getElementById('effect').value;
// loads the entire contents of the <textarea id="effect"> element into the redEffect object
redEffect.loadFromFXString(shaderString);
The red material for the cube is created in the initStep2() function and assigned to the performance draw list, which handles opaque materials. The following code also sets the material's effect to redEffect so that the graphics hardware can apply the proper shading to the cube. In this example, no shading calculations are performed. The simple color red is returned for all pixels. The createCube() function constructs the cube geometry, as described in Shapes, and uses the red material. An alternative to setting up the geometry within O3D, as shown in the Hello, Cube examples, is to import geometry constructed using an application such as SketchUp, 3ds Max, or Maya.
var redMaterial = g_pack.createObject('Material');
redMaterial.drawList = viewInfo.performanceDrawList;
redMaterial.effect = redEffect;
var cubeShape = createCube(redMaterial);
The Hello, Cube example has a very simple transform graph. The following code creates one transform for the cube shape, adds the shape to the transform, and then adds the transform to the O3D root.
g_cubeTransform = g_pack.createObject('Transform');
g_cubeTransform.addShape(cubeShape);
g_cubeTransform.parent = g_client.root;
Every primitive has a draw element constructed for it that describes what material and effect to use when the primitive is rendered. The createDrawElements() function creates draw elements for all primitives in the specified shape and adds the draw elements to the draw list associated with the primitive's material. At render time, one draw pass is performed for each draw list, and all draw elements in the lists are rendered.
cubeShape.createDrawElements(g_pack, null);
The scene is automatically rendered each time the hardware refreshes the screen. In this example, setRenderCallback() sets a callback that updates the cube's transform values each time the scene is rendered. This update makes the cube spin.
g_client.setRenderCallback(renderCallback);
Shapes describes how to specify the vertex information that describes a primitive—indices, normals, texture coordinates. Vertices are specified in arrays that are then loaded into buffers. A stream contains information on how to access the contents of the buffer.