summaryrefslogtreecommitdiffstats
path: root/o3d
diff options
context:
space:
mode:
authorluchen@google.com <luchen@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-17 22:51:39 +0000
committerluchen@google.com <luchen@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-17 22:51:39 +0000
commit084391bc16e3cc8696ae40eaea28b7f2d4009d69 (patch)
treeb2dac0727ae0bbd0d6dc555b5a41b01ba2558234 /o3d
parent3e069baf03d84e01ff9814709038ecb12d620b91 (diff)
downloadchromium_src-084391bc16e3cc8696ae40eaea28b7f2d4009d69.zip
chromium_src-084391bc16e3cc8696ae40eaea28b7f2d4009d69.tar.gz
chromium_src-084391bc16e3cc8696ae40eaea28b7f2d4009d69.tar.bz2
o3d-webgl: adding generate-texture demo, with implementation of texture.set.
Review URL: http://codereview.chromium.org/2821004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@50154 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d')
-rw-r--r--o3d/samples/o3d-webgl-samples/generate-texture.html259
-rw-r--r--o3d/samples/o3d-webgl/texture.js119
2 files changed, 341 insertions, 37 deletions
diff --git a/o3d/samples/o3d-webgl-samples/generate-texture.html b/o3d/samples/o3d-webgl-samples/generate-texture.html
new file mode 100644
index 0000000..7e10e51
--- /dev/null
+++ b/o3d/samples/o3d-webgl-samples/generate-texture.html
@@ -0,0 +1,259 @@
+<!--
+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.
+-->
+
+<!--
+How to generate a texture.
+-->
+<!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>
+Generate Texture.
+</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.util');
+o3djs.require('o3djs.math');
+o3djs.require('o3djs.rendergraph');
+o3djs.require('o3djs.primitives');
+o3djs.require('o3djs.material');
+
+// global variables
+var g_o3d;
+var g_math;
+var g_client;
+var g_pack;
+var g_viewInfo;
+var g_finished = false; // for selenium testing
+var g_samplers = [];
+
+/**
+ * Creates the client area.
+ */
+function init() {
+ // 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, 'FloatingPointTextures');
+}
+
+/**
+ * Initializes O3D, loads an effect, creates some textures
+ * and quads to display them.
+ * @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;
+
+ // 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 = o3dElement.client;
+
+ // Create 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);
+
+ var clientWidth = g_client.width;
+ var clientHeight = g_client.height;
+ g_viewInfo.drawContext.projection = g_math.matrix4.orthographic(
+ -clientWidth * 0.5,
+ clientWidth * 0.5,
+ -clientHeight * 0.5,
+ clientHeight * 0.5,
+ 0.001,
+ 1000);
+ g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
+ [0, 500, 0], // eye
+ [0, 0, 0], // target
+ [0, 0, -1]); // up
+
+ // Create and load the effects.
+ var effectInfos = {
+ texture_only: {name: 'texture-only-glsl.shader'}
+ };
+ for (var key in effectInfos) {
+ var info = effectInfos[key];
+ var material = o3djs.material.createMaterialFromFile(
+ g_pack,
+ '../shaders/' + info.name,
+ g_viewInfo.zOrderedDrawList);
+
+ // Create a quad.
+ var shape = o3djs.primitives.createPlane(g_pack,
+ material,
+ 1,
+ 1,
+ 1,
+ 1);
+ info.shape = shape;
+ }
+
+ // display our shape 4 times with 4 different textures
+ // by overriding the sampler on each instance.
+ for (var s = 0; s < 4; ++s) {
+ // create a transform for an instance
+ var transform = g_pack.createObject('Transform');
+ var x = s % 3;
+ var z = Math.floor(s / 3);
+ transform.translate((x - 1) * 140, 0, (z - 0.5) * 140);
+ transform.scale(128, 1, 128);
+ transform.parent = g_client.root;
+
+ // Create a ParamSampler on the transform with the same name as in
+ // the effect so this param will be used instead of the one on the material.
+ var samplerParam = transform.createParam('texSampler0', 'ParamSampler');
+
+ var sampler = g_pack.createObject('Sampler');
+ samplerParam.value = sampler;
+ sampler.addressModeU = g_o3d.Sampler.CLAMP;
+ sampler.addressModeV = g_o3d.Sampler.CLAMP;
+ g_samplers[s] = sampler;
+
+ // Create a texture.
+ {
+ var pixels = [];
+ var format;
+
+ switch (s) {
+ case 0: { // XRGB8
+ transform.addShape(effectInfos.texture_only.shape);
+ format = g_o3d.Texture.XRGB8;
+ for (var y = 0; y < 32; ++y) {
+ for (var x = 0; x < 32; ++x) {
+ var offset = (y * 32 + x) * 3; // rgb
+ var u = x / 32 * Math.PI * 0.5;
+ var v = y / 32 * Math.PI * 0.5;
+ pixels[offset + 0] = Math.cos(u); // red
+ pixels[offset + 1] = Math.sin(v); // green
+ pixels[offset + 2] = Math.sin(u); // blue
+ }
+ }
+ break;
+ }
+ case 1: { // ARGB8
+ transform.addShape(effectInfos.texture_only.shape);
+ format = g_o3d.Texture.ARGB8;
+ for (var y = 0; y < 32; ++y) {
+ for (var x = 0; x < 32; ++x) {
+ var offset = (y * 32 + x) * 4; // rgba
+ var u = x / 32 * Math.PI * 0.5;
+ var v = y / 32 * Math.PI * 0.5;
+ pixels[offset + 0] = Math.floor(y / 4) % 2; // red
+ pixels[offset + 1] = Math.sin(v); // green
+ pixels[offset + 2] = Math.floor(x / 4) % 2; // blue
+ pixels[offset + 3] = Math.abs(Math.sin(v * 4)); // alpha
+ }
+ }
+ break;
+ }
+ case 2: { // ABGR16F
+ transform.addShape(effectInfos.texture_only.shape);
+ format = g_o3d.Texture.ABGR16F;
+ for (var y = 0; y < 32; ++y) {
+ for (var x = 0; x < 32; ++x) {
+ var offset = (y * 32 + x) * 4; // rgba
+ var u = x / 32 * Math.PI * 0.5;
+ var v = y / 32 * Math.PI * 0.5;
+ pixels[offset + 0] = Math.cos(v); // red
+ pixels[offset + 1] = Math.sin(u); // green
+ pixels[offset + 2] = Math.sin(v); // blue
+ pixels[offset + 3] = Math.abs(Math.sin(u * 8)); // alpha
+ }
+ }
+ break;
+ }
+ case 3: { // ABGR32F
+ transform.addShape(effectInfos.texture_only.shape);
+ format = g_o3d.Texture.ABGR32F;
+ for (var y = 0; y < 32; ++y) {
+ for (var x = 0; x < 32; ++x) {
+ var offset = (y * 32 + x) * 4; // rgba
+ var u = x / 32 * Math.PI * 0.5;
+ var v = y / 32 * Math.PI * 0.5;
+ pixels[offset + 0] = Math.cos(v); // red
+ pixels[offset + 1] = Math.sin(u); // green
+ pixels[offset + 2] = Math.sin(v); // blue
+ pixels[offset + 3] = Math.abs(Math.sin(u * 8)); // alpha
+ }
+ }
+ break;
+ }
+
+ /**
+ * Note that R32F is not supported in WebGL.
+ */
+ }
+ var texture = g_pack.createTexture2D(32, 32, format, 1, false);
+ texture.set(0, pixels);
+ sampler.texture = texture;
+ }
+ }
+ window.o3d_prepForSelenium = prepForSelenium;
+ window.g_finished = true; // for selenium testing.
+}
+
+// Turn off all filtering in the samplers to get consistent testing
+// results.
+function prepForSelenium() {
+ for (var i = 0; i < g_samplers.length; i++) {
+ g_samplers[i].magFilter = g_o3d.Sampler.POINT;
+ g_samplers[i].minFilter = g_o3d.Sampler.POINT;
+ g_samplers[i].mipFilter = g_o3d.Sampler.NONE;
+ }
+}
+
+
+</script>
+</head>
+<body onload="init()">
+<h1>Generate Texture</h1>
+Shows how to create textures in Javascript.
+<br/>
+
+<!-- Start of O3D plugin -->
+<div id="o3d" style="width: 600px; height: 600px;"></div>
+<!-- End of O3D plugin -->
+</body>
+</html>
diff --git a/o3d/samples/o3d-webgl/texture.js b/o3d/samples/o3d-webgl/texture.js
index e8ea889..cfc7b77 100644
--- a/o3d/samples/o3d-webgl/texture.js
+++ b/o3d/samples/o3d-webgl/texture.js
@@ -185,6 +185,34 @@ o3d.Texture.nextHighestPowerOfTwo_ = function(value) {
/**
+ * Returns the GL texture format that is closest to this texture's O3D texture
+ * format. Not all formats specified in o3d.Texture have a webgl equivalent,
+ * thus we return the one with the correct number of channels, if such exists.
+ *
+ * @return {number} A webgl format.
+ * @private
+ */
+o3d.Texture.prototype.getGLTextureFormat_ = function() {
+ switch (this.format) {
+ case o3d.Texture.XRGB8:
+ return this.gl.RGB;
+
+ case o3d.Texture.ARGB8:
+ case o3d.Texture.ABGR16F:
+ case o3d.Texture.ABGR32F:
+ return this.gl.RGBA;
+
+ case o3d.Texture.R32F:
+ case o3d.Texture.DXT1:
+ case o3d.Texture.DXT3:
+ case o3d.Texture.DXT5:
+ notImplemented();
+ return 0;
+ }
+}
+
+
+/**
* Creates a webgl texture from the given image object rescaling to the
* smallest power of 2 in each dimension still no smaller than the original
* size.
@@ -231,6 +259,54 @@ o3d.Texture.prototype.setFromCanvas_ =
/**
+ * Sets the values of the data stored in the texture.
+ *
+ * It is not recommend that you call this for large textures but it is useful
+ * for making simple ramps or noise textures for shaders.
+ *
+ * NOTE: the number of values must equal the size of the texture * the number
+ * of elements. In other words, for a XRGB8 texture there must be
+ * width * height * 3 values. For an ARGB8, ABGR16F or ABGR32F texture there
+ * must be width * height * 4 values. For an R32F texture there must be
+ * width * height values.
+ *
+ * NOTE: the order of channels is R G B for XRGB8 textures and R G B A
+ * for ARGB8, ABGR16F and ABGR32F textures so for example for XRGB8 textures
+ *
+ * [1, 0, 0] = a red pixel
+ * [0, 0, 1] = a blue pixel
+ *
+ * For ARGB8, ABGR16F, ABGR32F textures
+ *
+ * [1, 0, 0, 0] = a red pixel with zero alpha
+ * [1, 0, 0, 1] = a red pixel with one alpha
+ * [0, 0, 1, 1] = a blue pixel with one alpha
+ *
+ * @param {number} level the mip level to update.
+ * @param {number} values Values to be stored in the buffer.
+ */
+o3d.Texture.prototype.set =
+ function(level, values) {
+ var target = this.texture_target_;
+ if (target == this.gl.TEXTURE_CUBE_MAP) {
+ target = this.gl.TEXTURE_CUBE_MAP_POSITIVE_X + face;
+ }
+
+ var pixels = new WebGLUnsignedByteArray(values.length);
+ for (var i = 0; i < values.length; ++i) {
+ pixels[i] = Math.min(255, Math.max(0, values[i] * 256.0));
+ }
+
+ var format = this.getGLTextureFormat_();
+
+ this.gl.bindTexture(target, this.texture_);
+ this.gl.texSubImage2D(
+ target, level, 0, 0, this.texture_width_, this.texture_height_,
+ format, this.gl.UNSIGNED_BYTE, pixels);
+};
+
+
+/**
* A class for 2D textures that defines the interface for getting
* the dimensions of the texture, its memory format and number of mipmap levels.
*
@@ -264,7 +340,6 @@ o3d.inherit('Texture2D', 'Texture');
o3d.ParamObject.setUpO3DParam_(o3d.Texture2D, 'width', 'ParamInteger');
o3d.ParamObject.setUpO3DParam_(o3d.Texture2D, 'height', 'ParamInteger');
-
/**
* Initializes this Texture2D object of the specified size and format and
* reserves the necessary resources for it.
@@ -285,6 +360,7 @@ o3d.Texture2D.prototype.init_ =
function(width, height, format, levels, enable_render_surfaces) {
this.width = width;
this.height = height;
+ this.format = format;
this.levels = levels;
this.texture_ = this.gl.createTexture();
this.texture_target_ = this.gl.TEXTURE_2D;
@@ -292,11 +368,13 @@ o3d.Texture2D.prototype.init_ =
if (width != undefined && height != undefined) {
this.gl.bindTexture(this.gl.TEXTURE_2D, this.texture_);
+ var format = this.getGLTextureFormat_();
+
// TODO(petersont): remove this allocation once Firefox supports
// passing null as argument to this form of ... some function.
- var t = new WebGLUnsignedByteArray(width * height * 4);
- this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, width, height,
- 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, t);
+ var pixels = new WebGLUnsignedByteArray(width * height * 4);
+ this.gl.texImage2D(this.gl.TEXTURE_2D, 0, format, width, height,
+ 0, format, this.gl.UNSIGNED_BYTE, pixels);
this.texture_width_ = width;
this.texture_height_ = height;
}
@@ -323,39 +401,6 @@ o3d.Texture2D.prototype.getRenderSurface =
/**
- * Sets the values of the data stored in the texture.
- *
- * It is not recommend that you call this for large textures but it is useful
- * for making simple ramps or noise textures for shaders.
- *
- * NOTE: the number of values must equal the size of the texture * the number
- * of elements. In other words, for a XRGB8 texture there must be
- * width * height * 3 values. For an ARGB8, ABGR16F or ABGR32F texture there
- * must be width * height * 4 values. For an R32F texture there must be
- * width * height values.
- *
- * NOTE: the order of channels is R G B for XRGB8 textures and R G B A
- * for ARGB8, ABGR16F and ABGR32F textures so for example for XRGB8 textures\n
- * \n
- * [1, 0, 0] = a red pixel\n
- * [0, 0, 1] = a blue pixel\n
- * \n
- * For ARGB8, ABGR16F, ABGR32F textures\n
- * \n
- * [1, 0, 0, 0] = a red pixel with zero alpha\n
- * [1, 0, 0, 1] = a red pixel with one alpha\n
- * [0, 0, 1, 1] = a blue pixel with one alpha\n
- *
- * @param {number} level the mip level to update.
- * @param {number} values Values to be stored in the buffer.
- */
-o3d.Texture2D.prototype.set =
- function(level, values) {
- o3d.notImplemented();
-};
-
-
-/**
* Sets a rectangular area of values in a texture.
*
* Does clipping. In other words if you pass in a 10x10 pixel array