summaryrefslogtreecommitdiffstats
path: root/o3d
diff options
context:
space:
mode:
authorluchen@google.com <luchen@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-08 18:21:18 +0000
committerluchen@google.com <luchen@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-08 18:21:18 +0000
commit6e0a36b0e6cc24dacde23635af162cd4de464bd8 (patch)
tree7af6905eba487133eaccd707ae20392f58799bd1 /o3d
parent9e3a1d836b29d513476df8942887c0ea22c3b86e (diff)
downloadchromium_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.html385
-rw-r--r--o3d/samples/o3d-webgl/buffer.js2
-rw-r--r--o3d/samples/o3d-webgl/primitive.js41
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.