summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--o3d/DEPS2
-rw-r--r--o3d/DEPS_gyp2
-rw-r--r--o3d/samples/MANIFEST1
-rw-r--r--o3d/samples/build.scons1
-rw-r--r--o3d/samples/o3djs/material.js38
-rw-r--r--o3d/samples/o3djs/rendergraph.js357
-rw-r--r--o3d/samples/old-school-shadows.html274
-rw-r--r--o3d/tests/selenium/sample_list.txt1
8 files changed, 569 insertions, 107 deletions
diff --git a/o3d/DEPS b/o3d/DEPS
index 547b10e..002cc4a 100644
--- a/o3d/DEPS
+++ b/o3d/DEPS
@@ -2,7 +2,7 @@ vars = {
"chromium_trunk":
"http://src.chromium.org/svn/trunk",
"nixysa_rev": "25",
- "o3d_code_rev": "92",
+ "o3d_code_rev": "93",
}
deps = {
diff --git a/o3d/DEPS_gyp b/o3d/DEPS_gyp
index 992efa3..d73b26a 100644
--- a/o3d/DEPS_gyp
+++ b/o3d/DEPS_gyp
@@ -3,7 +3,7 @@ vars = {
"http://src.chromium.org/svn/trunk",
"nixysa_rev": "25",
"chromium_rev": "19057",
- "o3d_code_rev": "92",
+ "o3d_code_rev": "93",
}
deps = {
diff --git a/o3d/samples/MANIFEST b/o3d/samples/MANIFEST
index 6eec245..181a43a 100644
--- a/o3d/samples/MANIFEST
+++ b/o3d/samples/MANIFEST
@@ -17,6 +17,7 @@ assets/iconback.png
assets/kitty_151_idle_stand05_cff1.o3dtgz
assets/normalmap.dds
assets/one-pixel-white.tga
+assets/old-school-shadow.png
assets/orange-flower.png
assets/part1.o3dtgz
assets/part2.o3dtgz
diff --git a/o3d/samples/build.scons b/o3d/samples/build.scons
index e98aed29..04f8be7 100644
--- a/o3d/samples/build.scons
+++ b/o3d/samples/build.scons
@@ -138,6 +138,7 @@ samples = [
'julia.html',
'multiple-clients.html',
'multiple-views.html',
+ 'old-school-shadows.html',
'particles.html',
'phongshading.html',
'picking.html',
diff --git a/o3d/samples/o3djs/material.js b/o3d/samples/o3djs/material.js
index 8ef180c..dde37de 100644
--- a/o3d/samples/o3djs/material.js
+++ b/o3d/samples/o3djs/material.js
@@ -337,6 +337,42 @@ o3djs.material.createBasicMaterial = function(pack,
};
/**
+ * This function creates a constant material. No lighting. It is especially
+ * useful for debugging shapes and 2d UI elements.
+ *
+ * @param {!o3d.Pack} pack Pack to manage created objects.
+ * @param {!o3djs.rendergraph.ViewInfo} viewInfo as returned from
+ * o3djs.rendergraph.createBasicView.
+ * @param {(!o3djs.math.Vector4|!o3d.Texture)} colorOrTexture Either a color in
+ * the format [r, g, b, a] or an O3D texture.
+ * @param {boolean} opt_transparent Whether or not the material is transparent.
+ * Defaults to false.
+ * @return {!o3d.Material} The created material.
+ */
+o3djs.material.createConstantMaterial = function(pack,
+ viewInfo,
+ colorOrTexture,
+ opt_transparent) {
+ var material = pack.createObject('Material');
+ material.drawList = opt_transparent ? viewInfo.zOrderedDrawList :
+ viewInfo.performanceDrawList;
+
+ // If it has a length assume it's a color, otherwise assume it's a texture.
+ if (colorOrTexture.length) {
+ material.createParam('emissive', 'ParamFloat4').value = colorOrTexture;
+ } else {
+ var paramSampler = material.createParam('emissiveSampler', 'ParamSampler');
+ var sampler = pack.createObject('Sampler');
+ paramSampler.value = sampler;
+ sampler.texture = colorOrTexture;
+ }
+
+ o3djs.material.attachStandardEffect(pack, material, viewInfo, 'constant');
+
+ return material;
+};
+
+/**
* This function creates 2 color procedureal texture material.
*
* @see o3djs.material.createBasicMaterial
@@ -344,7 +380,7 @@ o3djs.material.createBasicMaterial = function(pack,
* @param {!o3d.Pack} pack Pack to manage created objects.
* @param {!o3djs.rendergraph.ViewInfo} viewInfo as returned from
* o3djs.rendergraph.createBasicView.
- * @param {!o3djs.math.Vector4} opt_color1 a color in the format [r, g, b, a].
+ * @param {!o3djs.math.Vector4} opt_color1 a color in the format [r, g, b, a].
* Defaults to a medium blue-green.
* @param {!o3djs.math.Vector4} opt_color2 a color in the format [r, g, b, a].
* Defaults to a light blue-green.
diff --git a/o3d/samples/o3djs/rendergraph.js b/o3d/samples/o3djs/rendergraph.js
index dad66a0..3d99e83 100644
--- a/o3d/samples/o3djs/rendergraph.js
+++ b/o3d/samples/o3djs/rendergraph.js
@@ -173,8 +173,8 @@ o3djs.rendergraph.ViewInfo = function(pack,
opt_viewport,
opt_performanceDrawList,
opt_zOrderedDrawList) {
+ var that = this;
var clearColor = opt_clearColor || [0.5, 0.5, 0.5, 1.0];
-
var viewPriority = opt_priority || 0;
var priority = 0;
@@ -191,75 +191,14 @@ o3djs.rendergraph.ViewInfo = function(pack,
clearBuffer.priority = priority++;
clearBuffer.parent = viewport;
- // Create DrawLists
- var performanceDrawList;
- if (opt_performanceDrawList) {
- performanceDrawList = opt_performanceDrawList;
- this.ownPerformanceDrawList_ = false;
- } else {
- performanceDrawList = pack.createObject('DrawList');
- this.ownPerformanceDrawList_ = true;
- }
- var zOrderedDrawList;
- if (opt_zOrderedDrawList) {
- zOrderedDrawList = opt_zOrderedDrawList;
- this.ownZOrderedDrawList_ = false;
- } else {
- zOrderedDrawList = pack.createObject('DrawList');
- this.ownZOrderedDrawList_ = true;
- }
-
- // Create DrawContext.
- var drawContext = pack.createObject('DrawContext');
-
// Creates a TreeTraversal and parents it to the root.
var treeTraversal = pack.createObject('TreeTraversal');
treeTraversal.priority = priority++;
treeTraversal.parent = viewport;
-
- // Creates an empty stateSet to parent the performanceDrawPass to
- // just to make it easier to do certain effects.
- var performanceStateSet = pack.createObject('StateSet');
- var performanceState = pack.createObject('State');
- performanceStateSet.state = performanceState;
- performanceStateSet.priority = priority++;
- performanceStateSet.parent = viewport;
- performanceState.getStateParam('ColorWriteEnable').value = 7;
-
- // Creates a DrawPass for performance shapes.
- var performanceDrawPass = pack.createObject('DrawPass');
- performanceDrawPass.drawList = performanceDrawList;
- performanceDrawPass.parent = performanceStateSet;
-
- // Creates a StateSet so everything on the zOrderedDrawPass is assumed
- // to need alpha blending with the typical settings.
- var zOrderedStateSet = pack.createObject('StateSet');
- var zOrderedState = pack.createObject('State');
- zOrderedState.getStateParam('AlphaBlendEnable').value = true;
- zOrderedState.getStateParam('SourceBlendFunction').value =
- o3djs.base.o3d.State.BLENDFUNC_SOURCE_ALPHA;
- zOrderedState.getStateParam('DestinationBlendFunction').value =
- o3djs.base.o3d.State.BLENDFUNC_INVERSE_SOURCE_ALPHA;
- zOrderedState.getStateParam('AlphaTestEnable').value = true;
- zOrderedState.getStateParam('AlphaComparisonFunction').value =
- o3djs.base.o3d.State.CMP_GREATER;
- zOrderedState.getStateParam('ColorWriteEnable').value = 7;
-
- zOrderedStateSet.state = zOrderedState;
- zOrderedStateSet.priority = priority++;
- zOrderedStateSet.parent = viewport;
-
- // Creates a DrawPass for zOrdered shapes.
- var zOrderedDrawPass = pack.createObject('DrawPass');
- zOrderedDrawPass.drawList = zOrderedDrawList;
- zOrderedDrawPass.sortMethod = o3djs.base.o3d.DrawList.BY_Z_ORDER;
- zOrderedDrawPass.parent = zOrderedStateSet;
-
- // Register the passlists and drawcontext with the TreeTraversal
- treeTraversal.registerDrawList(performanceDrawList, drawContext, true);
- treeTraversal.registerDrawList(zOrderedDrawList, drawContext, true);
treeTraversal.transform = treeRoot;
+ this.drawPassInfos_ = [];
+
/**
* Pack that manages the objects created for this ViewInfo.
* @type {!o3d.Pack}
@@ -300,11 +239,93 @@ o3djs.rendergraph.ViewInfo = function(pack,
*/
this.clearBuffer = clearBuffer;
+ // Create DrawContext.
+ var drawContext = pack.createObject('DrawContext');
+
+ /**
+ * The DrawContext used by this ViewInfo.
+ * @type {!o3d.DrawContext}
+ */
+ this.drawContext = drawContext;
+
+ /**
+ * The TreeTraversal used by this ViewInfo.
+ * @type {!o3d.TreeTraversal}
+ */
+ this.treeTraversal = treeTraversal;
+
+ /**
+ * The highest priority used for objects under the Viewport RenderNode created
+ * by this ViewInfo.
+ * @type {number}
+ */
+ this.priority = priority;
+
+ /**
+ * This function is here just because the inside use case of
+ * ViewInfo.createDrawPass is the less common case.
+ * @param {o3d.DrawList.SortMethod} sortMethod how to sort.
+ * @param {!o3d.DrawList} opt_drawList DrawList to use.
+ */
+ function createDrawPass(sortMethod, opt_drawList) {
+ return that.createDrawPass(
+ sortMethod,
+ undefined,
+ undefined,
+ undefined,
+ opt_drawList);
+ }
+
+ // Setup a Performance Ordered DrawPass
+ var performanceDrawPassInfo = createDrawPass(
+ o3djs.base.o3d.DrawList.BY_PERFORMANCE,
+ opt_performanceDrawList);
+
+ var performanceState = performanceDrawPassInfo.state;
+ performanceState.getStateParam('ColorWriteEnable').value = 7;
+
+ // Setup a z Ordered DrawPass
+ var zOrderedDrawPassInfo = createDrawPass(
+ o3djs.base.o3d.DrawList.BY_Z_ORDER,
+ opt_zOrderedDrawList);
+
+ var zOrderedState = zOrderedDrawPassInfo.state;
+
+ zOrderedState.getStateParam('ColorWriteEnable').value = 7;
+ zOrderedState.getStateParam('AlphaBlendEnable').value = true;
+ zOrderedState.getStateParam('SourceBlendFunction').value =
+ o3djs.base.o3d.State.BLENDFUNC_SOURCE_ALPHA;
+ zOrderedState.getStateParam('DestinationBlendFunction').value =
+ o3djs.base.o3d.State.BLENDFUNC_INVERSE_SOURCE_ALPHA;
+ zOrderedState.getStateParam('AlphaTestEnable').value = true;
+ zOrderedState.getStateParam('AlphaComparisonFunction').value =
+ o3djs.base.o3d.State.CMP_GREATER;
+ zOrderedState.getStateParam('ColorWriteEnable').value = 7;
+
+ // Parent whatever the root is to the parent passed in.
+ if (opt_parent) {
+ this.root.parent = opt_parent;
+ }
+
+ /**
+ * The DrawPassInfo for the performance draw pass.
+ * @type {!o3djs.rendergraph.DrawPassInfo}
+ */
+ this.performanceDrawPassInfo = performanceDrawPassInfo;
+
+ /**
+ * The DrawPassInfo for the zOrdered draw pass.
+ * @type {!o3djs.rendergraph.DrawPassInfo}
+ */
+ this.zOrderedDrawPassInfo = zOrderedDrawPassInfo;
+
+ // Legacy properties
+
/**
* The StateSet RenderNode above the performance DrawPass in this ViewInfo
* @type {!o3d.StateSet}
*/
- this.performanceStateSet = performanceStateSet;
+ this.performanceStateSet = performanceDrawPassInfo.stateSet;
/**
* The State object used by the performanceStateSet object in this ViewInfo.
@@ -318,13 +339,13 @@ o3djs.rendergraph.ViewInfo = function(pack,
* materials.
* @type {!o3d.DrawList}
*/
- this.performanceDrawList = performanceDrawList;
+ this.performanceDrawList = performanceDrawPassInfo.drawList;
/**
* The StateSet RenderNode above the ZOrdered DrawPass in this ViewInfo
* @type {!o3d.StateSet}
*/
- this.zOrderedStateSet = zOrderedStateSet;
+ this.zOrderedStateSet = zOrderedDrawPassInfo.stateSet;
/**
* The State object used by the zOrderedStateSet object in this ViewInfo.
@@ -340,43 +361,19 @@ o3djs.rendergraph.ViewInfo = function(pack,
* materials.
* @type {!o3d.DrawList}
*/
- this.zOrderedDrawList = zOrderedDrawList;
-
- /**
- * The DrawContext used by this ViewInfo.
- * @type {!o3d.DrawContext}
- */
- this.drawContext = drawContext;
-
- /**
- * The TreeTraversal used by this ViewInfo.
- * @type {!o3d.TreeTraversal}
- */
- this.treeTraversal = treeTraversal;
+ this.zOrderedDrawList = zOrderedDrawPassInfo.drawList;
/**
* The DrawPass used with the performance DrawList created by this ViewInfo.
* @type {!o3d.DrawPass}
*/
- this.performanceDrawPass = performanceDrawPass;
+ this.performanceDrawPass = performanceDrawPassInfo.drawPass;
/**
* The DrawPass used with the zOrdered DrawList created by this ViewInfo.
* @type {!o3d.DrawPass}
*/
- this.zOrderedDrawPass = zOrderedDrawPass;
-
- /**
- * The highest priority used for objects under the Viewport RenderNode created
- * by this ViewInfo.
- * @type {number}
- */
- this.priority = priority;
-
- // Parent whatever the root is to the parent passed in.
- if (opt_parent) {
- this.root.parent = opt_parent;
- }
+ this.zOrderedDrawPass = zOrderedDrawPassInfo.drawPass;
};
/**
@@ -393,24 +390,18 @@ o3djs.rendergraph.ViewInfo.prototype.destroy = function(
if (opt_destroyDrawContext === undefined) {
opt_destroyDrawContext = true;
}
- if (opt_destroyDrawList === undefined) {
- opt_destroyDrawList = true;
+
+ for (var ii = 0; ii < this.drawPassInfos_.length; ++ii) {
+ this.drawPassInfos_[ii].destroy();
}
+
// Remove everything we created from the pack.
this.pack.removeObject(this.viewport);
this.pack.removeObject(this.clearBuffer);
- if (this.ownPerformanceDrawList_ && opt_destroyDrawList) {
- this.pack.removeObject(this.performanceDrawList);
- }
- if (this.ownZOrderedDrawList_ && opt_destroyDrawList) {
- this.pack.removeObject(this.zOrderedDrawList);
- }
if (opt_destroyDrawContext) {
this.pack.removeObject(this.drawContext);
}
this.pack.removeObject(this.treeTraversal);
- this.pack.removeObject(this.performanceDrawPass);
- this.pack.removeObject(this.zOrderedDrawPass);
// Remove our substree from its parent.
this.viewport.parent = null;
@@ -418,3 +409,161 @@ o3djs.rendergraph.ViewInfo.prototype.destroy = function(
// they should get removed.
};
+/**
+ * Creates a draw pass in this ViewInfo.
+ *
+ * @param {o3d.DrawList.SortMethod} sortMethod How to sort this draw pass's
+ * DrawElements.
+ * @param {!o3d.DrawContext} opt_drawContext The DrawContext for this draw pass.
+ * If not passed in the default DrawContext for this ViewInfo will be used.
+ * @param {number} opt_priority The priority for this draw pass. If not passed
+ * in the priority will be the next priority for this ViewInfo.
+ * @param {!o3d.RenderNode} opt_parent The RenderNode to parent this draw pass
+ * under. If not passed in the draw pass will be parented under the
+ * ViewInfo's viewport RenderNode.
+ * @param {!o3d.DrawList} opt_drawList The DrawList for this draw pass. If not
+ * passed in one will be created.
+ * @return {!o3djs.rendergraph.DrawPassInfo}
+ */
+o3djs.rendergraph.ViewInfo.prototype.createDrawPass = function(
+ sortMethod,
+ opt_drawContext,
+ opt_priority,
+ opt_parent,
+ opt_drawList) {
+ opt_drawContext = opt_drawContext || this.drawContext;
+ opt_parent = opt_parent || this.viewport;
+ opt_priority = (typeof opt_priority !== 'undefined') ? opt_priority :
+ this.priority++;
+ var drawPassInfo = o3djs.rendergraph.createDrawPassInfo(
+ this.pack,
+ opt_drawContext,
+ sortMethod,
+ opt_parent,
+ opt_drawList);
+ drawPassInfo.root.priority = opt_priority;
+ this.treeTraversal.registerDrawList(
+ drawPassInfo.drawList, opt_drawContext, true);
+
+ this.drawPassInfos_.push(drawPassInfo);
+
+ return drawPassInfo;
+};
+
+/**
+ * Creates a DrawPassInfo to manage a draw pass.
+ *
+ * @param {!o3d.Pack} pack Pack to manage created objects.
+ * @param {!o3d.DrawContext} drawContext The DrawContext for this draw pass.
+ * @param {o3d.DrawList.SortMethod} sortMethod How to sort this draw pass's
+ * DrawElements.
+ * @param {!o3d.DrawList} opt_drawList The DrawList for this draw pass. If not
+ * passed in one will be created.
+ * @param {!o3d.RenderNode} opt_parent The RenderNode to parent this draw pass
+ * under. If not passed the draw pass will not be parented.
+ * @return {!o3djs.rendergraph.DrawPassInfo}
+ */
+o3djs.rendergraph.createDrawPassInfo = function(
+ pack,
+ drawContext,
+ sortMethod,
+ opt_parent,
+ opt_drawList) {
+ return new o3djs.rendergraph.DrawPassInfo(
+ pack, drawContext, sortMethod, opt_parent, opt_drawList);
+};
+
+/**
+ * A class to manage a draw pass.
+ *
+ * @param {!o3d.Pack} pack Pack to manage created objects.
+ * @param {!o3d.DrawContext} drawContext The DrawContext for this draw pass.
+ * @param {o3d.DrawList.SortMethod} sortMethod How to sort this draw pass's
+ * DrawElements.
+ * @param {!o3d.DrawList} opt_drawList The DrawList for this draw pass. If not
+ * passed in one will be created.
+ * @param {!o3d.RenderNode} opt_parent The RenderNode to parent this draw pass
+ * under. If not passed the draw pass will not be parented.
+ * @return {!o3djs.rendergraph.DrawPassInfo}
+ */
+o3djs.rendergraph.DrawPassInfo = function(pack,
+ drawContext,
+ sortMethod,
+ opt_parent,
+ opt_drawList) {
+ var ownDrawList = opt_drawList ? false : true;
+
+ opt_parent = opt_parent || NULL;
+ opt_drawList = opt_drawList || pack.createObject('DrawList');
+
+ var stateSet = pack.createObject('StateSet');
+ var state = pack.createObject('State');
+ stateSet.state = state;
+ stateSet.parent = opt_parent;
+
+ var drawPass = pack.createObject('DrawPass');
+ drawPass.drawList = opt_drawList;
+ drawPass.sortMethod = sortMethod;
+ drawPass.parent = stateSet;
+
+ /**
+ * The pack managing the objects created for this DrawPassInfo.
+ * @type {!o3d.Pack}
+ */
+ this.pack = pack;
+
+ /**
+ * The State that affects all things drawn in this DrawPassInfo.
+ * @type {!o3d.State}
+ */
+ this.state = state;
+
+ /**
+ * The StateSet that applies the state for this DrawPassInfo.
+ * @type {!o3d.StateSet}
+ */
+ this.stateSet = stateSet;
+
+ /**
+ * The DrawPass for this DrawPassInfo.
+ * @type {!o3d.DrawPass}
+ */
+ this.drawPass = drawPass;
+
+ /**
+ * The DrawList for this DrawPassInfo.
+ * @type {!o3d.Pack}
+ */
+ this.drawList = opt_drawList;
+
+ /**
+ * The root RenderNode of this DrawPassInfo. This is the RenderNdoe you should
+ * use if you want to turn this draw pass off or reparent it.
+ * @type {!o3d.RenderNode}
+ */
+ this.root = stateSet;
+
+ /**
+ * A flag whether or not we created the DrawList for this DrawPassInfo.
+ * @private
+ * @type {boolean}
+ */
+ this.ownDrawList_ = ownDrawList;
+};
+
+/**
+ * Frees the resources created for this DrawPassInfo.
+ */
+o3djs.rendergraph.DrawPassInfo.prototype.destroy = function() {
+ // Remove everything we created from the pack.
+ if (this.ownDrawList_) {
+ this.drawList.parent = null;
+ this.pack_.removeObject(this.drawList);
+ }
+ this.drawPass.parent = null;
+ this.stateSet.parent = null;
+ this.pack.removeObject(this.drawPass);
+ this.pack.removeObject(this.stateSet);
+ this.pack.removeObject(this.state);
+};
+
diff --git a/o3d/samples/old-school-shadows.html b/o3d/samples/old-school-shadows.html
new file mode 100644
index 0000000..844603e
--- /dev/null
+++ b/o3d/samples/old-school-shadows.html
@@ -0,0 +1,274 @@
+<!--
+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 use simple circle texture for shadows.
+-->
+<!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>
+Old School Shadows.
+</title>
+<link rel="stylesheet" type="text/css" href="assets/style.css" />
+<!-- Include sample javascript library functions-->
+<script type="text/javascript" src="o3djs/base.js"></script>
+
+<!-- Our javascript code -->
+<script type="text/javascript">
+o3djs.require('o3djs.util');
+o3djs.require('o3djs.math');
+o3djs.require('o3djs.rendergraph');
+o3djs.require('o3djs.primitives');
+o3djs.require('o3djs.material');
+
+// Constants
+var SHADOW_SIZE = 5;
+
+// Events
+// init() once the page has finished loading.
+// unload() when the page is unloaded.
+window.onload = init;
+window.onunload = unload;
+
+// global variables
+var g_o3dElement;
+var g_o3d;
+var g_math;
+var g_client;
+var g_viewInfo;
+var g_pack;
+var g_root;
+var g_clock = 0;
+var g_timeMult = 1;
+var g_globalParams;
+var g_shadowDrawPassInfo;
+var g_o3dWidth;
+var g_o3dHeight;
+var g_o3dElement;
+var g_transforms = [];
+
+/**
+ * Creates the client area.
+ */
+function init() {
+ o3djs.util.makeClients(initStep2);
+}
+
+/**
+ * Initializes O3D and creates one shape.
+ * @param {Array} clientElements Array of o3d object elements.
+ */
+function initStep2(clientElements) {
+ // Initializes global variables and libraries.
+ g_o3dElement = clientElements[0];
+ g_o3d = g_o3dElement.o3d;
+ g_math = o3djs.math;
+ g_client = g_o3dElement.client;
+
+ // Creates a pack to manage our resources/assets
+ g_pack = g_client.createPack();
+
+ g_root = g_pack.createObject('Transform');
+
+ g_viewInfo = o3djs.rendergraph.createBasicView(
+ g_pack,
+ g_root,
+ g_client.renderGraphRoot);
+
+ // Make another draw pass just for the shadows so they get
+ // drawn last. We don't need to pass any extra info to createDrawPass
+ // because we are using the same drawContext and because we want it to
+ // happen last, both of which are the default.
+ g_shadowDrawPassInfo = g_viewInfo.createDrawPass(
+ g_o3d.DrawList.BY_PERFORMANCE);
+
+ // Get the state object the shadow draw pass and set states for the shadows.
+ var state = g_shadowDrawPassInfo.state;
+
+ // The following settings turn on blending for all objects using the
+ // shadow DrawList
+ state.getStateParam('AlphaBlendEnable').value = true;
+ state.getStateParam('SourceBlendFunction').value =
+ o3djs.base.o3d.State.BLENDFUNC_SOURCE_ALPHA;
+ state.getStateParam('DestinationBlendFunction').value =
+ o3djs.base.o3d.State.BLENDFUNC_INVERSE_SOURCE_ALPHA;
+ state.getStateParam('AlphaTestEnable').value = true;
+ state.getStateParam('AlphaComparisonFunction').value =
+ o3djs.base.o3d.State.CMP_GREATER;
+
+ // Make the shadow not write to the ZBuffer, otherwise they will interfere
+ // with each other. Try commenting this line out to see what happens. Look
+ // closely when 2 shadows overlap. It's easier to see the problem
+ // if you make the shadows larger. Set the shadow size to 15
+ state.getStateParam('ZWriteEnable').value = false;
+
+ // This setting pulls the shadow in front of the ground plane even though
+ // they are at the same position in space. Comment this 2 lines out
+ // to see what happens if you don't use this setting.
+ state.getStateParam('PolygonOffset1').value = -1;
+ state.getStateParam('PolygonOffset2').value = -1;
+
+ // Setup the view and projection matrices.
+ var eye = [15, 25, 50];
+ var target = [0, 10, 0];
+ var up = [0, 1, 0];
+ g_viewInfo.drawContext.view = g_math.matrix4.lookAt(eye, target, up);
+
+ g_viewInfo.drawContext.projection = g_math.matrix4.perspective(
+ g_math.degToRad(45), // field of view.
+ g_client.width / g_client.height, // aspect ratio
+ 0.1, // Near plane.
+ 5000); // Far plane.
+
+ // Load a small circle texture.
+ o3djs.io.loadTexture(
+ g_pack,
+ o3djs.util.getAbsoluteURI('assets/old-school-shadow.png'),
+ initStep3);
+}
+
+function initStep3(texture, exception) {
+ if (exception) {
+ alert(exception);
+ return;
+ }
+
+ // This material is used for the spheres.
+ var sphereMaterial = o3djs.material.createBasicMaterial(
+ g_pack,
+ g_viewInfo,
+ [1, 1, 1, 1]);
+ sphereMaterial.getParam('specularFactor').value = 0.4;
+
+ // The material for the ground.
+ var checkerMaterial = o3djs.material.createMaterialFromFile(
+ g_pack, 'shaders/green-blue-checker.shader',
+ g_viewInfo.performanceDrawList);
+
+ // Make a material to use for the shadow. A standard constant shader will
+ // be fine.
+ var shadowMaterial = o3djs.material.createConstantMaterial(
+ g_pack,
+ g_viewInfo,
+ texture,
+ true);
+ shadowMaterial.drawList = g_shadowDrawPassInfo.drawList;
+
+ // Setup the lighting for the ground and spheres.
+ g_globalParams = o3djs.material.createAndBindStandardParams(g_pack);
+ g_globalParams.lightWorldPos.value = [30, 60, 40];
+ g_globalParams.lightColor.value = [1, 1, 1, 1];
+
+ // Create a ground plane.
+ var shape = o3djs.primitives.createPlane(
+ g_pack, checkerMaterial, 100, 100, 10, 10);
+ var transform = g_pack.createObject('Transform');
+ transform.parent = g_root;
+ transform.addShape(shape);
+
+ // Create a sphere.
+ var sphere = o3djs.primitives.createSphere(
+ g_pack, sphereMaterial, 2.5, 24, 48,
+ g_math.matrix4.translation([0, 2.5, 0]));
+
+ // Create a plane for the shadow.
+ var shadow = o3djs.primitives.createPlane(g_pack, shadowMaterial,
+ SHADOW_SIZE, SHADOW_SIZE, 1, 1);
+
+ // Instance 100 spheres with shadows.
+ for (var ii = 0; ii < 100; ++ii) {
+ var transform = g_pack.createObject('Transform');
+ g_transforms.push(transform);
+ transform.parent = g_root;
+ transform.addShape(sphere);
+ // Give each sphere a pseudo random color.
+ transform.createParam('diffuse', 'ParamFloat4').value = [
+ (ii * 1.71) % 1,
+ (ii * 2.09) % 1,
+ (ii * 6.31) % 1,
+ 1];
+ var shadowTransform = g_pack.createObject('Transform');
+ shadowTransform.parent = transform;
+ shadowTransform.addShape(shadow);
+ }
+
+ // Setup a render callback for per frame processing.
+ g_client.setRenderCallback(onRender);
+
+ window.g_finished = true; // for selenium testing.
+}
+
+/**
+ * Called every frame.
+ * @param {!o3d.RenderEvent} renderEvent Rendering Information.
+ */
+function onRender(renderEvent) {
+ var elapsedTime = renderEvent.elapsedTime;
+ g_clock += elapsedTime * g_timeMult;
+
+ moveThings();
+};
+
+/**
+ * Moves all the sphere transforms in some pattern that is a function of
+ * g_clock so we can force it to a predictable state for testing.
+ */
+function moveThings() {
+ for (var ii = 0; ii < g_transforms.length; ++ii) {
+ var transform = g_transforms[ii];
+ var xSpeed = g_clock * 0.25 + ii * 1.1;
+ var ySpeed = g_clock * 0.27 + ii * 0.5;
+ transform.identity();
+ transform.translate(40 * Math.sin(xSpeed),
+ 0,
+ 40 * Math.cos(ySpeed));
+ var scale = (Math.sin(g_clock * 0.29 + ii * 20.7) + 1) * 0.5 + 0.3;
+ transform.scale(scale, scale, scale);
+ }
+}
+
+/**
+ * Remove any callbacks so they don't get called after the page has unloaded.
+ */
+function unload() {
+ if (g_client) {
+ g_client.cleanup();
+ }
+}
+</script>
+</head>
+<body>
+<h1>Old School Shadows</h1>
+<div id="o3d" style="width: 800px; height: 600px"></div>
+</body>
+</html>
diff --git a/o3d/tests/selenium/sample_list.txt b/o3d/tests/selenium/sample_list.txt
index 9f6958a..e7c5461 100644
--- a/o3d/tests/selenium/sample_list.txt
+++ b/o3d/tests/selenium/sample_list.txt
@@ -89,6 +89,7 @@ medium instancing screenshot pdiff_threshold(14300)
medium juggler screenshot downsample(1)
medium julia screenshot
small multiple-views screenshot pdiff_threshold(1900)
+medium old-school-shadows screenshot pdiff_threshold(2000)
medium particles screenshot pdiff_threshold(35500)
medium primitives screenshot pdiff_threshold(17200) pdiff_threshold_mac(20000) colorfactor(.7)
medium procedural-texture screenshot pdiff_threshold(1300)