summaryrefslogtreecommitdiffstats
path: root/o3d/samples
diff options
context:
space:
mode:
authorpetersont@google.com <petersont@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-26 18:17:10 +0000
committerpetersont@google.com <petersont@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-26 18:17:10 +0000
commit7a130f3789ad66ea6a3ed381c0a581ac3dab9bf3 (patch)
treecf1a017558144f55bbc8ff23d0f7e29739987e67 /o3d/samples
parent7526811eaf3754199f502c4b751a2f41ffe67272 (diff)
downloadchromium_src-7a130f3789ad66ea6a3ed381c0a581ac3dab9bf3.zip
chromium_src-7a130f3789ad66ea6a3ed381c0a581ac3dab9bf3.tar.gz
chromium_src-7a130f3789ad66ea6a3ed381c0a581ac3dab9bf3.tar.bz2
First check in of the o3d implimentation in webgl. Classes work well enough to run the hellocube sample.
Review URL: http://codereview.chromium.org/561026 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@40133 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d/samples')
-rw-r--r--o3d/samples/o3d-webgl-samples/hellocube.html300
-rw-r--r--o3d/samples/o3d-webgl/base.js211
-rw-r--r--o3d/samples/o3d-webgl/bitmap.js140
-rw-r--r--o3d/samples/o3d-webgl/bounding_box.js124
-rw-r--r--o3d/samples/o3d-webgl/buffer.js280
-rw-r--r--o3d/samples/o3d-webgl/clear_buffer.js125
-rw-r--r--o3d/samples/o3d-webgl/client.js841
-rw-r--r--o3d/samples/o3d-webgl/draw_context.js70
-rw-r--r--o3d/samples/o3d-webgl/draw_element.js69
-rw-r--r--o3d/samples/o3d-webgl/draw_list.js106
-rw-r--r--o3d/samples/o3d-webgl/draw_pass.js77
-rw-r--r--o3d/samples/o3d-webgl/effect.js424
-rw-r--r--o3d/samples/o3d-webgl/element.js214
-rw-r--r--o3d/samples/o3d-webgl/event.js260
-rw-r--r--o3d/samples/o3d-webgl/field.js134
-rw-r--r--o3d/samples/o3d-webgl/file_request.js170
-rw-r--r--o3d/samples/o3d-webgl/material.js77
-rw-r--r--o3d/samples/o3d-webgl/named_object.js72
-rw-r--r--o3d/samples/o3d-webgl/named_object_base.js47
-rw-r--r--o3d/samples/o3d-webgl/object_base.js69
-rw-r--r--o3d/samples/o3d-webgl/pack.js348
-rw-r--r--o3d/samples/o3d-webgl/param.js829
-rw-r--r--o3d/samples/o3d-webgl/param_object.js169
-rw-r--r--o3d/samples/o3d-webgl/primitive.js157
-rw-r--r--o3d/samples/o3d-webgl/raw_data.js94
-rw-r--r--o3d/samples/o3d-webgl/ray_intersection_info.js77
-rw-r--r--o3d/samples/o3d-webgl/render_node.js205
-rw-r--r--o3d/samples/o3d-webgl/render_surface.js89
-rw-r--r--o3d/samples/o3d-webgl/render_surface_set.js74
-rw-r--r--o3d/samples/o3d-webgl/shape.js128
-rw-r--r--o3d/samples/o3d-webgl/state.js567
-rw-r--r--o3d/samples/o3d-webgl/state_set.js62
-rw-r--r--o3d/samples/o3d-webgl/stream.js101
-rw-r--r--o3d/samples/o3d-webgl/stream_bank.js101
-rw-r--r--o3d/samples/o3d-webgl/texture.js463
-rw-r--r--o3d/samples/o3d-webgl/transform.js942
-rw-r--r--o3d/samples/o3d-webgl/tree_traversal.js111
-rw-r--r--o3d/samples/o3d-webgl/types.js119
-rw-r--r--o3d/samples/o3d-webgl/viewport.js96
-rw-r--r--o3d/samples/o3djs/webgl.js114
40 files changed, 8656 insertions, 0 deletions
diff --git a/o3d/samples/o3d-webgl-samples/hellocube.html b/o3d/samples/o3d-webgl-samples/hellocube.html
new file mode 100644
index 0000000..f0db297f
--- /dev/null
+++ b/o3d/samples/o3d-webgl-samples/hellocube.html
@@ -0,0 +1,300 @@
+<!--
+Copyright 2009, Google Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+
+<!--
+This sample shows how to place an O3D area in a page and draw simple
+3D shape in it.
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>
+Hello Cube: Getting started with O3D
+</title>
+<script type="text/javascript" src="../o3d-webgl/base.js"></script>
+<script type="text/javascript" src="../o3djs/base.js"></script>
+<script type="text/javascript" id="o3dscript">
+o3djs.base.o3d = o3d;
+o3djs.require('o3djs.webgl');
+o3djs.require('o3djs.math');
+o3djs.require('o3djs.rendergraph');
+
+// Events
+// Run the init() function once the page has finished loading.
+// Run the uninit() function when the page has is unloaded.
+window.onload = init;
+window.onunload = uninit;
+
+// global variables
+var g_o3d;
+var g_math;
+var g_client;
+var g_pack;
+var g_clock = 0;
+var g_timeMult = 1;
+var g_cubeTransform = null;
+var g_finished = false; // for selenium testing
+
+/**
+ * Creates an O3D shape representing a cube. The shape consists of
+ * a single primitive with eight vertices and 12 triangles (two for each face
+ * of the cube).
+ * @param {o3d.Material} material the material used by the primitive.
+ * @return {o3d.Shape} The Shape object created.
+ */
+function createCube(material) {
+ // Create a Shape object for the mesh.
+ var cubeShape = g_pack.createObject('Shape');
+
+ // Create the Primitive that will contain the geometry data for
+ // the cube.
+ var cubePrimitive = g_pack.createObject('Primitive');
+
+ // Create a StreamBank to hold the streams of vertex data.
+ var streamBank = g_pack.createObject('StreamBank');
+
+ // Assign the material that was passed in to the primitive.
+ cubePrimitive.material = material;
+
+ // Assign the Primitive to the Shape.
+ cubePrimitive.owner = cubeShape;
+
+ // Assign the StreamBank to the Primitive.
+ cubePrimitive.streamBank = streamBank;
+
+ // The cube is made of 12 triangles. There's eight vertices in total which
+ // are shared between the face triangles.
+ cubePrimitive.primitiveType = g_o3d.Primitive.TRIANGLELIST;
+ cubePrimitive.numberPrimitives = 12; // 12 triangles
+ cubePrimitive.numberVertices = 8; // 8 vertices in total
+
+ // Generate the draw element for the cube primitive.
+ cubePrimitive.createDrawElement(g_pack, null);
+
+ // Create a javascript array that stores the X, Y and Z coordinates of each
+ // of the 8 corners of the cube.
+ var positionArray = [
+ -0.5, -0.5, 0.5, // vertex 0
+ 0.5, -0.5, 0.5, // vertex 1
+ -0.5, 0.5, 0.5, // vertex 2
+ 0.5, 0.5, 0.5, // vertex 3
+ -0.5, 0.5, -0.5, // vertex 4
+ 0.5, 0.5, -0.5, // vertex 5
+ -0.5, -0.5, -0.5, // vertex 6
+ 0.5, -0.5, -0.5 // vertex 7
+ ];
+
+ // The following array defines how vertices are to be put together to form
+ // the triangles that make up the cube's faces. In the index array, every
+ // three elements define a triangle. So for example vertices 0, 1 and 2
+ // make up the first triangle, vertices 2, 1 and 3 the second one, etc.
+ var indicesArray = [
+ 0, 1, 2, // face 1
+ 2, 1, 3,
+ 2, 3, 4, // face 2
+ 4, 3, 5,
+ 4, 5, 6, // face 3
+ 6, 5, 7,
+ 6, 7, 0, // face 4
+ 0, 7, 1,
+ 1, 7, 3, // face 5
+ 3, 7, 5,
+ 6, 0, 4, // face 6
+ 4, 0, 2
+ ];
+
+ // Create buffers containing the vertex data.
+ var positionsBuffer = g_pack.createObject('VertexBuffer');
+ var positionsField = positionsBuffer.createField('FloatField', 3);
+ positionsBuffer.set(positionArray);
+
+ var indexBuffer = g_pack.createObject('IndexBuffer');
+ indexBuffer.set(indicesArray);
+
+ // Associate the positions Buffer with the StreamBank.
+ streamBank.setVertexStream(
+ g_o3d.Stream.POSITION, // semantic: This stream stores vertex positions
+ 0, // semantic index: First (and only) position stream
+ positionsField, // field: the field this stream uses.
+ 0); // start_index: How many elements to skip in the
+ // field.
+
+ // Associate the triangle indices Buffer with the primitive.
+ cubePrimitive.indexBuffer = indexBuffer;
+
+ return cubeShape;
+}
+
+/**
+ * This method gets called every time O3D renders a frame. Here's where
+ * we update the cube's transform to make it spin.
+ * @param {o3d.RenderEvent} renderEvent The render event object that gives
+ * us the elapsed time since the last time a frame was rendered.
+ */
+function renderCallback(renderEvent) {
+ g_clock += renderEvent.elapsedTime * g_timeMult;
+ // Rotate the cube around the Y axis.
+ g_cubeTransform.identity();
+ g_cubeTransform.rotateY(2.0 * g_clock);
+}
+
+
+/**
+ * Creates the client area.
+ */
+function init() {
+ o3djs.webgl.makeClients(initStep2);
+}
+
+/**
+ * Initializes O3D, creates the cube and sets up the transform and
+ * render graphs.
+ * @param {Array} clientElements Array of o3d object elements.
+ */
+function initStep2(clientElements) {
+ // Initializes global variables and libraries.
+ var o3dElement = clientElements[0];
+ g_client = o3dElement.client;
+ g_o3d = o3dElement.o3d;
+ g_math = o3djs.math;
+
+ // Create a pack to manage the objects created.
+ g_pack = g_client.createPack();
+
+ // Create the render graph for a view.
+ var viewInfo = o3djs.rendergraph.createBasicView(
+ g_pack,
+ g_client.root,
+ g_client.renderGraphRoot);
+
+ // Set up a perspective projection.
+ 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
+
+ // Create an Effect object and initialize it using the shaders from the
+ // text area.
+ var redEffect = g_pack.createObject('Effect');
+ var vertexShaderString = document.getElementById('vshader').value;
+ var pixelShaderString = document.getElementById('pshader').value;
+ redEffect.loadVertexShaderFromString(vertexShaderString);
+ redEffect.loadPixelShaderFromString(pixelShaderString);
+
+ // Create a Material for the mesh.
+ var redMaterial = g_pack.createObject('Material');
+
+ // Set the material's drawList.
+ redMaterial.drawList = viewInfo.performanceDrawList;
+
+ // Apply our effect to this material. The effect tells the 3D hardware
+ // which shaders to use.
+ redMaterial.effect = redEffect;
+
+ // Create the Shape for the cube mesh and assign its material.
+ var cubeShape = createCube(redMaterial);
+
+ // Create a new transform and parent the Shape under it.
+ g_cubeTransform = g_pack.createObject('Transform');
+ g_cubeTransform.addShape(cubeShape);
+
+ // Parent the cube's transform to the client root.
+ g_cubeTransform.parent = g_client.root;
+
+ // Set our render callback for animation.
+ // This sets a function to be executed every time a frame is rendered.
+ g_client.setRenderCallback(renderCallback);
+
+ g_finished = true; // for selenium testing.
+}
+
+/**
+ * Removes any callbacks so they don't get called after the page has unloaded.
+ */
+function uninit() {
+ if (g_client) {
+ g_client.cleanup();
+ }
+}
+
+</script>
+</head>
+<body>
+<h1>Hello Cube</h1>
+This example shows how to display a spinning red cube in O3D.
+<br/>
+
+<!-- Start of O3D plugin -->
+<div id="o3d" width="600px" height="600px"></div>
+<!-- End of O3D plugin -->
+
+<!-- Don't render the textarea -->
+<div style="display:none">
+<!-- Start of effect -->
+<textarea id="vshader">
+ // World View Projection matrix that will transform the input vertices
+ // to screen space.
+ attribute vec4 position;
+
+ uniform mat4 world;
+ uniform mat4 view;
+ uniform mat4 projection;
+
+ /**
+ * The vertex shader simply transforms the input vertices to screen space.
+ */
+ void main() {
+ // Multiply the vertex positions by the worldViewProjection matrix to
+ // transform them to screen space.
+ gl_Position = projection * view * world * position;
+ }
+</textarea>
+<textarea id="pshader">
+ /**
+ * This pixel shader just returns the color red.
+ */
+ void main() {
+ gl_FragColor = vec4(1, 0, 0, 1); // Red.
+ }
+</textarea>
+<!-- End of effect -->
+</div>
+</body>
+</html>
diff --git a/o3d/samples/o3d-webgl/base.js b/o3d/samples/o3d-webgl/base.js
new file mode 100644
index 0000000..9863ee6
--- /dev/null
+++ b/o3d/samples/o3d-webgl/base.js
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * @fileoverview Base for all o3d classes implemented in javscript.
+ * Include just this file in a script tag and it will include all other
+ * source files needed by o3d.
+ * For more information about o3d see
+ * http://code.google.com/p/o3d.
+ */
+
+/**
+ * A namespace for all the o3d classes.
+ * @namespace
+ */
+var o3d = o3d || {};
+
+/**
+ * Define this because the Google internal JSCompiler needs goog.typedef below.
+ */
+var goog = goog || {};
+
+/**
+ * A macro for defining composite types.
+ *
+ * By assigning goog.typedef to a name, this tells Google internal JSCompiler
+ * that this is not the name of a class, but rather it's the name of a composite
+ * type.
+ *
+ * For example,
+ * /** @type {Array|NodeList} / goog.ArrayLike = goog.typedef;
+ * will tell JSCompiler to replace all appearances of goog.ArrayLike in type
+ * definitions with the union of Array and NodeList.
+ *
+ * Does nothing in uncompiled code.
+ */
+goog.typedef = true;
+
+/**
+ * Reference to the global context. In most cases this will be 'window'.
+ */
+o3d.global = this;
+
+/**
+ * Path for included scripts.
+ * @type {string}
+ */
+o3d.basePath = '';
+
+/**
+ * Tries to detect the base path of the base.js script that
+ * bootstraps the o3d libraries.
+ * @private
+ */
+o3d.findBasePath_ = function() {
+ var doc = o3d.global.document;
+ if (typeof doc == 'undefined') {
+ return;
+ }
+ if (o3d.global.BASE_PATH) {
+ o3d.basePath = o3d.global.BASE_PATH;
+ return;
+ } else {
+ // HACK to hide compiler warnings :(
+ o3d.global.BASE_PATH = null;
+ }
+ var scripts = doc.getElementsByTagName('script');
+ for (var script, i = 0; script = scripts[i]; i++) {
+ var src = script.src;
+ var l = src.length;
+ var s = 'o3d-webgl/base.js';
+ var sl = s.length;
+ if (src.substr(l - sl) == s) {
+ o3d.basePath = src.substr(0, l - sl) + 'o3d-webgl/';
+ return;
+ }
+ }
+};
+
+/**
+ * Writes a script tag for the given o3d source file name
+ * to the document. (Must be called at execution time.)
+ * @param {string} src The full path to the source file.
+ * @private
+ */
+o3d.writeScriptTag_ = function(src) {
+ var doc = o3d.global.document;
+ if (typeof doc != 'undefined') {
+ doc.write('<script type="text/javascript" src="' +
+ src + '"></' + 'script>');
+ }
+};
+
+/**
+ * Includes the file indicated by the rule by adding a script tag.
+ * @param {string} rule Rule to include, in the form o3d.package.part.
+ */
+o3d.include = function(rule) {
+ var parts = rule.split('.');
+ var path = parts[parts.length - 1] + '.js';
+ o3d.writeScriptTag_(o3d.basePath + path);
+};
+
+
+/**
+ * Makes one class inherit from another. Adds the member variables superClass
+ * and superClassName to the prototype of the sub class.
+ * @param {string} subClass Class that wants to inherit.
+ * @param {string} superClass Class to inherit from.
+ */
+o3d.inherit = function(subClassName, superClassName) {
+ var superClass = o3d.global.o3d[superClassName];
+ var subClass = o3d.global.o3d[subClassName];
+
+ if (!superClass)
+ throw ('Invalid superclass: ' + superClassName);
+ if (!subClass)
+ throw ('Invalid subclass: ' + subClassName);
+
+ subClass.prototype = new superClass;
+ subClass.prototype.superClassName = superClassName;
+ subClass.prototype.superClass = superClass;
+};
+
+
+/**
+ * If an o3d function has not been implemented in javascript yet, it should
+ * call this function to throw an error because it's better than doing
+ * nothing.
+ */
+o3d.notImplemented = function() {
+ var callerName = arguments.caller.toString();
+ callerName = callerName.substr('function '.length);
+ callerName = ownName.substr(0, ownName.indexOf('('));
+ throw 'Not implemented: ' + callerName;
+};
+
+
+// First find the path to the directory where all o3d-webgl sources live.
+o3d.findBasePath_();
+
+
+// Unlike o3djs, we include all o3d-webgl files at once, this way, an o3d
+// developer converting to use these classes only has to include this
+// javascript file.
+o3d.include('object_base');
+o3d.include('named_object_base');
+o3d.include('named_object');
+o3d.include('param_object');
+o3d.include('param');
+o3d.include('event');
+o3d.include('raw_data');
+o3d.include('file_request');
+o3d.include('client');
+o3d.include('render_node');
+o3d.include('clear_buffer');
+o3d.include('state_set');
+o3d.include('viewport');
+o3d.include('tree_traversal');
+o3d.include('draw_list');
+o3d.include('draw_pass');
+o3d.include('render_surface_set');
+o3d.include('render_surface');
+o3d.include('state');
+o3d.include('draw_context');
+o3d.include('texture');
+o3d.include('sampler');
+o3d.include('transform');
+o3d.include('pack');
+o3d.include('bounding_box');
+o3d.include('draw_element');
+o3d.include('element');
+o3d.include('field');
+o3d.include('buffer');
+o3d.include('stream');
+o3d.include('stream_bank');
+o3d.include('primitive');
+o3d.include('shape');
+o3d.include('effect');
+o3d.include('material');
+
+
diff --git a/o3d/samples/o3d-webgl/bitmap.js b/o3d/samples/o3d-webgl/bitmap.js
new file mode 100644
index 0000000..6ce1df7
--- /dev/null
+++ b/o3d/samples/o3d-webgl/bitmap.js
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * Bitmap provides an interface for basic image operations on bitmap,
+ * including scale and crop. A Bitmap can be created from RawData via
+ * pack.createBitmapsFromRawData(), and also can be transferred to mip of a
+ * Texure2D or a specific face of TextureCUBE via methods in Texture.
+ * @constructor
+ */
+o3d.Bitmap = function() {
+ o3d.ParamObject.call(this);
+};
+o3d.inherit('Bitmap', 'ParamObject');
+
+
+/**
+ * @type {number}
+ */
+o3d.Bitmap.Semantic = goog.typedef;
+
+/**
+ * After loading an array of Bitmaps with pack.createBitmapsFromRawData
+ * you can inspect their semantic to see what they were intended for. This is
+ * mostly to distinguish between 6 bitmaps that are faces of a cubemap and 6
+ * bitmaps that are slices of a 3d texture.
+ *
+ * FACE_POSITIVE_X, 1 face of a cubemap
+ * FACE_NEGATIVE_X, 1 face of a cubemap
+ * FACE_POSITIVE_Y, 1 face of a cubemap
+ * FACE_NEGATIVE_Y, 1 face of a cubemap
+ * FACE_POSITIVE_Z, 1 face of a cubemap
+ * FACE_NEGATIVE_Z, 1 face of a cubemap
+ * IMAGE, normal 2d image
+ * SLICE, a slice of a 3d texture.
+ */
+o3d.Bitmap.FACE_POSITIVE_X = 0;
+o3d.Bitmap.FACE_NEGATIVE_X = 1;
+o3d.Bitmap.FACE_POSITIVE_Y = 2;
+o3d.Bitmap.FACE_NEGATIVE_Y = 3;
+o3d.Bitmap.FACE_POSITIVE_Z = 4;
+o3d.Bitmap.FACE_NEGATIVE_Z = 5;
+o3d.Bitmap.IMAGE = 6;
+o3d.Bitmap.SLICE = 7;
+
+
+
+/**
+ * Flips a bitmap vertically in place.
+ * @type {boolean}
+ */
+o3d.Bitmap.prototype.flipVertically = false;
+
+
+
+/**
+ * Generates mip maps from the source level to lower levels.
+ *
+ * You can not currently generate mips for DXT textures although you can load
+ * them from dds files.
+ *
+ * @param {number} source_level The level to use as the source of the mips.
+ * @param {number} num_levels The number of levels to generate below the
+ * source level.
+ */
+o3d.Bitmap.prototype.generateMips =
+ function(source_level, num_levels) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * The width of the bitmap (read only).
+ * @type {number}
+ */
+o3d.Bitmap.prototype.width = 0;
+
+
+
+/**
+ * The height of the bitmap (read only).
+ * @type {number}
+ */
+o3d.Bitmap.prototype.height = 0;
+
+
+
+/**
+ * The format of the bitmap (read only).
+ * @type {number}
+ */
+o3d.Bitmap.prototype.format = 0;
+
+
+
+/**
+ * Number mip-maps (read only)
+ * @type {number}
+ */
+o3d.Bitmap.prototype.numMipmaps = 1;
+
+
+
+/**
+ * The Semantic of the bitmap.
+ * @type {!o3d.Stream.Semantic}
+ */
+o3d.Bitmap.prototype.semantic = o3d.Stream.UNKNOWN_SEMANTIC;
+
+
+
diff --git a/o3d/samples/o3d-webgl/bounding_box.js b/o3d/samples/o3d-webgl/bounding_box.js
new file mode 100644
index 0000000..506dd2c
--- /dev/null
+++ b/o3d/samples/o3d-webgl/bounding_box.js
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * Creates BoundingBox from minExtent and maxExtent
+ * @param {!o3d.math.Point3} minExtent minimum extent of the box.
+ * @param {!o3d.math.Point3} maxExtent maximum extent of the box.
+ * @constructor
+ */
+o3d.BoundingBox =
+ function(minExtent, maxExtent) {
+ o3d.ParamObject.call(this);
+ this.minExtent = [minExtent[0], minExtent[1], minExtent[2]];
+ this.minExtent = [maxExtent[0], maxExtent[1], maxExtent[2]];
+};
+o3d.inherit('BoundingBox', 'ParamObject');
+
+
+/**
+ * True if this boundingbox has been initialized.
+ * @type {boolean}
+ */
+o3d.BoundingBox.prototype.valid_ = false;
+
+
+/**
+ * The min extent of the box.
+ * @type {!o3d.math.Point3}
+ */
+o3d.BoundingBox.prototype.minExtent = [0, 0, 0];
+
+
+
+/**
+ * The max extent of the box.
+ * @type {!o3d.math.Point3}
+ */
+o3d.BoundingBox.prototype.maxExtent = [0, 0, 0];
+
+
+
+/**
+ * Multiplies the bounding box by the given matrix returning a new bounding
+ * box.
+ * @param {!o3d.math.Matrix4} matrix The matrix to multiply by.
+ * @returns {!o3d.BoundingBox} The new bounding box.
+ */
+o3d.BoundingBox.prototype.mul =
+ function(matrix) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Adds a bounding box to this bounding box returning a bounding box that
+ * encompases both.
+ * @param {!o3d.BoundingBox} box BoundingBox to add to this BoundingBox.
+ * @returns {!o3d.BoundingBox} The new bounding box.
+ */
+o3d.BoundingBox.prototype.add =
+ function(box) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Checks if a ray defined in same coordinate system as this box intersects
+ * this bounding box.
+ * TODO(petersont): this can also take six coordinates as input.
+ * @param {!o3d.math.Point3} start position of start of ray in local space.
+ * @param {!o3d.math.Point3} end position of end of ray in local space.
+ * @returns {!o3d.RayIntersectionInfo} RayIntersectionInfo. If result.value
+ * is false then something was wrong like using this function with an
+ * uninitialized bounding box. If result.intersected is true then the ray
+ * intersected the box and result.position is the exact point of
+ * intersection.
+ */
+o3d.BoundingBox.prototype.intersectRay =
+ function(start, end) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Returns true if the bounding box is inside the frustum.
+ * @param {!o3d.math.Matrix4} matrix Matrix to transform the box from its
+ * local space to view frustum space.
+ * @returns {boolean} True if the box is in the frustum.
+ */
+o3d.BoundingBox.prototype.inFrustum =
+ function(matrix) {
+ o3d.notImplemented();
+};
+
+
diff --git a/o3d/samples/o3d-webgl/buffer.js b/o3d/samples/o3d-webgl/buffer.js
new file mode 100644
index 0000000..eb4447b
--- /dev/null
+++ b/o3d/samples/o3d-webgl/buffer.js
@@ -0,0 +1,280 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * The Buffer object is a low level container for a flat list of
+ * floating point or integer values. These are currently used to define
+ * geometry.
+ * @constructor
+ */
+o3d.Buffer = function() {
+ this.fields_ = [];
+ this.array_ = null;
+};
+o3d.inherit('Buffer', 'NamedObject');
+
+
+/**
+ * A private array to hold the fields.
+ * @type {!Array.<o3d.Field>}
+ */
+o3d.Buffer.prototype.fields_ = [];
+
+
+/**
+ * Total number of components.
+ * @type {number}
+ */
+o3d.Buffer.prototype.totalComponents = 0;
+
+/**
+ * Index of the corresponding gl buffer object.
+ * @type {number}
+ */
+o3d.Buffer.prototype.gl_buffer_ = 0;
+
+/**
+ * Type of the array element.
+ * @type {!WebGLFloatArray}
+ */
+o3d.Buffer.prototype.ArrayType = WebGLFloatArray;
+
+/**
+ * Allocates memory for the data to be stored in the buffer based on
+ * the types of fields set on the buffer.
+ *
+ * @param {number} numElements Number of elements to allocate..
+ * @returns {boolean} True if operation was successful.
+ */
+o3d.Buffer.prototype.allocateElements =
+ function(numElements) {
+ var total = 0;
+ for (var i = 0; i < this.fields_.length; ++i) {
+ this.fields_[i].offset_ = total;
+ total += this.fields_[i].numComponents;
+ }
+ this.totalComponents = total;
+
+ this.resize(numElements * this.totalComponents);
+};
+
+/**
+ * Reallocate the array element to have the given number of elements.
+ * @param {number} numElements The new number of elements.
+ */
+o3d.Buffer.prototype.resize = function(numElements) {
+ this.gl_buffer_ = this.gl.createBuffer();
+ this.array_ = new this.ArrayType(numElements);
+};
+
+/**
+ * Defines a field on this buffer.
+ *
+ * Note: Creating a field after having allocated the buffer is an expensive
+ * operation as the data currently in the buffer has to be shuffled around
+ * to make room for the new field.
+ *
+ * @param {string} field_type type of data in the field. Valid types
+ * are "FloatField", "UInt32Field", and "UByteNField".
+ * @param {number} num_components number of components in the field.
+ * @returns {!o3d.Field} The created field.
+ */
+o3d.Buffer.prototype.createField =
+ function(fieldType, numComponents) {
+ var f = new o3d.Field();
+ f.buffer = this;
+ f.numComponents = numComponents;
+ f.size = numComponents * (fieldType=='UByteNField' ? 1 : 4);
+ this.fields_.push(f);
+ return f;
+};
+
+
+/**
+ * Removes a field from this buffer.
+ *
+ * Note: Removing a field after having allocated the buffer is an expensive
+ * operation as the data currently in the buffer has to be shuffled around
+ * to remove the old field.
+ *
+ * @param {!o3d.Field} field field to remove.
+ */
+o3d.Buffer.prototype.removeField =
+ function(field) {
+ var i = 0;
+ for (var j = 0; j < this.fields_.length; ++j) {
+ if (this.fields_[i] == field)
+ j++;
+ this.fields_[j] = this.fields_[i];
+ i++;
+ }
+ if (this.fields_.length > i) {
+ this.fields_.pop();
+ }
+};
+
+
+/**
+ * Prepares the buffer for read/write.
+ */
+o3d.Buffer.prototype.lock = function() {
+ // For now, this doesn't need to do anything.
+};
+
+
+/**
+ * Delivers the buffer to the graphics hardware when read/write is finished.
+ */
+o3d.Buffer.prototype.unlock = function() {
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.gl_buffer_);
+ this.gl.bufferData(this.gl.ARRAY_BUFFER, this.array_, this.gl.STATIC_DRAW);
+};
+
+
+/**
+ * Sets the values in the buffer given array.
+ * TODO(petersont): This should take other kinds of arguments, like RawData.
+ *
+ * @param {!Array.<number>} values contains data to assign to the Buffer
+ * data itself.
+ * @returns {boolean} True if operation was successful.
+ */
+o3d.Buffer.prototype.set =
+ function(values) {
+ if (this.array_ == null) {
+ this.resize(values.length);
+ }
+ this.lock();
+ for (var i = 0; i < values.length; ++i) {
+ this.array_[i] = values[i];
+ }
+ this.unlock();
+};
+
+
+/**
+ * The total components in all fields in this buffer.
+ * @type {number}
+ */
+o3d.Buffer.prototype.total_components = 0;
+
+
+/**
+ * VertexBufferBase is a the base class for both VertexBuffer and SourceBuffer
+ * @constructor
+ */
+o3d.VertexBufferBase = function() {
+ o3d.Buffer.call(this);
+};
+o3d.inherit('VertexBufferBase', 'Buffer');
+
+
+/**
+ * Gets a copy of the values of the data stored in the buffer.
+ * Modifying this copy has no effect on the buffer.
+ */
+o3d.VertexBufferBase.prototype.get = function() {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Gets a copy of a sub range of the values in the data stored in the buffer.
+ * Modifying this copy has no effect on the buffer.
+ *
+ * @param {number} start_index index of the element value to get.
+ * @param {number} numElements the number of elements to get.
+ * @returns {!Array.<number>} An array of values.
+ */
+o3d.VertexBufferBase.prototype.getAt =
+ function(start_index, numElements) {
+};
+
+
+/**
+ * VertexBuffer is a Buffer object used for storing vertex data for geometry.
+ * (e.g. vertex positions, normals, colors, etc).
+ * A VertexBuffer can be rendered directly by the GPU.
+ * @constructor
+ */
+o3d.VertexBuffer = function() {
+ o3d.Buffer.call(this);
+};
+o3d.inherit('VertexBuffer', 'Buffer');
+
+/**
+ * The name of the class as a string.
+ * @type {string}
+ */
+o3d.VertexBuffer.prototype.className = "o3d.VertexBuffer";
+
+
+/**
+ * SourceBuffer is a Buffer object used for storing vertex data for
+ * geometry. (e.g. vertex positions, normals, colors, etc).
+ *
+ * A SourceBuffer is the source for operations like skinning and morph
+ * targets. It can not be directly rendered by the GPU.
+ * @constructor
+ */
+o3d.SourceBuffer = function() {
+ o3d.Buffer.call(this);
+};
+o3d.inherit('SourceBuffer', 'Buffer');
+
+
+/**
+ * IndexBuffer is a buffer object used for storing geometry index data (e.g.
+ * triangle indices).
+ * @constructor
+ */
+o3d.IndexBuffer = function() {
+ o3d.Buffer.call(this);
+};
+o3d.inherit('IndexBuffer', 'Buffer');
+
+
+/**
+ * Type of the array element.
+ * @type {!WebGLUnsignedShortArray}
+ */
+o3d.IndexBuffer.prototype.ArrayType = WebGLUnsignedShortArray;
+
+
+/**
+ * Delivers the buffer to the graphics hardware when read/write is finished.
+ */
+o3d.IndexBuffer.prototype.unlock = function() {
+ this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.gl_buffer_);
+ this.gl.bufferData(
+ this.gl.ELEMENT_ARRAY_BUFFER, this.array_, this.gl.STATIC_DRAW);
+};
diff --git a/o3d/samples/o3d-webgl/clear_buffer.js b/o3d/samples/o3d-webgl/clear_buffer.js
new file mode 100644
index 0000000..fbc116a
--- /dev/null
+++ b/o3d/samples/o3d-webgl/clear_buffer.js
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * A ClearBuffer is a render node that clears the color buffer, zbuffer and/or
+ * stencil buffer of the current render target.
+ *
+ * @constructor
+ */
+o3d.ClearBuffer = function() {
+ o3d.RenderNode.call(this);
+ this.clearColor = [0, 0, 0, 1];
+};
+o3d.inherit('ClearBuffer', 'RenderNode');
+
+
+
+/**
+ * The color to clear the buffer in RGBA Float4 format.
+ * @type {!o3d.Float4}
+ */
+o3d.ClearBuffer.prototype.clearColor = [0, 0, 0, 1];
+
+
+
+/**
+ * true clears the current render target's color buffer to the clear color.
+ * false does not clear the color buffer.
+ * @type {boolean}
+ */
+o3d.ClearBuffer.prototype.clearColorFlag = true;
+
+
+
+/**
+ * The value to clear the depth buffer (0.0 - 1.0)
+ * @type {number}
+ */
+o3d.ClearBuffer.prototype.clearDepth = 1;
+
+
+
+/**
+ * true clears the current render target's depth buffer to the clear depth
+ * value. false does not clear the depth buffer.
+ * @type {boolean}
+ */
+o3d.ClearBuffer.prototype.clearDepthFlag = true;
+
+
+
+/**
+ * The value to clear the stencil buffer to (0 - 255).
+ * @type {number}
+ */
+o3d.ClearBuffer.prototype.clearStencil = 0;
+
+
+
+/**
+ * true clears the current render target's stencil buffer to the clear stencil
+ * value. false does not clear the stencil buffer
+ * @type {boolean}
+ */
+o3d.ClearBuffer.prototype.clearStencilFlag = true;
+
+
+
+/**
+ * Function called in the render graph traversal before the children are
+ * rendered.
+ */
+o3d.ClearBuffer.prototype.before = function() {
+ var flags = 0;
+
+ this.gl.clearColor(
+ this.clearColor[0],
+ this.clearColor[1],
+ this.clearColor[2],
+ this.clearColor[3]);
+
+ this.gl.clearDepth(this.clearDepth);
+ this.gl.clearStencil(this.clearStencil);
+
+ if (this.clearColorFlag)
+ flags = flags | this.gl.COLOR_BUFFER_BIT;
+ if (this.clearDepthFlag)
+ flags = flags | this.gl.DEPTH_BUFFER_BIT;
+ if (this.clearStencilFlag)
+ flags = flags | this.gl.STENCIL_BUFFER_BIT;
+
+ this.gl.clear(flags);
+};
+
+
+
diff --git a/o3d/samples/o3d-webgl/client.js b/o3d/samples/o3d-webgl/client.js
new file mode 100644
index 0000000..5bbb7b2
--- /dev/null
+++ b/o3d/samples/o3d-webgl/client.js
@@ -0,0 +1,841 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * A namespace to hold the list of all clients.
+ * @namespace
+ */
+o3d.Renderer = {};
+
+
+/**
+ * @type {number}
+ */
+o3d.Renderer.InitStatus = goog.typedef;
+
+/**
+ * The initialization status of the renderer.
+ *
+ * InitStatus,
+ * UNINITIALIZED,
+ * SUCCESS, The renderer is initialized.
+ * GPU_NOT_UP_TO_SPEC, The renderer determined the user's machine cannot
+ * run O3D.
+ * OUT_OF_RESOURCES, The user's machine does not have enough graphic
+ * resources available to start another instance of the O3D renderer.
+ * INITIALIZATION_ERROR, Some unknown error such as e.g. drivers not
+ * being installed correctly.
+ */
+o3d.Renderer.UNINITIALIZED = 0;
+o3d.Renderer.SUCCESS = 1;
+o3d.Renderer.GPU_NOT_UP_TO_SPEC = 2;
+o3d.Renderer.OUT_OF_RESOURCES = 3;
+o3d.Renderer.INITIALIZATION_ERROR = 4;
+
+
+/**
+ * @type {number}
+ */
+o3d.Renderer.DisplayMode = goog.typedef;
+
+/**
+ * This is used in SetFullscreenClickRegion to request the current display
+ * mode, such that the change to full-screen mode won't change the screen
+ * resolution or refresh rate.
+ *
+ * DisplayModes,
+ * DISPLAY_MODE_DEFAULT
+ */
+o3d.Renderer.DISPLAY_MODE_DEFAULT = 0;
+
+
+/**
+ * The interval timer for the render callback.
+ * @type {Object}
+ */
+o3d.Renderer.render_callback_interval_ = null;
+
+
+/**
+ * Global private list of all clients to be rendered every frame.
+ * @type {!Array.<!o3d.Client>}
+ */
+o3d.Renderer.clients_ = [];
+
+
+/**
+ * Renders all clients associated with this renderer.
+ */
+o3d.Renderer.renderClients = function() {
+ for (var i = 0; i < o3d.Renderer.clients_.length; ++i) {
+ var client = o3d.Renderer.clients_[i];
+ var renderEvent = new o3d.RenderEvent;
+ var now = (new Date()).getTime() * 0.001;
+ if(client.then_ == 0.0)
+ renderEvent.elapsedTime = 0.0;
+ else
+ renderEvent.elapsedTime = now - client.then_;
+ if (client.render_callback) {
+ client.render_callback(renderEvent);
+ }
+ client.then_ = now;
+ client.renderTree(client.renderGraphRoot);
+ }
+};
+
+
+/**
+ * Sets a timer to traverse the rendergraph every sixtieth of a second.
+ */
+o3d.Renderer.installRenderInterval = function() {
+ o3d.Renderer.render_callback_interval_ = setInterval(
+ "o3d.Renderer.renderClients()", 1000.0 / 60.0);
+};
+
+
+/**
+ * The ClientInfo is used to get information about the client.
+ * @constructor
+ */
+o3d.ClientInfo = function() { };
+
+
+/**
+ * The number of objects the client is currently tracking.
+ * You can use this to check that you are correctly freeing resources.
+ * @type {number}
+ */
+o3d.ClientInfo.prototype.num_objects = 0;
+
+
+
+/**
+ * The amount of texture memory used.
+ * @type {number}
+ */
+o3d.ClientInfo.prototype.texture_memory_used = 0;
+
+
+
+/**
+ * The amount of texture memory used.
+ * @type {number}
+ */
+o3d.ClientInfo.prototype.buffer_memory_used = 0;
+
+
+
+/**
+ * Whether or not O3D is using the software renderer.
+ *
+ * For testing purposes you can force O3D to use the software renderer
+ * by setting the environment variable O3D_FORCE_SOFTWARE_RENDERER to
+ * anything.
+ *
+ *
+ * set O3D_FORCE_SOFTWARE_RENDERER=foo
+ *
+ * or
+ *
+ * export O3D_FORCE_SOFTWARE_RENDERER=foo
+ *
+ *
+ * You can set it at a system level if you want to set it for all
+ * browser instances or set it from a command line and start your
+ * browser from that same command line if you want to effect just
+ * that instance of the browser.
+ *
+ * Note that many browers require special command line options to
+ * run in a separate process, otherwise they default to finding
+ * the browser process already running and using that. For example
+ * firefox requires the option -no-remote.
+ *
+ * @type {boolean}
+ */
+o3d.ClientInfo.prototype.software_renderer = false;
+
+
+
+/**
+ * Whether or not the GPU supports non power of two textures.
+ * NOTE: O3D always allows non power of two textures.
+ *
+ * The only reason to look at this flag is for things like video that are
+ * updating the texture every frame. In that case, you might want to know
+ * that you could run faster if you used a power of 2 texture instead of
+ * a non power of 2 texture.
+ *
+ * @type {boolean}
+ */
+o3d.ClientInfo.prototype.non_power_of_two_textures = true;
+
+
+/**
+ * The Client class is the main point of entry to O3D. It defines methods
+ * for creating and deleting packs. Each new object created by the Client is
+ * assigned a unique ID.
+ *
+ * The Client has a root transform for the transform graph and a root render
+ * node for the render graph.
+ * @constructor
+ */
+o3d.Client = function() {
+ this.root = new o3d.Transform;
+ this.renderGraphRoot = new o3d.RenderNode;
+ this.root = new o3d.Transform;
+ this.clientId = o3d.Client.nextId++;
+
+ if (o3d.Renderer.clients_.length == 0)
+ o3d.Renderer.installRenderInterval();
+
+ o3d.Renderer.clients_.push(this);
+};
+o3d.inherit('Client', 'NamedObject');
+
+/**
+ * @type {function(!o3d.RenderEvent): void}
+ */
+o3d.Client.RenderCallback = goog.typedef;
+
+/**
+ * @type {function(!o3d.TickEvent): void}
+ */
+o3d.Client.TickCallback = goog.typedef;
+
+/**
+ * @type {function(!o3d.Event): void}
+ */
+o3d.Client.ErrorCallback = goog.typedef;
+
+/**
+ * The root of the render graph.
+ * @type {o3d.RenderNode}
+ */
+o3d.Client.prototype.renderGraphRoot = null;
+
+
+/**
+ * Global counter to give the client a unique ID number.
+ * @type {number}
+ */
+o3d.Client.nextId = 0;
+
+
+/**
+ * The time of the last render in seconds.
+ * @type {number}
+ */
+o3d.Client.prototype.then_ = 0;
+
+
+/**
+ * The transform graph root.
+ * @type {o3d.Transform}
+ */
+o3d.Client.prototype.root = null;
+
+/**
+ * Function that gets called when the client encounters an error.
+ */
+o3d.Client.prototype.error_callback = function(error_message) {};
+
+
+/**
+ * Function that gets called right before the client renders.
+ */
+o3d.Client.prototype.render_callback = function(render_event) {};
+
+
+/**
+ * Function that gets called every tick.
+ */
+o3d.Client.prototype.tick_callback = function(tick_event) {};
+
+
+/**
+ * Call this function from window.onunload to ensure the browser does not
+ * continue to call callbacks (like the render callback) after the page is
+ * unloaded. It is possible that during unload the browser unloads all the
+ * javascript code, but then, after that, still asks the plugin to render. The
+ * browser then calls javascript functions that no longer exist which causes an
+ * error. To prevent that situation you need to clear all your callbacks on
+ * unload. cleanup handles that for you so you don't have to dispose each and
+ * every callback by hand.
+ */
+o3d.Client.prototype.cleanup = function () {
+ this.clearRenderCallback();
+ this.clearTickCallback();
+ this.clearErrorCallback();
+};
+
+
+/**
+ * Creates a pack object.
+ * A pack object.
+ * @returns {!o3d.Pack} A new pack object.
+ */
+o3d.Client.prototype.createPack =
+ function() {
+ var pack = new o3d.Pack;
+ pack.gl = this.gl;
+ return pack;
+};
+
+
+/**
+ * Searches the Client for an object matching the given id.
+ *
+ * @param {number} id The id of the object to look for.
+ * @returns {o3d.ObjectBase} The object or null if a object
+ * with the given id is not found.
+ */
+o3d.Client.prototype.getObjectById =
+ function(id) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Searches the Client for objects of a particular name and type.
+ * @param {string} name name of object to look for.
+ * @param {string} class_name name of class to look for.
+ * @returns {!Array.<!o3d.ObjectBase>} Array of objects found.
+ */
+o3d.Client.prototype.getObjects =
+ function(name, class_name) {
+ o3d.notImplemented();
+ return [];
+};
+
+
+/**
+ * Searches the Client for objects of a particular type.
+ * @param {string} class_name name of class to look for.
+ * @returns {!Array.<!Object>} Array of objects found.
+ */
+o3d.Client.prototype.getObjectsByClassName =
+ function(class_name) {
+ o3d.notImplemented();
+ return [];
+};
+
+
+/**
+ * @type {number}
+ */
+o3d.Client.RenderMode = goog.typedef;
+
+/**
+ * RENDERMODE_CONTINUOUS, Draw as often as possible up to refresh rate.
+ * RENDERMODE_ON_DEMAND, Draw once then only when the OS requests it
+ * (like uncovering part of a window.)
+ */
+o3d.Client.RENDERMODE_CONTINUOUS = 0;
+o3d.Client.RENDERMODE_ON_DEMAND = 1;
+
+
+/**
+ * The current render mode. The default mode is RENDERMODE_CONTINUOUS.\n
+ * Valid values are:
+ * RENDERMODE_CONTINUOUS, Draw as often as possible up to refresh rate.
+ * RENDERMODE_ON_DEMAND, Draw when the OS requests it (like uncovering
+ * part of a window.)
+ * @type {o3d.Client.RenderMode}
+ */
+o3d.Client.prototype.renderMode = o3d.Client.RENDERMODE_CONTINUOUS;
+
+
+
+/**
+ * Forces a render of the current scene if the current render mode is
+ * RENDERMODE_ON_DEMAND.
+ */
+o3d.Client.prototype.render = function() {
+ this.renderTree();
+};
+
+
+
+/**
+ * Renders a render graph.
+ *
+ * Normally the client calls this function automatically for you effectively
+ * doing a client.renderTree(client.renderGraphRoot) but there are cases
+ * where it is beneficial to be able to call this yourself and pass it
+ * different roots when you need to manipulate something between calls.
+ *
+ * This function can only be called from inside a render callback. If you call
+ * it the client will not do its default call as mentioned above.
+ *
+ * @param {!o3d.RenderNode} render_node root RenderNode to start rendering from.
+ */
+o3d.Client.prototype.renderTree =
+ function(render_node) {
+ render_node.render();
+};
+
+
+/**
+ * Returns an array of DisplayModes which are available for use in full-screen
+ * mode.
+ * An array of DisplayModes.
+ * @type {!Array.<!o3d.Client.DispalyMode>}
+ */
+o3d.Client.prototype.getDisplayModes = [];
+
+
+
+/**
+ * Makes a region of the plugin area that will invoke full-screen mode if
+ * clicked. The developer is responsible for communicating this to the user,
+ * as this region has no visible marker. The developer is also responsible for
+ * updating this region if the plugin gets resized, as we don't know whether or
+ * how to scale it. There can be only one full-screen click region at a time;
+ * calling this again will override any previous call.
+ *
+ * @param {number} x x position in pixels.
+ * @param {number} y y position in pixels.
+ * @param {number} width width in pixels.
+ * @param {number} height height in pixels.
+ * @param {number} mode_id Id of mode to use.
+ */
+o3d.Client.prototype.setFullscreenClickRegion =
+ function(x, y, width, height, mode_id) {
+
+};
+
+
+/**
+ * Deactivates the plugin click region that was previously created with
+ * SetFullscreenClickRegion().
+ */
+o3d.Client.prototype.clearFullscreenClickRegion = function() {
+ o3d.notImplemented();
+};
+
+
+
+/**
+ * Cancels full-screen display, reverting to displaying content only in the
+ * plugin region. If the plugin is already not in full-screen mode, this has
+ * no effect. This does not deactivate the plugin click region--if the user
+ * clicks there again, we'll go back to full-screen display.
+ */
+o3d.Client.prototype.cancelFullscreenDisplay = function() {
+ render_node.render();
+};
+
+
+
+/**
+ * Gets info about the client.
+ * @type {!o3d.ClientInfo}
+ */
+o3d.Client.prototype.client_info = null;
+
+
+
+/**
+ * Whether content is displayed in full-screen mode or in a plugin window. The
+ * default is false [not full-screen].
+ * @type {boolean}
+ */
+o3d.Client.prototype.fullscreen = false;
+
+
+/**
+ * Returns the width of the current drawing area [plugin or full-screen] in
+ * pixels.
+ */
+o3d.Client.prototype.__defineGetter__('width',
+ function() {
+ return this.gl.canvas.width;
+ }
+);
+
+o3d.Client.prototype.__defineSetter__('width',
+ function(x) {
+ this.gl.canvas.width = x;
+ }
+);
+
+
+/**
+ * Returns the height of the current drawing area [plugin or full-screen] in
+ * pixels.
+ */
+o3d.Client.prototype.__defineGetter__('height',
+ function() {
+ return this.gl.canvas.height;
+ }
+);
+
+o3d.Client.prototype.__defineSetter__('height',
+ function(x) {
+ this.gl.canvas.height = x;
+ }
+);
+
+
+/**
+ * Sets the per frame render callback.
+ *
+ * Note: The callback will not be called recursively. When your callback is
+ * called if you somehow manage to cause the client to render more frames
+ * before you've returned from the callback you will not be called for those
+ * frames.
+ *
+ * g_client.setRenderCallback(onrender);
+ *
+ * function onrender(render_event) {
+ * var elapsedTime = render_event.elapsedTime;
+ * }
+ *
+ * @param {!o3d.RenderCallback} render_callback The callback to call
+ * each frame.
+ */
+o3d.Client.prototype.setRenderCallback =
+ function(render_callback) {
+ if (this.render_callback) {
+ this.clearRenderCallback();
+ }
+ this.render_callback = render_callback;
+};
+
+
+/**
+ * Clears the per frame render callback.
+ */
+o3d.Client.prototype.clearRenderCallback = function() {
+ clearInterval(this.render_callback_interval_);
+ this.render_callback = null;
+};
+
+
+/**
+ * Sets a render callback to be called at the end of the
+ * rendering cycle of each frame.
+ *
+ * Note: The callback will not be called recursively. When your callback is
+ * called if you somehow manage to cause the client to render more frames
+ * before you've returned from the callback you will not be called for those
+ * frames.
+ *
+ *
+ * g_client.setPostRenderCallback(onpostrender);
+ *
+ * function onpostrender(render_event) {
+ * var elapsedTime = render_event.elapsedTime;
+ * }
+ *
+ * @param {!o3d.RenderCallback} post_render_callback The callback to call
+ * each frame.
+ */
+o3d.Client.prototype.setPostRenderCallback =
+ function(post_render_callback) {
+ this.postRenderCallback = post_render_callback;
+};
+
+
+/**
+ * Clears the post render callback.
+ */
+o3d.Client.prototype.clearPostRenderCallback = function() {
+ this.postRenderCallback = null;
+};
+
+
+
+/**
+ * Sets the lost resources callback.
+ *
+ * The contents of certain resources, RenderSurfaces, can get discarded by the
+ * system under certain circumstances. If you application needs that contents
+ * to be in a certain state then you can set a callback giving your program the
+ * opportunity to restore that state if and when it is lost.
+ *
+ * @param {!o3d.LostResourcesCallback} lost_resources_callback The callback when
+ * resources are lost.
+ */
+o3d.Client.prototype.setLostResourcesCallback =
+ function(lost_resources_callback) {
+ this.lostResourcesCallback = lost_resources_callback;
+};
+
+
+/**
+ * Clears the lost resources callback.
+ */
+o3d.Client.prototype.clearLostResourcesCallback =
+ function() {
+ this.lostResourcesCallback = null;
+};
+
+
+
+/**
+ * Sets a callback for a given event type.
+ * types.
+ * There can be only one callback for a given event type at a time; setting a
+ * new one deletes the old one.
+ *
+ * @param {string} type Type of event to set callback for.
+ * @param {!o3d.EventCallback} handler Function to call on event.
+ */
+o3d.Client.prototype.setEventCallback =
+ function(type, handler) {
+ this.eventCallbacks[type] = handler;
+};
+
+
+/**
+ * Removes the previously-registered callback for an event of the given type.
+ * @param {string} type Type of event to clear callback for.
+ */
+o3d.Client.prototype.clearEventCallback =
+ function(type) {
+ this.eventCallbacks[type] = null;
+};
+
+
+/**
+ * Sets the texture to use when a Texture or Sampler is missing while
+ * rendering. The default is a red texture with a yellow no symbol.
+ * <span style="color:yellow; background-color: red;">&Oslash;.
+ * If you set it to null you'll get an error if you try to render something
+ * that is missing a needed Texture, Sampler or ParamSampler.
+ *
+ * For example if you don't care about missing textures, setting it to a black
+ * texture would be one option. Another example is if you want to write all
+ * your shaders to expect a texture then set this to a white texture. If you
+ * want to make sure you are not missing any textures set it null and see if
+ * you get any errors using Client.setErrorCallback or Client.lastError.
+ *
+ * var t = g_pack.createTexture2D('', 1, 1, g_o3d.Texture.XRGB8, 1);
+ * t.set(0, [0, 0, 0]);
+ * g_client.setErrorTexture(t);
+ *
+ * @param {o3d.Texture} texture texture to use for missing textures or null.
+ */
+o3d.Client.prototype.setErrorTexture =
+ function(texture) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Sets a callback for when the client ticks. The client processes some things
+ * like animation timers at up to 100hz. This callback will get called before
+ * each of those process ticks.
+ *
+ * NOTE: The client takes ownership of the TickCallback you
+ * pass in. It will be deleted if you call SetTickCallback a
+ * second time or if you call clearTickCallback.
+ *
+ * Note: The callback will not be called recursively.
+ *
+ * @param {o3d.TickCallback} tick_callback TickCallback to call when the
+ * Client ticks.
+ */
+o3d.Client.prototype.setTickCallback =
+ function(tick_callback) {
+ this.tickCallback = tick_callback;
+};
+
+
+/**
+ * Clears the tick callback
+ *
+ * NOTE: The client takes ownership of the TickCallback you
+ * pass in. It will be deleted if you call SetTickCallback a second
+ * time or if you call clearTickCallback
+ */
+o3d.Client.prototype.clearTickCallback = function() {
+ this.tickCallback = null;
+};
+
+
+/**
+ * Sets a callback for when the client gets an error. For example when a shader
+ * is compiled and there is an error or if you attempt to bind a param to a
+ * param of an incompatible type.
+ *
+ * NOTE: The client takes ownership of the ErrorCallback you
+ * pass in. It will be deleted if you call SetErrorCallback a
+ * second time or if you call ClearErrorCallback.
+ *
+ * NOTE: The callback will not be called recursively. If you are in a
+ * callback, and do something that causes another error before you have
+ * returned from the callback, your callback will not be called a second time.
+ *
+ * NOTE: If you put up an alert in response to an error it is best if you
+ * clear the error callback before you put up the alert. Otherwise you'll get
+ * an alert everytime the client tries to render which is every time you close
+ * the current alert which means you'll be in an infinite loop of alerts.
+ *
+ * @param {o3d.ErrorCallback} error_callback ErrorCallback to call when the
+ * Client gets an error.
+ */
+o3d.Client.prototype.setErrorCallback =
+ function(error_callback) {
+ this.error_callback = error_callback;
+};
+
+
+/**
+ * Clears the Error callback
+ *
+ * NOTE: The client takes ownership of the ErrorCallback you
+ * pass in. It will be deleted if you call SetErrorCallback a second
+ * time or if you call ClearErrorCallback.
+ */
+o3d.Client.prototype.clearErrorCallback = function() {
+ this.error_callback = null;
+};
+
+
+
+/**
+ * Makes all parameters get re-evaluated.
+ */
+o3d.Client.prototype.invalidateAllParameters = function() {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Gets a copy of the current backbuffer of O3D as a data: url.
+ * @param {string} mime_type The type of data url you want.
+ * Currently O3D only supports image/png. See HTML5 canvas tag
+ * for info about toDataURL.
+ * @returns {string} A Data URL for the backbuffer.
+ */
+o3d.Client.prototype.toDataURL =
+ function(opt_mime_type) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Returns the status of initializing the renderer so we can display the
+ * appropriate message. We require a certain minimum set of graphics
+ * capabilities. If the user's computer does not have his minimum
+ * set this will be GPU_NOT_UP_TO_SPEC. If the user is out of graphics
+ * resources this will be OUT_OF_RESOURCES. If some other error happened this
+ * will be INITIALIZATION_ERROR. Otherwise it will be SUCCESS.
+ */
+o3d.Client.prototype.renderer_init_status = 0;
+
+
+
+/**
+ * Gets / Sets the cursor's shape.
+ *
+ * @type {o3d.Cursor}
+ */
+o3d.Client.prototype.cursor = null;
+
+
+/**
+ * The last error reported by the plugin.
+ *
+ * @type {string}
+ */
+o3d.Client.prototype.last_error_ = '';
+
+
+
+/**
+ * All the objects managed by this client.
+ *
+ * Each access to this field gets the entire list so it is best to get it
+ * just once. For example:
+ *
+ * var objects = client.objects;
+ * for (var i = 0; i < objects.length; i++) {
+ * var object = objects[i];
+ * }
+ *
+ *
+ * Note that modifications to this array [e.g. push()] will not affect
+ * the underlying Client, while modifications to the array's members
+ * will affect them.
+ *
+ * @type {!Array.<!o3d.ObjectBase>}
+ */
+o3d.Client.prototype.objects = [];
+
+
+
+/**
+ * Clears the error returned in lastError.
+ */
+o3d.Client.prototype.clearLastError = function () {
+ o3d.notImplemented();
+};
+
+
+
+/**
+ * Resets the profiling information.
+ */
+o3d.Client.prototype.profileReset = function() {
+ o3d.notImplemented();
+};
+
+
+
+/**
+ * Returns the profiling information as a string.
+ * The profiling info.
+ * @return {string}
+ */
+o3d.Client.prototype.profileToString = function() {
+ o3d.notImplemented();
+};
+
+
+
+/**
+ * A unique id for this client.
+ * @type {number}
+ */
+o3d.Client.prototype.clientId = 0;
+
+
+
+/**
+ * The canvas associated with this client.
+ * @type {Element}
+ */
+o3d.Client.prototype.canvas = null;
+
+
diff --git a/o3d/samples/o3d-webgl/draw_context.js b/o3d/samples/o3d-webgl/draw_context.js
new file mode 100644
index 0000000..ee30d9b
--- /dev/null
+++ b/o3d/samples/o3d-webgl/draw_context.js
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * The DrawContext defines the parameters used for a particular drawing pass.
+ * It contains two 4-by-4 matrix params, view and
+ * projection. These correspond to the viewing and projection transformation
+ * matrices.
+ *
+ * @param {!o3d.Matrix4} opt_view The view matrix for this DrawContext.
+ * @param {!o3d.Matrix4} opt_projection The projection matrix
+ * for this DrawContext.
+ * @constructor
+ */
+o3d.DrawContext = function(opt_view, opt_projection) {
+ this.view = opt_view ||
+ [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]];
+ this.projection = opt_projection ||
+ [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]];
+};
+o3d.inherit('DrawContext', 'NamedObject');
+
+
+/**
+ * The view matrix represents the viewing transformation, used to take vertices
+ * from world space to view space.
+ * @type {o3d.Matrix4}
+ */
+o3d.DrawContext.prototype.view = [];
+
+
+
+/**
+ * The projection matrix represents the projection transformation, used to take
+ * vertices from view space to screen space. This matrix is usually an
+ * orthographic or perspective transformation.
+ * @type {o3d.Matrix4}
+ */
+o3d.DrawContext.prototype.projection = [];
+
+
diff --git a/o3d/samples/o3d-webgl/draw_element.js b/o3d/samples/o3d-webgl/draw_element.js
new file mode 100644
index 0000000..d4f802e
--- /dev/null
+++ b/o3d/samples/o3d-webgl/draw_element.js
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * A DrawElement causes an Element to be Drawn with a particular material.
+ * You can override other Effect parameters by adding corresponding params to
+ * the DrawElement.
+ *
+ * @param {!o3d.Material} opt_material The material used to render this element.
+ * @constructor
+ */
+o3d.DrawElement = function(opt_material) {
+ o3d.ParamObject.call(this);
+ this.material = opt_material || null;
+};
+o3d.inherit('DrawElement', 'ParamObject');
+
+
+/**
+ * The Material for this DrawElement. If it is null the material of owner will
+ * be used.
+ * @type {o3d.Material}
+ */
+o3d.DrawElement.prototype.material = null;
+
+
+
+/**
+ * The current owner of this Draw Element. Set to null to stop being owned.
+ *
+ * Note: DrawElements are referenced by the Pack they are created in and their
+ * owner. If the DrawElement is removed from its Pack then setting the owner
+ * to null will free the DrawElement. Or, visa versa, if you set the
+ * DrawElement's owner to null then removing it from its Pack will free the
+ * DrawElement.
+ * @type {o3d.Element}
+ */
+o3d.DrawElement.prototype.owner_ = null;
+
+
diff --git a/o3d/samples/o3d-webgl/draw_list.js b/o3d/samples/o3d-webgl/draw_list.js
new file mode 100644
index 0000000..537751b
--- /dev/null
+++ b/o3d/samples/o3d-webgl/draw_list.js
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * A DrawList gets used during rendering to collect DrawElements to
+ * render. Each Material references a DrawList. Depending on the material, as
+ * DrawElements get collected they will be put on different DrawLists.
+ * @constructor
+ */
+o3d.DrawList = function() {
+ this.list_ = [];
+};
+o3d.inherit('DrawList', 'NamedObject');
+
+/**
+ * Private list to actually hold the DrawElements
+ * @type {!Array.<!Object>}
+ */
+this.list_ = [];
+
+
+/**
+ * @type {number}
+ */
+o3d.DrawList.SortMethod = goog.typedef;
+
+
+/**
+ * SortMethod,
+ * BY_PERFORMANCE
+ * BY_Z_ORDER
+ * BY_PRIORITY
+ *
+ * Method to sort DrawList by.
+ */
+o3d.DrawList.BY_PERFORMANCE = 0;
+o3d.DrawList.BY_Z_ORDER = 1;
+o3d.DrawList.BY_PRIORITY = 2;
+
+
+/**
+ * Renders the draw list.
+ */
+o3d.DrawList.prototype.render = function() {
+ // TODO(petersont): Add sort.
+
+ for (var i = 0; i < this.list_.length; ++i) {
+ var drawElementInfo = this.list_[i];
+ var world = drawElementInfo.world;
+ var view = drawElementInfo.view;
+ var projection = drawElementInfo.projection;
+ var transform = drawElementInfo.transform;
+ var drawElement = drawElementInfo.drawElement;
+ var element = drawElementInfo.drawElement.owner;
+ var material = drawElementInfo.drawElement.material ||
+ drawElementInfo.drawElement.owner.material;
+ var effect = material.effect;
+
+ o3d.Param.SAS.setWorld(world);
+ o3d.Param.SAS.setView(view);
+ o3d.Param.SAS.setProjection(projection);
+
+ var paramObjects = [
+ transform,
+ drawElement,
+ element,
+ material,
+ effect,
+ o3d.Param.SAS
+ ];
+
+ material.effect.searchForParams(paramObjects);
+ element.render();
+ }
+};
+
+
diff --git a/o3d/samples/o3d-webgl/draw_pass.js b/o3d/samples/o3d-webgl/draw_pass.js
new file mode 100644
index 0000000..f3deea8
--- /dev/null
+++ b/o3d/samples/o3d-webgl/draw_pass.js
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * A DrawPass renders a DrawList.
+ *
+ * @param {o3d.DrawList} drawList The DrawList used by this DrawPass.
+ * @param {o3d.DrawPass.SortMethod} sortMethod ParamInteger The method
+ * of sorting this DrawPass.
+ * @constructor
+ */
+o3d.DrawPass = function(opt_drawList, opt_sortMethod) {
+ this.drawList = opt_drawList;
+ this.sortMethod = opt_sortMethod || o3d.DrawList.BY_PERFORMANCE;
+};
+o3d.inherit('DrawPass', 'RenderNode');
+
+
+/**
+ * The DrawList for this DrawPass.
+ * @type {o3d.DrawList}
+ */
+o3d.DrawPass.prototype.drawList = null;
+
+
+/**
+ * @type {number}
+ */
+o3d.DrawPass.SortMethod = goog.typedef;
+
+
+/**
+ * The sort method for this DrawPass to draw the DrawList by.
+ * Default = BY_PERFORMANCE.
+ * @type {o3d.DrawList.SortMethod}
+ */
+o3d.DrawPass.prototype.sortMethod = o3d.DrawList.BY_PERFORMANCE;
+
+/**
+ * Called in rendergraph traversal before children are rendered.
+ */
+o3d.DrawPass.prototype.before = function() {
+ if (this.drawList) {
+ this.drawList.render();
+ }
+};
+
+
diff --git a/o3d/samples/o3d-webgl/effect.js b/o3d/samples/o3d-webgl/effect.js
new file mode 100644
index 0000000..53d8882
--- /dev/null
+++ b/o3d/samples/o3d-webgl/effect.js
@@ -0,0 +1,424 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * EffectParameterInfo holds information about the Parameters an Effect needs.
+ * o3d.Effect.getParameterInfo
+ */
+o3d.EffectParameterInfo = function() { };
+o3d.inherit('EffectParameterInfo', 'NamedObject');
+
+
+/**
+ * The name of the parameter.
+ * @type {string}
+ */
+o3d.EffectParameterInfo.prototype.name = '';
+
+
+
+/**
+ * The type of the parameter.
+ * @type {string}
+ */
+o3d.EffectParameterInfo.prototype.className = '';
+
+
+
+/**
+ * The number of elements. Non-zero for array types, zero for non-array types.
+ * @type {number}
+ */
+o3d.EffectParameterInfo.prototype.numElements = 0;
+
+
+
+/**
+ * The semantic of the parameter. This is always in UPPERCASE.
+ * @type {o3d.Stream.Semantic}
+ */
+o3d.EffectParameterInfo.prototype.semantic = o3d.Stream.UNKNOWN_SEMANTIC;
+
+
+/**
+ * If this is a standard parameter (SAS) this will be the name of the type
+ * of Param needed. Otherwise it will be the empty string.
+ *
+ * Standard Parameters are generally handled automatically by o3d but you
+ * can supply your own if you have a unique situation.
+ *
+ * @type {string}
+ */
+o3d.EffectParameterInfo.prototype.sas_class_name = '';
+
+
+
+/**
+ * EffectStreamInfo holds information about the Streams an Effect needs.
+ * @param {o3d.Stream.Semantic} opt_semantic The semantic of the stream
+ * @param {number} opt_semantic_index
+ * @constructor
+ */
+o3d.EffectStreamInfo = function(opt_semantic, opt_semantic_index) {
+ if (!opt_semantic) {
+ opt_semantic = o3d.Stream.UNKNOWN_SEMANTIC;
+ }
+ if (!opt_semantic_index) {
+ opt_semantic_index = 0;
+ }
+ this.semantic = opt_semantic;
+ this.opt_semantic_index = opt_semantic_index;
+};
+o3d.inherit('EffectStreamInfo', 'NamedObject');
+
+
+/**
+ * The semantic of the stream.
+ * @type {!o3d.Stream.Semantic}
+ */
+o3d.EffectStreamInfo.prototype.semantic = o3d.Stream.UNKNOWN_SEMANTIC;
+
+
+
+/**
+ * The semantic index of the stream.
+ * @type {number}
+ */
+o3d.EffectStreamInfo.prototype.semanticIndex = 0;
+
+
+/**
+ * An Effect contains a vertex and pixel shader.
+ * @constructor
+ */
+o3d.Effect = function() {
+ o3d.ParamObject.call(this);
+ this.program_ = null;
+};
+o3d.inherit('Effect', 'ParamObject');
+
+
+/**
+ * Indicates whether the vertex shader has been loaded, so we can
+ * postpone linking until both shaders are in.
+ *
+ * @type {boolean}
+ */
+o3d.Effect.prototype.vertexShaderLoaded_ = false;
+
+
+/**
+ * Indicates whether the fragment shader has been loaded, so we can
+ * postpone linking until both shaders are in.
+ *
+ * @type {boolean}
+ */
+o3d.Effect.prototype.fragmentShaderLoaded_ = false;
+
+
+/**
+ * Binds standard attribute locations for the shader.
+ */
+o3d.Effect.prototype.bindAttributesAndLinkIfReady = function() {
+ if (this.vertexShaderLoaded_ && this.fragmentShaderLoaded_) {
+ var attributes = ['position', 'normal', 'tangent', 'binormal', 'color',
+ 'texCoord0', 'texCoord1', 'texCoord2', 'texCoord3',
+ 'texCoord4', 'texCoord5', 'texCoord6', 'texCoord7'];
+ for (var i = 0; i < attributes.length; ++i) {
+ this.gl.bindAttribLocation(this.program_, i, attributes[i]);
+ }
+ this.gl.linkProgram(this.program_);
+ this.getAllUniforms();
+ }
+};
+
+
+/**
+ * Helper function for loadVertexShaderFromString and
+ * loadPixelShaderFromString that takes the type as an argument.
+ * @param {string} shaderString The shader code.
+ * @param {number} type The type of the shader: either
+ * VERTEX_SHADER or FRAGMENT_SHADER.
+ */
+o3d.Effect.prototype.loadShaderFromString = function(shaderString, type) {
+ if (!this.program_) {
+ this.program_ = this.gl.createProgram();
+ }
+ var shader = this.gl.createShader(type);
+ this.gl.shaderSource(shader, shaderString);
+ this.gl.compileShader(shader);
+ this.gl.attachShader(this.program_, shader);
+};
+
+
+/**
+ * Loads a glsl vertex shader for this effect from a string.
+ * @param {string} shaderString The string.
+ */
+o3d.Effect.prototype.loadVertexShaderFromString =
+ function(shaderString) {
+ this.loadShaderFromString(shaderString, this.gl.VERTEX_SHADER);
+ this.vertexShaderLoaded_ = true;
+ o3d.Effect.prototype.bindAttributesAndLinkIfReady();
+};
+
+
+/**
+ * Loads a glsl vertex shader for this effect from a string.
+ * @param {string} shaderString The string.
+ */
+o3d.Effect.prototype.loadPixelShaderFromString =
+ function(shaderString) {
+ this.loadShaderFromString(shaderString, this.gl.FRAGMENT_SHADER);
+ this.fragmentShaderLoaded_ = true;
+ this.bindAttributesAndLinkIfReady();
+};
+
+
+/**
+ * Iterates through the active uniforms of the program and gets the
+ * location of each one and stores them by name in the uniforms
+ * object.
+ */
+o3d.Effect.prototype.getAllUniforms =
+ function() {
+ this.uniforms = {};
+ var numUniforms = this.gl.getProgramParameter(
+ this.program_, this.gl.ACTIVE_UNIFORMS);
+ for (var i = 0; i < numUniforms; ++i) {
+ var info = this.gl.getActiveUniform(this.program_, i);
+ this.uniforms[info.name] = {info:info,
+ location:this.gl.getUniformLocation(this.program_, info.name)};
+ }
+};
+
+
+/**
+ * For each of the effect's uniform parameters, creates corresponding
+ * parameters on the given ParamObject. Skips SAS Parameters.
+ *
+ * If a Param with the same name but the wrong type already exists on the
+ * given ParamObject createUniformParameters will attempt to replace it with
+ * one of the correct type.
+ *
+ * Note: The most common thing to pass to this function is a Material but
+ * depending on your application it may be more appropriate to pass in a
+ * Transform, Effect, Element or DrawElement.
+ *
+ * @param {!o3d.ParamObject} param_object The param object on which the
+ * new paramters will be created.
+ */
+o3d.Effect.prototype.createUniformParameters =
+ function(param_object) {
+ var sasNames = {'world': true,
+ 'view': true,
+ 'projection': true,
+ 'worldView': true,
+ 'worldProjection': true,
+ 'worldViewProjection': true,
+ 'worldI': true,
+ 'viewI': true,
+ 'projectionI': true,
+ 'worldViewI': true,
+ 'worldProjectionI': true,
+ 'worldViewProjectionI': true,
+ 'worldT': true,
+ 'viewT': true,
+ 'projectionT': true,
+ 'worldViewT': true,
+ 'worldProjectionT': true,
+ 'worldViewProjectionT': true,
+ 'worldIT': true,
+ 'viewIT': true,
+ 'projectionIT': true,
+ 'worldViewIT': true,
+ 'worldProjectionIT': true,
+ 'worldViewProjectionIT': true};
+
+ for (name in this.uniforms) {
+ var info = this.uniforms[name].info;
+
+ if (sasNames[name])
+ continue;
+
+ var paramType = '';
+ switch (info.type) {
+ case this.gl.FLOAT:
+ paramType = 'ParamFloat';
+ break;
+ case this.gl.FLOAT_VEC2:
+ paramType = 'ParamFloat2';
+ break;
+ case this.gl.FLOAT_VEC3:
+ paramType = 'ParamFloat3';
+ break;
+ case this.gl.FLOAT_VEC4:
+ paramType = 'ParamFloat4';
+ break;
+ case this.gl.INT:
+ paramType = 'ParamInteger';
+ break;
+ case this.gl.BOOL:
+ paramType = 'ParamBoolean';
+ break;
+ case this.gl.FLOAT_MAT4:
+ paramType = 'ParamMatrix4';
+ break;
+ case this.gl.SAMPLER_2D:
+ paramType = 'ParamSampler';
+ break;
+ case this.gl.SAMPLER_CUBE:
+ paramType = 'ParamSampler';
+ break;
+ }
+
+ param_object.createParam(info.name, paramType);
+ }
+};
+
+
+/**
+ * For each of the effect's uniform parameters, if it is a SAS parameter
+ * creates corresponding StandardParamMatrix4 parameters on the given
+ * ParamObject. Note that SAS parameters are handled automatically by the
+ * rendering system. so except in some rare cases there is no reason to call
+ * this function. Also be aware that the StandardParamMatrix4 Paramters like
+ * WorldViewProjectionParamMatrix4, etc.. are only valid during rendering.
+ * At all other times they will not return valid values.
+ *
+ * If a Param with the same name but the wrong type already exists on the
+ * given ParamObject CreateSASParameters will attempt to replace it with
+ * one of the correct type.
+ *
+ * @param {!o3d.ParamObject} param_object The param object on which the new
+ * paramters will be created.
+ */
+o3d.Effect.prototype.createSASParameters =
+ function(param_object) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Gets info about the parameters this effect needs.
+ * @returns {!Array.<!o3d.EffectParameterInfo>} an array of
+ * EffectParameterInfo objects.
+ */
+o3d.Effect.prototype.getParameterInfo = function() {
+ o3d.notImplemented();
+ return [];
+};
+
+
+/**
+ * Gets info about the streams this effect needs.
+ * @returns {!Array.<!o3d.EffectStreamInfo>} an array of
+ * EffectStreamInfo objects.
+ */
+o3d.Effect.prototype.getStreamInfo = function() {
+ var r = [];
+ // TODO(petersont): This is a stub, will remove later and replace with
+ // something that actually gets its streams from the shader.
+ var standard_semantic_index_pairs = [
+ {semantic: o3d.Stream.POSITION, index: 0},
+ {semantic: o3d.Stream.NORMAL, index: 0},
+ {semantic: o3d.Stream.COLOR, index: 0},
+ {semantic: o3d.Stream.TEXCOORD, index: 0}
+ ];
+
+ for (var i = 0; i < standard_semantic_index_pairs.length; ++i) {
+ var p = standard_semantic_index_pairs[i];
+ r.push(new o3d.EffectStreamInfo(p.semantic, p.index));
+ }
+ return r;
+};
+
+
+/**
+ * Searches the objects in the given list for parameters to apply to the
+ * uniforms defined on this effects program, and applies them, favoring
+ * the objects nearer the begining of the list.
+ *
+ * @param {!Array.<!o3d.ParamObject>} object_list The param objects to search.
+ */
+o3d.Effect.prototype.searchForParams = function(object_list) {
+ var filled_map = {};
+ for (name in this.uniforms) {
+ filled_map[name] = false;
+ }
+ this.gl.useProgram(this.program_);
+ for (var i = 0; i < object_list.length; ++i) {
+ var obj = object_list[i];
+ for (name in this.uniforms) {
+ var uniformInfo = this.uniforms[name];
+ if (filled_map[name]) {
+ continue;
+ }
+ var param = obj.getParam(name);
+ if (param) {
+ param.applyToLocation(this.gl, uniformInfo.location);
+ filled_map[name] = true;
+ }
+ }
+ }
+};
+
+
+/**
+ * @type {number}
+ */
+o3d.Effect.MatrixLoadOrder = goog.typedef;
+
+/**
+ * MatrixLoadOrder,
+ * ROW_MAJOR, Matrix parameters are loaded in row-major order (DX-style).
+ * COLUMN_MAJOR, Matrix parameters are loaded in column-major order
+ * (OpenGL-style).
+ */
+o3d.Effect.ROW_MAJOR = 0;
+o3d.Effect.COLUMN_MAJOR = 1;
+
+
+/**
+ * The order in which matrix data is loaded to the GPU.
+ * @type {o3d.Effect.MatrixLoadOrder}
+ */
+o3d.Effect.prototype.matrix_load_order_ = o3d.Effect.ROW_MAJOR;
+
+
+/**
+ * The source for the shaders on this Effect.
+ * @type {string}
+ */
+o3d.Effect.prototype.source_ = '';
+
+
diff --git a/o3d/samples/o3d-webgl/element.js b/o3d/samples/o3d-webgl/element.js
new file mode 100644
index 0000000..8a953a8
--- /dev/null
+++ b/o3d/samples/o3d-webgl/element.js
@@ -0,0 +1,214 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * An Element manages DrawElements for classes inherited from Element.
+ *
+ * @param {!o3d.Material} opt_material The Material used by this Element.
+ * @param {!o3d.BoundingBox} opt_boundingBox The BoundingBox used by this
+ * Element for culling.
+ * @param {!o3d.Point3} opt_zSortPoint The point to sort by when rendering
+ * this Element in a z ordered DrawPass.
+ * @param {boolean} opt_cull Whether or not to attempt to cull this
+ * Element based on whether or not its bounding box is in the view
+ * frustum.
+ * @constructor
+ */
+o3d.Element =
+ function(opt_material, opt_boundingBox, opt_zSortPoint, opt_cull) {
+ o3d.ParamObject.call(this);
+ this.material = opt_material;
+ this.boundingBox = opt_boundingBox ||
+ new o3d.BoundingBox([-1, -1, -1], [1, 1, 1]);
+ this.zSortPoint = opt_zSortPoint || [0, 0, 0];
+ this.cull = opt_cull || false;
+ this.drawElements = [];
+};
+o3d.inherit('Element', 'ParamObject');
+
+
+/**
+ * The Material for this element.
+ * @type {o3d.Material}
+ */
+o3d.Element.prototype.material = null;
+
+
+
+/**
+ * The BoundingBox for this element. If culling is on this bounding box will be
+ * tested against the view frustum of any draw context used to render this
+ * Element.
+ * @type {o3d.BoundingBox}
+ */
+o3d.Element.prototype.boundingBox = null;
+
+
+
+/**
+ * The z sort point for this element. If this Element is drawn by a DrawPass
+ * that is set to sort by z order this value will be multiplied by the
+ * worldViewProjection matrix to compute a z value to sort by.
+ * @type {o3d.Point3}
+ */
+o3d.Element.prototype.zSortPoint = [0, 0, 0];
+
+
+
+/**
+ * The priority for this element. Used to sort if this Element is drawn by a
+ * DrawPass that is set to sort by priority.
+ * @type {number}
+ */
+o3d.Element.prototype.priority = 0;
+
+
+
+/**
+ * The cull settings for this element. If true this Element will be culled
+ * by the bounding box above compared to the view frustum it is being rendered
+ * with.
+ *
+ * @type {boolean}
+ */
+o3d.Element.prototype.cull = false;
+
+
+
+/**
+ * The current owner of this Draw Element. Pass in null to stop being owned.
+ *
+ * Note: Elements are referenced by the Pack they are created in and their
+ * owner. If the Element is removed from its Pack, then setting the owner
+ * to null will free the Element. Or, visa versa, if you set the
+ * Element's owner to null then removing it from its Pack will free the
+ * Element.
+ *
+ * @type {o3d.Element}
+ */
+o3d.Element.prototype.owner_ = null;
+
+o3d.Element.prototype.__defineSetter__('owner',
+ function(o) {
+ this.owner_ = o;
+ o.addElement(this);
+ }
+);
+
+o3d.Element.prototype.__defineGetter__('owner',
+ function(o) {
+ return this.owner_;
+ }
+);
+
+
+
+/**
+ * Gets all the DrawElements under this Element.
+ *
+ * Each access to this field gets the entire list so it is best to get it
+ * just once. For example:
+ *
+ * var drawElements = element.drawElements;
+ * for (var i = 0; i < drawElements.length; i++) {
+ * var drawElement = drawElements[i];
+ * }
+ *
+ *
+ * Note that modifications to this array [e.g. push()] will not affect
+ * the underlying Element, while modifications to the members of the array.
+ * will affect them.
+ *
+ * @type {!Array.<!o3d.DrawElement>}
+ */
+o3d.Element.prototype.drawElements = [];
+
+
+
+/**
+ * Creates a DrawElement for this Element. Note that unlike
+ * Shape.createDrawElements and Transform.createDrawElements this one will
+ * create more than one element for the same material.
+ *
+ * @param {!o3d.Pack} pack pack used to manage created DrawElement.
+ * @param {!o3d.Material} material material to use for DrawElement. If you
+ * pass null it will use the material on this Element. This allows you
+ * to easily setup the default (just draw as is) by passing null or
+ * setup a shadow pass by passing in a shadow material.
+ * @returns {!o3d.DrawElement} The created draw element.
+ */
+o3d.Element.prototype.createDrawElement =
+ function(pack, material) {
+ drawElement = new o3d.DrawElement();
+ drawElement.owner = this;
+ drawElement.material = material || this.material;
+ this.drawElements.push(drawElement);
+ return drawElement;
+};
+
+
+/**
+ * Computes the intersection of a ray in the same coordinate system as
+ * the specified POSITION stream.
+ * @param {number} position_stream_index Index of POSITION stream.
+ * @param {o3d.Cull} cull which side of the triangles to ignore.
+ * @param {!o3d.math.Point3} start position of start of ray in local space.
+ * @param {!o3d.math.Point3} end position of end of ray. in local space.
+ * @returns {!o3d.RayIntersectionInfo} RayIntersectionInfo class. If valid()
+ * is false then something was wrong, Check GetLastError(). If
+ * intersected() is true then the ray intersected a something. position()
+ * is the exact point of intersection.
+ */
+o3d.Element.prototype.intersectRay =
+ function(position_stream_index, cull, start, end) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Computes the bounding box in same coordinate system as the specified
+ * POSITION stream.
+ * @param {number} position_stream_index Index of POSITION stream.
+ * @returns {!o3d.BoundingBox} The boundingbox for this element in local space.
+ */
+o3d.Element.prototype.getBoundingBox =
+ function(position_stream_index) {
+ return this.boundingBox;
+};
+
+
+/**
+ * Virtual function that renders the element.
+ */
+o3d.Element.prototype.render = function() { };
+
+
diff --git a/o3d/samples/o3d-webgl/event.js b/o3d/samples/o3d-webgl/event.js
new file mode 100644
index 0000000..91bfcbd
--- /dev/null
+++ b/o3d/samples/o3d-webgl/event.js
@@ -0,0 +1,260 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * An Event object contains information describing a JavaScript event; it's used
+ * as an argument to event handlers triggered by the plugin.
+ * @constructor
+ */
+o3d.Event = function() { };
+o3d.inherit('Event', 'ObjectBase');
+
+
+/**
+ * @type {number}
+ */
+o3d.Event.Type = goog.typedef;
+
+/**
+ * String identifiers for JavaScript events.
+ * type
+ * invalid
+ * click
+ * dblclick
+ * mousedown
+ * mousemove
+ * mouseup
+ * wheel
+ * keydown
+ * keypress
+ * keyup
+ * resize
+ */
+o3d.Event.TYPE_INVALID = 0;
+o3d.Event.TYPE_CLICK = 1;
+o3d.Event.TYPE_DBLCLICK = 2;
+o3d.Event.TYPE_MOUSEDOWN = 3;
+o3d.Event.TYPE_MOUSEMOVE = 4;
+o3d.Event.TYPE_MOUSEUP = 5;
+o3d.Event.TYPE_WHEEL = 6;
+o3d.Event.TYPE_KEYDOWN = 7;
+o3d.Event.TYPE_KEYPRESS = 8;
+o3d.Event.TYPE_KEYUP = 9;
+o3d.Event.TYPE_RESIZE = 10;
+
+/**
+ * The type of event this object represents.
+ * @type {o3d.Event.Type}
+ */
+o3d.Event.prototype.type = o3d.Event.TYPE_INVALID;
+
+
+/**
+ * @type {number}
+ */
+o3d.Event.Button = goog.typedef;
+
+/**
+ * Constants used to identify mouse buttons.
+ */
+o3d.Event.BUTTON_LEFT = 0;
+o3d.Event.BUTTON_MIDDLE = 1;
+o3d.Event.BUTTON_RIGHT = 2;
+o3d.Event.BUTTON_4 = 3;
+o3d.Event.BUTTON_5 = 4;
+
+
+
+/**
+ * Which mouse button caused the event, in the case of mousedown, mouseup,
+ * click, and dblclick events. This uses the values in enum Button.
+ */
+o3d.Event.prototype.button = o3d.Event.BUTTON_LEFT;
+
+
+
+/**
+ * Whether the ctrl key was pressed at the time of the event.
+ * @type {boolean}
+ */
+o3d.Event.prototype.ctrl_key = false;
+
+
+
+/**
+ * Whether the alt [option, on OSX] key was pressed at the time of the event.
+ * @type {boolean}
+ */
+o3d.Event.prototype.alt_key = false;
+
+
+
+/**
+ * Whether the shift key was pressed at the time of the event.
+ * @type {boolean}
+ */
+o3d.Event.prototype.shift_key = false;
+
+
+
+/**
+ * Whether the meta [command, on OSX] key was pressed at the time of the event.
+ * @type {boolean}
+ */
+o3d.Event.prototype.meta_key = false;
+
+
+
+/**
+ * The key code of the key pressed or released.
+ * @type {number}
+ */
+o3d.Event.prototype.key_code = 0;
+
+
+
+/**
+ * The character created by a keypress event.
+ * @type {number}
+ */
+o3d.Event.prototype.char_code = 0;
+
+
+
+/**
+ * The x-coordinate in pixels from the left side of the plugin or fullscreen
+ * display region.
+ * @type {number}
+ */
+o3d.Event.prototype.x = 0;
+
+
+
+/**
+ * The y-coordinate in pixels from the top of the plugin or fullscreen
+ * display region.
+ * @type {number}
+ */
+o3d.Event.prototype.y = 0;
+
+
+
+/**
+ * The x-coordinate in pixels from the left side of the screen.
+ * @type {number}
+ */
+o3d.Event.prototype.screenX = 0;
+
+
+
+/**
+ * The y-coordinate in pixels from the top of the screen.
+ * @type {number}
+ */
+o3d.Event.prototype.screenY = 0;
+
+
+
+/**
+ * The horizontal scroll offset for wheel events, in arbitrary units.
+ * Positive values mean right; negative mean left.
+ * @type {number}
+ */
+o3d.Event.prototype.deltaX = 0;
+
+
+
+/**
+ * The vertical scroll offset for wheel events, in arbitrary units.
+ * Positive values mean up or away from the user; negative mean down or toward
+ * the user.
+ * @type {number}
+ */
+o3d.Event.prototype.deltaY = 0;
+
+
+
+/**
+ * The width in pixels of the plugin or fullscreen display region as a result
+ * of this event.
+ * @type {number}
+ */
+o3d.Event.prototype.width = 0;
+
+
+
+/**
+ * The height in pixels of the plugin or fullscreen display region as a result
+ * of this event.
+ * @type {number}
+ */
+o3d.Event.prototype.height = 0;
+
+
+
+/**
+ * Whether we're currently displaying in fullscreen mode.
+ * @type {boolean}
+ */
+o3d.Event.prototype.fullscreen = false;
+
+
+
+/**
+ * An Event that gets sent to the render callback.
+ * @constructor
+ */
+o3d.RenderEvent = function() {};
+o3d.inherit('RenderEvent', 'Event');
+
+
+/**
+ * Time in seconds since the last time the client rendered.
+ * @type {number}
+ */
+o3d.RenderEvent.prototype.elapsedTime = 0;
+
+
+/**
+ * An Event that gets sent to the render callback.
+ * @constructor
+ */
+o3d.TickEvent = function() {};
+o3d.inherit('RenderEvent', 'Event');
+
+
+/**
+ * Time in seconds since the last time the client rendered.
+ * @type {number}
+ */
+o3d.TickEvent.prototype.elapsedTime = 0;
+
diff --git a/o3d/samples/o3d-webgl/field.js b/o3d/samples/o3d-webgl/field.js
new file mode 100644
index 0000000..5f82237
--- /dev/null
+++ b/o3d/samples/o3d-webgl/field.js
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * A Field is a base class that manages a set of components in a
+ * Buffer of a specific type. Fields are managed by Buffers and can not be
+ * directly created. When a Buffer is destroyed or if a Field is removed from a
+ * Buffer the Field's buffer property will be set to null.
+ * @constructor
+ */
+o3d.Field = function() { };
+o3d.inherit('Field', 'NamedObject');
+
+/**
+ * The number of components in this field.
+ * @type {number}
+ */
+o3d.Field.prototype.numComponents = 0;
+
+
+/**
+ * The Buffer the field belongs to.
+ * @type {o3d.Buffer}
+ */
+o3d.Field.prototype.buffer = null;
+
+
+/**
+ * The offset of this field in the Buffer.
+ * @type {number}
+ */
+o3d.Field.prototype.offset_ = 0;
+
+
+/**
+ * The size of one element of this field.
+ * @type {number}
+ */
+o3d.Field.prototype.size = 0;
+
+
+/**
+ * Sets the values of the data stored in the field.
+ *
+ * The buffer for the field must have already been created either through
+ * buffer.set or through buffer.allocateElements.
+ *
+ * The number of values passed in must be a multiple of the number of
+ * components needed for the field.
+ *
+ * @param {number} start_index index of first value to set.
+ * @param {number} values Values to be stored in the buffer starting at index.
+ */
+o3d.Field.prototype.setAt =
+ function(start_index, values) {
+ this.buffer.lock();
+ var l = values.length / this.numComponents;
+ for (var i = 0; i < l; i++) {
+ for (var c = 0; c < this.numComponents; ++c) {
+ this.buffer.array_[
+ (start_index + i) * this.buffer.totalComponents + this.offset_ + c] =
+ values[this.numComponents * i + c];
+ }
+ }
+ this.buffer.unlock();
+ return true;
+};
+
+
+/**
+ * Gets the values stored in the field.
+ *
+ * @param {number} start_index index of the first value to get.
+ * @param {number} num_elements number of elements to read from field.
+ * @returns {number} The values of the field.
+ */
+o3d.Field.prototype.getAt =
+ function(start_index, num_elements) {
+ o3d.notImplemented();
+};
+
+
+
+/**
+ * A field that contains floating point numbers.
+ * @constructor
+ */
+o3d.FloatField = function() { };
+o3d.inherit('FloatField', 'Field');
+
+/**
+ * A field that contains unsigned integers.
+ * @constructor
+ */
+o3d.UInt32Field = function() { };
+o3d.inherit('UInt32Field', 'Field');
+
+/**
+ * A field that contains unsigned bytes.
+ * @constructor
+ */
+o3d.UByteNField = function() { };
+o3d.inherit('UByteNField', 'Field');
+
+
diff --git a/o3d/samples/o3d-webgl/file_request.js b/o3d/samples/o3d-webgl/file_request.js
new file mode 100644
index 0000000..122364a
--- /dev/null
+++ b/o3d/samples/o3d-webgl/file_request.js
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * A FileRequest is used to carry out an asynchronous request for a file
+ * to be loaded. Its use parallels that of XMLHttpRequest; you create one, call
+ * open, set the onreadystatechange callback, and call send.
+ * Note that unlike XMLHttpRequests, FileRequests cannot be reused.
+ *
+ * For RawData loads, on success the RawData will be stored in the data field
+ * on the FileRequest itself. It is only valid until the FileRequest is freed by
+ * calling pack.removeObject(request).
+ *
+ * var request = pack.createFileRequest("RAWDATA");
+ * request.open("GET", url, true);
+ * request.onreadystatechange = function() {
+ * if (request.done) {
+ * if (request.success) {
+ * var rawData = request.data;
+ *
+ * ...
+ * } else {
+ * dump('Load of rawdata returned failure.');
+ * }
+ *
+ * pack.removeObject(request);
+ * }
+ * };
+ * request.send();
+ */
+o3d.FileRequest = function() {
+ this.request_ = new XMLHttpRequest();
+ var fileRequest = this;
+ this.request_.onreadystatechange = function() {
+ fileRequest.readyState = this.readyState;
+ fileRequest.done = fileRequest.done || this.done;
+ if (this.readyState == 4) {
+ if (this.responseText) {
+ fileRequest.success = true;
+ }
+ fileRequest.done = true;
+ }
+ fileRequest.data = this.responseText;
+ if (fileRequest.onreadystatechange)
+ fileRequest.onreadystatechange.apply(fileRequest, arguments);
+ }
+};
+o3d.inherit('FileRequest', 'NamedObject');
+
+
+/**
+ * A callback to call whenever the ready state of the request changes.
+ * @type {Object}
+ */
+o3d.FileRequest.prototype.onreadystatechange = null;
+
+
+
+/**
+ * The URI this request is for.
+ * @type {string}
+ */
+o3d.FileRequest.prototype.uri = '';
+
+
+
+/**
+ * On completion of successful RawData file loads, this holds the loaded
+ * RawData.
+ * @type {o3d.RawData}
+ */
+o3d.FileRequest.prototype.data = null;
+
+
+
+/**
+ * This holds the same values as in XMLHttpRequest:
+ * 0 = uninitialized
+ * 1 = opened
+ * 2 = sent
+ * 3 = receiving
+ * 4 = loaded (the file has been downloaded, but may or may not have been
+ * parsed yet)
+ * @type {number}
+ */
+o3d.FileRequest.prototype.readyState = 0;
+
+
+
+/**
+ * This indicates whether any further processing will be done on this
+ * FileRequest.
+ * @type {boolean}
+ */
+o3d.FileRequest.prototype.done = false;
+
+
+
+/**
+ * This field is only valid if done is true. It indicates whether or not the
+ * request succeeded. If it failed error holds an error message.
+ * @type {boolean}
+ */
+o3d.FileRequest.prototype.success = false;
+
+
+
+/**
+ * An error message.
+ * If done is true and success is false this will be an error message
+ * describing what went wrong.
+ * @type {string}
+ */
+o3d.FileRequest.prototype.error = '';
+
+
+
+/**
+ * Set up several of the request fields.
+ * @param {string} method "GET" is the only supported method at this time
+ * @param {string} uri the location of the file to fetch
+ * @param {boolean} async true is the only legal value at this time
+ */
+o3d.FileRequest.prototype.open =
+ function(method, uri, async) {
+ this.uri = uri;
+ this.request_.open(method, uri, async);
+};
+
+
+/**
+ * Send the request.
+ * Unlike XMLHttpRequest the onreadystatechange callback will be called no
+ * matter what, with success or failure.
+ */
+o3d.FileRequest.prototype.send = function() {
+ this.request_.send();
+};
+
+
+
diff --git a/o3d/samples/o3d-webgl/material.js b/o3d/samples/o3d-webgl/material.js
new file mode 100644
index 0000000..a7d6d3f
--- /dev/null
+++ b/o3d/samples/o3d-webgl/material.js
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * A Material holds the various uniform parameters an Effect needs to render.
+ * For example a Lambert effect might need "diffuse", "ambient", "emissive".
+ * The parameters needed on a Material will vary depending its Effect.
+ * Note that a material MUST have its drawList set in order for objects using it
+ * to render.
+ *
+ * @param {!o3d.State} opt_state The State used by this material.
+ * @param {!o3d.Effect} opt_effect The Effect used by this material.
+ * @param {!o3d.DrawList} opt_draw_list The the DrawList used by this material.
+ * @constructor
+ */
+o3d.Material = function(opt_state, opt_effect, opt_draw_list) {
+ o3d.ParamObject.call(this);
+ this.state = opt_state;
+ this.effect = opt_effect;
+ this.drawList = opt_draw_list;
+};
+o3d.inherit('Material', 'ParamObject');
+
+
+/**
+ * The Effect for this material.
+ * @type {o3d.Effect}
+ */
+o3d.Material.prototype.effect = null;
+
+
+
+/**
+ * The State for this material.
+ * @type {o3d.State}
+ */
+o3d.Material.prototype.state = null;
+
+
+
+/**
+ * The DrawList this material will render on.
+ * @type {o3d.DrawList}
+ */
+o3d.Material.prototype.drawList = null;
+
+
+
diff --git a/o3d/samples/o3d-webgl/named_object.js b/o3d/samples/o3d-webgl/named_object.js
new file mode 100644
index 0000000..ce6c871
--- /dev/null
+++ b/o3d/samples/o3d-webgl/named_object.js
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * Takes the name of a class as an argument, and returns true if this object is
+ * either an instance of that class or derives from that class.
+ *
+ * var t = pack.createObject('o3d.Transform');
+ * t.isAClassName('o3d.Transform');
+ * t.isAClassName('o3d.ParamObject');
+ * t.isAClassName('o3d.Shape');
+ *
+ * @param {o3d.String} class_name Name of class to check for.
+ * @returns {o3d.bool} true if this object is a or is derived from the given
+ * class name.
+ */
+o3d.ObjectBase.prototype.isAClassName =
+ function(class_name) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Base class for all objects that can have their name set.
+ * @constructor
+ */
+o3d.NamedObject = function() { };
+o3d.inherit('NamedObject', 'NamedObjectBase');
+
+
+/**
+ * The object's name.
+ *
+ * Setting this has no meaning to O3D, but is useful for debugging and for
+ * the functions Client.getObjects, Pack.getObject,
+ * RenderNode.getRenderNodesByNameInTree and
+ * RenderNode.getTransformsByNameInTree
+ * which search for objects by name.
+ * @type {string}
+ */
+o3d.NamedObject.prototype.name = '';
+
+
diff --git a/o3d/samples/o3d-webgl/named_object_base.js b/o3d/samples/o3d-webgl/named_object_base.js
new file mode 100644
index 0000000..5176426
--- /dev/null
+++ b/o3d/samples/o3d-webgl/named_object_base.js
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * Base class for all objects that are identifiable by a name.
+ * @constructor
+ */
+o3d.NamedObjectBase = function() { };
+o3d.inherit('NamedObjectBase', 'ObjectBase');
+
+
+/**
+ * The object's name.
+ * @type {string}
+ */
+o3d.NamedObjectBase.prototype.name = "";
+
+
diff --git a/o3d/samples/o3d-webgl/object_base.js b/o3d/samples/o3d-webgl/object_base.js
new file mode 100644
index 0000000..42931eb
--- /dev/null
+++ b/o3d/samples/o3d-webgl/object_base.js
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * A ObjectBase is a base class that manages a set of components in a
+ * Buffer of a specific type. ObjectBases are managed by Buffers and can
+ * not be directly created. When a Buffer is destroyed or if a ObjectBase
+ * is removed from a Buffer the ObjectBase's buffer property will be set
+ * to null.
+ */
+o3d.ObjectBase = function() { };
+
+
+/**
+ * Used by isAClassName.
+ * @type {string}
+ */
+o3d.ObjectBase.prototype.className = 'o3d.ObjectBase';
+
+/**
+ * @type {o3d.ObjectBase}
+ */
+o3d.ObjectBase.prototype.superClass = null;
+
+/**
+ * Traverses the current object's class and all its superclasses and
+ * determines if any of them are of the given name.
+ * returns {bool}
+ */
+o3d.ObjectBase.isAClassName = function(o, className) {
+ while (o != undefined) {
+ if (o.className == 'className') {
+ return true;
+ }
+ o = o.superClass.prototype;
+ }
+ return false;
+};
+
+
diff --git a/o3d/samples/o3d-webgl/pack.js b/o3d/samples/o3d-webgl/pack.js
new file mode 100644
index 0000000..fc10e49
--- /dev/null
+++ b/o3d/samples/o3d-webgl/pack.js
@@ -0,0 +1,348 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * A Pack object functions as a container for O3D objects. The Pack
+ * is used to control the lifetime scope of a collection of objects in bulk. The
+ * Pack object achieves this by simply storing a set of references to its
+ * contained objects, which ensures that the ref-counts for those objects never
+ * reach zero while the pack is alive.
+ * @constructor
+ */
+o3d.Pack = function() {
+ this.objects_ = [];
+};
+o3d.inherit('Pack', 'NamedObject');
+
+
+/**
+ * Removes all internal references to the Pack from the client.
+ * The pack, and all objects contained in it are permitted to be destroyed
+ * after the pack's destruction. Objects will only be destroyed after all
+ * references to them have been removed.
+ *
+ * NOTE: Calling pack.destroy does NOT free your resources. It justs releases
+ * the pack's reference to those resources. An example should hopefully make
+ * it clearer.
+ *
+ * pack.destroy() is effectively almost the same as this.
+ *
+ * var objectsInPack = pack.getObjectsByClassName('o3d.ObjectBase');
+ * for (var ii = 0; ii < objectsInPack.length; ++ii) {
+ * pack.removeObject(objectsInPack[ii]);
+ * }
+ *
+ * The only difference is that after all the objects are removed the pack
+ * itself will be released from the client. See documentation on
+ * pack.removeObject for why this is important.
+ *
+ * It's important to note that many objects are only referenced by the pack.
+ * Textures, Effects, Materials, for example. That means the moment you call
+ * pack.destroy() those objects will be freed. If the client then tries to
+ * render and some objects are missing you'll immediately get an error.
+ */
+o3d.Pack.prototype.destroy = function() {
+ this.objects_ = [];
+};
+
+
+
+/**
+ * Removes a pack's reference to an object. Any object created from
+ * pack.create___ function can be removed. This releases the pack's reference
+ * to that object so if nothing else is referencing that object it will be
+ * deleted.
+ *
+ * NOTE: Calling pack.removeObject does NOT automatically free your resource.
+ * It just releases the pack's reference to that resource. An example should
+ * hopefully make it clearer.
+ *
+ * Suppose you make a transform like this:
+ *
+ *
+ * var myTransform = pack.createObject('Transform');
+ * myTransform.parent = g_client.root;
+ * pack.removeObject(myTransform);
+ *
+ *
+ * In the code above, myTransform is referenced twice. Once by the pack, and
+ * again by g_client.root So in this case, calling pack.removeObject()
+ * only releases the pack's reference leaving the reference by g_client.root.
+ *
+ *
+ * myTransform.parent = null;
+ *
+ *
+ * Now the last reference has been removed and myTransform will be freed.
+ *
+ * @param {o3d.ObjectBase} object Object to remove.
+ * @returns {boolean} True if the object was successfully removed.
+ * False if the object is not part of this pack.
+ */
+o3d.Pack.prototype.removeObject =
+ function(object) {
+ var i = 0;
+ for (var j = 0; j < this.objects_.length; ++j) {
+ if (this.objects_[i] == object) {
+ j++;
+ }
+ this.objects_[j] = this.objects_[i];
+ i++;
+ }
+ if (this.objects_.length > i) {
+ this.objects_.pop();
+ }
+};
+
+
+/**
+ * Creates an Object by Class name.
+ *
+ * Note: You may omit the 'o3d.'.
+ *
+ * @param {string} type_name name of Class to create. Valid type names are:
+ * Bitmap
+ * Canvas
+ * CanvasLinearGradient
+ * CanvasPaint
+ * ClearBuffer
+ * Counter
+ * Curve
+ * DrawContext
+ * DrawElement
+ * DrawList
+ * DrawPass
+ * Effect
+ * FunctionEval
+ * IndexBuffer
+ * Material
+ * ParamArray
+ * ParamObject
+ * Primitive
+ * RenderFrameCounter
+ * RenderNode
+ * RenderSurfaceSet
+ * Sampler
+ * SecondCounter
+ * Shape
+ * Skin
+ * SkinEval
+ * SourceBuffer
+ * State
+ * StateSet
+ * StreamBank
+ * Texture2D
+ * TextureCUBE
+ * TickCounter
+ * Transform
+ * TreeTraversal
+ * VertexBuffer
+ * Viewport
+ * Matrix4AxisRotation
+ * Matrix4Composition
+ * Matrix4Scale
+ * Matrix4Translation
+ * ParamOp2FloatsToFloat2
+ * ParamOp3FloatsToFloat3
+ * ParamOp4FloatsToFloat4
+ * ParamOp16FloatsToMatrix4
+ * TRSToMatrix4
+ * @returns {o3d.ObjectBase} The created object.
+ */
+o3d.Pack.prototype.createObject =
+ function(type_name) {
+ var foo = o3d.global.o3d[type_name];
+ if (typeof foo != 'function') {
+ throw 'cannot find type in o3d namespace: ' + type_name
+ }
+ var object = new foo();
+ object.gl = this.gl;
+ return object;
+};
+
+
+/**
+ * Creates a new Texture2D object of the specified size and format and
+ * reserves the necessary resources for it.
+ *
+ * Note: If enable_render_surfaces is true, then the dimensions must be a
+ * power of two.
+ *
+ * @param {number} width The width of the texture area in texels (max = 2048)
+ * @param {number} height The height of the texture area in texels (max = 2048)
+ * @param {o3d.Texture.Format} format The memory format of each texel
+ * @param {number} levels The number of mipmap levels. Use zero to create the
+ * compelete mipmap chain.
+ * @param {boolean} enable_render_surfaces If true, the texture object will
+ * expose RenderSurface objects through GetRenderSurface(...).
+ * @returns {!o3d.Texture2D} The Texture2D object.
+ */
+o3d.Pack.prototype.createTexture2D =
+ function(width, height, format, levels, enable_render_surfaces) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Creates a new TextureCUBE object of the specified size and format and
+ * reserves the necessary resources for it.
+ * Note: If enable_render_surfaces is true, then the dimensions must be a
+ * power of two.
+ *
+ * @param {number} edge_length The edge of the texture area in texels
+ * (max = 2048)
+ * @param {o3d.Texture.Format} format The memory format of each texel.
+ * @param {number} levels The number of mipmap levels. Use zero to create
+ * the compelete mipmap chain.
+ * @param {boolean} enable_render_surfaces If true, the texture object
+ * will expose RenderSurface objects through GetRenderSurface(...).
+ * @returns {!o3d.TextureCUBE} The TextureCUBE object.
+ */
+o3d.Pack.prototype.createTextureCUBE =
+ function(edge_length, format, levels, enable_render_surfaces) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Creates a new RenderDepthStencilSurface object of a format suitable for use
+ * as a depth-stencil render target.
+ * Note: The dimensions of the RenderDepthStencilSurface must be a power of
+ * two.
+ *
+ * @param {number} width The width of the RenderSurface in pixels
+ * @param {number} height The height of the RenderSurface in pixels
+ * @returns {!o3d.RenderDepthStencilSurface} The RenderSurface object.
+ */
+o3d.Pack.prototype.createDepthStencilSurface =
+ function(width, height) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Search the pack for all objects of a certain class with a certain name.
+ *
+ * Note that modifications to this array [e.g. push()] will not affect
+ * the underlying Pack, while modifications to the array's members
+ * will affect them.
+ *
+ * @param {string} name Name to look for
+ * @param {string} class_type_name the Class of the object. It is okay
+ * to pass base types for example "o3d.RenderNode" will return
+ * ClearBuffers, DrawPasses, etc...
+ * @returns {!Array.<!o3d.ObjectBase>} Array of Objects.
+ */
+o3d.Pack.prototype.getObjects =
+ function(name, class_type_name) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Search the pack for all objects of a certain class
+ *
+ * Note that modifications to this array [e.g. push()] will not affect
+ * the underlying Pack, while modifications to the array's members
+ * will affect them.
+ *
+ * @param {string} class_type_name the Class of the object. It is
+ * okay to pass base types for example "o3d.RenderNode" will return
+ * ClearBuffers, DrawPasses, etc...
+ * @returns {!Array.<!o3d.ObjectBase>} Array of Objects.
+ */
+o3d.Pack.prototype.getObjectsByClassName =
+ function(class_type_name) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * All the objects managed by this pack.
+ *
+ * Each access to this field gets the entire list so it is best to get it
+ * just once. For example:
+ *
+ * var objects = pack.objects;
+ * for (var i = 0; i < objects.length; i++) {
+ * var object = objects[i];
+ * }
+ *
+ *
+ * Note that modifications to this array [e.g. push()] will not affect
+ * the underlying Pack, while modifications to the array's members
+ * will affect them.
+ */
+o3d.Pack.prototype.objects_ = [];
+
+
+/**
+ * Creates a FileRequest to be used to asynchronously load a Texture or
+ * RawData. Note: Loading a "TEXTURE" is deprecated. The recommended way to
+ * load a texture is to load a RawData, use that to create Bitmap, Massage
+ * the Bitmap to your liking the use that to create a Texture.
+ * @param {string} type Must be "TEXTURE" or "RAWDATA"
+ * @returns {!o3d.FileRequest} a FileRequest
+ */
+o3d.Pack.prototype.createFileRequest =
+ function(type) {
+ return this.createObject('FileRequest');
+};
+
+
+/**
+ * Create Bitmaps from RawData.
+ *
+ * If you load a cube map you'll get an array of 6 Bitmaps.
+ * If you load a volume map you'll get an array of n Bitmaps.
+ * If there is an error you'll get an empty array.
+ *
+ * @param {!o3d.RawData} raw_data contains the bitmap data in a supported
+ * format.
+ * @returns {!o3d.Bitmap} An Array of Bitmaps object.
+ */
+o3d.Pack.prototype.createBitmapsFromRawData =
+ function(raw_data) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Create RawData given a data URL.
+ * @param {string} data_url The data URL from which to create the RawData.
+ * @returns {!o3d.RawData} The RawData.
+ */
+o3d.Pack.prototype.createRawDataFromDataURL =
+ function(data_url) {
+ o3d.notImplemented();
+};
+
diff --git a/o3d/samples/o3d-webgl/param.js b/o3d/samples/o3d-webgl/param.js
new file mode 100644
index 0000000..0bb28fe
--- /dev/null
+++ b/o3d/samples/o3d-webgl/param.js
@@ -0,0 +1,829 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * Params store data defined name/value pairs on ParamObjects.
+ * Each Param has a name, a type and a value that can be set and queried.
+ * One of their uses is to hold "uniform constants" used to parameterize
+ * shaders. Params can be connected in a source/destination fashion such
+ * that a target Param gets its value from the source param.
+ * @constructor
+ */
+o3d.Param = function(param_type_name) {
+ o3d.Param.prototype.output_connections = [];
+ this.outputConnections = [];
+}
+o3d.inherit('Param', 'NamedObject');
+
+
+/**
+ * If true, this param will make sure its input param is up to date when
+ * using it as a source. Default = true.
+ *
+ * This is for helping with Param cycles.
+ *
+ * If paramA gets its value from paramB and paramB gets its value from
+ * paramA:
+ * If you go paramA.value, paramB will evaluate then copy to paramA.
+ * If you go paramB.value, paramA will evaluate then copy to paramB.
+ * If you set paramB.updateInput = false, then:
+ * If you go paramA.value, paramB will evaluate then copy to paramA.
+ * If you go paramB.value, paramB just copy paramA. paramA will NOT evaluate
+ * when paramB asks for its value.
+ */
+o3d.Param.prototype.update_input = true;
+
+/**
+ * @type {o3d.Param}
+ */
+o3d.Param.prototype.inputConnection = null;
+
+/**
+ * @type {Array.<!o3d.Param>}
+ */
+o3d.Param.prototype.outputConnections = [];
+
+
+/**
+ * @type {o3d.ParamObject}
+ */
+o3d.Param.prototype.owner_ = null;
+
+/**
+ * Directly binds two Param elements such that this parameter gets its value
+ * from the source parameter. The source must be compatible with this
+ * parameter.
+ *
+ * @param {o3d.Param} source_param The parameter that the value originates
+ * from. Passing in null will unbind any parameter currently bound.
+ * @returns {boolean} True if the bind succeeded.
+ */
+o3d.Param.prototype.bind =
+ function(source_param) {
+ source_param.outputConnections.push(this);
+ this.inputConnection = source_param;
+};
+
+
+/**
+ * Breaks any input connection coming into the Param.
+ */
+o3d.Param.prototype.unbindInput =
+ function() {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Breaks a specific param-bind output connection on this param.
+ *
+ * @param {o3d.Param} destination_param param to unbind.
+ */
+o3d.Param.prototype.unbindOutput =
+ function(destination_param) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Breaks all param-bind output connections on this param.
+ */
+o3d.Param.prototype.unbindOutputs = function() {
+ o3d.notImplemented();
+};
+
+
+
+/**
+ * If true the param is read only. Its value can not be set nor can it be used
+ * as the destination in a ParamBind.
+ */
+o3d.Param.prototype.read_only_ = false;
+
+
+
+/**
+ * The input connection for this param.
+ */
+o3d.Param.prototype.input_connection = null;
+
+
+
+/**
+ * The output connections for this param.
+ */
+o3d.Param.prototype.output_connections = [];
+
+
+/**
+ * @constructor
+ */
+o3d.ParamBoolean = function() {
+ o3d.Param.call(this);
+ this.value = false;
+};
+o3d.inherit('ParamBoolean', 'Param');
+
+
+/**
+ * @constructor
+ */
+o3d.ParamBoundingBox = function() {
+ o3d.Param.call(this);
+ this.value = null;
+};
+o3d.inherit('ParamBoundingBox', 'Param');
+
+
+/**
+ * @constructor
+ */
+o3d.ParamDrawContext = function() {
+ o3d.Param.call(this);
+ this.value = null;
+};
+o3d.inherit('ParamDrawContext', 'Param');
+
+
+/**
+ * @constructor
+ */
+o3d.ParamDrawList = function() {
+ o3d.Param.call(this);
+ this.value = null;
+};
+o3d.inherit('ParamDrawList', 'Param');
+
+
+/**
+ * @constructor
+ */
+o3d.ParamEffect = function() {
+ o3d.Param.call(this);
+ this.value = null;
+};
+o3d.inherit('ParamEffect', 'Param');
+
+
+/**
+ * @constructor
+ */
+o3d.ParamFloat = function() {
+ o3d.Param.call(this);
+ this.value = 0.0;
+};
+o3d.inherit('ParamFloat', 'Param');
+
+
+/**
+ * @constructor
+ */
+o3d.ParamFloat2 = function() {
+ o3d.Param.call(this);
+ this.value = [0.0, 0.0];
+};
+o3d.inherit('ParamFloat2', 'Param');
+
+
+/**
+ * @constructor
+ */
+o3d.ParamFloat3 = function() {
+ o3d.Param.call(this);
+ this.value = [0.0, 0.0, 0.0];
+};
+o3d.inherit('ParamFloat3', 'Param');
+
+
+/**
+ * @constructor
+ */
+o3d.ParamFloat4 = function() {
+ o3d.Param.call(this);
+ this.value = [0.0, 0.0, 0.0, 0.0];
+};
+o3d.inherit('ParamFloat4', 'Param');
+
+
+/**
+ * @constructor
+ */
+o3d.ParamFunction = function() {
+ o3d.Param.call(this);
+ this.value = null;
+};
+o3d.inherit('ParamFunction', 'Param');
+
+
+/**
+ * @constructor
+ */
+o3d.ParamInteger = function() {
+ o3d.Param.call(this);
+ this.value = 0;
+};
+o3d.inherit('ParamInteger', 'Param');
+
+
+/**
+ * @constructor
+ */
+o3d.ParamMaterial = function() {
+ o3d.Param.call(this);
+ this.value = null;
+};
+o3d.inherit('ParamMaterial', 'Param');
+
+
+/**
+ * @constructor
+ */
+o3d.ParamMatrix4 = function() {
+ o3d.Param.call(this);
+ this.value = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]];
+};
+o3d.inherit('ParamMatrix4', 'Param');
+
+
+/**
+ * @constructor
+ */
+o3d.ParamParamArray = function() {
+ o3d.Param.call(this);
+ this.value = [];
+};
+o3d.inherit('ParamParamArray', 'Param');
+
+
+/**
+ * @constructor
+ */
+o3d.ParamRenderSurface = function() {
+ o3d.Param.call(this);
+ this.value = null;
+};
+o3d.inherit('ParamRenderSurface', 'Param');
+
+
+/**
+ * @constructor
+ */
+o3d.ParamRenderDepthStencilSurface = function() {
+ o3d.Param.call(this);
+ this.value = null;
+};
+o3d.inherit('ParamRenderDepthStencilSurface', 'Param');
+
+
+/**
+ * @constructor
+ */
+o3d.ParamSampler = function() {
+ o3d.Param.call(this);
+ this.value = null;
+};
+o3d.inherit('ParamSampler', 'Param');
+
+
+/**
+ * @constructor
+ */
+o3d.ParamSkin = function() {
+ o3d.Param.call(this);
+ this.value = null;
+};
+o3d.inherit('ParamSkin', 'Param');
+
+
+/**
+ * @constructor
+ */
+o3d.ParamSteamBank = function() {
+ o3d.Param.call(this);
+ this.value = null;
+};
+o3d.inherit('ParamSteamBank', 'Param');
+
+
+/**
+ * @constructor
+ */
+o3d.ParamState = function() {
+ o3d.Param.call(this);
+ this.value = null;
+};
+o3d.inherit('ParamState', 'Param');
+
+
+/**
+ * @constructor
+ */
+o3d.ParamString = function() {
+ o3d.Param.call(this);
+ this.value = null;
+};
+o3d.inherit('ParamString', 'Param');
+
+
+/**
+ * @constructor
+ */
+o3d.ParamTexture = function() {
+ o3d.Param.call(this);
+ this.value = null;
+};
+o3d.inherit('ParamTexture', 'Param');
+
+
+/**
+ * @constructor
+ */
+o3d.ParamTransform = function() {
+ o3d.Param.call(this);
+ this.value = null;
+};
+o3d.inherit('ParamTransform', 'Param');
+
+
+/**
+ * Base class for the types of matrix4 params that compute their own
+ * value when asked (ProjectionParamMatrix4 etc).
+ * @constructor
+ */
+o3d.CompositionParamMatrix4 = function() {
+ o3d.ParamMatrix4.call(this);
+ this.matrix_names_ = [];
+};
+o3d.inherit('CompositionParamMatrix4', 'ParamMatrix4');
+
+/**
+ * The array of names of matrix params for the matrices that are to be
+ * composed to get the value.
+ * @type {Array.<o3d.ParamMatrix4>}
+ */
+o3d.CompositionParamMatrix4.prototype.matrix_names_ = [];
+
+/**
+ * Whether the inverse is taken right before returning the value.
+ * @type {Array.<o3d.ParamMatrix4>}
+ */
+o3d.CompositionParamMatrix4.prototype.inverse_ = false;
+
+
+/**
+ * Whether the inverse is taken right before returning the value.
+ * @type {Array.<o3d.ParamMatrix4>}
+ */
+o3d.CompositionParamMatrix4.prototype.transpose_ = false;
+
+o3d.CompositionParamMatrix4.prototype.__defineGetter__('value',
+ // TODO(petersont): Cache the result if it hasn't changed.
+ function() {
+ var product = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]];
+ for (var i = 0; i < this.matrix_names_.length; ++i) {
+ o3d.Transform.compose(product, o3d.Param.SAS[this.matrix_names_[i]]);
+ }
+ if (this.inverse_) {
+ o3d.Transform.inverse(product);
+ }
+ if (this.transpose_) {
+ o3d.Transform.transpose(product);
+ }
+ return product;
+ }
+);
+
+o3d.CompositionParamMatrix4.prototype.__defineSetter__('value',
+ function(value) { }
+);
+
+
+/**
+ * @constructor
+ */
+o3d.ProjectionParamMatrix4 = function() {
+ o3d.CompositionParamMatrix4.call(this);
+ this.matrix_names_ = ['projection'];
+};
+o3d.inherit('ProjectionParamMatrix4', 'CompositionParamMatrix4');
+
+
+/**
+ * @constructor
+ */
+o3d.ProjectionInverseParamMatrix4 = function() {
+ o3d.CompositionParamMatrix4.call(this);
+ this.matrix_names_ = ['projection'];
+ this.inverse_ = true;
+};
+o3d.inherit('ProjectionInverseParamMatrix4', 'CompositionParamMatrix4');
+
+
+/**
+ * @constructor
+ */
+o3d.ProjectionTransposeParamMatrix4 = function() {
+ o3d.CompositionParamMatrix4.call(this);
+ this.matrix_names_ = ['projection'];
+ this.transpose_ = true;
+};
+o3d.inherit('ProjectionTransposeParamMatrix4', 'CompositionParamMatrix4');
+
+
+/**
+ * @constructor
+ */
+o3d.ProjectionInverseTransposeParamMatrix4 = function() {
+ o3d.CompositionParamMatrix4.call(this);
+ this.matrix_names_ = ['projection'];
+ this.inverse_ = true;
+ this.transpose_ = true;
+};
+o3d.inherit('ProjectionInverseTransposeParamMatrix4',
+ 'CompositionParamMatrix4');
+
+
+/**
+ * @constructor
+ */
+o3d.ViewParamMatrix4 = function() {
+ o3d.CompositionParamMatrix4.call(this);
+ this.matrix_names_ = ['view'];
+};
+o3d.inherit('ViewParamMatrix4', 'CompositionParamMatrix4');
+
+
+/**
+ * @constructor
+ */
+o3d.ViewInverseParamMatrix4 = function() {
+ o3d.CompositionParamMatrix4.call(this);
+ this.matrix_names_ = ['view'];
+ this.inverse_ = true;
+};
+o3d.inherit('ViewInverseParamMatrix4', 'CompositionParamMatrix4');
+
+
+/**
+ * @constructor
+ */
+o3d.ViewTransposeParamMatrix4 = function() {
+ o3d.CompositionParamMatrix4.call(this);
+ this.matrix_names_ = ['view'];
+ this.transpose_ = true;
+};
+o3d.inherit('ViewTransposeParamMatrix4', 'CompositionParamMatrix4');
+
+
+/**
+ * @constructor
+ */
+o3d.ViewInverseTransposeParamMatrix4 = function() {
+ o3d.CompositionParamMatrix4.call(this);
+ this.matrix_names_ = ['view'];
+ this.inverse_ = true;
+ this.transpose_ = true;
+};
+o3d.inherit('ViewInverseTransposeParamMatrix4', 'CompositionParamMatrix4');
+
+
+/**
+ * @constructor
+ */
+o3d.ViewProjectionParamMatrix4 = function() {
+ o3d.CompositionParamMatrix4.call(this);
+ this.matrix_names_ = ['projection', 'view'];
+};
+o3d.inherit('ViewProjectionParamMatrix4', 'CompositionParamMatrix4');
+
+
+/**
+ * @constructor
+ */
+o3d.ViewProjectionInverseParamMatrix4 = function() {
+ o3d.CompositionParamMatrix4.call(this);
+ this.matrix_names_ = ['projection', 'view'];
+ this.inverse_ = true;
+};
+o3d.inherit('ViewProjectionInverseParamMatrix4', 'CompositionParamMatrix4');
+
+
+/**
+ * @constructor
+ */
+o3d.ViewProjectionTransposeParamMatrix4 = function() {
+ o3d.CompositionParamMatrix4.call(this);
+ this.matrix_names_ = ['projection', 'view'];
+ this.transpose_ = true;
+};
+o3d.inherit('ViewProjectionTransposeParamMatrix4', 'CompositionParamMatrix4');
+
+
+/**
+ * @constructor
+ */
+o3d.ViewProjectionInverseTransposeParamMatrix4 = function() {
+ o3d.CompositionParamMatrix4.call(this);
+ this.matrix_names_ = ['projection', 'view'];
+ this.inverse_ = true;
+ this.transpose_ = true;
+};
+o3d.inherit('ViewProjectionInverseTransposeParamMatrix4',
+ 'CompositionParamMatrix4');
+
+
+/**
+ * @constructor
+ */
+o3d.WorldParamMatrix4 = function() {
+ o3d.CompositionParamMatrix4.call(this);
+ this.matrix_names_ = ['world'];
+};
+o3d.inherit('WorldParamMatrix4', 'CompositionParamMatrix4');
+
+
+/**
+ * @constructor
+ */
+o3d.WorldInverseParamMatrix4 = function() {
+ o3d.CompositionParamMatrix4.call(this);
+ this.matrix_names_ = ['world'];
+ this.inverse_ = true;
+};
+o3d.inherit('WorldInverseParamMatrix4', 'CompositionParamMatrix4');
+
+
+/**
+ * @constructor
+ */
+o3d.WorldTransposeParamMatrix4 = function() {
+ o3d.CompositionParamMatrix4.call(this);
+ this.matrix_names_ = ['world'];
+ this.transpose_ = true;
+};
+o3d.inherit('WorldTransposeParamMatrix4', 'CompositionParamMatrix4');
+
+
+/**
+ * @constructor
+ */
+o3d.WorldInverseTransposeParamMatrix4 = function() {
+ o3d.CompositionParamMatrix4.call(this);
+ this.matrix_names_ = ['world'];
+ this.inverse_ = true;
+ this.transpose_ = true;
+};
+o3d.inherit('WorldInverseTransposeParamMatrix4', 'CompositionParamMatrix4');
+
+
+/**
+ * @constructor
+ */
+o3d.WorldViewParamMatrix4 = function() {
+ o3d.CompositionParamMatrix4.call(this);
+ this.matrix_names_ = ['view', 'world'];
+};
+o3d.inherit('WorldViewParamMatrix4', 'CompositionParamMatrix4');
+
+
+/**
+ * @constructor
+ */
+o3d.WorldViewInverseParamMatrix4 = function() {
+ o3d.CompositionParamMatrix4.call(this);
+ this.matrix_names_ = ['view', 'world'];
+ this.inverse_ = true;
+};
+o3d.inherit('WorldViewInverseParamMatrix4',
+ 'CompositionParamMatrix4');
+
+
+/**
+ * @constructor
+ */
+o3d.WorldViewTransposeParamMatrix4 = function() {
+ o3d.CompositionParamMatrix4.call(this);
+ this.matrix_names_ = ['view', 'world'];
+ this.transpose_ = true;
+};
+o3d.inherit('WorldViewTransposeParamMatrix4',
+ 'CompositionParamMatrix4');
+
+
+/**
+ * @constructor
+ */
+o3d.WorldViewInverseTransposeParamMatrix4 = function() {
+ o3d.CompositionParamMatrix4.call(this);
+ this.matrix_names_ = ['view', 'world'];
+ this.inverse_ = true;
+ this.transpose_ = true;
+};
+o3d.inherit('WorldViewInverseTransposeParamMatrix4',
+ 'CompositionParamMatrix4');
+
+
+/**
+ * @constructor
+ */
+o3d.WorldViewProjectionParamMatrix4 = function() {
+ o3d.CompositionParamMatrix4.call(this);
+ this.matrix_names_ = ['projection', 'view', 'world'];
+};
+o3d.inherit('WorldViewProjectionParamMatrix4',
+ 'CompositionParamMatrix4');
+
+
+/**
+ * @constructor
+ */
+o3d.WorldViewProjectionInverseParamMatrix4 = function() {
+ o3d.CompositionParamMatrix4.call(this);
+ this.matrix_names_ = ['projection', 'view', 'world'];
+ this.inverse_ = true;
+};
+o3d.inherit('WorldViewProjectionInverseParamMatrix4',
+ 'CompositionParamMatrix4');
+
+
+/**
+ * @constructor
+ */
+o3d.WorldViewProjectionTransposeParamMatrix4 = function() {
+ o3d.CompositionParamMatrix4.call(this);
+ this.matrix_names_ = ['projection', 'view', 'world'];
+ this.transpose_ = true;
+};
+o3d.inherit('WorldViewProjectionTransposeParamMatrix4',
+ 'CompositionParamMatrix4');
+
+
+/**
+ * @constructor
+ */
+o3d.WorldViewProjectionInverseTransposeParamMatrix4 = function() {
+ o3d.CompositionParamMatrix4.call(this);
+ this.matrix_names_ = ['projection', 'view', 'world'];
+ this.inverse_ = true;
+ this.transpose_ = true;
+};
+o3d.inherit('WorldViewProjectionInverseTransposeParamMatrix4',
+ 'CompositionParamMatrix4');
+
+/**
+ * Called to specify the value of a uniform variable.
+ */
+o3d.ParamFloat.prototype.applyToLocation = function(gl, location) {
+ gl.uniform4fv(location, this.value);
+};
+
+/**
+ * Called to specify the value of a uniform variable.
+ */
+o3d.ParamFloat2.prototype.applyToLocation = function(gl, location) {
+ gl.uniform2fv(location, this.value);
+};
+
+/**
+ * Called to specify the value of a uniform variable.
+ */
+o3d.ParamFloat3.prototype.applyToLocation = function(gl, location) {
+ gl.uniform3fv(location, this.value);
+};
+
+/**
+ * Called to specify the value of a uniform variable.
+ */
+o3d.ParamFloat4.prototype.applyToLocation = function(gl, location) {
+ gl.uniform4fv(location, this.value);
+};
+
+/**
+ * Called to specify the value of a uniform variable.
+ */
+o3d.ParamMatrix4.prototype.applyToLocation = function(gl, location) {
+ gl.uniformMatrix4fv(location,
+ false,
+ o3d.Transform.flattenMatrix4(this.value));
+};
+
+
+
+/**
+ * Object to compute all combinations of world/view/projection
+ * inverse/transpose matrices and provide them as parameters.
+ *
+ * @type {o3d.ParamObject}
+ */
+o3d.Param.SAS = new o3d.ParamObject;
+
+o3d.Param.SAS.createParam('world',
+ 'WorldParamMatrix4');
+o3d.Param.SAS.createParam('view',
+ 'ViewParamMatrix4');
+o3d.Param.SAS.createParam('projection',
+ 'ProjectionParamMatrix4');
+o3d.Param.SAS.createParam('worldView',
+ 'WorldViewParamMatrix4');
+o3d.Param.SAS.createParam('viewProjection',
+ 'ViewProjectionParamMatrix4');
+o3d.Param.SAS.createParam('worldViewProjection',
+ 'WorldViewProjectionParamMatrix4');
+
+o3d.Param.SAS.createParam('worldI',
+ 'WorldInverseParamMatrix4');
+o3d.Param.SAS.createParam('viewI',
+ 'ViewInverseParamMatrix4');
+o3d.Param.SAS.createParam('projectionI',
+ 'ProjectionInverseParamMatrix4');
+o3d.Param.SAS.createParam('worldViewI',
+ 'WorldViewInverseParamMatrix4');
+o3d.Param.SAS.createParam('viewProjectionI',
+ 'ViewProjectionInverseParamMatrix4');
+o3d.Param.SAS.createParam('worldViewProjectionI',
+ 'WorldViewProjectionInverseParamMatrix4');
+
+o3d.Param.SAS.createParam('worldT',
+ 'WorldInverseParamMatrix4');
+o3d.Param.SAS.createParam('viewT',
+ 'ViewTransposeParamMatrix4');
+o3d.Param.SAS.createParam('projectionT',
+ 'ProjectionTransposeParamMatrix4');
+o3d.Param.SAS.createParam('worldViewT',
+ 'WorldViewTransposeParamMatrix4');
+o3d.Param.SAS.createParam('viewProjectionT',
+ 'ViewProjectionTransposeParamMatrix4');
+o3d.Param.SAS.createParam('worldViewProjectionT',
+ 'WorldViewProjectionTransposeParamMatrix4');
+
+o3d.Param.SAS.createParam('worldIT',
+ 'WorldInverseTransposeParamMatrix4');
+o3d.Param.SAS.createParam('viewIT',
+ 'ViewInverseTransposeParamMatrix4');
+o3d.Param.SAS.createParam('projectionIT',
+ 'ProjectionInverseTransposeParamMatrix4');
+o3d.Param.SAS.createParam('worldViewIT',
+ 'WorldViewInverseTransposeParamMatrix4');
+o3d.Param.SAS.createParam('viewProjectionIT',
+ 'ViewProjectionInverseTransposeParamMatrix4');
+o3d.Param.SAS.createParam('worldViewProjectionIT',
+ 'WorldViewProjectionInverseTransposeParamMatrix4');
+
+/**
+ * Sets the base world matrix that gets use to compute all other products for
+ * SAS parameters.
+ */
+o3d.Param.SAS.setWorld = function(world) {
+ this['world'] = world;
+};
+
+/**
+ * Sets the base world matrix that gets use to compute all other products for
+ * SAS parameters.
+ */
+o3d.Param.SAS.setView = function(view) {
+ this['view'] = view;
+};
+
+/**
+ * Sets the base world matrix that gets use to compute all other products for
+ * SAS parameters.
+ */
+o3d.Param.SAS.setProjection = function(projection) {
+ var adjustedProjection =
+ [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 2, 0], [0, 0, -1, 1]];
+ o3d.Transform.compose(
+ adjustedProjection, projection, adjustedProjection);
+ this['projection'] = projection;
+};
+
+
diff --git a/o3d/samples/o3d-webgl/param_object.js b/o3d/samples/o3d-webgl/param_object.js
new file mode 100644
index 0000000..625f876
--- /dev/null
+++ b/o3d/samples/o3d-webgl/param_object.js
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * A ParamObject is the base class for all objects that can have Params.
+ * Defines methods to add and remove params, search for params, etc.
+ * @constructor
+ */
+o3d.ParamObject = function() {
+ this.params_ = {};
+};
+o3d.inherit('ParamObject', 'NamedObject');
+
+
+/**
+ * Creates a Param with the given name and type on the ParamObject.
+ * Will fail if a param with the same name already exists.
+ *
+ * @param {string} param_name The name of the Param to be created.
+ * @param {string} param_type_name The type of Param to create.
+ * Valid types are
+ * 'ParamBoolean'
+ * 'ParamBoundingBox'
+ * 'ParamDrawContext'
+ * 'ParamDrawList'
+ * 'ParamEffect'
+ * 'ParamFloat'
+ * 'ParamFloat2'
+ * 'ParamFloat3'
+ * 'ParamFloat4'
+ * 'ParamFunction'
+ * 'ParamInteger'
+ * 'ParamMaterial'
+ * 'ParamMatrix4'
+ * 'ParamParamArray'
+ * 'ParamRenderSurface'
+ * 'ParamRenderDepthStencilSurface'
+ * 'ParamSampler'
+ * 'ParamSkin'
+ * 'ParamSteamBank'
+ * 'ParamState'
+ * 'ParamString'
+ * 'ParamTexture'
+ * 'ParamTransform'
+ * 'ProjectionParamMatrix4'
+ * 'ProjectionInverseParamMatrix4'
+ * 'ProjectionTransposeParamMatrix4'
+ * 'ProjectionInverseTransposeParamMatrix4'
+ * 'ViewParamMatrix4'
+ * 'ViewInverseParamMatrix4'
+ * 'ViewTransposeParamMatrix4'
+ * 'ViewInverseTransposeParamMatrix4'
+ * 'ViewProjectionParamMatrix4'
+ * 'ViewProjectionInverseParamMatrix4'
+ * 'ViewProjectionTransposeParamMatrix4'
+ * 'ViewProjectionInverseTransposeParamMatrix4'
+ * 'WorldParamMatrix4'
+ * 'WorldInverseParamMatrix4'
+ * 'WorldTransposeParamMatrix4'
+ * 'WorldInverseTransposeParamMatrix4'
+ * 'WorldViewParamMatrix4'
+ * 'WorldViewInverseParamMatrix4'
+ * 'WorldViewTransposeParamMatrix4'
+ * 'WorldViewInverseTransposeParamMatrix4'
+ * 'WorldViewProjectionParamMatrix4'
+ * 'WorldViewProjectionInverseParamMatrix4'
+ * 'WorldViewProjectionTransposeParamMatrix4'
+ * 'WorldViewProjectionInverseTransposeParamMatrix4'
+ * @returns {!o3d.Param} The newly created Param or null on failure.
+ */
+o3d.ParamObject.prototype.createParam =
+ function(param_name, param_type_name) {
+ if (!o3d.global.o3d[param_type_name])
+ throw ('Invalid param type name: ' + param_type_name);
+ var param = new o3d.global.o3d[param_type_name];
+ param.gl = this.gl;
+ param.owner_ = this;
+ this.params_[param_name] = param;
+ return this.params_[param_name];
+};
+
+
+/**
+ * Searches by name for a Param defined in the object.
+ *
+ * @param {string} param_name Name to search for.
+ * @returns {!o3d.Param} The Param with the given name, or null otherwise.
+ */
+o3d.ParamObject.prototype.getParam =
+ function(param_name) {
+ return this.params_[param_name];
+};
+
+
+/**
+ * Removes a Param from a ParamObject.
+ *
+ * This function will fail if the param does not exist on this ParamObject
+ * or if the param is unremovable.
+ *
+ * @param {!o3d.Param} param param to remove.
+ * @returns {boolean} True if the param was removed.
+ */
+o3d.ParamObject.prototype.removeParam =
+ function(param) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Gets all the param on this param object.
+ *
+ * Each access to this field gets the entire list, so it is best to get it
+ * just once. For example:
+ *
+ * var params = paramObject.params;
+ * for (var i = 0; i < params.length; i++) {
+ * var param = params[i];
+ * }
+ *
+ * Note that modifications to this array [e.g. push()] will not affect
+ * the underlying ParamObject, while modifications to the array's members
+ * will affect them.
+ */
+o3d.ParamObject.prototype.params_ = {};
+
+
+/**
+ * Copies all the params from a the given source_param_object to this param
+ * object. Does not replace any currently existing params with the same name.
+ *
+ * @param {o3d.ParamObject} source_param_object param object to copy params
+ * from.
+ */
+o3d.ParamObject.prototype.copyParams =
+ function(source_param_object) {
+ o3d.notImplemented();
+};
+
+
diff --git a/o3d/samples/o3d-webgl/primitive.js b/o3d/samples/o3d-webgl/primitive.js
new file mode 100644
index 0000000..ed45a65
--- /dev/null
+++ b/o3d/samples/o3d-webgl/primitive.js
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * A Primitive is a type of Element that is made from a list of points,
+ * lines or triangles that use a single material.
+ *
+ * @param opt_streamBank o3d.StreamBank The StreamBank used by this
+ * Primitive.
+ * @constructor
+ */
+o3d.Primitive = function(opt_streamBank) {
+ o3d.Element.call(this);
+ this.streamBank = opt_streamBank;
+};
+o3d.inherit('Primitive', 'Element');
+
+
+/**
+ * @type {number}
+ */
+o3d.Primitive.Type = goog.typedef;
+
+/**
+ * Type of geometric primitives used by the Primitive.
+ */
+o3d.Primitive.POINTLIST = 1;
+o3d.Primitive.LINELIST = 2;
+o3d.Primitive.LINESTRIP = 3;
+o3d.Primitive.TRIANGLELIST = 4;
+o3d.Primitive.TRIANGLESTRIP = 5;
+o3d.Primitive.TRIANGLEFAN = 6;
+
+
+
+/**
+ * The type of primitive the primitive is (i.e., POINTLIST, LINELIST,
+ * TRIANGLELIST, etc.)
+ *
+ * @type {o3d.Primitive.Type}
+ */
+o3d.Primitive.prototype.primitiveType = o3d.Primitive.TRIANGLELIST;
+
+
+
+/**
+ * The number of vertices the primitive has.
+ *
+ * @type {number}
+ */
+o3d.Primitive.prototype.numberVertices = 0;
+
+
+
+/**
+ * The number of rendering primitives (i.e., triangles, points, lines) the
+ * primitive has.
+ *
+ * @type {number}
+ */
+o3d.Primitive.prototype.numberPrimitives = 0;
+
+
+
+/**
+ * The index of the first vertex to render.
+ * Default = 0.
+ *
+ * @type {number}
+ */
+o3d.Primitive.prototype.startIndex = 0;
+
+
+
+/**
+ * The stream bank this primitive uses for vertices.
+ * @type {o3d.StreamBank}
+ */
+o3d.Primitive.prototype.streamBank = null;
+
+
+
+/**
+ * The index buffer for the primitive. If null the primitive is non-indexed.
+ * @type {number}
+ */
+o3d.Primitive.prototype.indexBuffer = null;
+
+
+
+/**
+ * Binds the vertex and index streams required to draw the shape.
+ */
+o3d.Primitive.prototype.render = function() {
+ var streamBank = this.streamBank;
+ var indexBuffer = this.indexBuffer;
+
+ for (var semantic = 0;
+ semantic < streamBank.vertexStreams.length;
+ ++semantic) {
+ var streams = streamBank.vertexStreams[semantic];
+ if (streams && streams.length) {
+ for (var semantic_index = 0;
+ semantic_index < streams.length;
+ ++semantic_index) {
+ var gl_index = semantic + semantic_index - 1;
+ var stream = streams[semantic_index];
+ var field = stream.field;
+ var buffer = field.buffer;
+
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer.gl_buffer_);
+ this.gl.enableVertexAttribArray(gl_index);
+
+ // TODO(petersont): Change that hard-coded 4 down there.
+ this.gl.vertexAttribPointer(
+ gl_index, field.numComponents, this.gl.FLOAT, false,
+ buffer.totalComponents * 4, field.offset_ * 4);
+ }
+ }
+ }
+
+ // TODO(petersont): Change the hard-coded 3 and triangles too.
+ this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, indexBuffer.gl_buffer_);
+ this.gl.drawElements(this.gl.TRIANGLES,
+ this.numberPrimitives * 3,
+ this.gl.UNSIGNED_SHORT,
+ 0);
+};
diff --git a/o3d/samples/o3d-webgl/raw_data.js b/o3d/samples/o3d-webgl/raw_data.js
new file mode 100644
index 0000000..ab3c0f4
--- /dev/null
+++ b/o3d/samples/o3d-webgl/raw_data.js
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * A RawData object contains raw binary data which could contain
+ * image, audio, text, or other information.
+ *
+ * var request = g_pack.createArchiveRequest();
+ *
+ * request.onfileavailable = function(rawData) {
+ * var texture = g_pack.createTextureFromRawData(rawData, true);
+ * ...
+ * };
+ *
+ * request.send();
+ * @constructor
+ */
+o3d.RawData = function() { };
+o3d.inherit('RawData', 'NamedObject');
+
+
+/**
+ * Returns the raw data as a string. The data must be a valid utf-8 string
+ * and the uri must end in .json, .txt, .xml, .ini or .csv
+ * @type {string}
+ */
+o3d.RawData.prototype.string_value = '';
+
+
+
+/**
+ * The uri of the RawData.
+ * @type {string}
+ */
+o3d.RawData.prototype.uri = '';
+
+
+
+/**
+ * The length in bytes of the RawData.
+ * @type {number}
+ */
+o3d.RawData.prototype.length = 0;
+
+
+
+/**
+ * Discards all the resources associated with this data object.
+ */
+o3d.RawData.prototype.discard = function() {
+ o3d.notImplemented();
+};
+
+
+
+/**
+ * Flushes the memory resources associated with this data object,
+ * but keeps a cache in case the data object is used later.
+ */
+o3d.RawData.prototype.flush = function() {
+ o3d.notImplemented();
+};
+
+
+
diff --git a/o3d/samples/o3d-webgl/ray_intersection_info.js b/o3d/samples/o3d-webgl/ray_intersection_info.js
new file mode 100644
index 0000000..ab317b4
--- /dev/null
+++ b/o3d/samples/o3d-webgl/ray_intersection_info.js
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * A RayIntersectionInfo is used to return the results of ray intersection
+ * tests.
+ * @constructor
+ */
+o3d.RayIntersectionInfo = function() {
+ o3d.RayIntersectionInfo.prototype.position = [0, 0, 0];
+};
+o3d.inherit('RayIntersectionInfo', 'NamedObject');
+
+
+/**
+ * True if this ray intersection info is valid. For example if you call
+ * element.intersectRay on an element that has no vertex buffers the result
+ * will be invalid.
+ * @type {boolean}
+ */
+o3d.RayIntersectionInfo.prototype.valid = false;
+
+
+
+/**
+ * True if this ray intersection intersected something.
+ * @type {boolean}
+ */
+o3d.RayIntersectionInfo.prototype.intersected = false;
+
+
+
+/**
+ * The position the ray intersected something.
+ * type {!o3d.Point3}
+ */
+o3d.RayIntersectionInfo.prototype.position = [0, 0, 0];
+
+
+
+/**
+ * The index of the primitive that was intersected.
+ * @type {number}
+ */
+o3d.RayIntersectionInfo.prototype.primitiveIndex = -1;
+
+
+
diff --git a/o3d/samples/o3d-webgl/render_node.js b/o3d/samples/o3d-webgl/render_node.js
new file mode 100644
index 0000000..d97b2e9
--- /dev/null
+++ b/o3d/samples/o3d-webgl/render_node.js
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * RenderNode is the base of all RenderNodes in the render graph.
+ * RenderNodes are rendered in order of priority.
+ *
+ * @param {number} opt_priority The priority of this render node. Lower
+ * priorities are rendered first.
+ * @param {boolean} opt_active If true this node is processed. If false
+ * it is not.
+ * @constructor
+ */
+o3d.RenderNode = function(opt_priority, opt_active) {
+ this.priority = opt_priority;
+ this.children = [];
+};
+o3d.inherit('RenderNode','ParamObject');
+
+
+/**
+ * Sets the priority of this render node. lower priorities are rendered first.
+ *
+ * @type {number}
+ */
+o3d.RenderNode.prototype.priority = 0;
+
+
+
+/**
+ * Setting false skips this render node. Setting true processes this render
+ * node. (ie, renders whatever it's supposed to render)
+ *
+ * @type {boolean}
+ */
+o3d.RenderNode.prototype.active = true;
+
+
+
+/**
+ * Sets the parent of the node by re-parenting the node under parent_node.
+ * Setting parent_node to null removes the node and the entire subtree below
+ * it from the render graph.
+ *
+ * @type {o3d.RenderNode}
+ */
+o3d.RenderNode.prototype.parent = null;
+
+o3d.RenderNode.prototype.__defineSetter__('parent',
+ function(p) {
+ this.parent_ = p;
+ p.addChild(this);
+ }
+);
+
+o3d.RenderNode.prototype.__defineGetter__('parent',
+ function(p) {
+ return this.parent_;
+ }
+);
+
+/**
+ * Adds a child node.
+ * @param {o3d.RenderNode} child The child to add.
+ */
+o3d.RenderNode.prototype.addChild = function(child) {
+ this.children.push(child);
+};
+
+
+
+/**
+ * The immediate children of this RenderNode.
+ *
+ * Each access to this field gets the entire list so it is best to get it
+ * just once. For example:
+ *
+ * var children = renderNode.children;
+ * for (var i = 0; i < children.length; i++) {
+ * var child = children[i];
+ * }
+ *
+ * Note that modifications to this array [e.g. push()] will not affect
+ * the underlying RenderNode, while modifications to the array's members
+ * will affect them.
+ *
+ * @type {!Array.<o3d.RenderNode>}
+ */
+o3d.RenderNode.prototype.children = [];
+
+
+
+/**
+ * Returns this render node and all its descendants. Note that this render node
+ * might not be in the render graph.
+ *
+ * Note that modifications to this array [e.g. push()] will not affect
+ * the underlying RenderNode, while modifications to the array's members
+ * will affect them.
+ *
+ * An array containing all render nodes of the subtree.
+ */
+o3d.RenderNode.prototype.getRenderNodesInTree =
+ function() {
+ o3d.notImplemented();
+};
+
+
+
+/**
+ * Searches for render nodes that match the given name in the hierarchy under
+ * and including this render node. Since there can be several render nodes
+ * with a given name the results are returned in an array.
+ *
+ * Note that modifications to this array [e.g. push()] will not affect
+ * the underlying RenderNode, while modifications to the array's members
+ * will affect them.
+ *
+ * @param {string} name Rendernode name to look for.
+ * @returns {Array.<!o3d.RenderNode>} An array containing all nodes among
+ * this node and its decendants that have the given name.
+ */
+o3d.RenderNode.prototype.getRenderNodesByNameInTree =
+ function(name) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Searches for render nodes that match the given class name in the hierarchy
+ * under and including this render node.
+ *
+ * Note that modifications to this array [e.g. push()] will not affect
+ * the underlying RenderNode, while modifications to the array's members
+ * will affect them.
+ *
+ * @param {string} class_name class name to look for.
+ * @returns {Array.<!o3d.RenderNode>} An array containing all nodes among
+ * this node and its decendants whose type is class_name.
+ */
+o3d.RenderNode.prototype.getRenderNodesByClassNameInTree =
+ function(class_name) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Recursively traverses the render graph starting at this node.
+ */
+o3d.RenderNode.prototype.render = function() {
+ function compare(a, b) {
+ return a.priority - b.priority;
+ }
+ this.children.sort(compare);
+ var children = this.children;
+
+ this.before();
+ for (var i = 0; i < children.length; ++i) {
+ children[i].render();
+ }
+ this.after();
+};
+
+
+/**
+ * Called during the rendergraph traversal before the children are rendered.
+ */
+o3d.RenderNode.prototype.before = function() { };
+
+
+/**
+ * Called during the rendergraph traversal after the children are rendered.
+ */
+o3d.RenderNode.prototype.after = function() { };
+
+
diff --git a/o3d/samples/o3d-webgl/render_surface.js b/o3d/samples/o3d-webgl/render_surface.js
new file mode 100644
index 0000000..d3b3877
--- /dev/null
+++ b/o3d/samples/o3d-webgl/render_surface.js
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * A RenderSurfaceBase is the base for RenderSurface and
+ * RenderDepthStencilSurface.
+ *
+ * @param {number} width The width of this RenderSurface.
+ * @param {number} height The height of this RenderSurface.
+ * @param {o3d.Texture} texture The texture of this RenderSurface.
+ * @constructor
+ */
+o3d.RenderSurfaceBase = function(width, height, texture) {
+ o3d.ParamObject.call(this);
+};
+o3d.inherit('RenderSurfaceBase', 'ParamObject');
+
+
+/**
+ * The width of the surface, in pixels.
+ * @type {number}
+ */
+o3d.RenderSurfaceBase.prototype.width = 0;
+
+
+
+/**
+ * The height of the surface, in pixels.
+ * @type {number}
+ */
+o3d.RenderSurfaceBase.prototype.height = 0;
+
+
+
+/**
+ * A RenderSurface encapsulates the notion of a renderable surface.
+ * When used in conjunction with a RenderSurfaceSet node in the render graph,
+ * the API allows for rendering of primitives to the given surface.
+ * RenderSurface objects are not constructable through the Pack API, they may
+ * only be accessed through the texture getRenderSurface(...) interfaces.
+ * @constructor
+ */
+o3d.RenderSurface = function() { };
+o3d.inherit('RenderSurface', 'RenderSurfaceBase');
+
+
+/**
+ * The texture in which this surface is contained.
+ */
+o3d.RenderSurface.prototype.texture = null;
+
+
+/**
+ * A RenderDepthStencilSurface represents a depth stencil render surface.
+ * @constructor
+ */
+o3d.RenderDepthStencilSurface = function() { };
+o3d.inherit('RenderDepthStencilSurface', 'RenderSurfaceBase');
+
+
diff --git a/o3d/samples/o3d-webgl/render_surface_set.js b/o3d/samples/o3d-webgl/render_surface_set.js
new file mode 100644
index 0000000..dfcd901
--- /dev/null
+++ b/o3d/samples/o3d-webgl/render_surface_set.js
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * A RenderSurfaceSet node will bind depth and color RenderSurface nodes
+ * to the current rendering context. All RenderNodes descending
+ * from the given RenderSurfaceSet node will operate on the contents of
+ * the bound depth and color buffers.
+ * Note the following usage constraints of this node:
+ * 1) If both a color and depth surface is bound, then they must be of matching
+ * dimensions.
+ * 2) At least one of render_surface and render_depth_surface must non-null.
+ *
+ * @param {o3d.RenderSurface} opt_renderSurface The render surface to set.
+ * @param {o3d.RenderDepthStencilSurface} opt_renderDepthStencilSurface The
+ * depth stencil render surface to set.
+ * @constructor
+ */
+o3d.RenderSurfaceSet = function() {
+ o3d.RenderSurfaceSet.prototype.renderSurface =
+ opt_renderSurface;
+ o3d.RenderSurfaceSet.prototype.renderDepthStencilSurface =
+ opt_renderDepthStencilSurface;
+};
+o3d.inherit('RenderSurfaceSet', 'RenderNode');
+
+
+/**
+ * The render surface to which the color contents of all RenderNode children
+ * should be drawn.
+ * @type {o3d.RenderSurface}
+ */
+o3d.RenderSurfaceSet.prototype.renderSurface = null;
+
+
+
+/**
+ * The render depth stencil surface to which the depth contents of all
+ * RenderNode children should be drawn.
+ * @type {o3d.RenderDepthStencilSurface}
+ */
+o3d.RenderSurfaceSet.prototype.renderDepthStencilSurface = null;
+
+
+
diff --git a/o3d/samples/o3d-webgl/shape.js b/o3d/samples/o3d-webgl/shape.js
new file mode 100644
index 0000000..4754869
--- /dev/null
+++ b/o3d/samples/o3d-webgl/shape.js
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * The Shape represents a collection of Elements. The typical example is a
+ * cube with 6 faces where each face uses a different material would be
+ * represented as 1 Shape with 6 Elements, one for each material.
+ * @constructor
+ */
+o3d.Shape = function() {
+ this.elements = [];
+};
+o3d.inherit('Shape', 'ParamObject');
+
+
+/**
+ * The elements owned by this shape.
+ *
+ * Each access to this field gets the entire list so it is best to get it
+ * just once. For example:
+ *
+ * var elements = renderNode.elements;
+ * for (var i = 0; i < elements.length; i++) {
+ * var element = elements[i];
+ * }
+ *
+ * Note that modifications to this array [e.g. push()] will not affect
+ * the underlying Shape, while modifications to the array's members
+ * will affect them.
+ */
+o3d.Shape.prototype.elements = [];
+
+
+/**
+ * Creates a DrawElement for each Element owned by this Shape.
+ * If an Element already has a DrawElement that uses \a material a new
+ * DrawElement will not be created.
+ * @param {o3d.Pack} pack pack used to manage created DrawElements.
+ * @param {o3d.Material} material material to use for each DrawElement.
+ * If you pass null it will use the material on the corresponding Element.
+ * This allows you to easily setup the default (just draw as is) by
+ * passing null or setup a shadow pass by passing in a shadow material.
+ */
+o3d.Shape.prototype.createDrawElements =
+ function(pack, material) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Adds and element to the list of elements for this shape.
+ * @param {o3d.Element} element The element to add.
+ */
+o3d.Shape.prototype.addElement = function(element) {
+ this.elements.push(element);
+};
+
+
+/**
+ * Removes and element to the list of elements for this shape.
+ * @param {o3d.Element} element The element to add.
+ */
+o3d.Shape.prototype.removeElement = function(element) {
+
+};
+
+
+/**
+ * Called when the tree traversal finds this shape in the transform tree.
+ * Adds objects to the given drawlists if the drawlist of the material matches.
+ * @param {Array.<Object>} drawListInfos A list of objects containing
+ * drawlists and matrix info.
+ * @param {o3d.math.Matrix4} world The world matrix.
+ */
+o3d.Shape.prototype.writeToDrawLists =
+ function(drawListInfos, world, transform) {
+ var elements = this.elements;
+ for (var i = 0; i < elements.length; ++i) {
+ var element = elements[i];
+ for (var j = 0; j < element.drawElements.length; ++j) {
+ var drawElement = element.drawElements[j];
+ var materialDrawList = drawElement.material.drawList;
+ for (var k = 0; k < drawListInfos.length; ++k) {
+ var drawListInfo = drawListInfos[k];
+ var list = drawListInfo.list;
+ var context = drawListInfo.context;
+ if (materialDrawList == list) {
+ list.list_.push({
+ view: context.view,
+ projection: context.projection,
+ world: world,
+ transform: transform,
+ drawElement: drawElement
+ });
+ }
+ }
+ }
+ }
+};
diff --git a/o3d/samples/o3d-webgl/state.js b/o3d/samples/o3d-webgl/state.js
new file mode 100644
index 0000000..cf5fea7
--- /dev/null
+++ b/o3d/samples/o3d-webgl/state.js
@@ -0,0 +1,567 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * A State object sets the RenderStates for a particular material or StateSet.
+ * @constructor
+ */
+o3d.State = function() {
+ o3d.ParamObject.call(this);
+
+ // TODO(petersont): Only some of these have been implemented.
+ var stateInfos = [
+ {name: 'AlphaBlendEnable', paramType: 'ParamBoolean',
+ defaultValue: false},
+ {name: 'AlphaComparisonFunction', paramType: 'ParamInteger',
+ defaultValue: o3d.State.CMP_ALWAYS},
+ {name: 'AlphaReference', paramType: 'ParamFloat',
+ defaultValue: 0},
+ {name: 'AlphaTestEnable', paramType: 'ParamBoolean',
+ defaultValue: false},
+ {name: 'BlendAlphaEquation', paramType: 'ParamInteger',
+ defaultValue: o3d.State.BLEND_ADD},
+ {name: 'BlendEquation', paramType: 'ParamInteger',
+ defaultValue: o3d.State.BLEND_ADD},
+ {name: 'CCWStencilComparisonFunction', paramType: 'ParamInteger',
+ defaultValue: o3d.State.CMP_ALWAYS},
+ {name: 'CCWStencilFailOperation', paramType: 'ParamInteger',
+ defaultValue: o3d.State.STENCIL_KEEP},
+ {name: 'CCWStencilPassOperation', paramType: 'ParamInteger',
+ defaultValue: o3d.State.STENCIL_KEEP},
+ {name: 'CCWStencilZFailOperation', paramType: 'ParamInteger',
+ defaultValue: o3d.State.STENCIL_KEEP},
+ {name: 'ColorWriteEnable', paramType: 'ParamInteger',
+ defaultValue: 15},
+ {name: 'CullMode', paramType: 'ParamInteger',
+ defaultValue: o3d.State.CULL_CW},
+ {name: 'DestinationBlendAlphaFunction', paramType: 'ParamInteger',
+ defaultValue: o3d.State.BLENDFUNC_ZERO},
+ {name: 'DestinationBlendFunction', paramType: 'ParamInteger',
+ defaultValue: o3d.State.BLENDFUNC_ZERO},
+ {name: 'DitherEnable', paramType: 'ParamBoolean',
+ defaultValue: false},
+ {name: 'FillMode', paramType: 'ParamInteger',
+ defaultValue: o3d.State.SOLID},
+ {name: 'LineSmoothEnable', paramType: 'ParamBoolean',
+ defaultValue: false},
+ {name: 'PointSize', paramType: 'ParamFloat',
+ defaultValue: 0},
+ {name: 'PointSpriteEnable', paramType: 'ParamBoolean',
+ defaultValue: false},
+ {name: 'PolygonOffset1', paramType: 'ParamFloat',
+ defaultValue: 0},
+ {name: 'PolygonOffset2', paramType: 'ParamFloat',
+ defaultValue: 0},
+ {name: 'SeparateAlphaBlendEnable', paramType: 'ParamBoolean',
+ defaultValue: false},
+ {name: 'SourceBlendAlphaFunction', paramType: 'ParamInteger',
+ defaultValue: o3d.State.BLENDFUNC_ONE},
+ {name: 'SourceBlendFunction', paramType: 'ParamInteger',
+ defaultValue: o3d.State.BLENDFUNC_ONE},
+ {name: 'StencilComparisonFunction', paramType: 'ParamInteger',
+ defaultValue: o3d.State.CMP_ALWAYS},
+ {name: 'StencilEnable', paramType: 'ParamBoolean',
+ defaultValue: false},
+ {name: 'StencilFailOperation', paramType: 'ParamInteger',
+ defaultValue: o3d.State.STENCIL_KEEP},
+ {name: 'StencilMask', paramType: 'ParamInteger',
+ defaultValue: 255},
+ {name: 'StencilPassOperation', paramType: 'ParamInteger',
+ defaultValue: o3d.State.STENCIL_KEEP},
+ {name: 'StencilReference', paramType: 'ParamInteger',
+ defaultValue: 0},
+ {name: 'StencilWriteMask', paramType: 'ParamInteger',
+ defaultValue: 255},
+ {name: 'StencilZFailOperation', paramType: 'ParamInteger',
+ defaultValue: o3d.State.STENCIL_KEEP},
+ {name: 'TwoSidedStencilEnable', paramType: 'ParamBoolean',
+ defaultValue: false},
+ {name: 'ZComparisonFunction', paramType: 'ParamInteger',
+ defaultValue: o3d.State.CMP_LESS},
+ {name: 'ZEnable', paramType: 'ParamBoolean',
+ defaultValue: true},
+ {name: 'ZWriteEnable', paramType: 'ParamBoolean',
+ defaultValue: true}
+ ];
+
+ this.state_params_ = {};
+
+ for (var i = 0; i < stateInfos.length; ++i) {
+ var info = stateInfos[i];
+ var param = new o3d.global.o3d[info.paramType];
+ param.value = info.defaultValue;
+ this.state_params_[info.name] = param;
+ }
+};
+o3d.inherit('State', 'ParamObject');
+
+/**
+ * A private object containing the the state params by name.
+ */
+o3d.State.prototype.state_params_ = { };
+
+
+/**
+ * Comparison
+ * CMP_NEVER (Never)
+ * CMP_LESS (Less Than)
+ * CMP_EQUAL (Equal To)
+ * CMP_LEQUAL (Less Than or Equal To)
+ * CMP_GREATER (Greater Than)
+ * CMP_NOTEQUAL (Not Equal To)
+ * CMP_GEQUAL (Greater Than or Equal To)
+ * CMP_ALWAYS (Always)
+ */
+o3d.State.CMP_NEVER = 0;
+o3d.State.CMP_LESS = 1;
+o3d.State.CMP_EQUAL = 2;
+o3d.State.CMP_LEQUAL = 3;
+o3d.State.CMP_GREATER = 4;
+o3d.State.CMP_NOTEQUAL = 5;
+o3d.State.CMP_GEQUAL = 6;
+o3d.State.CMP_ALWAYS = 7;
+
+
+
+/**
+ * type {number}
+ */
+o3d.Cull = goog.typedef;
+
+/**
+ * Cull
+ * CULL_NONE Don't Cull by face
+ * CULL_CW Cull clock-wise faces
+ * CULL_CCW Cull counter clock-wise faces
+ */
+o3d.State.CULL_NONE = 0;
+o3d.State.CULL_CW = 1;
+o3d.State.CULL_CCW = 2;
+
+
+
+
+/**
+ * Fill
+ * POINT
+ * WIREFRAME
+ * SOLID
+ */
+o3d.State.POINT = 0;
+o3d.State.WIREFRAME = 1;
+o3d.State.SOLID = 2;
+
+
+
+/**
+ * BlendingFunction
+ * BLENDFUNC_ZERO
+ * BLENDFUNC_ONE
+ * BLENDFUNC_SOURCE_COLOR
+ * BLENDFUNC_INVERSE_SOURCE_COLOR
+ * BLENDFUNC_SOURCE_ALPHA
+ * BLENDFUNC_INVERSE_SOURCE_ALPHA
+ * BLENDFUNC_DESTINATION_ALPHA
+ * BLENDFUNC_INVERSE_DESTINATION_ALPHA
+ * BLENDFUNC_DESTINATION_COLOR
+ * BLENDFUNC_INVERSE_DESTINATION_COLOR
+ * BLENDFUNC_SOURCE_ALPHA_SATUTRATE
+ */
+o3d.State.BLENDFUNC_ZERO = 0;
+o3d.State.BLENDFUNC_ONE = 1;
+o3d.State.BLENDFUNC_SOURCE_COLOR = 2;
+o3d.State.BLENDFUNC_INVERSE_SOURCE_COLOR = 3;
+o3d.State.BLENDFUNC_SOURCE_ALPHA = 4;
+o3d.State.BLENDFUNC_INVERSE_SOURCE_ALPHA = 5;
+o3d.State.BLENDFUNC_DESTINATION_ALPHA = 6;
+o3d.State.BLENDFUNC_INVERSE_DESTINATION_ALPHA = 7;
+o3d.State.BLENDFUNC_DESTINATION_COLOR = 8;
+o3d.State.BLENDFUNC_INVERSE_DESTINATION_COLOR = 9;
+o3d.State.BLENDFUNC_SOURCE_ALPHA_SATUTRATE = 10;
+
+
+
+/**
+ * BlendingEquation
+ * BLEND_ADD
+ * BLEND_SUBTRACT
+ * BLEND_REVERSE_SUBTRACT
+ * BLEND_MIN
+ * BLEND_MAX
+ */
+o3d.State.BLEND_ADD = 0;
+o3d.State.BLEND_SUBTRACT = 1;
+o3d.State.BLEND_REVERSE_SUBTRACT = 2;
+o3d.State.BLEND_MIN = 3;
+o3d.State.BLEND_MAX = 4;
+
+
+
+/**
+ * StencilOperation
+ * STENCIL_KEEP
+ * STENCIL_ZERO
+ * STENCIL_REPLACE
+ * STENCIL_INCREMENT_SATURATE
+ * STENCIL_DECREMENT_SATURATE
+ * STENCIL_INVERT
+ * STENCIL_INCREMENT
+ * STENCIL_DECREMENT
+ */
+o3d.State.STENCIL_KEEP = 0;
+o3d.State.STENCIL_ZERO = 1;
+o3d.State.STENCIL_REPLACE = 2;
+o3d.State.STENCIL_INCREMENT_SATURATE = 3;
+o3d.State.STENCIL_DECREMENT_SATURATE = 4;
+o3d.State.STENCIL_INVERT = 5;
+o3d.State.STENCIL_INCREMENT = 6;
+o3d.State.STENCIL_DECREMENT = 7;
+
+
+
+/**
+ * Returns a Param for a given state. If the param does not already exist it
+ * will be created. If the state_name is invalid it will return null.
+ * @param {string} state_name name of the state
+ * @returns {o3d.Param} param or null if no matching state.
+ *
+ * Example:
+ *
+ *
+ * g_o3d = document.o3d.o3d;
+ * ...
+ *
+ * var state = my_pack.createState("my_state");
+ *
+ *
+ * state.getStateParam('StencilEnable').value = true;
+ * state.getStateParam('StencilReference').value = 25;
+ * state.getStateParam('StencilPassOperation').value =
+ * g_o3d.State.STENCIL_REPLACE;
+ * state.getStateParam('StencilComparisonFunction').value =
+ * g_o3d.State.CMP_ALWAYS;
+ * state.getStateParam('ZEnable').value = false;
+ * state.getStateParam('ZWriteEnable').value = false;
+ * state.getStateParam('ColorWriteEnable').value = 0;
+ *
+ * Valid states:
+ *
+ * State NameTypeDefault Value
+ * o3d.AlphaBlendEnableParamBoolean
+ * default = false
+ * o3d.AlphaComparisonFunctionParamInteger,
+ * State.Comparisondefault = State.CMP_ALWAYS
+ * o3d.AlphaReferenceParamFloat 0-1
+ * default = 0
+ * o3d.AlphaTestEnableParamBoolean
+ * default = false
+ * o3d.BlendAlphaEquation
+ * ParamInteger, State.BlendingEquation
+ * default = State.BLEND_ADD
+ * o3d.BlendEquation
+ * ParamInteger, State.BlendingEquation
+ * default = State.BLEND_ADD
+ * o3d.CCWStencilComparisonFunction
+ * ParamInteger, State.Comparison
+ * default = State.CMP_ALWAYS
+ * o3d.CCWStencilFailOperation
+ * ParamInteger, State.StencilOperation
+ * default = State.STENCIL_KEEP
+ * o3d.CCWStencilPassOperation
+ * ParamInteger, State.StencilOperation
+ * default = State.STENCIL_KEEP
+ * o3d.CCWStencilZFailOperation
+ * ParamInteger, State.StencilOperation
+ * default = State.STENCIL_KEEP
+ * o3d.ColorWriteEnable
+ * ParamInteger 0-15 bit 0 = red, bit 1 = green,
+ * bit 2 = blue, bit 3 = alphadefault = 15
+ * o3d.CullModeParamInteger, State.Cull
+ * default = State.CULL_CW
+ * o3d.DestinationBlendAlphaFunction
+ * ParamInteger, State.BlendingFunction
+ * default = State.BLENDFUNC_ZERO
+ * o3d.DestinationBlendFunction
+ * ParamInteger, State.BlendingFunction
+ * default = State.BLENDFUNC_ZERO
+ * o3d.DitherEnableParamBoolean
+ * default = false
+ * o3d.FillModeParamInteger, State.Fill
+ * default = State.SOLID
+ * o3d.LineSmoothEnableParamBoolean
+ * default = false
+ * o3d.PointSizeParamFloatTBD
+ * o3d.PointSpriteEnableParamBoolean
+ * default = false
+ * o3d.PolygonOffset1
+ * ParamFloat, polygon offset slope factor0
+ * o3d.PolygonOffset2ParamFloat, polygon offset bias (in
+ * resolvable units)0
+ * o3d.SeparateAlphaBlendEnableParamBoolean
+ * default = false
+ * o3d.SourceBlendAlphaFunction
+ * ParamInteger, State.BlendingFunction
+ * default = State.BLENDFUNC_ONE
+ * o3d.SourceBlendFunction
+ * ParamInteger, State.BlendingFunction
+ * default = State.BLENDFUNC_ONE
+ * o3d.StencilComparisonFunction
+ * ParamInteger, State.Comparison
+ * default = State.CMP_ALWAYS
+ * o3d.StencilEnableParamBoolean
+ * default = false
+ * o3d.StencilFailOperation
+ * ParamInteger, State.StencilOperation
+ * default = State.STENCIL_KEEP
+ * o3d.StencilMaskParamInteger 0-255
+ * default = 255
+ * o3d.StencilPassOperation
+ * ParamInteger, State.StencilOperation
+ * default = State.STENCIL_KEEP
+ * o3d.StencilReferenceParamInteger 0-255
+ * default = 0
+ * o3d.StencilWriteMaskParamInteger 0-255
+ * default = 255
+ * o3d.StencilZFailOperation
+ * ParamInteger, State.StencilOperation
+ * default = State.STENCIL_KEEP
+ * o3d.TwoSidedStencilEnableParamBoolean
+ * default = false
+ * o3d.ZComparisonFunction
+ * ParamInteger, State.Comparison
+ * default = State.CMP_LESS
+ * o3d.ZEnableParamBoolean
+ * default = true
+ * o3d.ZWriteEnableParamBoolean
+ * default = true
+ *
+ *
+ * Note: Polygon offset is computed with the following formula:
+ *
+ * totalOffset = PolygonOffset1 * slope + PolygonOffset2 * r
+ *
+ * Slope is the maximum difference in depth between 2 adjacent pixels of the
+ * polygon. r is the smallest value that would fail the NOTEQUAL test against
+ * 0.
+ * Typical useful values to layer a polygon on top of another one are -1.0 for
+ * each of PolygonOffset1 and PolygonOffset2.
+ */
+o3d.State.prototype.getStateParam =
+ function(state_name) {
+ return this.state_params_[state_name];
+};
+
+
+
+o3d.State.prototype.convertCmpFunc = function(cmp) {
+ switch(cmp) {
+ case o3d.State.CMP_ALWAYS:
+ return this.gl.ALWAYS;
+ case o3d.State.CMP_NEVER:
+ return this.gl.NEVER;
+ case o3d.State.CMP_LESS:
+ return this.gl.LESS;
+ case o3d.State.CMP_GREATER:
+ return this.gl.GREATER;
+ case o3d.State.CMP_LEQUAL:
+ return this.gl.LEQUAL;
+ case o3d.State.CMP_GEQUAL:
+ return this.gl.GEQUAL;
+ case o3d.State.CMP_EQUAL:
+ return this.gl.EQUAL;
+ case o3d.State.CMP_NOTEQUAL:
+ return this.gl.NOTEQUAL;
+ default:
+ break;
+ }
+ return this.gl.ALWAYS;
+};
+
+
+o3d.State.prototype.convertFillMode = function(mode) {
+ switch (mode) {
+ case o3d.State.POINT:
+ return this.gl.POINT;
+ case o3d.State.WIREFRAME:
+ return this.gl.LINE;
+ case o3d.State.SOLID:
+ return this.gl.FILL;
+ default:
+ break;
+ }
+ return this.gl.FILL;
+};
+
+
+o3d.State.prototype.convertBlendFunc = function(blend_func) {
+ switch (blend_func) {
+ case o3d.State.BLENDFUNC_ZERO:
+ return this.gl.ZERO;
+ case o3d.State.BLENDFUNC_ONE:
+ return this.gl.ONE;
+ case o3d.State.BLENDFUNC_SOURCE_COLOR:
+ return this.gl.SRC_COLOR;
+ case o3d.State.BLENDFUNC_INVERSE_SOURCE_COLOR:
+ return this.gl.ONE_MINUS_SRC_COLOR;
+ case o3d.State.BLENDFUNC_SOURCE_ALPHA:
+ return this.gl.SRC_ALPHA;
+ case o3d.State.BLENDFUNC_INVERSE_SOURCE_ALPHA:
+ return this.gl.ONE_MINUS_SRC_ALPHA;
+ case o3d.State.BLENDFUNC_DESTINATION_ALPHA:
+ return this.gl.DST_ALPHA;
+ case o3d.State.BLENDFUNC_INVERSE_DESTINATION_ALPHA:
+ return this.gl.ONE_MINUS_DST_ALPHA;
+ case o3d.State.BLENDFUNC_DESTINATION_COLOR:
+ return this.gl.DST_COLOR;
+ case o3d.State.BLENDFUNC_INVERSE_DESTINATION_COLOR:
+ return this.gl.ONE_MINUS_DST_COLOR;
+ case o3d.State.BLENDFUNC_SOURCE_ALPHA_SATUTRATE:
+ return this.gl.SRC_ALPHA_SATURATE;
+ default:
+ break;
+ }
+ return this.gl.ONE;
+};
+
+
+o3d.State.prototype.convertBlendEquation = function(blend_equation) {
+ switch (blend_equation) {
+ case o3d.State.BLEND_ADD:
+ return this.gl.FUNC_ADD;
+ case o3d.State.BLEND_SUBTRACT:
+ return this.gl.FUNC_SUBTRACT;
+ case o3d.State.BLEND_REVERSE_SUBTRACT:
+ return this.gl.FUNC_REVERSE_SUBTRACT;
+ case o3d.State.BLEND_MIN:
+ return this.gl.MIN;
+ case o3d.State.BLEND_MAX:
+ return this.gl.MAX;
+ default:
+ break;
+ }
+ return this.gl.FUNC_ADD;
+};
+
+
+o3d.State.prototype.convertStencilOp = function(stencil_func) {
+ switch (stencil_func) {
+ case o3d.State.STENCIL_KEEP:
+ return this.gl.KEEP;
+ case o3d.State.STENCIL_ZERO:
+ return this.gl.ZERO;
+ case o3d.State.STENCIL_REPLACE:
+ return this.gl.REPLACE;
+ case o3d.State.STENCIL_INCREMENT_SATURATE:
+ return this.gl.INCR;
+ case o3d.State.STENCIL_DECREMENT_SATURATE:
+ return this.gl.DECR;
+ case o3d.State.STENCIL_INVERT:
+ return this.gl.INVERT;
+ case o3d.State.STENCIL_INCREMENT:
+ return this.gl.INCR_WRAP;
+ case o3d.State.STENCIL_DECREMENT:
+ return this.gl.DECR_WRAP;
+ default:
+ break;
+ }
+ return this.gl.KEEP;
+};
+
+
+o3d.State.prototype.set = function() {
+ var stateParams = this.state_params_;
+
+ if (stateParams['AlphaBlendEnable'].value) {
+ this.gl.enable(this.gl.ALPHA);
+ } else {
+ this.gl.disable(this.gl.ALPHA);
+ }
+
+ if (stateParams['SeparateAlphaBlendEnable'].value) {
+ this.gl.blendFuncSeparate(
+ this.convertBlendFunc(stateParams['SourceBlendFunction'].value),
+ this.convertBlendFunc(stateParams['DestinationBlendFunction'].value),
+ this.convertBlendFunc(stateParams['SourceBlendAlphaFunction'].value),
+ this.convertBlendFunc(
+ stateParams['DestinationBlendAlphaFunction'].value));
+ } else {
+ this.gl.blendFuncSeparate(
+ this.convertBlendFunc(stateParams['SourceBlendFunction'].value),
+ this.convertBlendFunc(stateParams['DestinationBlendFunction'].value));
+ }
+
+ switch (stateParams['CullMode'].value) {
+ case o3d.State.CULL_CW:
+ this.gl.enable(this.gl.CULL_FACE);
+ this.gl.cullFace(this.gl.BACK);
+ break;
+ case o3d.State.CULL_CCW:
+ this.gl.enable(this.gl.CULL_FACE);
+ this.gl.cullFace(this.gl.FRONT);
+ break;
+ default:
+ this.gl.disable(this.gl.CULL_FACE);
+ break;
+ }
+
+ if (stateParams['SeparateAlphaBlendEnable'].value) {
+ this.gl.blendEquationSeparate(
+ this.convertBlendEquation(stateParams['BlendEquation'].value),
+ this.convertBlendEquation(stateParams['BlendAlphaEquation'].value));
+ } else {
+ this.gl.blendEquation(
+ this.convertBlendEquation(stateParams['BlendEquation'].value));
+ }
+
+ if (stateParams['DitherEnable'].value) {
+ this.gl.enable(this.gl.DITHER);
+ } else {
+ this.gl.disable(this.gl.DITHER);
+ }
+
+ if (stateParams['ZEnable'].value) {
+ this.gl.enable(this.gl.DEPTH_TEST);
+ this.gl.depthFunc(
+ this.convertCmpFunc(stateParams['ZComparisonFunction'].value));
+ } else {
+ this.gl.disable(this.gl.DEPTH_TEST);
+ }
+
+ if (stateParams['StencilEnable'].value) {
+ this.gl.enable(this.gl.STENCIL_TEST);
+ this.gl.stencilFunc(
+ this.convertCmpFunc(stateParams['StencilComparisonFunction'].value));
+ } else {
+ this.gl.disable(this.gl.STENCIL_TEST);
+ }
+};
+
diff --git a/o3d/samples/o3d-webgl/state_set.js b/o3d/samples/o3d-webgl/state_set.js
new file mode 100644
index 0000000..8fe1881
--- /dev/null
+++ b/o3d/samples/o3d-webgl/state_set.js
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * A StateSet is a render node that sets render states of all of its
+ * children. You can make this a parent of a part of the render graph to set
+ * render states in a more global way.
+ *
+ * @param {o3d.State} opt_state The State the defines what states to set.
+ * @constructor
+ */
+o3d.StateSet = function(opt_state) {
+ o3d.ParamObject.call(this);
+ this.state = opt_state || null;
+};
+o3d.inherit('StateSet', 'RenderNode');
+
+
+/**
+ * The State for this StateSet.
+ */
+o3d.StateSet.prototype.state = null;
+
+
+/**
+ * Sets the current state to the member state.
+ */
+o3d.StateSet.prototype.before = function() {
+ if (this.state)
+ this.state.set();
+};
+
+
diff --git a/o3d/samples/o3d-webgl/stream.js b/o3d/samples/o3d-webgl/stream.js
new file mode 100644
index 0000000..0a3cf19
--- /dev/null
+++ b/o3d/samples/o3d-webgl/stream.js
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * Namespace o3d
+ * @constructor
+ */
+o3d.Stream = function(semantic, semantic_index, field, start_index) {
+ this.semantic = semantic;
+ this.semanticIndex = semantic_index;
+ this.field = field;
+ this.startIndex = start_index;
+};
+o3d.inherit('Stream', 'NamedObject')
+
+/**
+ * @type {number}
+ */
+o3d.Stream.Semantic = goog.typedef;
+
+/**
+ * Semantic,
+ * UNKNOWN_SEMANTIC = 0,
+ * POSITION,
+ * NORMAL,
+ * TANGENT,
+ * BINORMAL,
+ * COLOR,
+ * TEXCOORD
+ *
+ * Semantics used when binding buffers to the streambank. They determine how
+ * the Stream links up to the shader inputs.
+ */
+o3d.Stream.UNKNOWN_SEMANTIC = 0;
+o3d.Stream.POSITION = 1;
+o3d.Stream.NORMAL = 2;
+o3d.Stream.TANGENT = 3;
+o3d.Stream.BINORMAL = 4;
+o3d.Stream.COLOR = 5;
+o3d.Stream.TEXCOORD = 6;
+
+
+
+/**
+ * The associated Field.
+ */
+o3d.Stream.prototype.field = null;
+
+
+
+/**
+ * The semantic specified for the Stream.
+ */
+o3d.Stream.prototype.semantic = o3d.Stream.UNKNOWN_SEMANTIC;
+
+
+
+/**
+ * The semantic index specified for the Stream
+ * (eg., TEXCOORD1 = 1, BINORMAL7 = 7, etc).
+ */
+o3d.Stream.prototype.semanticIndex = 0;
+
+
+
+/**
+ * The start index for the Stream.
+ */
+o3d.Stream.prototype.startIndex = 0;
+
+
+
diff --git a/o3d/samples/o3d-webgl/stream_bank.js b/o3d/samples/o3d-webgl/stream_bank.js
new file mode 100644
index 0000000..b6c032a
--- /dev/null
+++ b/o3d/samples/o3d-webgl/stream_bank.js
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * The StreamBank a collection of streams that hold vertices.
+ * @constructor
+ */
+o3d.StreamBank = function() {
+ this.vertexStreams = [];
+};
+o3d.inherit('StreamBank', 'NamedObject');
+
+/**
+ * Array of streams.
+ */
+o3d.StreamBank.prototype.vertexStreams = [];
+
+
+/**
+ * Binds a VertexBuffer field to the StreamBank and defines how the data in
+ * the buffer should be interpreted. The field's buffer must be of a
+ * compatible type otherwise the binding fails and the function returns false.
+ * @param {o3d.Stream.Semantic} semantic The particular use of this stream.
+ * @param {number} semantic_index Which index of a particular semantic to use.
+ * @param {o3d.Field} field The field containing information for this stream.
+ * @param {number} start_index The first element to use.
+ * @returns {boolean} True if successful.
+ */
+o3d.StreamBank.prototype.setVertexStream =
+ function(semantic, semantic_index, field, start_index) {
+ if (this.vertexStreams[semantic] == undefined) {
+ this.vertexStreams[semantic] = [];
+ }
+ this.vertexStreams[semantic][semantic_index] = new o3d.Stream(
+ semantic, semantic_index, field, start_index);
+};
+
+
+/**
+ * Searches the vertex streams bound to the StreamBank for one with the given
+ * stream semantic. If a stream is not found then it returns null.
+ * @param {o3d.Stream.Semantic} semantic The particular use of this stream.
+ * @param {o3d.Stream.Semantic} semantic_index Which index of a particular
+ * semantic to use.
+ * @returns {o3d.Stream} The found stream or null if it does not exist.
+ */
+o3d.StreamBank.prototype.getVertexStream =
+ function(semantic, semantic_index) {
+ if (this.vertexStreams[semantic] == undefined) {
+ return;
+ }
+ return this.vertexStreams[semantic][semantic_index];
+};
+
+
+/**
+ * Removes a vertex stream from this StreamBank.
+ * @param {o3d.Stream.Semantic} semantic The particular use of this stream.
+ * @param {o3d.Stream.Semantic} semantic_index Which index of a particular
+ * semantic to use.
+ * @returns {boolean} true if the specified stream existed.
+ */
+o3d.StreamBank.prototype.removeVertexStream =
+ function(semantic, semantic_index) {
+ if (this.vertexStreams[semantic] == undefined) {
+ return false;
+ }
+ this.vertexStreams[semantic][semantic_index] = null;
+ return true;
+};
+
+
diff --git a/o3d/samples/o3d-webgl/texture.js b/o3d/samples/o3d-webgl/texture.js
new file mode 100644
index 0000000..767e608
--- /dev/null
+++ b/o3d/samples/o3d-webgl/texture.js
@@ -0,0 +1,463 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * The Texture class is a base class for image data used in texture mapping.
+ * @constructor
+ */
+o3d.Texture = function() {
+ o3d.ParamObject.call(this);
+};
+o3d.inherit('Texture', 'ParamObject');
+
+
+/**
+ * @type {number}
+ */
+o3d.Texture.Format = goog.typedef;
+
+/**
+ * Format,
+ * UNKNOWN_FORMAT
+ * XRGB8
+ * ARGB8
+ * ABGR16F
+ * R32F
+ * ABGR32F
+ * DXT1
+ * DXT3
+ * DXT5
+ *
+ * The in-memory format of the texture bitmap.
+ *
+ * NOTE: The R32F format is different on GL vs D3D. If you use it in a shader
+ * you must only use the red channel. The green, blue and alpha channels are
+ * undefined.
+ *
+ * For example:
+ *
+ * ...
+ *
+ * sampler texSampler0;
+ *
+ * ...
+ *
+ * struct PixelShaderInput {
+ * float4 position : POSITION;
+ * float2 texcoord : TEXCOORD0;
+ * };
+ *
+ * float4 pixelShaderFunction(PixelShaderInput input): COLOR {
+ * return tex2D(texSampler0, input.texcoord).rrrr;
+ * }
+ *
+ * @param {number} levels The number of mip levels in this texture.
+ */
+o3d.Texture.UNKNOWN_FORMAT = 0;
+o3d.Texture.XRGB8 = 1;
+o3d.Texture.ARGB8 = 2;
+o3d.Texture.ABGR16F = 3;
+o3d.Texture.R32F = 4;
+o3d.Texture.ABGR32F = 5;
+o3d.Texture.DXT1 = 6;
+o3d.Texture.DXT3 = 7;
+o3d.Texture.DXT5 = 8;
+
+
+
+/**
+ * The memory format used for storing the bitmap associated with the texture
+ * object.
+ * @type {o3d.Texture.Format}
+ */
+o3d.Texture.prototype.format = o3d.Texture.UNKNOWN_FORMAT;
+
+
+
+/**
+ * The number of mipmap levels used by the texture.
+ * type {number}
+ */
+o3d.Texture.prototype.levels = 1;
+
+
+
+/**
+ * True if all the alpha values in the texture are 1.0
+ * type {boolean}
+ */
+o3d.Texture.prototype.alphaIsOne = true;
+
+
+
+/**
+ * Generates Mips.
+ * @param {number} source_level the mip to use as the source.
+ * @param {number} num_levels the number of mips from the source to generate.
+ */
+o3d.Texture.prototype.generateMips =
+ function(source_level, num_levels) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * A class for 2D textures that defines the interface for getting
+ * the dimensions of the texture, its memory format and number of mipmap levels.
+ *
+ * @param {number} opt_width The width of this texture in pixels.
+ * @param {number} opt_height The height of this texture in pixels.
+ * @constructor
+ */
+o3d.Texture2D = function() {
+ this.width = opt_width || 0;
+ this.height = opt_height || 0;
+};
+o3d.inherit('Texture2D', 'Texture');
+
+
+/**
+ * The width of the texture, in texels.
+ * @type {number}
+ */
+o3d.Texture2D.prototype.width = 0;
+
+
+
+/**
+ * The height of the texture, in texels.
+ * @type {number}
+ */
+o3d.Texture2D.prototype.height = 0;
+
+
+
+/**
+ * Returns a RenderSurface object associated with a mip_level of a texture.
+ *
+ * @param {number} mip_level The mip-level of the surface to be returned.
+ * @param {number} opt_pack pack This parameter is no longer used.
+ * The surface exists as long as the texture it came from exists.
+ * @returns {o3d.RenderSurface} The RenderSurface object.
+ */
+o3d.Texture2D.prototype.getRenderSurface =
+ function(mip_level, opt_pack) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Sets the values of the data stored in the texture.
+ *
+ * It is not recommend that you call this for large textures but it is useful
+ * for making simple ramps or noise textures for shaders.
+ *
+ * NOTE: the number of values must equal the size of the texture * the number
+ * of elements. In other words, for a XRGB8 texture there must be
+ * width * height * 3 values. For an ARGB8, ABGR16F or ABGR32F texture there
+ * must be width * height * 4 values. For an R32F texture there must be
+ * width * height values.
+ *
+ * NOTE: the order of channels is R G B for XRGB8 textures and R G B A
+ * for ARGB8, ABGR16F and ABGR32F textures so for example for XRGB8 textures\n
+ * \n
+ * [1, 0, 0] = a red pixel\n
+ * [0, 0, 1] = a blue pixel\n
+ * \n
+ * For ARGB8, ABGR16F, ABGR32F textures\n
+ * \n
+ * [1, 0, 0, 0] = a red pixel with zero alpha\n
+ * [1, 0, 0, 1] = a red pixel with one alpha\n
+ * [0, 0, 1, 1] = a blue pixel with one alpha\n
+ *
+ * @param {number} level the mip level to update.
+ * @param {number} values Values to be stored in the buffer.
+ */
+o3d.Texture2D.prototype.set =
+ function(level, values) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Sets a rectangular area of values in a texture.
+ *
+ * Does clipping. In other words if you pass in a 10x10 pixel array
+ * and give it destination of (-5, -5) it will only use the bottom 5x5
+ * pixels of the array you passed in to set the top 5x5 pixels of the
+ * texture.
+ *
+ * See o3d.Texture2D.set for details on formats.
+ *
+ * @param {number} level the mip level to update.
+ * @param {number} destination_x The x coordinate of the area in the texture
+ * to affect.
+ * @param {number} destination_y The y coordinate of the area in the texture
+ * to affect.
+ * @param {number} source_width The width of the area to effect. The height is
+ * determined by the size of the array passed in.
+ * @param {number} values Values to be stored in the buffer.
+ */
+o3d.Texture2D.prototype.setRect =
+ function(level, destination_x, destination_y, source_width, values) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Gets a rectangular area of values from a texture.
+ *
+ * See o3d.Texture2D.set for details on formats.
+ * Can not be used for compressed textures.
+ *
+ * @param {number} level the mip level to get.
+ * @param {number} x The x coordinate of the area in the texture to retrieve.
+ * @param {number} y The y coordinate of the area in the texture to retrieve.
+ * @param {number} width The width of the area to retrieve.
+ * @param {number} height The height of the area to retrieve.
+ * @returns {number} Array of pixel values.
+ */
+o3d.Texture2D.prototype.getRect =
+ function(level, x, y, width, height) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Sets the content of the texture to the content of the bitmap. The texture
+ * and the bitmap must be the same dimensions and the same format.
+ *
+ * @param {o3d.Bitmap} bitmap The bitmap to copy data from.
+ */
+o3d.Texture2D.prototype.setFromBitmap =
+ function(bitmap) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Copy pixels from source bitmap to certain mip level.
+ * Scales if the width and height of source and dest do not match.
+ * TODO(petersont): Takes optional arguments.
+ *
+ * @param {o3d.Bitmap} source_img The source bitmap.
+ * @param {number} source_mip which mip from the source to copy from.
+ * @param {number} source_x x-coordinate of the starting pixel in the
+ * source image.
+ * @param {number} source_y y-coordinate of the starting pixel in the
+ * source image.
+ * @param {number} source_width width of the source image to draw.
+ * @param {number} source_height Height of the source image to draw.
+ * @param {number} dest_mip on which mip level to draw to.
+ * @param {number} dest_x x-coordinate of the starting pixel in the
+ * destination texture.
+ * @param {number} dest_y y-coordinate of the starting pixel in the
+ * destination texture.
+ * @param {number} dest_width width of the dest image.
+ * @param {number} dest_height height of the dest image.
+ */
+o3d.Texture2D.prototype.drawImage =
+ function(source_img, source_mip, source_x, source_y, source_width,
+ source_height, dest_mip, dest_x, dest_y, dest_width,
+ dest_height) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * TextureCUBE is a class for textures used for cube mapping. A cube texture
+ * stores bitmaps for the 6 faces of a cube and is addressed via three texture
+ * coordinates.
+ *
+ * @param {number} edgeLength The length of any edge of this texture
+ * @constructor
+ */
+o3d.TextureCUBE = function() { };
+o3d.inherit('TextureCUBE', 'Texture');
+
+
+/**
+ * @type {number}
+ */
+o3d.TextureCUBE.CubeFace = goog.typedef;
+
+
+/**
+ * CubeFace,
+ * FACE_POSITIVE_X
+ * FACE_NEGATIVE_X
+ * FACE_POSITIVE_Y
+ * FACE_NEGATIVE_Y
+ * FACE_POSITIVE_Z
+ * FACE_NEGATIVE_Z
+ *
+ * The names of each of the six faces of a cube map texture.
+ */
+o3d.TextureCUBE.FACE_POSITIVE_X = 0;
+o3d.TextureCUBE.FACE_NEGATIVE_X = 1;
+o3d.TextureCUBE.FACE_POSITIVE_Y = 2;
+o3d.TextureCUBE.FACE_NEGATIVE_Y = 3;
+o3d.TextureCUBE.FACE_POSITIVE_Z = 4;
+o3d.TextureCUBE.FACE_NEGATIVE_Z = 5;
+
+
+/**
+ * The length of each edge of the cube, in texels.
+ * @type {number}
+ */
+o3d.TextureCUBE.prototype.edge_length = 0;
+
+
+/**
+ * Returns a RenderSurface object associated with a given cube face and
+ * mip_level of a texture.
+ *
+ * @param {o3d.TextureCUBE.CubeFace} face The cube face from which to extract
+ * the surface.
+ * @param {o3d.Pack} pack This parameter is no longer used. The surface exists
+ * as long as the texture it came from exists.
+ * @param {number} mip_level The mip-level of the surface to be returned.
+ * @returns {o3d.RenderSurface} The RenderSurface object.
+ */
+o3d.TextureCUBE.prototype.getRenderSurface =
+ function(face, mip_level, opt_pack) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Sets the values of the data stored in the texture.
+ *
+ * It is not recommend that you call this for large textures but it is useful
+ * for making simple ramps or noise textures for shaders.
+ *
+ * See o3d.Texture2D.set for details on formats.
+ *
+ * @param {o3d.TextureCUBE.CubeFace} face the face to update.
+ * @param {number} level the mip level to update.
+ * @param {number} values Values to be stored in the buffer.
+ */
+o3d.TextureCUBE.prototype.set =
+ function(face, level, values) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Sets a rectangular area of values in a texture.
+ *
+ * Does clipping. In other words if you pass in a 10x10 pixel array
+ * and give it destination of (-5, -5) it will only use the bottom 5x5
+ * pixels of the array you passed in to set the top 5x5 pixels of the
+ * texture.
+ *
+ * See o3d.Texture2D.set for details on formats.
+ *
+ * @param {o3d.TextureCUBE.CubeFace} face the face to update.
+ * @param {number} level the mip level to update.
+ * @param {number} destination_x The x coordinate of the area in the texture
+ * to affect.
+ * @param {number} destination_y The y coordinate of the area in the texture
+ * to affect.
+ * @param {number} source_width The width of the area to effect. The height is
+ * determined by the size of the array passed in.
+ * @param {number} values Values to be stored in the buffer.
+ */
+o3d.TextureCUBE.prototype.setRect =
+ function(face, level, destination_x, destination_y, source_width, values) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Gets a rectangular area of values from a texture.
+ *
+ * See o3d.Texture2D.set for details on formats.
+ * Can not be used for compressed textures.
+ *
+ * @param {o3d.TextureCUBE.CubeFace} face the face to get.
+ * @param {number} level the mip level to get.
+ * @param {number} x The x coordinate of the area in the texture to retrieve.
+ * @param {number} y The y coordinate of the area in the texture to retrieve.
+ * @param {number} width The width of the area to retrieve.
+ * @param {number} height The height of the area to retrieve.
+ * @returns {number} Array of pixel values.
+ */
+o3d.TextureCUBE.prototype.getRect =
+ function(face, level, x, y, width, height) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Sets the content of a face of the texture to the content of the bitmap. The
+ * texture and the bitmap must be the same dimensions and the same format.
+ *
+ * @param {o3d.TextureCUBE.CubeFace} face The face to set.
+ * @param {o3d.Bitmap} bitmap The bitmap to copy data from.
+ */
+o3d.TextureCUBE.prototype.setFromBitmap =
+ function(face, bitmap) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Copy pixels from source bitmap to certain face and mip level.
+ * Scales if the width and height of source and dest do not match.
+ * TODO(petersont): Should take optional arguments.
+ *
+ * @param {o3d.Bitmap} source_img The source bitmap.
+ * @param {number} source_mip which mip of the source to copy from.
+ * @param {number} source_x x-coordinate of the starting pixel in the
+ * source image.
+ * @param {number} source_y y-coordinate of the starting pixel in the
+ * source image.
+ * @param {number} source_width width of the source image to draw.
+ * @param {number} source_height Height of the source image to draw.
+ * @param {o3d.TextureCUBE.CubeFace} face on which face to draw on.
+ * @param {number} dest_mip on which mip level to draw on.
+ * @param {number} dest_x x-coordinate of the starting pixel in the
+ * destination texture.
+ * @param {number} dest_y y-coordinate of the starting pixel in the
+ * destination texture.
+ * @param {number} dest_width width of the destination image.
+ * @param {number} dest_height height of the destination image.
+ */
+o3d.TextureCUBE.prototype.drawImage =
+ function(source_img, source_mip, source_x, source_y, source_width,
+ source_height, face, dest_mip, dest_x, dest_y, dest_width,
+ dest_height) {
+ o3d.notImplemented();
+};
+
+
diff --git a/o3d/samples/o3d-webgl/transform.js b/o3d/samples/o3d-webgl/transform.js
new file mode 100644
index 0000000..2ef5d21
--- /dev/null
+++ b/o3d/samples/o3d-webgl/transform.js
@@ -0,0 +1,942 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * The Transform defines parent child relationship and a localMatrix..
+ * A Transform can have one or no parents and
+ * an arbitrary number of children.
+ *
+ * @param {o3d.math.Matrix4} opt_localMatrix The local matrix for this
+ * transform.
+ * @param {o3d.math.Matrix4} opt_worldMatrix ParamMatrix4 The world matrix of
+ * this transform.
+ * @param {boolean} opt_visible Whether or not this transform and all its
+ * children are visible.
+ * @param {o3d.BoundingBox} opt_boundingBox ParamBoundingBox The bounding box
+ * for this transform and all its children.
+ * @param {boolean} opt_cull ParamBoolean Whether or not to attempt to
+ * cull this transform and all its children based on whether or not its
+ * bounding box is in the view frustum.
+ * @constructor
+ */
+o3d.Transform =
+ function(opt_localMatrix, opt_worldMatrix, opt_visible, opt_boundingBox,
+ opt_cull) {
+ this.localMatrix = opt_localMatrix ||
+ [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]];
+ this.worldMatrix = opt_worldMatrix ||
+ [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]];
+ this.visible = opt_visible || true;
+ this.boundingBox = opt_boundingBox ||
+ new o3d.BoundingBox([-1, -1, -1], [1, 1, 1]);
+ this.cull = opt_cull || false;
+
+ this.children = [];
+ this.shapes = [];
+};
+o3d.inherit('Transform', 'ParamObject');
+
+
+/**
+ * The Visibility for this transform.
+ * Default = true.
+ */
+o3d.Transform.prototype.visible = true;
+
+
+
+/**
+ * Sets the parent of the transform by re-parenting the transform under
+ * parent. Setting parent to null removes the transform and the
+ * entire subtree below it from the transform graph.
+ * If the operation would create a cycle it fails.
+ */
+o3d.Transform.prototype.parent = null;
+
+o3d.Transform.prototype.__defineSetter__('parent',
+ function(p) {
+ this.parent_ = p;
+ p.addChild(this);
+ }
+);
+
+o3d.Transform.prototype.__defineGetter__('parent',
+ function(p) {
+ return this.parent_;
+ }
+);
+
+
+/**
+ * The immediate children of this Transform.
+ *
+ * Each access to this field gets the entire list, so it is best to get it
+ * just once. For example:
+ *
+ * var children = transform.children;
+ * for (var i = 0; i < children.length; i++) {
+ * var child = children[i];
+ * }
+ *
+ * Note that modifications to this array [e.g. additions to it] will not affect
+ * the underlying Transform, while modifications to the members of the array
+ * will affect them.
+ */
+o3d.Transform.prototype.children = [];
+
+
+/**
+ * Adds a child transform.
+ * @param {o3d.Transform} The new child.
+ */
+o3d.Transform.prototype.addChild = function(child) {
+ this.children.push(child);
+};
+
+
+/**
+ * Returns all the transforms under this transform including this one.
+ *
+ * Note that modifications to this array [e.g. additions to it] will not affect
+ * the underlying Transform, while modifications to the members of the array
+ * will affect them.
+ *
+ * An array containing the transforms of the subtree.
+ */
+o3d.Transform.prototype.getTransformsInTree =
+ function() {
+
+};
+
+
+
+/**
+ * Searches for transforms that match the given name in the hierarchy under and
+ * including this transform. Since there can be more than one transform with a
+ * given name, results are returned in an array.
+ *
+ * Note that modifications to this array [e.g. additions to it] will not affect
+ * the underlying Transform, while modifications to the members of the array
+ * will affect them.
+ *
+ * @param {string} name Transform name to look for.
+ * @returns {Array.<o3d.Transform>} An array containing the transforms of the
+ * under and including this transform matching the given name.
+ */
+o3d.Transform.prototype.getTransformsByNameInTree =
+ function(name) {
+
+};
+
+
+/**
+ * Evaluates and returns the current world matrix.
+ *
+ * The updated world matrix.
+ */
+o3d.Transform.prototype.getUpdatedWorldMatrix =
+ function() {
+
+};
+
+
+/**
+ * Adds a shape do this transform.
+ * @param {o3d.Shape} shape Shape to add.
+ */
+o3d.Transform.prototype.addShape =
+ function(shape) {
+ this.shapes.push(shape);
+};
+
+
+/**
+ * Removes a shape from this transform.
+ * @param {o3d.Shape} shape Shape to remove.
+ * @returns {boolean} true if successful, false if shape was not in
+ * this transform.
+ */
+o3d.Transform.prototype.removeShape =
+ function(shape) {
+
+};
+
+
+/**
+ * Gets the shapes owned by this transform.
+ *
+ * Each access to this field gets the entire list so it is best to get it
+ * just once. For example:
+ *
+ * var shapes = transform.shapes;
+ * for (var i = 0; i < shapes.length; i++) {
+ * var shape = shapes[i];
+ * }
+ *
+ *
+ * Note that modifications to this array [e.g. additions to it] will not affect
+ * the underlying Transform, while modifications to the members of the array
+ * will affect them.
+ */
+o3d.Transform.prototype.shapes = [];
+
+
+
+/**
+ * Walks the tree of transforms starting with this transform and creates
+ * draw elements. If an Element already has a DrawElement that uses material a
+ * new DrawElement will not be created.
+ * @param {o3d.Pack} pack Pack used to manage created elements.
+ * @param {o3d.Material} material Material to use for each element. If you
+ * pass null, it will use the material on the element to which a draw
+ * element is being added. In other words, a DrawElement will use the
+ * material of the corresponding Element if material is null. This allows
+ * you to easily setup the default (just draw as is) by passing null or
+ * setup a shadow pass by passing in a shadow material.
+ */
+o3d.Transform.prototype.createDrawElements =
+ function(pack, material) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * World (model) matrix as it was last computed.
+ */
+o3d.Transform.prototype.worldMatrix = [];
+
+
+
+/**
+ * Local transformation matrix.
+ * Default = Identity.
+ */
+o3d.Transform.prototype.local_matrix = [];
+
+
+
+/**
+ * The cull setting for this transform. If true this Transform will be culled
+ * by having its bounding box compared to the view frustum of any draw context
+ * it is used with.
+ * Default = false.
+ */
+o3d.Transform.prototype.cull_ = false;
+
+
+
+/**
+ * The BoundingBox for this Transform. If culling is on this bounding box will
+ * be tested against the view frustum of any draw context used to with this
+ * Transform.
+ */
+o3d.Transform.prototype.boundingBox = null;
+
+
+
+/**
+ * Sets the local matrix of this transform to the identity matrix.
+ */
+o3d.Transform.prototype.identity = function() {
+ var m = this.localMatrix;
+ for (var i = 0; i < 4; ++i) {
+ for (var j = 0; j < 4; ++j) {
+ m[i][j] = i==j ? 1 : 0;
+ }
+ }
+};
+
+
+/*
+ * Utility function to copose a matrix with another matrix.
+ * Precomposes b with a, changing a, or if the target matrix if
+ * one is provided.
+ *
+ * @param {!Array.<!Array.<number>>} a
+ * @param {!Array.<!Array.<number>>} b
+ * @param {!Array.<!Array.<number>>} opt_target
+ */
+o3d.Transform.compose = function(a, b, opt_target) {
+ var t = opt_target || a;
+ var a0 = a[0];
+ var a1 = a[1];
+ var a2 = a[2];
+ var a3 = a[3];
+ var b0 = b[0];
+ var b1 = b[1];
+ var b2 = b[2];
+ var b3 = b[3];
+ var a00 = a0[0];
+ var a01 = a0[1];
+ var a02 = a0[2];
+ var a03 = a0[3];
+ var a10 = a1[0];
+ var a11 = a1[1];
+ var a12 = a1[2];
+ var a13 = a1[3];
+ var a20 = a2[0];
+ var a21 = a2[1];
+ var a22 = a2[2];
+ var a23 = a2[3];
+ var a30 = a3[0];
+ var a31 = a3[1];
+ var a32 = a3[2];
+ var a33 = a3[3];
+ var b00 = b0[0];
+ var b01 = b0[1];
+ var b02 = b0[2];
+ var b03 = b0[3];
+ var b10 = b1[0];
+ var b11 = b1[1];
+ var b12 = b1[2];
+ var b13 = b1[3];
+ var b20 = b2[0];
+ var b21 = b2[1];
+ var b22 = b2[2];
+ var b23 = b2[3];
+ var b30 = b3[0];
+ var b31 = b3[1];
+ var b32 = b3[2];
+ var b33 = b3[3];
+ t[0].splice(0, 4, a00 * b00 + a10 * b01 + a20 * b02 + a30 * b03,
+ a01 * b00 + a11 * b01 + a21 * b02 + a31 * b03,
+ a02 * b00 + a12 * b01 + a22 * b02 + a32 * b03,
+ a03 * b00 + a13 * b01 + a23 * b02 + a33 * b03);
+ t[1].splice(0, 4, a00 * b10 + a10 * b11 + a20 * b12 + a30 * b13,
+ a01 * b10 + a11 * b11 + a21 * b12 + a31 * b13,
+ a02 * b10 + a12 * b11 + a22 * b12 + a32 * b13,
+ a03 * b10 + a13 * b11 + a23 * b12 + a33 * b13);
+ t[2].splice(0, 4, a00 * b20 + a10 * b21 + a20 * b22 + a30 * b23,
+ a01 * b20 + a11 * b21 + a21 * b22 + a31 * b23,
+ a02 * b20 + a12 * b21 + a22 * b22 + a32 * b23,
+ a03 * b20 + a13 * b21 + a23 * b22 + a33 * b23);
+ t[3].splice(0, 4, a00 * b30 + a10 * b31 + a20 * b32 + a30 * b33,
+ a01 * b30 + a11 * b31 + a21 * b32 + a31 * b33,
+ a02 * b30 + a12 * b31 + a22 * b32 + a32 * b33,
+ a03 * b30 + a13 * b31 + a23 * b32 + a33 * b33);
+};
+
+
+/**
+ * Tests whether two matrices are either equal in the sense that they
+ * refer to the same memory, or equal in the sense that they have equal
+ * entries.
+ *
+ * @param {!Array.<!Array.<number>>} a A matrix.
+ * @param {!Array.<!Array.<number>>} b Another matrix.
+ * @returns {boolean} Whether they are equal.
+ */
+o3d.Transform.matricesEqual = function(a, b) {
+ if (a==b) {
+ return true;
+ }
+ for (var i = 0; i < 4; ++i) {
+ for (var j = 0; j < 4; ++j) {
+ if (a[i][j] != b[i][j]) {
+ return false;
+ }
+ }
+ }
+ return true;
+};
+
+
+/**
+ * Computes the transpose of the matrix a in place if no target is provided.
+ * Or if a target is provided, turns the target into the transpose of a.
+ *
+ * @param {!Array.<!Array.<number>>} m A matrix.
+ * @param {Array.<!Array.<number>>} opt_target
+ * The matrix to become the transpose of m.
+ */
+o3d.Transform.transpose = function(m, opt_target) {
+ var t = opt_target || m;
+ var m0 = m[0];
+ var m1 = m[1];
+ var m2 = m[2];
+ var m3 = m[3];
+ var m00 = m0[0];
+ var m01 = m0[1];
+ var m02 = m0[2];
+ var m03 = m0[3];
+ var m10 = m1[0];
+ var m11 = m1[1];
+ var m12 = m1[2];
+ var m13 = m1[3];
+ var m20 = m2[0];
+ var m21 = m2[1];
+ var m22 = m2[2];
+ var m23 = m2[3];
+ var m30 = m3[0];
+ var m31 = m3[1];
+ var m32 = m3[2];
+ var m33 = m3[3];
+ t[0].splice(0, 4, m00, m10, m20, m30);
+ t[1].splice(0, 4, m01, m11, m21, m31);
+ t[2].splice(0, 4, m02, m12, m22, m32);
+ t[3].splice(0, 4, m03, m13, m23, m33);
+};
+
+
+/**
+ * Computes the inverse of the matrix a in place if no target is provided.
+ * Or if a target is provided, turns the target into the transpose of a.
+ *
+ * @param {!Array.<!Array.<number>>} m A matrix.
+ * @param {Array.<!Array.<number>>} opt_target The matrix to become the
+ * inverse of a.
+ */
+o3d.Transform.inverse = function(m, opt_target) {
+ var t = opt_target || a;
+ var m0 = m[0];
+ var m1 = m[1];
+ var m2 = m[2];
+ var m3 = m[3];
+ var m00 = m0[0];
+ var m01 = m0[1];
+ var m02 = m0[2];
+ var m03 = m0[3];
+ var m10 = m1[0];
+ var m11 = m1[1];
+ var m12 = m1[2];
+ var m13 = m1[3];
+ var m20 = m2[0];
+ var m21 = m2[1];
+ var m22 = m2[2];
+ var m23 = m2[3];
+ var m30 = m3[0];
+ var m31 = m3[1];
+ var m32 = m3[2];
+ var m33 = m3[3];
+
+ var tmp_0 = m22 * m33;
+ var tmp_1 = m32 * m23;
+ var tmp_2 = m12 * m33;
+ var tmp_3 = m32 * m13;
+ var tmp_4 = m12 * m23;
+ var tmp_5 = m22 * m13;
+ var tmp_6 = m02 * m33;
+ var tmp_7 = m32 * m03;
+ var tmp_8 = m02 * m23;
+ var tmp_9 = m22 * m03;
+ var tmp_10 = m02 * m13;
+ var tmp_11 = m12 * m03;
+ var tmp_12 = m20 * m31;
+ var tmp_13 = m30 * m21;
+ var tmp_14 = m10 * m31;
+ var tmp_15 = m30 * m11;
+ var tmp_16 = m10 * m21;
+ var tmp_17 = m20 * m11;
+ var tmp_18 = m00 * m31;
+ var tmp_19 = m30 * m01;
+ var tmp_20 = m00 * m21;
+ var tmp_21 = m20 * m01;
+ var tmp_22 = m00 * m11;
+ var tmp_23 = m10 * m01;
+
+ var t0 = (tmp_0 * m11 + tmp_3 * m21 + tmp_4 * m31) -
+ (tmp_1 * m11 + tmp_2 * m21 + tmp_5 * m31);
+ var t1 = (tmp_1 * m01 + tmp_6 * m21 + tmp_9 * m31) -
+ (tmp_0 * m01 + tmp_7 * m21 + tmp_8 * m31);
+ var t2 = (tmp_2 * m01 + tmp_7 * m11 + tmp_10 * m31) -
+ (tmp_3 * m01 + tmp_6 * m11 + tmp_11 * m31);
+ var t3 = (tmp_5 * m01 + tmp_8 * m11 + tmp_11 * m21) -
+ (tmp_4 * m01 + tmp_9 * m11 + tmp_10 * m21);
+
+ var d = 1.0 / (m00 * t0 + m10 * t1 + m20 * t2 + m30 * t3);
+
+ t[0].splice(0, 4, d * t0, d * t1, d * t2, d * t3);
+ t[1].splice(0, 4, d * ((tmp_1 * m10 + tmp_2 * m20 + tmp_5 * m30) -
+ (tmp_0 * m10 + tmp_3 * m20 + tmp_4 * m30)),
+ d * ((tmp_0 * m00 + tmp_7 * m20 + tmp_8 * m30) -
+ (tmp_1 * m00 + tmp_6 * m20 + tmp_9 * m30)),
+ d * ((tmp_3 * m00 + tmp_6 * m10 + tmp_11 * m30) -
+ (tmp_2 * m00 + tmp_7 * m10 + tmp_10 * m30)),
+ d * ((tmp_4 * m00 + tmp_9 * m10 + tmp_10 * m20) -
+ (tmp_5 * m00 + tmp_8 * m10 + tmp_11 * m20)));
+ t[2].splice(0, 4, d * ((tmp_12 * m13 + tmp_15 * m23 + tmp_16 * m33) -
+ (tmp_13 * m13 + tmp_14 * m23 + tmp_17 * m33)),
+ d * ((tmp_13 * m03 + tmp_18 * m23 + tmp_21 * m33) -
+ (tmp_12 * m03 + tmp_19 * m23 + tmp_20 * m33)),
+ d * ((tmp_14 * m03 + tmp_19 * m13 + tmp_22 * m33) -
+ (tmp_15 * m03 + tmp_18 * m13 + tmp_23 * m33)),
+ d * ((tmp_17 * m03 + tmp_20 * m13 + tmp_23 * m23) -
+ (tmp_16 * m03 + tmp_21 * m13 + tmp_22 * m23)));
+ t[3].splice(0, 4, d * ((tmp_14 * m22 + tmp_17 * m32 + tmp_13 * m12) -
+ (tmp_16 * m32 + tmp_12 * m12 + tmp_15 * m22)),
+ d * ((tmp_20 * m32 + tmp_12 * m02 + tmp_19 * m22) -
+ (tmp_18 * m22 + tmp_21 * m32 + tmp_13 * m02)),
+ d * ((tmp_18 * m12 + tmp_23 * m32 + tmp_15 * m02) -
+ (tmp_22 * m32 + tmp_14 * m02 + tmp_19 * m12)),
+ d * ((tmp_22 * m22 + tmp_16 * m02 + tmp_21 * m12) -
+ (tmp_20 * m12 + tmp_23 * m22 + tmp_17 * m02)));
+};
+
+
+/**
+ * Pre-composes the local matrix of this Transform with a translation. For
+ * example, if the local matrix is a rotation then new local matrix will
+ * translate by the given vector and then rotated.
+ */
+o3d.Transform.prototype.translate =
+ function() {
+ var v;
+ if (arguments.length == 3) {
+ v = arguments;
+ } else {
+ v = arguments[0];
+ }
+ var m = this.localMatrix;
+
+ var v0 = v[0];
+ var v1 = v[1];
+ var v2 = v[2];
+ var m0 = m[0];
+ var m1 = m[1];
+ var m2 = m[2];
+ var m3 = m[3];
+ var m00 = m0[0];
+ var m01 = m0[1];
+ var m02 = m0[2];
+ var m03 = m0[3];
+ var m10 = m1[0];
+ var m11 = m1[1];
+ var m12 = m1[2];
+ var m13 = m1[3];
+ var m20 = m2[0];
+ var m21 = m2[1];
+ var m22 = m2[2];
+ var m23 = m2[3];
+ var m30 = m3[0];
+ var m31 = m3[1];
+ var m32 = m3[2];
+ var m33 = m3[3];
+
+ m3.splice(0, 4, m00 * v0 + m10 * v1 + m20 * v2 + m30,
+ m01 * v0 + m11 * v1 + m21 * v2 + m31,
+ m02 * v0 + m12 * v1 + m22 * v2 + m32,
+ m03 * v0 + m13 * v1 + m23 * v2 + m33);
+};
+
+
+/**
+ * Pre-composes the local matrix of this Transform with a rotation about the
+ * x-axis. For example, if the local matrix is a tranlsation, the new local
+ * matrix will rotate around the x-axis and then translate.
+ *
+ * @param {number} radians The number of radians to rotate around x-axis.
+ */
+o3d.Transform.prototype.rotateX =
+ function(angle) {
+ var m = this.localMatrix;
+
+ var m0 = m[0];
+ var m1 = m[1];
+ var m2 = m[2];
+ var m3 = m[3];
+ var m10 = m1[0];
+ var m11 = m1[1];
+ var m12 = m1[2];
+ var m13 = m1[3];
+ var m20 = m2[0];
+ var m21 = m2[1];
+ var m22 = m2[2];
+ var m23 = m2[3];
+ var c = Math.cos(angle);
+ var s = Math.sin(angle);
+
+ m1.splice(0, 4, c * m10 + s * m20,
+ c * m11 + s * m21,
+ c * m12 + s * m22,
+ c * m13 + s * m23);
+ m2.splice(0, 4, c * m20 - s * m10,
+ c * m21 - s * m11,
+ c * m22 - s * m12,
+ c * m23 - s * m13);
+};
+
+
+/**
+ * Pre-composes the local matrix of this Transform with a rotation about the
+ * y-axis. For example, if the local matrix is a translation, the new local
+ * matrix will rotate around the y-axis and then translate.
+ *
+ * @param {number} radians The number of radians to rotate around y-axis.
+ */
+o3d.Transform.prototype.rotateY =
+ function(angle) {
+ var m = this.localMatrix;
+
+ var m0 = m[0];
+ var m1 = m[1];
+ var m2 = m[2];
+ var m3 = m[3];
+ var m00 = m0[0];
+ var m01 = m0[1];
+ var m02 = m0[2];
+ var m03 = m0[3];
+ var m20 = m2[0];
+ var m21 = m2[1];
+ var m22 = m2[2];
+ var m23 = m2[3];
+ var c = Math.cos(angle);
+ var s = Math.sin(angle);
+
+ m0.splice(0, 4, c * m00 - s * m20,
+ c * m01 - s * m21,
+ c * m02 - s * m22,
+ c * m03 - s * m23);
+ m2.splice(0, 4, c * m20 + s * m00,
+ c * m21 + s * m01,
+ c * m22 + s * m02,
+ c * m23 + s * m03);
+};
+
+
+/**
+ * Pre-composes the local matrix of this Transform with a rotation about the
+ * z-axis. For example, if the local matrix is a translation, the new local
+ * matrix will rotate around the z-axis and then translate.
+ *
+ * @param {number} radians The number of radians to rotate around z-axis.
+ */
+o3d.Transform.prototype.rotateZ =
+ function(angle) {
+ var m = this.localMatrix;
+
+ var m0 = m[0];
+ var m1 = m[1];
+ var m2 = m[2];
+ var m3 = m[3];
+ var m00 = m0[0];
+ var m01 = m0[1];
+ var m02 = m0[2];
+ var m03 = m0[3];
+ var m10 = m1[0];
+ var m11 = m1[1];
+ var m12 = m1[2];
+ var m13 = m1[3];
+ var c = Math.cos(angle);
+ var s = Math.sin(angle);
+
+ m0.splice(0, 4, c * m00 + s * m10,
+ c * m01 + s * m11,
+ c * m02 + s * m12,
+ c * m03 + s * m13);
+ m1.splice(0, 4, c * m10 - s * m00,
+ c * m11 - s * m01,
+ c * m12 - s * m02,
+ c * m13 - s * m03);
+};
+
+
+/**
+ * Pre-composes the local matrix of this Transform with a rotation.
+ * Interprets the three entries of the given vector as angles by which to
+ * rotate around the x, y and z axes. Rotates around the x-axis first,
+ * then the y-axis, then the z-axis.
+ *
+ * @param {!o3d.math.Vector3} v A vector of angles (in radians) by which
+ * to rotate around the x, y and z axes.
+ */
+o3d.Transform.prototype.rotateZYX =
+ function(v) {
+ var m = this.localMatrix;
+
+ var sinX = Math.sin(v[0]);
+ var cosX = Math.cos(v[0]);
+ var sinY = Math.sin(v[1]);
+ var cosY = Math.cos(v[1]);
+ var sinZ = Math.sin(v[2]);
+ var cosZ = Math.cos(v[2]);
+
+ var cosZSinY = cosZ * sinY;
+ var sinZSinY = sinZ * sinY;
+
+ var r00 = cosZ * cosY;
+ var r01 = sinZ * cosY;
+ var r02 = -sinY;
+ var r10 = cosZSinY * sinX - sinZ * cosX;
+ var r11 = sinZSinY * sinX + cosZ * cosX;
+ var r12 = cosY * sinX;
+ var r20 = cosZSinY * cosX + sinZ * sinX;
+ var r21 = sinZSinY * cosX - cosZ * sinX;
+ var r22 = cosY * cosX;
+
+ var m0 = m[0];
+ var m1 = m[1];
+ var m2 = m[2];
+ var m3 = m[3];
+
+ var m00 = m0[0];
+ var m01 = m0[1];
+ var m02 = m0[2];
+ var m03 = m0[3];
+ var m10 = m1[0];
+ var m11 = m1[1];
+ var m12 = m1[2];
+ var m13 = m1[3];
+ var m20 = m2[0];
+ var m21 = m2[1];
+ var m22 = m2[2];
+ var m23 = m2[3];
+ var m30 = m3[0];
+ var m31 = m3[1];
+ var m32 = m3[2];
+ var m33 = m3[3];
+
+ m0.splice(0, 4,
+ r00 * m00 + r01 * m10 + r02 * m20,
+ r00 * m01 + r01 * m11 + r02 * m21,
+ r00 * m02 + r01 * m12 + r02 * m22,
+ r00 * m03 + r01 * m13 + r02 * m23);
+
+ m1.splice(0, 4,
+ r10 * m00 + r11 * m10 + r12 * m20,
+ r10 * m01 + r11 * m11 + r12 * m21,
+ r10 * m02 + r11 * m12 + r12 * m22,
+ r10 * m03 + r11 * m13 + r12 * m23);
+
+ m2.splice(0, 4,
+ r20 * m00 + r21 * m10 + r22 * m20,
+ r20 * m01 + r21 * m11 + r22 * m21,
+ r20 * m02 + r21 * m12 + r22 * m22,
+ r20 * m03 + r21 * m13 + r22 * m23);
+};
+
+
+/**
+ * Pre-composes the local matrix of this Transform with a rotation around the
+ * given axis. For example, if the local matrix is a translation, the new
+ * local matrix will rotate around the given axis and then translate.
+ *
+ * @param {number} angle The number of radians to rotate.
+ * @param {!o3d.math.Vector3} axis a non-zero vector representing the axis
+ * around which to rotate.
+ */
+o3d.Transform.prototype.axisRotate =
+ function(axis, angle) {
+ var m = this.localMatrix;
+
+ var x = axis[0];
+ var y = axis[1];
+ var z = axis[2];
+ var n = Math.sqrt(x * x + y * y + z * z);
+ x /= n;
+ y /= n;
+ z /= n;
+ var xx = x * x;
+ var yy = y * y;
+ var zz = z * z;
+ var c = Math.cos(angle);
+ var s = Math.sin(angle);
+ var oneMinusCosine = 1 - c;
+
+ var r00 = xx + (1 - xx) * c;
+ var r01 = x * y * oneMinusCosine + z * s;
+ var r02 = x * z * oneMinusCosine - y * s;
+ var r10 = x * y * oneMinusCosine - z * s;
+ var r11 = yy + (1 - yy) * c;
+ var r12 = y * z * oneMinusCosine + x * s;
+ var r20 = x * z * oneMinusCosine + y * s;
+ var r21 = y * z * oneMinusCosine - x * s;
+ var r22 = zz + (1 - zz) * c;
+
+ var m0 = m[0];
+ var m1 = m[1];
+ var m2 = m[2];
+ var m3 = m[3];
+
+ var m00 = m0[0];
+ var m01 = m0[1];
+ var m02 = m0[2];
+ var m03 = m0[3];
+ var m10 = m1[0];
+ var m11 = m1[1];
+ var m12 = m1[2];
+ var m13 = m1[3];
+ var m20 = m2[0];
+ var m21 = m2[1];
+ var m22 = m2[2];
+ var m23 = m2[3];
+ var m30 = m3[0];
+ var m31 = m3[1];
+ var m32 = m3[2];
+ var m33 = m3[3];
+
+ m0.splice(0, 4,
+ r00 * m00 + r01 * m10 + r02 * m20,
+ r00 * m01 + r01 * m11 + r02 * m21,
+ r00 * m02 + r01 * m12 + r02 * m22,
+ r00 * m03 + r01 * m13 + r02 * m23);
+
+ m1.splice(0, 4,
+ r10 * m00 + r11 * m10 + r12 * m20,
+ r10 * m01 + r11 * m11 + r12 * m21,
+ r10 * m02 + r11 * m12 + r12 * m22,
+ r10 * m03 + r11 * m13 + r12 * m23);
+
+ m2.splice(0, 4,
+ r20 * m00 + r21 * m10 + r22 * m20,
+ r20 * m01 + r21 * m11 + r22 * m21,
+ r20 * m02 + r21 * m12 + r22 * m22,
+ r20 * m03 + r21 * m13 + r22 * m23);
+};
+
+
+/**
+ * Pre-composes the local matrix of this Transform with a rotation defined by
+ * the given quaternion.
+ *
+ * @param {o3d.math.Quat} q A non-zero quaternion to be interpreted as a
+ * rotation.
+ */
+o3d.Transform.prototype.quaternionRotate =
+ function(q) {
+ var m = this.localMatrix;
+
+ var qX = q[0];
+ var qY = q[1];
+ var qZ = q[2];
+ var qW = q[3];
+
+ var qWqW = qW * qW;
+ var qWqX = qW * qX;
+ var qWqY = qW * qY;
+ var qWqZ = qW * qZ;
+ var qXqW = qX * qW;
+ var qXqX = qX * qX;
+ var qXqY = qX * qY;
+ var qXqZ = qX * qZ;
+ var qYqW = qY * qW;
+ var qYqX = qY * qX;
+ var qYqY = qY * qY;
+ var qYqZ = qY * qZ;
+ var qZqW = qZ * qW;
+ var qZqX = qZ * qX;
+ var qZqY = qZ * qY;
+ var qZqZ = qZ * qZ;
+
+ var d = qWqW + qXqX + qYqY + qZqZ;
+
+ o3d.Transform.compose(this.localMatrix, [
+ [(qWqW + qXqX - qYqY - qZqZ) / d,
+ 2 * (qWqZ + qXqY) / d,
+ 2 * (qXqZ - qWqY) / d, 0],
+ [2 * (qXqY - qWqZ) / d,
+ (qWqW - qXqX + qYqY - qZqZ) / d,
+ 2 * (qWqX + qYqZ) / d, 0],
+ [2 * (qWqY + qXqZ) / d,
+ 2 * (qYqZ - qWqX) / d,
+ (qWqW - qXqX - qYqY + qZqZ) / d, 0],
+ [0, 0, 0, 1]]);
+};
+
+
+/**
+ * Pre-composes the local matrix of this transform by a scaling transformation.
+ * For example, if the local matrix is a rotation, the new local matrix will
+ * scale and then rotate.
+ */
+o3d.Transform.prototype.scale =
+ function() {
+ var v;
+ if (arguments.length == 3) {
+ v = arguments;
+ } else {
+ v = arguments[0];
+ }
+
+ var m = this.localMatrix;
+
+ var v0 = v[0];
+ var v1 = v[1];
+ var v2 = v[2];
+
+ var m0 = m[0];
+ var m1 = m[1];
+ var m2 = m[2];
+ var m3 = m[3];
+
+ m0.splice(0, 4, v0 * m0[0], v0 * m0[1], v0 * m0[2], v0 * m0[3]);
+ m1.splice(0, 4, v1 * m1[0], v1 * m1[1], v1 * m1[2], v1 * m1[3]);
+ m2.splice(0, 4, v2 * m2[0], v2 * m2[1], v2 * m2[2], v2 * m2[3]);
+};
+
+
+/**
+ * Utility function to flatten an o3djs-style matrix
+ * (which is an array of arrays) into one array of entries.
+ * @param {Array.<Array.<number> >} m The o3djs-style matrix.
+ * @returns {Array.<number>} The flattened matrix.
+ */
+o3d.Transform.flattenMatrix4 = function(m) {
+ var m0 = m[0];
+ var m1 = m[1];
+ var m2 = m[2];
+ var m3 = m[3];
+ return [m0[0], m0[1], m0[2], m0[3],
+ m1[0], m1[1], m1[2], m1[3],
+ m2[0], m2[1], m2[2], m2[3],
+ m3[0], m3[1], m3[2], m3[3]];
+};
+
+
+/**
+ * Traverses the transform tree starting at this node and adds DrawElements
+ * for each shape to DrawList.
+ * @param {Array.<Object>} drawListInfos A list of objects containing a draw
+ * list and matrix information.
+ * @param {o3d.math.Matrix4} opt_parentWorldMatrix
+ */
+o3d.Transform.prototype.traverse =
+ function(drawListInfos, opt_parentWorldMatrix) {
+ opt_parentWorldMatrix =
+ opt_parentWorldMatrix ||
+ [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]];
+
+ o3d.Transform.compose(
+ opt_parentWorldMatrix, this.localMatrix, this.worldMatrix);
+
+ var children = this.children;
+ var shapes = this.shapes;
+
+ for (var i = 0; i < shapes.length; ++i) {
+ shapes[i].writeToDrawLists(drawListInfos, this.worldMatrix, this);
+ }
+
+ for (var i = 0; i < children.length; ++i) {
+ children[i].traverse(drawListInfos, this.worldMatrix);
+ }
+};
+
+
diff --git a/o3d/samples/o3d-webgl/tree_traversal.js b/o3d/samples/o3d-webgl/tree_traversal.js
new file mode 100644
index 0000000..5a5dbb6
--- /dev/null
+++ b/o3d/samples/o3d-webgl/tree_traversal.js
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * A TreeTraversal has multiple DrawLists registered with it. Each DrawList has
+ * a DrawContext registered with it. At render time the TreeTraversal walks the
+ * transform graph from the transform it's pointing at and for each DrawElement
+ * it finds who's matertial matches one of its registered DrawLists it adds that
+ * DrawElement to that DrawList.
+ *
+ * @param {o3d.Transform} opt_transform The root transform to start traversing
+ * by this TreeTraveral.
+ * @constructor
+ */
+o3d.TreeTraversal = function(opt_transform) {
+ this.transform = opt_transform;
+ this.drawLists = [];
+ this.drawListsToReset_ = [];
+};
+o3d.inherit('TreeTraversal', 'RenderNode');
+
+
+/**
+ * The root Transform this TreeTraversal will start traversing from.
+ */
+o3d.TreeTraversal.prototype.transform = null;
+
+
+/**
+ * Private list of registered drawlists.
+ */
+o3d.TreeTraversal.prototype.drawLists_ = [];
+
+/**
+ * Private list of drawlists to reset at render-time before traversal.
+ */
+o3d.TreeTraversal.prototype.drawListsToReset_ = [];
+
+/**
+ * Registers a DrawList with this TreeTraversal so that when this
+ * TreeTraversal traverses its tree, DrawElements using materials that use
+ * this DrawList will be added though possibly culled by the view frustum of
+ * the DrawContext. Note: passing in the same DrawList more than once will
+ * override the previous settings for that DrawList.
+ * @param {o3d.DrawList} draw_list DrawList to register.
+ * @param {o3d.DrawContext} draw_context DrawContext to use with the DrawList.
+ * @param {boolean} reset true if you want the DrawList reset before
+ * traversing.
+ */
+o3d.TreeTraversal.prototype.registerDrawList =
+ function(draw_list, draw_context, reset) {
+ if (reset) {
+ this.drawListsToReset_.push(draw_list);
+ }
+ this.drawLists_.push({
+ list:draw_list,
+ context:draw_context});
+};
+
+
+/**
+ * Unregisters a DrawList with this TreeTraversal.
+ * @param {o3d.DrawList} draw_list DrawList to unregister.
+ * @returns {boolean} true if unregistered. false if this draw_list was
+ * not registered.
+ */
+o3d.TreeTraversal.prototype.unregisterDrawList =
+ function(draw_list) {
+ o3d.notImplemented();
+};
+
+
+/**
+ * Called in the render graph traversal before the children are rendered.
+ */
+o3d.TreeTraversal.prototype.before =
+ function() {
+ for(var i = 0; i < this.drawListsToReset_.length; ++i) {
+ this.drawListsToReset_[i].list_ = [];
+ }
+ this.transform.traverse(this.drawLists_);
+};
diff --git a/o3d/samples/o3d-webgl/types.js b/o3d/samples/o3d-webgl/types.js
new file mode 100644
index 0000000..1207059
--- /dev/null
+++ b/o3d/samples/o3d-webgl/types.js
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * Namespace for math types.
+ */
+o3d.math = {}
+
+
+/**
+ * An Array of 3 numbers.
+ * @type {!Array.<number>}
+ */
+o3d.math.Point3 = goog.typedef;
+
+
+/**
+ * An Array of 3 numbers.
+ * @type {!Array.<number>}
+ */
+o3d.math.Vector3 = goog.typedef;
+
+
+/**
+ * An Array of 2 numbers.
+ * @type {!Array.<number>}
+ */
+o3d.Float2 = goog.typedef;
+
+
+/**
+ * An Array of 3 numbers.
+ * @type {!Array.<number>}
+ */
+o3d.Float3 = goog.typedef;
+
+
+/**
+ * An Array of 4 numbers.
+ * @type {!Array.<number>}
+ */
+o3d.Float4 = goog.typedef;
+
+
+/**
+ * A 4x4 Matrix of numbers.
+ * @type {!Array.<!Array.<number>>}
+ */
+o3d.math.Matrix4 = goog.typedef;
+
+/**
+ * An array of 4 numbers.
+ * @type {!Array.<number>}
+ */
+o3d.math.Quat = goog.typedef;
+
+
+/**
+ * A function.
+ * @type {Object}
+ */
+o3d.ErrorCallback = goog.typedef;
+
+
+/**
+ * A function.
+ * @type {Object}
+ */
+o3d.TickCallback = goog.typedef;
+
+
+/**
+ * A function.
+ * @type {Object}
+ */
+o3d.RenderCallback = goog.typedef;
+
+
+/**
+ * A function.
+ * @type {Object}
+ */
+o3d.LostResourcesCallback = goog.typedef;
+
+
+/**
+ * A function.
+ * @type {Object}
+ */
+o3d.EventCallback = goog.typedef;
diff --git a/o3d/samples/o3d-webgl/viewport.js b/o3d/samples/o3d-webgl/viewport.js
new file mode 100644
index 0000000..6c082c0
--- /dev/null
+++ b/o3d/samples/o3d-webgl/viewport.js
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * A Viewport is a render node that sets the render viewport and depth range
+ * for its children. It uses an array in the format [left, top, width, height]
+ * where left, top, width and height are in a 0.0 to 1.0 range that represent
+ * positions and dimensions relative to the size of the client's rendering
+ * area. The depth range is represented by an array in the format
+ * [min Z, max Z]. The depth range provides the mapping of the clip space
+ * coordinates into normalized z buffer coordinates.
+ *
+ * @param {o3d.math.Float4} viewport The viewport setting.
+ * @param {o3d.math.Float2} depthRange ParamFloat2 The depth range setting.
+ * @constructor
+ */
+o3d.Viewport = function(opt_viewport, opt_depthRange) {
+ this.viewport = opt_viewport || [0.0, 0.0, 1.0, 1.0];
+ this.depthRange = opt_depthRange || [0.0, 1.0];
+};
+o3d.inherit('Viewport', 'RenderNode');
+
+
+/**
+ * The position and size to set the viewport in
+ * [left, top, width, height] format.
+ *
+ * Note: These values must describe a rectangle that is 100% inside the client
+ * area. In other words, [0.5, 0.0, 1.0, 1.0] would describe an area that is
+ * 1/2 off right side of the screen. That is an invalid value and will be
+ * clipped to [0.5, 0.0, 0.5, 1.0].
+ *
+ * Default = [0.0, 0.0, 1.0, 1.0]. In other words, the full area.
+ *
+ * @type {!Array.<number>}
+ */
+o3d.Viewport.prototype.viewport = [0.0, 0.0, 1.0, 1.0];
+
+
+
+/**
+ * The min Z and max Z depth range in [min Z, max Z] format.
+ * Default = [0.0, 1.0].
+ *
+ * @type {!Array.<number>}
+ */
+o3d.Viewport.prototype.depthRange = [0.0, 1.0];
+
+
+/**
+ * Called before the children are rendered. Sets up a viewport and
+ * scissor region in gl.
+ */
+o3d.Viewport.prototype.before = function() {
+ var x = this.viewport[0] * this.gl.canvas.width;
+ var y = this.viewport[1] * this.gl.canvas.height;
+ var width = this.viewport[2] * this.gl.canvas.width;
+ var height = this.viewport[3] * this.gl.canvas.height;
+ this.gl.viewport(x, y, width, height);
+ if (x != 0 || y != 0 || this.viewport[2] != 1 || this.viewport[3] != 1) {
+ this.gl.enable(this.gl.SCISSOR_TEST);
+ this.gl.scissor(x, y, width, height);
+ } else {
+
+ }
+};
+
diff --git a/o3d/samples/o3djs/webgl.js b/o3d/samples/o3djs/webgl.js
new file mode 100644
index 0000000..6940660
--- /dev/null
+++ b/o3d/samples/o3djs/webgl.js
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * @fileoverview This file contains utility functions for o3d running on
+ * top of webgl. The function o3djs.webgl.makeClients replaces the
+ * function o3djs.util.makeClients.
+ */
+
+o3djs.provide('o3djs.webgl');
+
+o3djs.require('o3djs.util');
+
+/**
+ * A Module with various utilities.
+ * @namespace
+ */
+o3djs.webgl = o3djs.webgl || {};
+
+
+/**
+ * Finds all divs with an id that starts with "o3d" and inits a canvas
+ * under them with o3d client object and the o3d namespace.
+ */
+o3djs.webgl.makeClients = function(callback,
+ opt_features,
+ opt_requiredVersion,
+ opt_failureCallback,
+ opt_id,
+ opt_tag) {
+ opt_failureCallback = opt_failureCallback || o3djs.webgl.informPluginFailure;
+
+ var clientElements = [];
+ var elements = o3djs.util.getO3DContainerElements(opt_id, opt_tag);
+
+ for (var ee = 0; ee < elements.length; ++ee) {
+ var element = elements[ee];
+ var features = opt_features;
+ if (!features) {
+ var o3d_features = element.getAttribute('o3d_features');
+ if (o3d_features) {
+ features = o3d_features;
+ } else {
+ features = '';
+ }
+ }
+ var objElem = o3djs.webgl.createClient(element, features);
+ clientElements.push(objElem);
+ }
+
+ callback(clientElements);
+};
+
+
+/**
+ * Creates a canvas under the given parent element and an o3d.Client
+ * under that.
+ */
+o3djs.webgl.createClient = function(element, opt_features) {
+ opt_features = opt_features || '';
+
+ // TODO(petersont): Not sure what to do with the features object.
+ var canvas;
+ canvas = document.createElement('canvas');
+ canvas.setAttribute('width', element.getAttribute('width'));
+ canvas.setAttribute('height', element.getAttribute('height'));
+ canvas.client = new o3d.Client;
+ canvas.o3d = o3d;
+
+ var gl;
+ try {gl = canvas.getContext("experimental-webgl") } catch(e) { }
+ if (!gl)
+ try {gl = canvas.getContext("moz-webgl") } catch(e) { }
+ if (!gl) {
+ alert("No WebGL context found");
+ return null;
+ }
+
+ canvas.client.gl = gl;
+
+ element.appendChild(canvas);
+ return canvas;
+};
+
+