diff options
author | gman@google.com <gman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-19 00:07:49 +0000 |
---|---|---|
committer | gman@google.com <gman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-19 00:07:49 +0000 |
commit | 8653167fd370f88b3bcc2be052a9aa26873dbe44 (patch) | |
tree | 602e188104e6d3992adac469f17d5c1605690f73 /o3d/samples | |
parent | c1b7f06be387b3828d38eccbf0e88d1ec71bac3b (diff) | |
download | chromium_src-8653167fd370f88b3bcc2be052a9aa26873dbe44.zip chromium_src-8653167fd370f88b3bcc2be052a9aa26873dbe44.tar.gz chromium_src-8653167fd370f88b3bcc2be052a9aa26873dbe44.tar.bz2 |
expose Bitmap to JavaScript.
Also added Texture.drawImage(canvas...)
There's still the big question of whether we
should flip textures by default in the o3d code.
Currently I'm flipping them by default in
o3djs.texture.createTextureFromRawData
and I'm flipping them by default in
o3djs.canvas.CanvasQuad.updateTexture.
I'm torn whether or not I should be flipping
them. I feel like 2d examples and examples
of displaying images, like a picasa viewer,
would be simpler if we didn't flip by default
but the problem then is if you load some textures
through a collada scene they'll be flipped
the opposite of any textures you load by hand.
Review URL: http://codereview.chromium.org/171060
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@23678 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d/samples')
-rw-r--r-- | o3d/samples/MANIFEST | 1 | ||||
-rw-r--r-- | o3d/samples/archive-textures.html | 3 | ||||
-rw-r--r-- | o3d/samples/bitmap-draw-image.html | 25 | ||||
-rw-r--r-- | o3d/samples/o3djs/canvas.js | 5 | ||||
-rw-r--r-- | o3d/samples/o3djs/io.js | 15 | ||||
-rw-r--r-- | o3d/samples/o3djs/js_list.scons | 1 | ||||
-rw-r--r-- | o3d/samples/o3djs/serialization.js | 11 | ||||
-rw-r--r-- | o3d/samples/o3djs/texture.js | 236 | ||||
-rw-r--r-- | o3d/samples/o3djs/util.js | 2 |
9 files changed, 274 insertions, 25 deletions
diff --git a/o3d/samples/MANIFEST b/o3d/samples/MANIFEST index d7b0963..b17fd66 100644 --- a/o3d/samples/MANIFEST +++ b/o3d/samples/MANIFEST @@ -198,6 +198,7 @@ o3djs/serialization.js o3djs/shape.js o3djs/simple.js o3djs/test.js +o3djs/texture.js o3djs/util.js pingpong/instructions.gif pingpong/logo.gif diff --git a/o3d/samples/archive-textures.html b/o3d/samples/archive-textures.html index 2e33a3e..7b7b4ea 100644 --- a/o3d/samples/archive-textures.html +++ b/o3d/samples/archive-textures.html @@ -49,6 +49,7 @@ o3djs.require('o3djs.io'); o3djs.require('o3djs.rendergraph'); o3djs.require('o3djs.primitives'); o3djs.require('o3djs.effect'); +o3djs.require('o3djs.texture'); // Events // Run the init() once the page has finished loading. @@ -173,7 +174,7 @@ function createArchiveRequest(effect) { g_streamingStarted = true; // Create a texture from the RawData object that was just made available. - var texture = g_pack.createTextureFromRawData(rawData, true); + var texture = o3djs.texture.createTextureFromRawData(g_pack, rawData, true); // Free the raw data object immediately since we're done with it. // If we don't call this the RawData will stay around so we can use it diff --git a/o3d/samples/bitmap-draw-image.html b/o3d/samples/bitmap-draw-image.html index 1e3bac0..e4a5208 100644 --- a/o3d/samples/bitmap-draw-image.html +++ b/o3d/samples/bitmap-draw-image.html @@ -177,28 +177,33 @@ function initStep2(clientElements) { function callback(archiveInfo, exception) {
if (!exception) {
var rawdata1 = archiveInfo.getFileByURI('shaving_cream_300x300.jpg', true);
- var bitmap1 = g_pack.createBitmapFromRawData(rawdata1);
+ var bitmap1 = g_pack.createBitmapsFromRawData(rawdata1)[0];
+ bitmap1.flipVertically();
var rawdata2 = archiveInfo.getFileByURI('four_pixel.png', true);
- var bitmap2 = g_pack.createBitmapFromRawData(rawdata2);
+ var bitmap2 = g_pack.createBitmapsFromRawData(rawdata2)[0];
+ bitmap2.flipVertically();
var rawdata_hi = archiveInfo.getFileByURI('hi.jpg', true);
- var bitmap_hi = g_pack.createBitmapFromRawData(rawdata_hi);
+ var bitmapHi = g_pack.createBitmapsFromRawData(rawdata_hi)[0];
+ bitmapHi.flipVertically();
var texture = g_pack.createTexture2D(300, 300, g_o3d.Texture.XRGB8, 0,
false);
// draw image on bitmap.
// scale down on top left corner.
- texture.drawImage(bitmap1, 0, 0, 300, 300, 0, 0, 150, 150, 0);
+ texture.drawImage(bitmap1, 0, 0, 0, 300, 300, 0, 0, 0, 150, 150);
// scale up on top right corner.
- texture.drawImage(bitmap1, 0, 0, 100, 100, 150, 0, 150, 150, 0);
+ texture.drawImage(bitmap1, 0, 0, 156, 100, 100, 0, 150, 0, 150, 150);
// flip and draw part of the img on bottom left.
- texture.drawImage(bitmap1, 150, 0, 150, 150, 149, 299, -150, -150, 0);
+ texture.drawImage(
+ bitmap1, 0, 150, 100, 150, 150, 0, 149, 299, -150, -150);
// draw out of boundary.
- texture.drawImage(bitmap1, 0, 0, 300, 300, 150, 150, 300, 300, 0);
+ texture.drawImage(bitmap1, 0, 0, 135, 300, 300, 0, 150, 150, 300, 300);
// draw o3d.
- texture.drawImage(bitmap_hi, 0, 0, 100, 50, 100, 125, 100, 50, 0);
+ texture.drawImage(bitmapHi, 0, 0, 0, 100, 50, 0, 100, 125, 100, 50);
// draw image on different mip-maps.
- texture.drawImage(bitmap1, 0, 0, 300, 300, 0, 0, 150, 150, 1);
- texture.drawImage(bitmap2, 0, 0, 2, 2, 0, 0, 75, 75, 2);
+ texture.drawImage(bitmap1, 0, 0, 0, 300, 300, 1, 0, 0, 150, 150);
+ texture.drawImage(bitmap2, 0, 0, 0, 2, 2, 2, 0, 0, 75, 75);
+ texture.setRect(0, 0, 0, 1, [1, 0, 0]);
makeShape(texture, effect);
}
diff --git a/o3d/samples/o3djs/canvas.js b/o3d/samples/o3djs/canvas.js index 3c264b7..b2f6247 100644 --- a/o3d/samples/o3djs/canvas.js +++ b/o3d/samples/o3djs/canvas.js @@ -355,7 +355,10 @@ o3djs.canvas.CanvasQuad = function(canvasInfo, * been issued to the CanvasQuad's Canvas object. */ o3djs.canvas.CanvasQuad.prototype.updateTexture = function() { - this.canvas.copyToTexture(this.texture); + var width = this.texture.width; + var height = this.texture.height; + this.texture.drawImage(this.canvas, 0, height - 1, width, -height, + 0, 0, 0, width, height); }; /** diff --git a/o3d/samples/o3djs/io.js b/o3d/samples/o3djs/io.js index 690bd2c..f575eff 100644 --- a/o3d/samples/o3djs/io.js +++ b/o3d/samples/o3djs/io.js @@ -36,6 +36,9 @@ o3djs.provide('o3djs.io'); +o3djs.require('o3djs.texture'); + + /** * A Module with various io functions and classes. * @namespace @@ -543,11 +546,10 @@ o3djs.io.loadArchiveAdvanced = function(pack, * texture is loaded. It will be passed the texture and an exception on * error or null on success. * @return {!o3djs.io.LoadInfo} A LoadInfo to track progress. - * @see o3djs.io.createLoader + * @see o3djs.loader.createLoader */ o3djs.io.loadTexture = function(pack, url, callback) { - // TODO: change this to get use RawData and Bitmap - var request = pack.createFileRequest('TEXTURE'); + var request = pack.createFileRequest('RAWDATA'); var loadInfo = o3djs.io.createLoadInfo( /** @type {!o3d.FileRequest} */ (request), false); @@ -557,9 +559,13 @@ o3djs.io.loadTexture = function(pack, url, callback) { */ request.onreadystatechange = function() { if (request.done) { - var texture = request.texture; + var rawData = /** @type {!o3d.RawData} */ request.data; var success = request.success; var exception = request.error; + var texture = null; + if (success) { + texture = o3djs.texture.createTextureFromRawData(pack, rawData, true); + } loadInfo.finish(); pack.removeObject(request); if (!success && !exception) { @@ -572,4 +578,3 @@ o3djs.io.loadTexture = function(pack, url, callback) { return loadInfo; }; - diff --git a/o3d/samples/o3djs/js_list.scons b/o3d/samples/o3djs/js_list.scons index f590330..c5fad39 100644 --- a/o3d/samples/o3djs/js_list.scons +++ b/o3d/samples/o3djs/js_list.scons @@ -55,6 +55,7 @@ O3D_JS_SOURCES = [ 'shape.js', 'simple.js', 'test.js', + 'texture.js', 'util.js', ] diff --git a/o3d/samples/o3djs/serialization.js b/o3d/samples/o3djs/serialization.js index bc459a3..2514bd7 100644 --- a/o3d/samples/o3djs/serialization.js +++ b/o3d/samples/o3djs/serialization.js @@ -39,6 +39,7 @@ o3djs.provide('o3djs.serialization'); o3djs.require('o3djs.error'); +o3djs.require('o3djs.texture'); /** * A Module for handling events related to o3d and various browsers. @@ -162,9 +163,7 @@ o3djs.serialization.Deserializer = function(pack, json) { if (!rawData) { throw 'Could not find texture ' + uri + ' in the archive'; } - return deserializer.pack.createTextureFromRawData( - rawData, - true); + return o3djs.texture.createTextureFromRawData(pack, rawData, true); } else { return deserializer.pack.createTexture2D( json.custom.width, @@ -182,9 +181,7 @@ o3djs.serialization.Deserializer = function(pack, json) { if (!rawData) { throw 'Could not find texture ' + uri + ' in the archive'; } - return deserializer.pack.createTextureFromRawData( - rawData, - true); + return o3djs.texture.createTextureFromRawData(pack, rawData, true); } else { return deserializer.pack.createTextureCUBE( json.custom.edgeLength, @@ -683,7 +680,7 @@ o3djs.serialization.deserialize = function(pack, json) { /** * Deserializes a single json object named 'scene.json' from a loaded * o3djs.io.ArchiveInfo. - * @param {!o3djs.io.archiveInfo} archiveInfo Archive to load from. + * @param {!o3djs.io.ArchiveInfo} archiveInfo Archive to load from. * @param {string} sceneJsonUri The relative URI of the scene JSON file within * the archive. * @param {!o3d.Client} client An O3D client object. diff --git a/o3d/samples/o3djs/texture.js b/o3d/samples/o3djs/texture.js new file mode 100644 index 0000000..6571503 --- /dev/null +++ b/o3d/samples/o3djs/texture.js @@ -0,0 +1,236 @@ +/*
+ * 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.
+ */
+
+
+/**
+ * @fileoverview This file contains functions helping to manipulate and manage
+ * textures.
+ */
+
+o3djs.provide('o3djs.texture');
+
+/**
+ * A Module for bitmaps.
+ * @namespace
+ */
+o3djs.texture = o3djs.texture || {};
+
+/**
+ * The maximum dimension of a texture.
+ * @type {number}
+ */
+o3djs.texture.MAX_TEXTURE_DIMENSION = 2048;
+
+/**
+ * Computes the maximum number of levels of mips a given width and height could
+ * use.
+ * @param {number} width Width of texture.
+ * @param {number} height Height of texture.
+ * @return {number} The maximum number of levels for the given width and height.
+ */
+o3djs.texture.computeNumLevels = function(width, height) {
+ if (width == 0 || height == 0) {
+ return 0;
+ }
+ var max = Math.max(width, height);
+ var levels = 0;
+ while (max > 0) {
+ ++levels;
+ max = max >> 1;
+ }
+ return levels;
+};
+
+/**
+ * Creates a texture from a RawData object.
+ * @param {!o3d.Pack} pack The pack to create the texture in.
+ * @param {!o3d.RawData} rawData The raw data to create the texture from.
+ * @param {boolean} opt_generateMips Whether or not to generate mips. Note, mips
+ * can not be generated for DXT textures although they will be loaded if they
+ * exist in the RawData.
+ * @param {boolean} opt_flip Whether or not to flip the texture. Most DCC tools
+ * Like Maya, Max, etc expect the textures to be flipped. Note that only
+ * 2D (image) textures will be flipped. Cube textures will not be flipped.
+ * Default = true.
+ * @param {number} opt_maxWidth The maximum width of the texture. If the RawData
+ * is larger than this size it will be scaled down to this size. Note that
+ * DXT format textures can not be scaled. Default = 2048.
+ * @param {number} opt_maxHeight The maximum width of the texture. If the
+ * RawData is larger than this size it will be scaled down to this size. Note
+ * that DXT format textures can not be scaled. Default = 2048.
+ * @return {!o3d.Texture} The created texture.
+ */
+o3djs.texture.createTextureFromRawData = function(
+ pack,
+ rawData,
+ opt_generateMips,
+ opt_flip,
+ opt_maxWidth,
+ opt_maxHeight) {
+ // Make a bitmaps from the raw data.
+ var bitmaps = pack.createBitmapsFromRawData(rawData);
+ if (opt_flip || typeof opt_flip === 'undefined') {
+ for (var ii = 0; ii < bitmaps.length; ++ii) {
+ var bitmap = bitmaps[ii];
+ if (bitmap.semantic == o3djs.base.o3d.Bitmap.IMAGE) {
+ bitmaps[ii].flipVertically();
+ }
+ }
+ }
+
+ // Create a texture from the bitmaps.
+ var texture = o3djs.texture.createTextureFromBitmaps(
+ pack, bitmaps, opt_generateMips);
+
+ // Delete the bitmaps.
+ for (var ii = 0; ii < bitmaps.length; ++ii) {
+ pack.removeObject(bitmaps[ii]);
+ }
+
+ return texture;
+};
+
+/**
+ * Returns whether or not a given texture format can be scaled.
+ * @param {!o3d.Texture.Format} format The format to check.
+ * @return {boolean} True if you can scale and make mips for the given format.
+ */
+o3djs.texture.canMakeMipsAndScale = function(format) {
+ switch (format) {
+ case o3djs.base.o3d.Texture.XRGB8:
+ case o3djs.base.o3d.Texture.ARGB8:
+ case o3djs.base.o3d.Texture.ABGR16F:
+ case o3djs.base.o3d.Texture.R32F:
+ case o3djs.base.o3d.Texture.ABGR32F:
+ return true;
+ case o3djs.base.o3d.Texture.DXT1:
+ case o3djs.base.o3d.Texture.DXT3:
+ case o3djs.base.o3d.Texture.DXT5:
+ return false;
+ }
+ return false;
+};
+
+/**
+ * Creates a Texture from an array of bitmaps.
+ * @param {!o3d.Pack} pack The pack to create the texture in.
+ * @param {!Array.<!o3d.Bitmap>} bitmaps An array of bitmaps to create the
+ * texture from. For a 2D texture this would be 1 bitmap. For a cubemap this
+ * would be 6 bitmaps.
+ * @param {boolean} opt_generateMips Whether or not to generate mips. Note, mips
+ * can not be generated for DXT textures although they will be loaded if they
+ * exist in the RawData.
+ * @return {!o3d.Texture} The created texture.
+ */
+o3djs.texture.createTextureFromBitmaps = function(
+ pack,
+ bitmaps,
+ opt_generateMips) {
+
+ if (bitmaps.length == 0) {
+ throw 'no bitmaps';
+ }
+
+ var srcWidth = bitmaps[0].width;
+ var srcHeight = bitmaps[0].height;
+ var format = bitmaps[0].format;
+ var mipMaps = bitmaps[0].numMipmaps;
+ var maxMips = o3djs.texture.computeNumLevels(srcWidth, srcHeight);
+ var targetMips = mipMaps;
+ var dstWidth = srcWidth;
+ var dstHeight = srcHeight;
+ if (opt_generateMips && o3djs.texture.canMakeMipsAndScale(format) &&
+ mipMaps == 1 && maxMips > 1) {
+ targetMips = maxMips;
+ }
+
+ // Check that all the bitmaps are the same size and make mips
+ for (var ii = 0; ii < bitmaps.length; ++ii) {
+ var bitmap = bitmaps[ii];
+ if (bitmap.width != srcWidth ||
+ bitmap.height != srcHeight ||
+ bitmap.format != format ||
+ bitmap.numMipmaps != mipMaps) {
+ throw 'bitmaps must all be the same width, height, mips and format';
+ }
+ if (targetMips != mipMaps) {
+ bitmap.generateMips(0, targetMips - 1);
+ }
+ }
+
+ var levels = bitmap.numMipmaps > 1 ? bitmap.numMipmaps :
+ o3djs.texture.computeNumLevels(dstWidth, dstHeight);
+ var texture;
+ if (bitmaps.length == 6 &&
+ bitmaps[0].semantic != o3djs.base.o3d.Bitmap.SLICE) {
+ if (srcWidth != srcHeight ||
+ srcWidth != dstWidth ||
+ srcHeight != dstHeight) {
+ throw 'Cubemaps must be square';
+ }
+ texture = pack.createTextureCUBE(dstWidth, format, targetMips, false);
+ for (var ii = 0; ii < 6; ++ii) {
+ texture.setFromBitmap(ii, bitmaps[ii]);
+ }
+ } else if (bitmaps.length == 1) {
+ texture = pack.createTexture2D(
+ dstWidth, dstHeight, format, targetMips, false);
+ texture.setFromBitmap(bitmaps[0]);
+ }
+
+ return texture;
+};
+
+/**
+ * Creates a TextureCUBE from 6 bitmaps. The bitmaps do not have to be the same
+ * size thought they do have to be the same format.
+ *
+ * @param {!o3d.Pack} pack The pack to create the texture in.
+ * @param {number} edgeLength The size of the cubemap.
+ * @param {!Array.<!o3d.Bitmap>} bitmaps An array of 6 bitmaps in the order
+ * FACE_POSITIVE_X, FACE_NEGATIVE_X, FACE_POSITIVE_Y, FACE_NEGATIVE_Y,
+ * FACE_POSITIVE_Z, FACE_NEGATIVE_Z.
+ * @return {!o3d.Texture} The created texture.
+ */
+o3djs.texture.createCubeTextureFrom6Bitmaps = function(
+ pack, edgeLength, bitmaps) {
+ var numMips = o3djs.texture.computeNumLevels(edgeLength, edgeLength);
+ var texture = pack.createTextureCUBE(
+ edgeLength, bitmaps[0].format, numMips, false);
+ for (var ii = 0; ii < 6; ++ii) {
+ var bitmap = bitmaps[ii];
+ texture.drawImage(bitmap, 0, 0, 0, bitmap.width, bitmap.height,
+ ii, 0, 0, edgeLength, edgeLength);
+ }
+ texture.generateMips(0, numMips - 1);
+ return texture;
+};
+
diff --git a/o3d/samples/o3djs/util.js b/o3d/samples/o3djs/util.js index 66722e1..6df3e93 100644 --- a/o3d/samples/o3djs/util.js +++ b/o3d/samples/o3djs/util.js @@ -60,7 +60,7 @@ o3djs.util.PLUGIN_NAME = 'O3D Plugin'; * utility libraries. * @type {string} */ -o3djs.util.REQUIRED_VERSION = '0.1.38.0'; +o3djs.util.REQUIRED_VERSION = '0.1.40.0'; /** * A URL at which to download the client. |