diff options
author | luchen@google.com <luchen@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-17 22:54:47 +0000 |
---|---|---|
committer | luchen@google.com <luchen@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-17 22:54:47 +0000 |
commit | c925b4bab4abc7f6b72f7408b7ec75bb49851033 (patch) | |
tree | 603cd72b673552fcb98c98accf6bc66a59b50e74 /o3d/samples | |
parent | 740f19ec5c056e340fae3343a7678448e897275f (diff) | |
download | chromium_src-c925b4bab4abc7f6b72f7408b7ec75bb49851033.zip chromium_src-c925b4bab4abc7f6b72f7408b7ec75bb49851033.tar.gz chromium_src-c925b4bab4abc7f6b72f7408b7ec75bb49851033.tar.bz2 |
Adding instancing and render target demos.
Note: json scene for yard.o3dtgz; replaced this with teapot. (How much effort does it take to generate yard json scene?)
Also, the instancing demos run sluggishly. (Limitation of JS?)
Review URL: http://codereview.chromium.org/2714013
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@50158 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d/samples')
-rw-r--r-- | o3d/samples/o3d-webgl-samples/instance-override.html | 182 | ||||
-rw-r--r-- | o3d/samples/o3d-webgl-samples/instancing.html | 211 | ||||
-rw-r--r-- | o3d/samples/o3d-webgl-samples/multiple-clients.html | 229 | ||||
-rw-r--r-- | o3d/samples/o3d-webgl-samples/multiple-views.html | 222 | ||||
-rw-r--r-- | o3d/samples/o3d-webgl-samples/picking.html | 345 | ||||
-rw-r--r-- | o3d/samples/o3d-webgl-samples/procedural-texture.html | 255 | ||||
-rw-r--r-- | o3d/samples/o3d-webgl-samples/render-targets.html | 333 | ||||
-rw-r--r-- | o3d/samples/o3d-webgl/viewport.js | 5 | ||||
-rw-r--r-- | o3d/samples/shaders/vertex-color-glsl.shader | 59 |
9 files changed, 1839 insertions, 2 deletions
diff --git a/o3d/samples/o3d-webgl-samples/instance-override.html b/o3d/samples/o3d-webgl-samples/instance-override.html new file mode 100644 index 0000000..37132fe --- /dev/null +++ b/o3d/samples/o3d-webgl-samples/instance-override.html @@ -0,0 +1,182 @@ +<!-- +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. +--> + +<!-- +O3D Instancing Override example. + +Display a single instanced object but change some shader parameters for each +instance by putting them on the transform. +--> +<!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> +Instancing with Overrides. +</title> +<!-- Include sample javascript library functions--> +<script type="text/javascript" src="../o3d-webgl/base.js"></script> +<script type="text/javascript" src="../o3djs/base.js"></script> + +<!-- Our javascript code --> +<script type="text/javascript" id="o3dscript"> +o3djs.base.o3d = o3d; +o3djs.require('o3djs.webgl'); +o3djs.require('o3djs.math'); +o3djs.require('o3djs.rendergraph'); +o3djs.require('o3djs.primitives'); +o3djs.require('o3djs.material'); + +// Events +// init() once the page has finished loading. +// unload() when the page is unloaded. +window.onload = init; +window.onunload = unload; + +// global variables +var g_o3d; +var g_math; +var g_client; +var g_viewInfo; +var g_pack; +var g_clock = 0; +var g_timeMult = 1; +var g_finished = false; // for selenium testing. + +function createInstances(pack, shape) { + // make a grid of transforms and put a sphere instance on each one + for (var x = 0; x < 10; x++) { + for (var y = 0; y < 10; y++) { + for (var z = 0; z < 10; z++) { + var transform = pack.createObject('Transform'); + transform.parent = g_client.root; + transform.addShape(shape); + transform.translate((x - 4.5) * 100, + (y - 4.5) * 100, + (z - 4.5) * 100); + transform.createParam('diffuse', 'ParamFloat4').value = [ + x * 0.1, + y * 0.1, + z * 0.1, + 1.0]; + } + } + } +} + +/** + * Creates the client area. + */ +function init() { + o3djs.webgl.makeClients(initStep2); +} + +/** + * Initializes O3D and creates a sphere. + * @param {Array} clientElements Array of o3d object elements. + */ +function initStep2(clientElements) { + // Initializes global variables and libraries. + var o3dElement = clientElements[0]; + g_o3d = o3dElement.o3d; + g_math = o3djs.math; + g_client = o3dElement.client; + + // Creates a pack to manage our resources/assets + g_pack = g_client.createPack(); + + // Create the render graph for a view. + g_viewInfo = o3djs.rendergraph.createBasicView( + g_pack, + g_client.root, + g_client.renderGraphRoot); + + // Create our projection matrix, with a vertical field of view of 45 degrees + // a near clipping plane of 0.1 and far clipping plane of 10000. + g_viewInfo.drawContext.projection = g_math.matrix4.perspective( + g_math.degToRad(45), + g_client.width / g_client.height, + 0.1, + 10000); + + // Create a material. + var material = o3djs.material.createBasicMaterial( + g_pack, + g_viewInfo, + [1, 1, 1, 1]); + + // Create a sphere. + var shape = o3djs.primitives.createSphere(g_pack, material, 25, 10, 12); + + createInstances(g_pack, shape); + + // Setup an onrender callback for animation. + g_client.setRenderCallback(onrender); + + g_finished = true; // for selenium testing. +} + +// spin the camera. +function onrender(render_event) { + // Get the number of seconds since the last render. + var elapsedTime = render_event.elapsedTime; + g_clock += elapsedTime * g_timeMult; + + var x = Math.sin(g_clock * 0.3) * 1000; + var z = Math.cos(g_clock * 0.3) * 1000; + var y = Math.sin(g_clock * 0.7) * 500; + + g_viewInfo.drawContext.view = g_math.matrix4.lookAt( + [x, y, z], // eye + [0, 0, 0], // target + [0, 1, 0]); // up +} + +/** + * Removes 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>Instancing with overrides</h1> +1000 Instances of the same sphere. +<br/> +<!-- Start of O3D plugin --> +<div id="o3d" style="width: 800px; height: 600px;"></div> +<!-- End of O3D plugin --> +</body> +</html> diff --git a/o3d/samples/o3d-webgl-samples/instancing.html b/o3d/samples/o3d-webgl-samples/instancing.html new file mode 100644 index 0000000..2ddad3c --- /dev/null +++ b/o3d/samples/o3d-webgl-samples/instancing.html @@ -0,0 +1,211 @@ +<!-- +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. +--> + +<!-- +O3D Instancing example. + +Load the teapot, display it a bunch of times. +--> +<!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> +Instancing. +</title> +<!-- Include sample javascript library functions--> +<script type="text/javascript" src="../o3d-webgl/base.js"></script> +<script type="text/javascript" src="../o3djs/base.js"></script> + +<!-- Our javascript code --> +<script type="text/javascript" id="o3dscript"> +o3djs.base.o3d = o3d; +o3djs.require('o3djs.webgl'); +o3djs.require('o3djs.util'); +o3djs.require('o3djs.math'); +o3djs.require('o3djs.rendergraph'); +o3djs.require('o3djs.pack'); +o3djs.require('o3djs.scene'); + +// Events +// init() once the page has finished loading. +// unload() when the page is unloaded. +window.onload = init; +window.onunload = unload; + +// global variables +var g_o3d; +var g_math; +var g_client; +var g_viewInfo; +var g_pack; +var g_clock = 0; +var g_timeMult = 1; +var g_finished = false; // for selenium testing + +/** + * Loads a scene into the transform graph. + * @param {!o3d.Pack} pack Pack to load scene into. + * @param {string} fileName filename of the scene. + * @param {!o3d.Transform} parent parent node in the transform graph to + * which to load the scene into. + */ +function loadScene(pack, fileName, parent) { + // Get our full path to the scene + var scenePath = o3djs.util.getCurrentURI() + fileName; + + // Load the file given the full path, and call the callback function + // when its done loading. + o3djs.scene.loadScene(g_client, pack, parent, scenePath, callback); + + /** + * Our callback is called once the scene has been loaded into memory + * from the web or locally. + * @param {!o3d.Pack} pack The pack that was passed in above. + * @param {!o3d.Transform} parent The parent that was passed in above. + * @param {*} exception null if loading succeeded. + */ + function callback(pack, parent, exception) { + if (exception) { + alert('Could not load: ' + fileName + '\n' + exception); + return; + } + // Generate draw elements and setup material draw lists. + o3djs.pack.preparePack(pack, g_viewInfo); + + // Find the "shape" for the teapot. + // I'm going to assume there is only one since I know the contents + // of the file. + var shape = pack.getObjectsByClassName('o3d.Shape')[0]; + + // now make a grid of transforms and put a teapot instance on each one + for (var x = 0; x < 10; x++) { + for (var y = 0; y < 10; y++) { + for (var z = 0; z < 10; z++) { + var transform = pack.createObject('Transform'); + transform.parent = g_client.root; + transform.addShape(shape); + var angles = [ + (x - 4.5) * 0.2, + (y - 4.5) * 0.2, + (z - 4.5) * 0.2]; + transform.translate((x - 4.5) * 100, + (y - 4.5) * 100, + (z - 4.5) * 100); + transform.rotateZYX(angles); + } + } + } + + g_finished = true; // for selenium testing. + } +} + +/** + * Creates the client area. + */ +function init() { + o3djs.webgl.makeClients(initStep2); +} + +/** + * Initializes O3D and loads the scene into the transform graph. + * @param {Array} clientElements Array of o3d object elements. + */ +function initStep2(clientElements) { + // Initializes global variables and libraries. + var o3dElement = clientElements[0]; + g_o3d = o3dElement.o3d; + g_math = o3djs.math; + g_client = o3dElement.client; + + // Creates a pack to manage our resources/assets + g_pack = g_client.createPack(); + + // Create the render graph for a view. + g_viewInfo = o3djs.rendergraph.createBasicView( + g_pack, + g_client.root, + g_client.renderGraphRoot); + + // Create our projection matrix, with a vertical field of view of 45 degrees + // a near clipping plane of 0.1 and far clipping plane of 10000. + g_viewInfo.drawContext.projection = g_math.matrix4.perspective( + g_math.degToRad(45), + g_client.width / g_client.height, + 0.1, + 10000); + + // Creates a transform to put our data on. + var my_data_root = g_pack.createObject('Transform'); + + // Load the scene into the transform graph as a child my_data_root + loadScene(g_pack, '../assets/teapot/scene.json', my_data_root); + + // Setup an onrender callback for animation. + g_client.setRenderCallback(onrender); +} + +// spin the camera. +function onrender(render_event) { + // Get the number of seconds since the last render. + var elapsedTime = render_event.elapsedTime; + g_clock += elapsedTime * g_timeMult; + + var x = Math.sin(g_clock * 0.41) * 400; + var z = Math.cos(g_clock * 0.31) * 1000; + var y = Math.sin(g_clock * 0.61) * 200; + + g_viewInfo.drawContext.view = g_math.matrix4.lookAt([x, y, z], // eye + [0, 0, 0], // target + [0, 1, 0]); // up +} + +/** + * Removes 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>Instancing</h1> +1000 Teapots +<br/> +<!-- Start of O3D plugin --> +<div id="o3d" style="width: 800px; height: 600px;"></div> +<!-- End of O3D plugin --> +</body> +</html> diff --git a/o3d/samples/o3d-webgl-samples/multiple-clients.html b/o3d/samples/o3d-webgl-samples/multiple-clients.html new file mode 100644 index 0000000..ec6d5c8 --- /dev/null +++ b/o3d/samples/o3d-webgl-samples/multiple-clients.html @@ -0,0 +1,229 @@ +<!-- +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 demonstrates running more than 1 instance of the plugin at +the same time. +--> +<!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> +Multiple Clients +</title> +<!-- Our javascript code --> +<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.io'); +o3djs.require('o3djs.rendergraph'); +o3djs.require('o3djs.primitives'); + +// Events +// Run the init() function once the page has finished loading. +// uninit() when the page is unloaded. +window.onload = init; +window.onunload = uninit; + +// global variables +var g_o3d; +var g_math; +var g_clients = []; +var g_packs = []; +var g_viewInfos = []; +var g_num_clients; +var g_setupDone = false; + +var g_animate_angle = []; +var g_eye; + +var NUM_ACROSS = 10; +var NUM_DOWN = 5; + +/** + * Initializes O3D, loads the effect, and draws the cube. + */ +function init() { + // Create a bunch of clients. + var ii = 0; + var tbodyElem = document.getElementById('clients'); + for (var row = 0; row < NUM_DOWN; row++) { + var trElem = document.createElement('tr'); + for (var column = 0; column < NUM_ACROSS; column++) { + var tdElem = document.createElement('td'); + var objElem = o3djs.webgl.createClient(tdElem); + objElem.style.width = '60px'; + objElem.style.height = '60px'; + objElem.id = 'o3d' + ii; + objElem.name = 'o3d' + ii; + trElem.appendChild(tdElem); + ii++; + } + tbodyElem.appendChild(trElem); + } + g_num_clients = ii; + + // wait for the browser to settle down. + var clearId = window.setInterval(function() { + var lastClient = NUM_ACROSS * NUM_DOWN - 1; + var element = document.getElementById('o3d' + lastClient); + if (!element || element && !element.o3d) { + return; + } + window.clearInterval(clearId); + setup(); + }, 10); +} + +function setup() { + // Lookup all the clients. + for (var ii = 0; ii < g_num_clients; ++ii) { + g_clients[ii] = document.getElementById('o3d' + ii).client; + } + + // Get constants and math functions. + g_o3d = document.getElementById('o3d0').o3d; + g_math = o3djs.math; + + var effectSource = + o3djs.io.loadTextFileSynchronous('../shaders/vertex-color-glsl.shader'); + + // For each client make a cube, context, effect,... + for (ii = 0; ii < g_num_clients; ii++) { + // Create a pack to manage our resources/assets + g_packs[ii] = g_clients[ii].createPack(); + + // Create the render graph for a view. + g_viewInfos[ii] = o3djs.rendergraph.createBasicView( + g_packs[ii], + g_clients[ii].root, + g_clients[ii].renderGraphRoot); + + g_animate_angle[ii] = 0; + + // Create our projection matrix, with a vertical field of view of 45 degrees + // a near clipping plane of 0.1 and far clipping plane of 100. + g_viewInfos[ii].drawContext.projection = g_math.matrix4.perspective( + g_math.degToRad(45), + 128 / 128, + 0.1, + 100); + + // Create and load the effect. + var effect = g_packs[ii].createObject('Effect'); + effect.loadFromFXString(effectSource); + + // Create a material for it. + var material = g_packs[ii].createObject('Material'); + + // Set the material's drawList + material.drawList = g_viewInfos[ii].performanceDrawList; + + // Apply our effect to this material. + material.effect = effect; + effect.createUniformParameters(material); + + // Create a cube using the effect we have loaded. + createCube(g_clients[ii].root, g_packs[ii], material); + } + + // Set our render callback for animation. + // This sets a function to be executed every time a frame is rendered. + g_clients[0].setRenderCallback(onrender); + g_setupDone = true; +} + +/** + * Creates a cube with the given effect. + * + * @param {!o3d.Transform} parent Transform to parent shape to. + * @param {!o3d.Pack} pack Pack to use. + * @param {!o3d.Material} material Material to use. + */ +function createCube(parent, pack, material) { + // First, create a 'shape' node to store our sphere. + var myShape = o3djs.primitives.createRainbowCube(pack, material, 0.5); + + // Attach the cube to the root of the transform graph. + parent.addShape(myShape); +} + +// Animates the cubes. +// This function executes on each frame. +// It was set using document.o3d.setEventCallback(..) in setup(). +function onrender(render_event) { + var elapsedTime = render_event.elapsedTime; + for (var ii = 0; ii < g_num_clients; ii++) { + // Rotate frame rate independently. + g_animate_angle[ii] += (0.1 + 0.1 * ii) * elapsedTime; + + // Eye-position, this is where our camera is at. + var eye = [ + 0.0 + Math.sin(g_animate_angle[ii]) * 1.0, + 1.0, + 0.0 + Math.cos(g_animate_angle[ii]) * 1.0 + ]; + + // Target, this is where our camera is pointed at. + var target = [0, 0, 0]; + + // Up-vector, this tells the camera which direction is 'up'. + // We define the positive y-direction to be up in this example. + var up = [0, 1, 0]; + + g_viewInfos[ii].drawContext.view = g_math.matrix4.lookAt(eye, target, up); + } +} + +/** + * Removes any callbacks so they don't get called after the page has unloaded. + */ +function uninit() { + if (g_clients[0]) { + g_clients[0].cleanup(); + } +} + +</script> +</head> +<body> +<h1>Multiple Clients</h1> +<table> + <tbody id="clients"> + </tbody> +</table> +</body> +</html> diff --git a/o3d/samples/o3d-webgl-samples/multiple-views.html b/o3d/samples/o3d-webgl-samples/multiple-views.html new file mode 100644 index 0000000..bd1f222 --- /dev/null +++ b/o3d/samples/o3d-webgl-samples/multiple-views.html @@ -0,0 +1,222 @@ +<!-- +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. +--> + +<!-- +Example of multiple views into the same scene. +--> +<!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> +Multiple Views +</title> +<!-- Include sample javascript library functions--> +<script type="text/javascript" src="../o3d-webgl/base.js"></script> +<script type="text/javascript" src="../o3djs/base.js"></script> + +<!-- Our javascript code --> +<script type="text/javascript" id="o3dscript"> +o3djs.base.o3d = o3d; +o3djs.require('o3djs.webgl'); +o3djs.require('o3djs.math'); +o3djs.require('o3djs.rendergraph'); +o3djs.require('o3djs.camera'); +o3djs.require('o3djs.pack'); +o3djs.require('o3djs.scene'); + +// Events +// init() once the page has finished loading. +window.onload = init; + +// global variables +var g_o3d; +var g_math; +var g_client; +var g_viewInfos = []; +var g_pack; +var g_finished = false; // for selenium testing + +/** + * Loads a scene into the transform graph. + * @param {!o3d.Pack} pack Pack to load scene into. + * @param {string} fileName filename of the scene. + * @param {!o3d.Transform} parent parent node in the transform graph to + * which to load the scene into. + */ +function loadScene(pack, fileName, parent) { + // Get our full path to the scene + var scenePath = o3djs.util.getCurrentURI() + fileName; + + // Load the file given the full path, and call the callback function + // when its done loading. + o3djs.scene.loadScene(g_client, pack, parent, scenePath, callback); + + /** + * Our callback is called once the scene has been loaded into memory + * from the web or locally. + * @param {!o3d.Pack} pack The pack that was passed in above. + * @param {!o3d.Transform} parent The parent that was passed in above. + * @param {*} exception null if loading succeeded. + */ + function callback(pack, parent, exception) { + if (exception) { + alert('Could not load: ' + fileName + '\n' + exception); + return; + } + // Get a cameraInfo (an object with a view and projection matrix) + // using our javascript library function + var cameraInfo = o3djs.camera.getViewAndProjectionFromCameras( + parent, + g_client.width / 2, // because this context is only used 1/2 the area + g_client.height); + + // Copy the view and projection to the draw context. + g_viewInfos[0].drawContext.view = cameraInfo.view; + g_viewInfos[0].drawContext.projection = cameraInfo.projection; + + // Generate draw elements and setup material draw lists. + o3djs.pack.preparePack(pack, g_viewInfos[0]); + + g_finished = true; // for selenium testing. + } +} + +/** + * Creates the client area. + */ +function init() { + o3djs.webgl.makeClients(initStep2); +} + +/** + * Initializes O3D and loads the scene into the transform graph. + * @param {Array} clientElements Array of o3d object elements. + */ +function initStep2(clientElements) { + // Initializes global variables and libraries. + var o3dElement = clientElements[0]; + g_o3d = o3dElement.o3d; + g_math = o3djs.math; + g_client = o3dElement.client; + + // Creates a pack to manage our resources/assets + g_pack = g_client.createPack(); + + // Create the render graph for a view for the left half of screen. + g_viewInfos[0] = o3djs.rendergraph.createBasicView( + g_pack, + g_client.root, + g_client.renderGraphRoot, + [0.7, 0.2, 0.2, 1], + 0, + [0, 0, 0.5, 1]); // left half of screen. + + // Setup 3 areas. Each area needs a viewport, a tree traveral, 2 drawpasses + // and although we could clear the screen once let's do it per viewport just + // as an example. The original area is already setup except it needs a + // viewport setting. + + // make the 2 right viewports + for (var yy = 0; yy < 2; yy++) { + // Set the view extents to the right half, top or bottom. + var viewExtents = [0.5, yy * 0.5, 0.5, 0.5]; + + // Give each view a different background color. + var viewBackgroundColor = [0.5, 0.2 + 0.5 * yy, 0.7 - 0.5 * yy, 1.0]; + + // Make this view get processes after the first view. + var viewPriority = yy + 1; + + // Create an extra view. We call createExtraView because we want to + // share DrawLists with the first view so that all 3 views draw the same + // things. + var viewInfo = o3djs.rendergraph.createExtraView( + g_viewInfos[0], + viewExtents, + viewBackgroundColor, + viewPriority); + + // Save it off for later. + g_viewInfos[g_viewInfos.length] = viewInfo; + + // Get the DrawContext for this area and set the view and + // projection matrices. + var drawContext = viewInfo.drawContext; + + if (yy == 0) { + drawContext.projection = g_math.matrix4.perspective( + g_math.degToRad(45), + (g_client.width * 0.5) / (g_client.height * 0.5), + 0.1, + 100); + drawContext.view = g_math.matrix4.lookAt( + [-10, 3, -15], // eye + [0, 2, 0], // target + [0, 1, 0]); // up + } else { + // lets make this one orthographic + var aspect = g_client.width / g_client.height; + drawContext.projection = g_math.matrix4.orthographic( + -10, + 10, + -10 / aspect, + 10 / aspect, + 0, + 100); + // look directly from the front + drawContext.view = g_math.matrix4.lookAt( + [0, 5, 30], // eye + [0, 5, 0], // target + [0, 1, 0]); // up + } + } + + // Creates a transform to put our data on. + var my_data_root = g_pack.createObject('Transform'); + + // Connects our root to the client's root. + my_data_root.parent = g_client.root; + + // Load the scene into the transform graph as a child my_data_root + loadScene(g_pack, '../assets/yard/scene.json', my_data_root); +} +</script> +</head> +<body> +<h1>Multiple Views</h1> +<br/> +<!-- Start of O3D plugin --> +<div id="o3d" style="width: 800px; height: 600px;"></div> +<!-- End of O3D plugin --> +</body> +</html> diff --git a/o3d/samples/o3d-webgl-samples/picking.html b/o3d/samples/o3d-webgl-samples/picking.html new file mode 100644 index 0000000..c6b6de1 --- /dev/null +++ b/o3d/samples/o3d-webgl-samples/picking.html @@ -0,0 +1,345 @@ +<!-- +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. +--> + +<!-- +O3D Picking Example. + +This example shows one way to implement picking. Because O3D is shader +agnostic we can't handle picking automatically since we have no way of knowing +what the developer is going to do with their shaders. On the other hand, we can +provide various functions that make it possible to do your own picking. Only you +know which objects are pickable and which are not. For example if you are +making an RTS game, only you would know that units are pickable but ground and +explosions are not and that neither is your HUD. + +It's possible that someone, maybe us, will create an engine to use o3d +that given a bunch of restrictions and flags on the data it excepts can +do picking in a more automatic way but that is not the goal of the o3d api. +Its goal is to provide a LOW-LEVEL shader agnostic API. +--> +<!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> +O3D Picking Example. +</title> +<!-- Include default javascript library functions--> +<script type="text/javascript" src="../o3d-webgl/base.js"></script> +<script type="text/javascript" src="../o3djs/base.js"></script> +<!-- Our javascript code --> +<script type="text/javascript" id="o3dscript"> +o3djs.base.o3d = o3d; +o3djs.require('o3djs.webgl'); +o3djs.require('o3djs.util'); +o3djs.require('o3djs.math'); +o3djs.require('o3djs.rendergraph'); +o3djs.require('o3djs.pack'); +o3djs.require('o3djs.camera'); +o3djs.require('o3djs.picking'); +o3djs.require('o3djs.scene'); +o3djs.require('o3djs.debug'); + +// Events +// init() once the page has finished loading. +// unload() when the page is unloaded. +window.onload = init; +window.onunload = unload; + +// constants +var NORMAL_SCALE_FACTOR = 2.0; + +// global variables +var g_o3d; +var g_math; +var g_client; +var g_pack; +var g_viewInfo; +var g_pickManager; // information about the transform graph. +var g_pickInfoElem; +var g_debugHelper; +var g_debugLineGroup; +var g_debugLine; +var g_selectedInfo = null; +var g_flashTimer = 0; +var g_highlightMaterial; +var g_highlightShape; +var g_finished = false; // for selenium testing. + +function updateInfo() { + if (!g_pickManager) { + g_pickManager = o3djs.picking.createPickManager(g_client.root); + } + g_pickManager.update(); +} + +function unSelectAll() { + if (g_selectedInfo) { + // Remove it from the transform of the selected object. + g_selectedInfo.shapeInfo.parent.transform.removeShape(g_highlightShape); + // Remove everything related to it. + o3djs.shape.deleteDuplicateShape(g_highlightShape, g_pack); + g_highlightShape = null; + g_selectedInfo = null; + // Turn off the debug line. + g_debugLine.setVisible(false); + } +} + +function select(pickInfo) { + unSelectAll(); + if (pickInfo) { + g_selectedInfo = pickInfo; + // make a copy of the selected shape so we can use it to highlight. + g_highlightShape = o3djs.shape.duplicateShape( + g_pack, + g_selectedInfo.shapeInfo.shape, + 'highlight_'); + // Set all of it's elements to use the highlight material. + var elements = g_highlightShape.elements; + for (var ee = 0; ee < elements.length; ee++) { + elements[ee].material = g_highlightMaterial; + } + + // Add it to the same transform + g_selectedInfo.shapeInfo.parent.transform.addShape(g_highlightShape); + g_flashTimer = 0.0; // make it change color immediately. + } +} + +function pick(e) { + var worldRay = o3djs.picking.clientPositionToWorldRay( + e.x, + e.y, + g_viewInfo.drawContext, + g_client.width, + g_client.height); + unSelectAll(); + + // Update the entire tree in case anything moved. + // NOTE: This function is very SLOW! + // If you really want to use picking you should manually update only those + // transforms and shapes that moved, were added, or deleted by writing your + // own picking library. You should also make sure that you are only + // considering things that are pickable. By that I mean if you have a scene of + // a meadow with trees, grass, bushes, and animals and the only thing the user + // can pick is the animals then put the animals on their own sub branch of the + // transform graph and only pick against that subgraph. + // Even better, make a separate transform graph with only cubes on it to + // represent the animals and use that instead of the actual animals. + g_pickManager.update(); + + var pickInfo = g_pickManager.pick(worldRay); + if (pickInfo) { + select(pickInfo); + g_pickInfoElem.innerHTML = pickInfo.shapeInfo.shape.name; + + // Display the normal + // NOTE: Lookup the normal with this function is very SLOW!! + // If you need performance, for a game or something, you should consider + // other methods. + var normal = o3djs.element.getNormalForTriangle( + pickInfo.element, + pickInfo.rayIntersectionInfo.primitiveIndex); + + // Convert the normal from local to world space. + normal = g_math.matrix4.transformNormal( + pickInfo.shapeInfo.parent.transform.worldMatrix, + normal); + + // Remove the scale from the normal. + normal = g_math.normalize(normal); + + // Get the world position of the collision. + var worldPosition = pickInfo.worldIntersectionPosition; + + // Add the normal to it to get a point in space above it with some + // multiplier to scale it. + var normalSpot = g_math.addVector( + worldPosition, + g_math.mulVectorScalar(normal, NORMAL_SCALE_FACTOR)); + + // Move our debug line to show the normal + g_debugLine.setVisible(true); + g_debugLine.setEndPoints(worldPosition, normalSpot); + } else { + g_pickInfoElem.innerHTML = '--nothing--'; + } +} + +function onrender(renderEvent) { + g_flashTimer += renderEvent.elapsedTime; + g_flashTimer = g_flashTimer % 0.5; + if (g_selectedInfo) { + if (g_flashTimer < 0.25) { + g_highlightMaterial.getParam('emissive').value = [1, 1, 1, 1]; + } else { + g_highlightMaterial.getParam('emissive').value = [0, 0, 0, 1]; + } + } +} + +/** + * Loads a scene into the transform graph. + * @param {!o3d.Pack} pack Pack to load scene into. + * @param {string} fileName filename of the scene. + * @param {!o3d.Transform} parent parent node in the transform graph to + * which to load the scene into. + */ +function loadScene(pack, fileName, parent) { + // Get our full path to the scene + var scenePath = o3djs.util.getCurrentURI() + fileName; + + // Load the file given the full path, and call the callback function + // when its done loading. + o3djs.scene.loadScene(g_client, pack, parent, scenePath, callback); + + /** + * Our callback is called once the scene has been loaded into memory + * from the web or locally. + * @param {!o3d.Pack} pack The pack that was passed in above. + * @param {!o3d.Transform} parent The parent that was passed in above. + * @param {*} exception null if loading succeeded. + */ + function callback(pack, parent, exception) { + if (exception) { + alert('Could not load: ' + fileName + '\n' + exception); + return; + } + // Get a cameraInfo (an object with a view and projection matrix) + // using our javascript library function + var cameraInfo = o3djs.camera.getViewAndProjectionFromCameras( + parent, + g_client.width, + g_client.height); + + // Copy the one from the file to ours. + g_viewInfo.drawContext.view = cameraInfo.view; + g_viewInfo.drawContext.projection = cameraInfo.projection; + + // Generate draw elements and setup material draw lists. + o3djs.pack.preparePack(pack, g_viewInfo); + + // Update our info + updateInfo(); + + g_pickManager.dump(''); + + g_finished = true; // for selenium testing. + } +} + +/** + * Creates the client area. + */ +function init() { + o3djs.webgl.makeClients(initStep2); +} + +/** + * Initializes O3D and loads the scene into the transform graph. + * @param {Array} clientElements Array of o3d object elements. + */ +function initStep2(clientElements) { + // Initializes global variables and libraries. + var o3dElement = clientElements[0]; + o3dElement.name = 'o3dObj'; // This is only for our selenium tests. + g_o3d = o3dElement.o3d; + g_math = o3djs.math; + g_client = o3dElement.client; + + g_pickInfoElem = document.getElementById('pickInfo'); + + // Creates a pack to manage our resources/assets + g_pack = g_client.createPack(); + + // Create the render graph for a view. + g_viewInfo = o3djs.rendergraph.createBasicView( + g_pack, + g_client.root, + g_client.renderGraphRoot); + + // Use the debug library to create a line we can position to show + // the normal. + g_debugHelper = o3djs.debug.createDebugHelper(g_client.createPack(), + g_viewInfo); + g_debugLineGroup = g_debugHelper.createDebugLineGroup(g_client.root); + g_debugLine = g_debugLineGroup.addLine(); + g_debugLine.setColor([0,1,0,1]); + g_debugLine.setVisible(false); + + // Create a material for highlighting. + g_highlightMaterial = o3djs.material.createConstantMaterial( + g_pack, + g_viewInfo, + [1, 1, 1, 1]); + // Setup a state to bring the lines forward. + var state = g_pack.createObject('State'); + state.getStateParam('PolygonOffset2').value = -1.0; + state.getStateParam('FillMode').value = g_o3d.State.WIREFRAME; + g_highlightMaterial.state = state; + + // Creates a transform to put our data on. + var my_data_root = g_pack.createObject('Transform'); + + // Connects our root to the client's root. + my_data_root.parent = g_client.root; + + // Load the scene into the transform graph as a child of my_data_root + loadScene(g_pack, '../assets/seven_shapes/scene.json', my_data_root); + + g_client.setRenderCallback(onrender); + + // Start picking; it won't do anything until the scene finishes loading. + o3djs.event.addEventListener(o3dElement, 'mousedown', pick); +} + +/** + * Removes 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>Picking</h1> +Click on an object +<br/> +<!-- Start of O3D plugin --> +<div id="o3d" style="width: 600px; height: 600px;"></div> +<!-- End of O3D plugin --> +<div style="font-family: sans-serif; font-size: large;">PICKED: <span id="pickInfo"></span></div> +</body> +</html> diff --git a/o3d/samples/o3d-webgl-samples/procedural-texture.html b/o3d/samples/o3d-webgl-samples/procedural-texture.html new file mode 100644 index 0000000..abd31df --- /dev/null +++ b/o3d/samples/o3d-webgl-samples/procedural-texture.html @@ -0,0 +1,255 @@ +<!-- +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. +--> + +<!-- +O3D Tutorial + +In this tutorial, we load and display a scene in O3D and then +apply a procedural texture to 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> +Applying a Procedural Texture to a scene +</title> +<!-- Include sample javascript library functions--> +<script type="text/javascript" src="../o3d-webgl/base.js"></script> +<script type="text/javascript" src="../o3djs/base.js"></script> + +<!-- Our javascript code --> +<script type="text/javascript" id="o3dscript"> +o3djs.base.o3d = o3d; +o3djs.require('o3djs.webgl'); +o3djs.require('o3djs.util'); +o3djs.require('o3djs.rendergraph'); +o3djs.require('o3djs.pack'); +o3djs.require('o3djs.camera'); +o3djs.require('o3djs.scene'); + +// Events +// init() once the page has finished loading. +window.onload = init; + +// global variables +var g_o3d; +var g_client; +var g_viewInfo; +var g_pack; +var g_finished = false; // for selenium testing + +/** + * Loads a scene into the transform graph. + * @param {!o3d.Pack} pack Pack to load scene into. + * @param {string} fileName filename of the scene. + * @param {!o3d.Transform} parent parent node in the transform graph to + * which to load the scene into. + */ +function loadScene(pack, fileName, parent) { + // Get our full path to the scene + var scenePath = o3djs.util.getCurrentURI() + fileName; + + // Load the file given the full path, and call the callback function + // when its done loading. + o3djs.scene.loadScene(g_client, pack, parent, scenePath, callback); + + /** + * Our callback is called once the scene has been loaded into memory + * from the web or locally. + * @param {!o3d.Pack} pack The pack that was passed in above. + * @param {!o3d.Transform} parent The parent that was passed in above. + * @param {*} exception null if loading succeeded. + */ + function callback(pack, parent, exception) { + if (exception) { + alert('Could not load: ' + fileName + '\n' + exception); + return; + } + // Get a CameraInfo (an object with a view and projection matrix) + // using our javascript library function + var cameraInfo = o3djs.camera.getViewAndProjectionFromCameras( + parent, + g_client.width, + g_client.height); + + // Copy the view and projection to the draw context. + g_viewInfo.drawContext.view = cameraInfo.view; + g_viewInfo.drawContext.projection = cameraInfo.projection; + + // Add our checker pattern + createCheckerBoard(pack, 'Material__26'); + + // Generate draw elements and setup material draw lists. + o3djs.pack.preparePack(pack, g_viewInfo); + + g_finished = true; // for selenium testing. + } +} + +/** + * In order to apply the texture you must know the material name which you wish + * to change. The bulk of the calculation takes place in the shader itself. + * Alternatively, you could change the first or all the materials if you don't + * know the material name. + * @param {!o3d.Pack} pack The pack the scene was loaded into. + * @param {string} materialName Name of material you wish to turn into checkers. + */ +function createCheckerBoard(pack, materialName) { + var effectString = document.getElementById('checkerShader').value; + var effect = g_pack.createObject('Effect'); + effect.loadFromFXString(effectString); + var materials = pack.getObjects(materialName, 'o3d.Material'); + for (var m = 0; m < materials.length; m++) { + var material = materials[m]; + // Set the material to use the checker effect. + material.effect = effect; + // Create any parameters the effect needs on the material. + effect.createUniformParameters(material); + } +} + +/** + * Creates the client area. + */ +function init() { + o3djs.webgl.makeClients(initStep2); +} + +/** + * Initializes O3D and loads the scene into the transform graph. + * @param {Array} clientElements Array of o3d object elements. + */ +function initStep2(clientElements) { + // Initializes global variables and libraries. + var o3dElement = clientElements[0]; + g_o3d = o3dElement.o3d; + g_client = o3dElement.client; + + // Creates a pack to manage our resources/assets + g_pack = g_client.createPack(); + + // Create the render graph for a view. + g_viewInfo = o3djs.rendergraph.createBasicView( + g_pack, + g_client.root, + g_client.renderGraphRoot); + + // Creates a transform to put our data on. + var myDataRoot = g_pack.createObject('Transform'); + + // Connects our root to the client's root. + myDataRoot.parent = g_client.root; + + // Load the scene into the transform graph as a child myDataRoot + loadScene(g_pack, '../assets/teapot/scene.json', myDataRoot); +} +</script> +</head> +<body> +<h1>Applying a Procedural Texture to a scene</h1> +This tutorial shows how to apply a procedural texture to a scene. +<br/> +<!-- Start of O3D plugin --> +<div id="o3d" style="width: 600px; height: 600px;"></div> +<!-- End of O3D plugin --> +<!-- Don't render the textarea --> +<textarea id="checkerShader" style="display: none;"> +// The 4x4 world view projection matrix. +uniform mat4 worldViewProjection; + +// input parameters for our vertex shader +attribute vec4 position; +attribute vec3 normal; +attribute vec2 texCoord0; + +// input parameters for our pixel shader +varying vec4 col; +varying vec2 texcoord; + +/** + * Our vertex shader. In the vertex shader, we calculate the lighting. + * Then we'll combine it with our checker pattern in the pixel shader. + */ +void main() { + gl_Position = worldViewProjection * position; + + /** + * lightVector - light vector + * normal - normal vector + * We put the light such that it illuminates our model. + */ + vec4 diffuseColor = vec4(1, 1, 1, 1); + vec3 lightPos = vec3(1000, -1000, 1000); + + vec3 lightVector = normalize(lightPos - position.xyz); + vec3 normal = normalize(normal); + vec4 diffuse = dot(normal, lightVector) * diffuseColor; + + col = diffuse; + texcoord = texCoord0; +} + +// #o3d SplitMarker + +// function for getting the checker pattern + +vec4 checker(vec2 uv) { + float checkSize = 4.0; + float fmodResult = mod(floor(checkSize * uv.x) + floor(checkSize * uv.y), + 2.0); + if (fmodResult < 1.0) { + return vec4(0, 1, 1, 1); + } else { + return vec4(1, 0, 1, 1); + } +} + +// input parameters for our pixel shader +varying vec4 col; +varying vec2 texcoord; + + +/** + * Our pixel shader. We take the lighting color we got from the vertex sahder + * and combine it with our checker pattern. + */ +void main() { + vec4 check = checker(texcoord); + vec4 color = col * check; + gl_FragColor = color; +} + +// #o3d MatrixLoadOrder RowMajor +</textarea> +</body> +</html> diff --git a/o3d/samples/o3d-webgl-samples/render-targets.html b/o3d/samples/o3d-webgl-samples/render-targets.html new file mode 100644 index 0000000..4dd9d06 --- /dev/null +++ b/o3d/samples/o3d-webgl-samples/render-targets.html @@ -0,0 +1,333 @@ +<!-- +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 setup a basic render graph making use of RenderSurface +nodes to implement render-target functionality. +--> +<!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> +O3D: Render-Target Sample +</title> +<!-- Include sample javascript library functions--> +<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.util'); +o3djs.require('o3djs.math'); +o3djs.require('o3djs.rendergraph'); +o3djs.require('o3djs.pack'); +o3djs.require('o3djs.camera'); +o3djs.require('o3djs.primitives'); +o3djs.require('o3djs.scene'); + +// constants. +var RENDER_TARGET_WIDTH = 512; +var RENDER_TARGET_HEIGHT = 512; + +// global variables +var g_o3d; +var g_math; +var g_client; +var g_viewInfo; +var g_pack; +var g_teapotPack; +var g_teapotRoot; +var g_cubeRoot; + +/** + * Loads a scene into the transform graph. + * @param {!o3d.Pack} pack Pack to load scene into. + * @param {string} fileName filename of the scene. + * @param {!o3d.Transform} parent parent node in the transform graph to + * which to load the scene into. + * @param {!o3djs.rendergraph.ViewInfo} viewInfo who's view and projection will + * be set from the scene after it's loaded. + */ +function loadScene(pack, fileName, parent, viewInfo) { + // Get our full path to the scene + var scenePath = o3djs.util.getCurrentURI() + fileName; + + // Load the file given the full path, and call the callback function + // when its done loading. + o3djs.scene.loadScene(g_client, pack, parent, scenePath, callback); + + /** + * Our callback is called once the scene has been loaded into memory + * from the web or locally. + * @param {!o3d.Pack} pack The pack that was passed in above. + * @param {!o3d.Transform} parent The parent that was passed in above. + * @param {*} exception null if loading succeeded. + */ + function callback(pack, parent, exception) { + if (exception) { + alert('Could not load: ' + fileName + '\n' + exception); + return; + } + // Get a CameraInfo (an object with a view and projection matrix) + // using our javascript library function + var cameraInfo = o3djs.camera.getViewAndProjectionFromCameras( + parent, + RENDER_TARGET_WIDTH, + RENDER_TARGET_HEIGHT); + + // Copy the view and projection to the passed in viewInfo structure.. + viewInfo.drawContext.view = cameraInfo.view; + viewInfo.drawContext.projection = cameraInfo.projection; + + // Generate draw elements and setup material draw lists. + o3djs.pack.preparePack(pack, viewInfo); + + window.g_finished = true; // for selenium testing. + } +} + +/** + * Creates the client area. + */ +function init() { + // These are here so that they are visible to both the browser (so + // selenium sees them) and the embedded V8 engine. + window.g_clock = 0; + window.g_timeMult = 1; + window.g_finished = false; // for selenium testing. + + // Comment out the line below to run the sample in the browser + // JavaScript engine. This may be helpful for debugging. + o3djs.util.setMainEngine(o3djs.util.Engine.V8); + + o3djs.webgl.makeClients(initStep2); +} + +/** + * Initializes O3D and loads the scene into the transform graph. + * @param {Array} clientElements Array of o3d object elements. + */ +function initStep2(clientElements) { + // Initializes global variables and libraries. + var o3d = clientElements[0]; + g_o3d = o3d.o3d; + g_math = o3djs.math; + + // Set window.g_client as well. Otherwise when the sample runs in + // V8, selenium won't be able to find this variable (it can only see + // the browser environment). + window.g_client = g_client = o3d.client; + + // Creates a pack to manage our resources/assets + g_pack = g_client.createPack(); + + // Create a sub-pack to manage the resources required for the teapot. + g_teapotPack = g_client.createPack(); + + // Create the texture required for the color render-target. + var texture2d = g_pack.createTexture2D(RENDER_TARGET_WIDTH, + RENDER_TARGET_HEIGHT, + g_o3d.Texture.XRGB8, 1, true); + var renderSurface = texture2d.getRenderSurface(0); + + // Create the depth-stencil buffer required when rendering the teapot. + var depthSurface = g_pack.createDepthStencilSurface(RENDER_TARGET_WIDTH, + RENDER_TARGET_HEIGHT); + + g_cubeRoot = g_pack.createObject('Transform'); + g_teapotRoot = g_pack.createObject('Transform'); + g_cubeRoot.parent = g_client.root; + g_teapotRoot.parent = g_client.root; + + var teapotRenderRoot = g_pack.createObject('RenderNode'); + teapotRenderRoot.priority = 0; + var cubeRenderRoot = g_pack.createObject('RenderNode'); + cubeRenderRoot.priority = 1; + + teapotRenderRoot.parent = g_client.renderGraphRoot; + cubeRenderRoot.parent = g_client.renderGraphRoot; + + var renderSurfaceSet = g_pack.createObject('RenderSurfaceSet'); + renderSurfaceSet.renderSurface = renderSurface; + renderSurfaceSet.renderDepthStencilSurface = depthSurface; + renderSurfaceSet.parent = teapotRenderRoot; + + // Create the render graph for a view. + var teapotViewInfo = o3djs.rendergraph.createBasicView( + g_teapotPack, + g_teapotRoot, + renderSurfaceSet); + + var cubeViewInfo = o3djs.rendergraph.createBasicView( + g_pack, + g_cubeRoot, + cubeRenderRoot); + + var myMaterial = g_pack.createObject('Material'); + myMaterial.drawList = cubeViewInfo.performanceDrawList; + + var effect = g_pack.createObject('Effect'); + var fxString = o3djs.util.getElementContentById('fx'); + effect.loadFromFXString(fxString); + + // Apply our effect to this material. + myMaterial.effect = effect; + effect.createUniformParameters(myMaterial); + + var samplerParam = myMaterial.getParam('texSampler0'); + var sampler = g_pack.createObject('Sampler'); + sampler.texture = texture2d; + samplerParam.value = sampler; + + // Create a transform to put our data on. + var myDataRoot = g_pack.createObject('Transform'); + + // Connect our root to the client. + myDataRoot.parent = g_teapotRoot; + var vec3 = [0.5, 0.5, 0.5]; + + var cubeShape = o3djs.primitives.createCube(g_pack, + myMaterial, + 300.0); + + // Attach the cube to the root of the transform graph. + g_cubeRoot.addShape(cubeShape); + + o3djs.pack.preparePack(g_pack, cubeViewInfo); + + // Points at the origin. + var target = [0, 0, 0]; + // Puts the camera outside the origin. + var eye = [500, 500, 500]; + // Defines UP as Y up. + var up = [0, 1, 0]; + cubeViewInfo.drawContext.view = g_math.matrix4.lookAt(eye, + target, + up); + + cubeViewInfo.drawContext.projection = g_math.matrix4.perspective( + g_math.degToRad(30), + g_client.width / g_client.height, 1, 5000); + + // Load the scene into the transform graph as a child myDataRoot + loadScene(g_teapotPack, '../assets/teapot/scene.json', myDataRoot, + teapotViewInfo); + + // Set a render callback. + g_client.setRenderCallback(onRender); +} + +/** + * Called every frame. + * @param {!o3d.RenderEvent} renderEvent Rendering Information. + */ +function onRender(renderEvent) { + var elapsedTime = renderEvent.elapsedTime; + // Update g_clock in the browser and cache a V8 copy that can be + // accessed efficiently. g_clock must be in the browser for selenium. + var clock = window.g_clock + elapsedTime * window.g_timeMult; + window.g_clock = clock; + + g_teapotRoot.identity(); + g_teapotRoot.rotateX(clock); + g_teapotRoot.rotateY(clock * 1.3); + + g_cubeRoot.identity(); + g_cubeRoot.rotateX(clock * 0.4); + g_cubeRoot.rotateY(clock * 0.1); +} + +/** + * Cleanup before exiting. + */ +function unload() { + if (g_client) { + g_client.cleanup(); + } +} +</script> +</head> +<body onload="init()" onunload="unload()"> +<h1>Basic Render-Target Example</h1> +<br/> +<!-- Start of O3D plugin --> +<div id="o3d" style="width: 600px; height: 600px;"></div> +<!-- End of O3D plugin --> +<!-- + We embed the code for our effect inside this hidden textarea. + Effects contain the functions that define + the vertex and pixel shaders used by our shape. +--> +<!-- Don't render the textarea --> +<div style="display:none"> +<textarea id="fx" name="fx" cols="80" rows="20"> + // The 4x4 world view projection matrix. + uniform mat4 worldViewProjection; + + attribute vec4 position; + attribute vec2 texCoord0; + varying vec2 texcoord; + + /** + * Vertex Shader performing basic viewing transformation. + */ + void main() { + /** + * We transform each vertex by the view projection matrix to bring + * it from world space to projection space. + * + * We return its color unchanged. + */ + gl_Position = worldViewProjection * position; + texcoord = texCoord0; + } + + // #o3d SplitMarker + + uniform sampler2D texSampler0; + varying vec2 texcoord; + + /** + * Pixel Shader + */ + void main() { + gl_FragColor = texture2D(texSampler0, texcoord * 5.0) + + vec4(0.2, 0.2, 0.0, 1.0); + } + + // #o3d MatrixLoadOrder RowMajor +</textarea> +</div> +</body> + +</html> diff --git a/o3d/samples/o3d-webgl/viewport.js b/o3d/samples/o3d-webgl/viewport.js index a9ffebc..36eea87 100644 --- a/o3d/samples/o3d-webgl/viewport.js +++ b/o3d/samples/o3d-webgl/viewport.js @@ -38,7 +38,7 @@ * 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 @@ -80,7 +80,8 @@ o3d.ParamObject.setUpO3DParam_(o3d.Viewport, 'depthRange', 'ParamFloat2'); */ o3d.Viewport.prototype.before = function() { var x = this.viewport[0] * this.gl.displayInfo.width; - var y = this.viewport[1] * this.gl.displayInfo.height; + var y = (1 - this.viewport[1] - this.viewport[3]) * + this.gl.displayInfo.height; var width = this.viewport[2] * this.gl.displayInfo.width; var height = this.viewport[3] * this.gl.displayInfo.height; diff --git a/o3d/samples/shaders/vertex-color-glsl.shader b/o3d/samples/shaders/vertex-color-glsl.shader new file mode 100644 index 0000000..9569387 --- /dev/null +++ b/o3d/samples/shaders/vertex-color-glsl.shader @@ -0,0 +1,59 @@ +/* + * 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. + */ + +// The 4x4 world view projection matrix. +uniform mat4 worldViewProjection; + +// input parameters for our vertex shader +attribute vec4 position; +attribute vec4 color; + +// input parameters for our pixel shader +// also the output parameters for our vertex shader +varying vec4 v_color; + +/** + * Vertex Shader - our vertex shader + */ +void main() { + gl_Position = worldViewProjection * position; + v_color = color; +} + +// #o3d SplitMarker +varying vec4 v_color; +/** + * pixel shader does nothing but return whatever color it was given. + */ +void main() { + gl_FragColor = v_color; +} +// #o3d MatrixLoadOrder RowMajor |