diff options
author | luchen@google.com <luchen@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-08 18:21:18 +0000 |
---|---|---|
committer | luchen@google.com <luchen@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-08 18:21:18 +0000 |
commit | 6e0a36b0e6cc24dacde23635af162cd4de464bd8 (patch) | |
tree | 7af6905eba487133eaccd707ae20392f58799bd1 /o3d | |
parent | 9e3a1d836b29d513476df8942887c0ea22c3b86e (diff) | |
download | chromium_src-6e0a36b0e6cc24dacde23635af162cd4de464bd8.zip chromium_src-6e0a36b0e6cc24dacde23635af162cd4de464bd8.tar.gz chromium_src-6e0a36b0e6cc24dacde23635af162cd4de464bd8.tar.bz2 |
Adding support for pointlist, linelist, linestrip, trianglestrip and triangelfan primitive drawing types. Demo file included.
Review URL: http://codereview.chromium.org/2645003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@49173 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d')
-rw-r--r-- | o3d/samples/o3d-webgl-samples/hellocube-wireframe.html | 385 | ||||
-rw-r--r-- | o3d/samples/o3d-webgl/buffer.js | 2 | ||||
-rw-r--r-- | o3d/samples/o3d-webgl/primitive.js | 41 |
3 files changed, 423 insertions, 5 deletions
diff --git a/o3d/samples/o3d-webgl-samples/hellocube-wireframe.html b/o3d/samples/o3d-webgl-samples/hellocube-wireframe.html new file mode 100644 index 0000000..86eae19 --- /dev/null +++ b/o3d/samples/o3d-webgl-samples/hellocube-wireframe.html @@ -0,0 +1,385 @@ +<!-- +Copyright 2009, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> + +<!-- +This sample shows how to place an O3D area in a page and draw simple +3D shape in it. +--> +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> +<html> +<head> +<meta http-equiv="content-type" content="text/html; charset=UTF-8"> +<title> +Hello Cube: Primitives +</title> +<script type="text/javascript" src="../o3d-webgl/base.js"></script> +<script type="text/javascript" src="../o3djs/base.js"></script> +<script type="text/javascript" id="o3dscript"> +o3djs.base.o3d = o3d; +o3djs.require('o3djs.webgl'); +o3djs.require('o3djs.math'); +o3djs.require('o3djs.rendergraph'); + +// Events +// Run the init() function once the page has finished loading. +// Run the uninit() function when the page has is unloaded. +window.onload = init; +window.onunload = uninit; + +// global variables +var g_o3d; +var g_math; +var g_client; +var g_pack; +var g_clock = 0; +var g_timeMult = 1; +var g_cubeTransform; +var g_cubePrimitive; +var g_finished = false; // for selenium testing + +/** + * Changes the primitive type of the displayed cube. Some primitive types will + * only draw a partial cube. + * @param {string} type the desired primitive type + */ +function changePrimitive(type) { + var indicesArray; + var primitiveType; + var numberPrimitives; + + // All of the indices arrays below reference the same set of 8 vertices, + // defined below in the createCube method. + switch (type) { + case 'PointList': + primitiveType = g_o3d.Primitive.POINTLIST; + numberPrimitives = 8; + indicesArray = [0, 1, 2, 3, 4, 5, 6, 7]; + break; + case 'LineList': + primitiveType = g_o3d.Primitive.LINELIST; + numberPrimitives = 12; + indicesArray = [ + 0, 1, + 1, 3, + 3, 2, + 2, 0, + 6, 7, + 7, 5, + 5, 4, + 4, 6, + 2, 4, + 3, 5, + 0, 6, + 1, 7 + ]; + break; + case 'LineStrip': + primitiveType = g_o3d.Primitive.LINESTRIP; + numberPrimitives = 8; + // Forms an incomplete cube, where indices 0 and 1 are the first segment, + // 1 and 3 are the second segement, 3 and 5 are the third, and so forth. + indicesArray = [0, 1, 3, 5, 7, 6, 4, 2, 0]; + break; + case 'TriangleList': + primitiveType = g_o3d.Primitive.TRIANGLELIST; + numberPrimitives = 12; + indicesArray = [ + 0, 1, 2, // face 1 + 2, 1, 3, + 2, 3, 4, // face 2 + 4, 3, 5, + 4, 5, 6, // face 3 + 6, 5, 7, + 6, 7, 0, // face 4 + 0, 7, 1, + 1, 7, 3, // face 5 + 3, 7, 5, + 6, 0, 4, // face 6 + 4, 0, 2 + ]; + break; + case 'TriangleStrip': + primitiveType = g_o3d.Primitive.TRIANGLESTRIP; + numberPrimitives = 8; + // Forms a cube missing two faces. Indices (0, 1, 2) forms the first + // triangle, (1, 2, 3) forms the second triangle, and so forth. + indicesArray = [0, 1, 2, 3, 4, 5, 6, 7, 0, 1]; + break; + case 'TriangleFan': + primitiveType = g_o3d.Primitive.TRIANGLEFAN; + numberPrimitives = 6; + // Forms a half cube, missing three faces. Indices (2, 0, 1) forms the + // first triangle, (2, 1, 3) is the second, (2, 3, 5) is the third, etc. + indicesArray = [2, 0, 1, 3, 5, 4, 6, 0]; + break; + default: + alert('Invalid selection type!'); + return; + } + + g_cubePrimitive.primitiveType = primitiveType; + g_cubePrimitive.numberPrimitives = numberPrimitives; + g_cubePrimitive.indexBuffer.set(indicesArray); +} + +/** + * Creates an O3D shape representing a cube. The shape consists of + * a single primitive with eight vertices. + * + * @param {o3d.Material} material the material used by the primitive. + * @return {o3d.Shape} The Shape object created. + */ +function createCube(material) { + // Create a Shape object for the mesh. + var cubeShape = g_pack.createObject('Shape'); + + // Create the Primitive that will contain the geometry data for + // the cube. + var cubePrimitive = g_pack.createObject('Primitive'); + g_cubePrimitive = cubePrimitive; + + // Create a StreamBank to hold the streams of vertex data. + var streamBank = g_pack.createObject('StreamBank'); + + // Assign the material that was passed in to the primitive. + cubePrimitive.material = material; + + // Assign the Primitive to the Shape. + cubePrimitive.owner = cubeShape; + + // Assign the StreamBank to the Primitive. + cubePrimitive.streamBank = streamBank; + + // Generate the draw element for the cube primitive. + cubePrimitive.createDrawElement(g_pack, null); + + // Create a javascript array that stores the X, Y and Z coordinates of each + // of the 8 corners of the cube. + var positionArray = [ + -0.5, -0.5, 0.5, // vertex 0 + 0.5, -0.5, 0.5, // vertex 1 + -0.5, 0.5, 0.5, // vertex 2 + 0.5, 0.5, 0.5, // vertex 3 + -0.5, 0.5, -0.5, // vertex 4 + 0.5, 0.5, -0.5, // vertex 5 + -0.5, -0.5, -0.5, // vertex 6 + 0.5, -0.5, -0.5 // vertex 7 + ]; + + // Create buffers containing the vertex data. + var positionsBuffer = g_pack.createObject('VertexBuffer'); + var positionsField = positionsBuffer.createField('FloatField', 3); + positionsBuffer.set(positionArray); + cubePrimitive.indexBuffer = g_pack.createObject('IndexBuffer'); + + // Associate the positions Buffer with the StreamBank. + streamBank.setVertexStream( + g_o3d.Stream.POSITION, // semantic: This stream stores vertex positions + 0, // semantic index: First (and only) position stream + positionsField, // field: the field this stream uses. + 0); // start_index: How many elements to skip in the + // field. + + return cubeShape; +} + +/** + * This method gets called every time O3D renders a frame. Here's where + * we update the cube's transform to make it spin. + * @param {o3d.RenderEvent} renderEvent The render event object that gives + * us the elapsed time since the last time a frame was rendered. + */ +function renderCallback(renderEvent) { + g_clock += renderEvent.elapsedTime * g_timeMult; + // Rotate the cube around the Y axis. + g_cubeTransform.identity(); + g_cubeTransform.rotateY(2.0 * g_clock); +} + + +/** + * Creates the client area. + */ +function init() { + o3djs.webgl.makeClients(initStep2); +} + +/** + * Initializes O3D, creates the cube and sets up the transform and + * render graphs. + * @param {Array} clientElements Array of o3d object elements. + */ +function initStep2(clientElements) { + // Initializes global variables and libraries. + var o3dElement = clientElements[0]; + g_client = o3dElement.client; + g_o3d = o3dElement.o3d; + g_math = o3djs.math; + + // Create a pack to manage the objects created. + g_pack = g_client.createPack(); + + // Create the render graph for a view. + var viewInfo = o3djs.rendergraph.createBasicView( + g_pack, + g_client.root, + g_client.renderGraphRoot, + [1, 1, 1, 1]); + + // Set up a perspective projection. + viewInfo.drawContext.projection = g_math.matrix4.perspective( + g_math.degToRad(30), // 30 degree fov. + g_client.width / g_client.height, + 1, // Near plane. + 5000); // Far plane. + + // Set up our view transformation to look towards the world origin where the + // cube is located. + viewInfo.drawContext.view = g_math.matrix4.lookAt([0, 1, 5], // eye + [0, 0, 0], // target + [0, 1, 0]); // up + + // Create an Effect object and initialize it using the shaders from the + // text area. + var myEffect = g_pack.createObject('Effect'); + var vertexShaderString = document.getElementById('vshader').value; + var pixelShaderString = document.getElementById('pshader').value; + myEffect.loadVertexShaderFromString(vertexShaderString); + myEffect.loadPixelShaderFromString(pixelShaderString); + + // Create a Material for the mesh. + var myMaterial = g_pack.createObject('Material'); + + // Set the material's drawList. + myMaterial.drawList = viewInfo.performanceDrawList; + + // Turn off culling. + viewInfo.performanceDrawPassInfo.state.getStateParam('CullMode').value = + g_o3d.State.CULL_NONE; + + // Apply our effect to this material. The effect tells the 3D hardware + // which shaders to use. + myMaterial.effect = myEffect; + + // Create the Shape for the cube mesh and assign its material. + var cubeShape = createCube(myMaterial); + + // Render with line lists to begin with. + changePrimitive('LineList'); + + // Create a new transform and parent the Shape under it. + g_cubeTransform = g_pack.createObject('Transform'); + g_cubeTransform.addShape(cubeShape); + + // Parent the cube's transform to the client root. + g_cubeTransform.parent = g_client.root; + + // Set our render callback for animation. + // This sets a function to be executed every time a frame is rendered. + g_client.setRenderCallback(renderCallback); + + g_finished = true; // for selenium testing. +} + +/** + * Removes any callbacks so they don't get called after the page has unloaded. + */ +function uninit() { + if (g_client) { + g_client.cleanup(); + } +} + +</script> +</head> +<body> +<h1>Hello Cube - Primitives</h1> +This example shows how to display a cube in O3D using different primitive types. +<br/> + + +<!-- Start of O3D plugin --> +<div id="o3d" style="width: 600px; height: 600px;"></div> + +<form name="default_form" action="#" method="get"> + <p> + Change type: + <select onchange="changePrimitive(this.options[this.selectedIndex].value);"> + <option value="PointList">PointList</option> + <option value="LineList" selected>LineList</option> + <option value="LineStrip">LineStrip</option> + <option value="TriangleList">TriangleList</option> + <option value="TriangleStrip">TriangleStrip</option> + <option value="TriangleFan">TriangleFan</option> + </select> (PointList may be hard to see.) + </p> +</form> + +<!-- End of O3D plugin --> + +<!-- Don't render the textarea --> +<div style="display:none"> +<!-- Start of effect --> +<textarea id="vshader"> + attribute vec4 position; + + uniform mat4 world; + uniform mat4 view; + uniform mat4 projection; + + varying vec4 pos; + + /** + * The vertex shader simply transforms the input vertices to screen space. + */ + void main() { + // Multiply the vertex positions by the worldViewProjection matrix to + // transform them to screen space. + gl_Position = projection * view * world * position; + pos = position; + } +</textarea> +<textarea id="pshader"> + varying vec4 pos; + + /** + * The fragment shader derives color based on the position. + */ + void main() { + gl_FragColor = pos; + } +</textarea> +<!-- End of effect --> +</div> +</body> +</html> + diff --git a/o3d/samples/o3d-webgl/buffer.js b/o3d/samples/o3d-webgl/buffer.js index bf8d572..52520d2 100644 --- a/o3d/samples/o3d-webgl/buffer.js +++ b/o3d/samples/o3d-webgl/buffer.js @@ -194,7 +194,7 @@ o3d.Buffer.prototype.set = if (!values.length) { o3d.notImplemented(); } - if (this.array_ == null) { + if (this.array_ == null || this.array_.length != values.length) { this.resize(values.length); } this.lock(); diff --git a/o3d/samples/o3d-webgl/primitive.js b/o3d/samples/o3d-webgl/primitive.js index 904abf8..4c74c69 100644 --- a/o3d/samples/o3d-webgl/primitive.js +++ b/o3d/samples/o3d-webgl/primitive.js @@ -143,10 +143,44 @@ o3d.Primitive.prototype.render = function() { this.gl.client.render_stats_['primitivesRendered'] += this.numberPrimitives; - // TODO(petersont): Change the hard-coded 3 and triangles too. + var glMode; + var glNumElements; + + switch (this.primitiveType) { + case o3d.Primitive.POINTLIST: + glMode = this.gl.POINTS; + glNumElements = this.numberPrimitives; + break; + case o3d.Primitive.LINELIST: + glMode = this.gl.LINES; + glNumElements = this.numberPrimitives * 2; + break; + case o3d.Primitive.LINESTRIP: + glMode = this.gl.LINE_STRIP; + glNumElements = this.numberPrimitives + 1; + break; + case o3d.Primitive.TRIANGLELIST: + glMode = this.gl.TRIANGLES; + glNumElements = this.numberPrimitives * 3; + break; + case o3d.Primitive.TRIANGLESTRIP: + glMode = this.gl.TRIANGLE_STRIP; + glNumElements = this.numberPrimitives + 2; + break; + case o3d.Primitive.TRIANGLEFAN: + glMode = this.gl.TRIANGLE_FAN; + glNumElements = this.numberPrimitives + 2; + break; + case o3d.Primitive.TRIANGLELIST: + default: + glMode = this.gl.TRIANGLES; + glNumElements = this.numberPrimitives * 3; + break; + } + this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, indexBuffer.gl_buffer_); - this.gl.drawElements(this.gl.TRIANGLES, - this.numberPrimitives * 3, + this.gl.drawElements(glMode, + glNumElements, this.gl.UNSIGNED_SHORT, 0); @@ -155,7 +189,6 @@ o3d.Primitive.prototype.render = function() { } }; - /** * Computes the bounding box in same coordinate system as the specified * POSITION stream. |