diff options
-rw-r--r-- | o3d/DEPS | 2 | ||||
-rw-r--r-- | o3d/DEPS_gyp | 2 | ||||
-rw-r--r-- | o3d/samples/MANIFEST | 1 | ||||
-rw-r--r-- | o3d/samples/build.scons | 1 | ||||
-rw-r--r-- | o3d/samples/o3djs/material.js | 38 | ||||
-rw-r--r-- | o3d/samples/o3djs/rendergraph.js | 357 | ||||
-rw-r--r-- | o3d/samples/old-school-shadows.html | 274 | ||||
-rw-r--r-- | o3d/tests/selenium/sample_list.txt | 1 |
8 files changed, 569 insertions, 107 deletions
@@ -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) |