summaryrefslogtreecommitdiffstats
path: root/o3d/samples
diff options
context:
space:
mode:
authorpetersont@google.com <petersont@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-29 02:56:15 +0000
committerpetersont@google.com <petersont@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-29 02:56:15 +0000
commit1fc0028e763b6fcfba140940fa33bdec0502a473 (patch)
tree523d836c073364782cb0fa172b4158d52002bec8 /o3d/samples
parent41ffdc7bf92a79ca6d6b917ab943989185b9d1a0 (diff)
downloadchromium_src-1fc0028e763b6fcfba140940fa33bdec0502a473.zip
chromium_src-1fc0028e763b6fcfba140940fa33bdec0502a473.tar.gz
chromium_src-1fc0028e763b6fcfba140940fa33bdec0502a473.tar.bz2
Added capability for an error (default) cube map texture, so if a cube sampler doesn't have a texture associated with it, it doesn't choke WebGL.
Review URL: http://codereview.chromium.org/3162048 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@57808 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d/samples')
-rw-r--r--o3d/samples/o3d-webgl/client.js79
-rw-r--r--o3d/samples/o3d-webgl/effect.js18
-rw-r--r--o3d/samples/o3d-webgl/param.js8
-rw-r--r--o3d/samples/o3d-webgl/primitive.js5
-rw-r--r--o3d/samples/o3d-webgl/sampler.js10
-rw-r--r--o3d/samples/o3d-webgl/texture.js305
-rw-r--r--o3d/samples/o3djs/texture.js4
7 files changed, 308 insertions, 121 deletions
diff --git a/o3d/samples/o3d-webgl/client.js b/o3d/samples/o3d-webgl/client.js
index 3706958..5e940a6 100644
--- a/o3d/samples/o3d-webgl/client.js
+++ b/o3d/samples/o3d-webgl/client.js
@@ -449,7 +449,6 @@ o3d.Client.RENDERMODE_ON_DEMAND = 1;
o3d.Client.prototype.renderMode = o3d.Client.RENDERMODE_CONTINUOUS;
-
/**
* Forces a render of the current scene if the current render mode is
* RENDERMODE_ON_DEMAND.
@@ -517,7 +516,6 @@ o3d.Client.prototype.render_stats = {}
*/
o3d.Client.prototype.renderTree =
function(render_node) {
-
this.render_stats_ = {
drawElementsCulled: 0,
drawElementsProcessed: 0,
@@ -678,10 +676,18 @@ o3d.Client.prototype.initWithCanvas = function(canvas) {
height: canvas.height};
o3d.State.createDefaultState_(gl).push_();
- // Create the default error texture.
- var defaultTexture = new o3d.Texture2D();
- defaultTexture.gl = this.gl;
- defaultTexture.init_(8, 8, o3d.Texture.ARGB8, 1, false);
+ this.initErrorTextures_();
+
+ return true;
+}
+
+
+/**
+ * Creates the yellow-and-red 8x8 error textures.
+ * @private
+ */
+o3d.Client.prototype.initErrorTextures_ = function() {
+ // First create the yellow-and-red pattern.
var r = [1, 0, 0, 1];
var Y = [1, 1, 0, 1];
var error = [r, r, r, r, r, r, r, r,
@@ -698,12 +704,29 @@ o3d.Client.prototype.initWithCanvas = function(canvas) {
pixels[i * 4 + j] = error[i][j];
}
}
+
+ // Create the default error cube map using the same data.
+ var defaultTextureCube = new o3d.TextureCUBE();
+
+ defaultTextureCube.gl = this.gl;
+ defaultTextureCube.init_(8, o3d.Texture.ARGB8, 1, false, true);
+
+ for (var i = 0; i < 6; ++i) {
+ defaultTextureCube.set(i, 0, pixels);
+ }
+ defaultTextureCube.name = 'DefaultTextureCube';
+ this.error_texture_cube_ = defaultTextureCube;
+ this.fallback_error_texture_cube_ = defaultTextureCube;
+
+ // Create the default error texture.
+ var defaultTexture = new o3d.Texture2D();
+ defaultTexture.gl = this.gl;
+ defaultTexture.init_(8, 8, o3d.Texture.ARGB8, 1, false);
+
defaultTexture.set(0, pixels);
defaultTexture.name = 'DefaultTexture';
- this.fallback_error_texture_ = defaultTexture;
this.error_texture_ = defaultTexture;
-
- return true;
+ this.fallback_error_texture_ = defaultTexture;
};
@@ -973,6 +996,21 @@ o3d.Client.prototype.setErrorTexture =
/**
+ * Sets the cubemap texture to use when a Texture or Sampler is missing while
+ * rendering. The default is a red texture with a yellow no symbol.
+ * <span style="color:yellow; background-color: red;">&Oslash;.
+ * If you set it to null you'll get an error if you try to render something
+ * that is missing a needed Texture, Sampler or ParamSampler.
+ *
+ * @param {o3d.Texture} texture Texture to use for missing textures or null.
+ */
+o3d.Client.prototype.setErrorTextureCube =
+ function(texture) {
+ this.error_texture_cube_map_ = texture;
+};
+
+
+/**
* Sets a callback for when the client ticks. The client processes some things
* like animation timers at up to 100hz. This callback will get called before
* each of those process ticks.
@@ -1182,23 +1220,42 @@ o3d.Client.prototype.cursor = null;
/**
* The current error texture.
*
- * @type {o3d.Texture}
+ * @type {o3d.Texture2D}
* @private
*/
o3d.Client.prototype.error_texture_ = null;
/**
+ * The current error cube texture.
+ *
+ * @type {o3d.TextureCUBE}
+ * @private
+ */
+o3d.Client.prototype.error_texture_cube_ = null;
+
+
+/**
* The fallback error texture. Should only be initialized once per client and
* is read-only.
*
- * @type {!o3d.Texture}
+ * @type {!o3d.Texture2D}
* @private
*/
o3d.Client.prototype.fallback_error_texture_ = null;
/**
+ * The fallback error texture. Should only be initialized once per client and
+ * is read-only.
+ *
+ * @type {!o3d.TextureCUBE}
+ * @private
+ */
+o3d.Client.prototype.fallback_error_texture_cube_ = null;
+
+
+/**
* The last error reported by the plugin.
*
* @type {string}
diff --git a/o3d/samples/o3d-webgl/effect.js b/o3d/samples/o3d-webgl/effect.js
index 3d9f85e..f45dab0 100644
--- a/o3d/samples/o3d-webgl/effect.js
+++ b/o3d/samples/o3d-webgl/effect.js
@@ -229,7 +229,7 @@ o3d.Effect.prototype.loadVertexShaderFromString =
function(shaderString) {
var success =
this.loadShaderFromString(shaderString, this.gl.VERTEX_SHADER);
- this.vertexShaderLoaded_ = true;
+ this.vertexShaderLoaded_ = success;
o3d.Effect.prototype.bindAttributesAndLinkIfReady();
return success;
};
@@ -244,7 +244,7 @@ o3d.Effect.prototype.loadPixelShaderFromString =
function(shaderString) {
var success =
this.loadShaderFromString(shaderString, this.gl.FRAGMENT_SHADER);
- this.fragmentShaderLoaded_ = true;
+ this.fragmentShaderLoaded_ = success;
this.bindAttributesAndLinkIfReady();
return success;
};
@@ -260,8 +260,11 @@ o3d.Effect.prototype.loadPixelShaderFromString =
o3d.Effect.prototype.loadFromFXString =
function(shaderString) {
var splitIndex = shaderString.indexOf('// #o3d SplitMarker');
- return this.loadVertexShaderFromString(shaderString.substr(0, splitIndex)) &&
- this.loadPixelShaderFromString(shaderString.substr(splitIndex));
+ var vertexShaderString = shaderString.substr(0, splitIndex);
+ var pixelShaderString = shaderString.substr(splitIndex);
+ var result = this.loadVertexShaderFromString(vertexShaderString) &&
+ this.loadPixelShaderFromString(pixelShaderString);
+ return result;
};
@@ -409,6 +412,7 @@ o3d.Effect.reverseSemanticMap_ = [];
}
})();
+
/**
* For each of the effect's uniform parameters, creates corresponding
* parameters on the given ParamObject. Skips SAS Parameters.
@@ -552,7 +556,11 @@ o3d.Effect.prototype.searchForParams_ = function(object_list) {
if (uniformInfo.kind == o3d.Effect.ARRAY) {
param.applyToLocations(this.gl, uniformInfo.locations);
} else {
- param.applyToLocation(this.gl, uniformInfo.location);
+ if (uniformInfo.info.type == this.gl.SAMPLER_CUBE) {
+ param.applyToLocation(this.gl, uniformInfo.location, true);
+ } else {
+ param.applyToLocation(this.gl, uniformInfo.location);
+ }
}
filled_map[name] = true;
}
diff --git a/o3d/samples/o3d-webgl/param.js b/o3d/samples/o3d-webgl/param.js
index 0f8a819..9ea8bd0 100644
--- a/o3d/samples/o3d-webgl/param.js
+++ b/o3d/samples/o3d-webgl/param.js
@@ -893,8 +893,12 @@ o3d.Param.texture_index_ = 0;
* Called to specify the value of a uniform variable.
* @param {WebGLContext} gl The current context.
* @param {WebGLUniformLocation} location The location to which to apply.
+ * @param {boolean} opt_isCube Optional boolean indicating whether the Sampler
+ * connects to a samplerCube type uniform. If set to true, and there is an
+ * error, we use the error cube map.
*/
-o3d.ParamSampler.prototype.applyToLocation = function(gl, location) {
+o3d.ParamSampler.prototype.applyToLocation =
+ function(gl, location, opt_isCube) {
// When before the effect object assigns values to parameters,
// it sets this variable to 0.
var i = o3d.Param.texture_index_;
@@ -914,7 +918,7 @@ o3d.ParamSampler.prototype.applyToLocation = function(gl, location) {
}
}
- sampler.bindAndSetParameters_();
+ sampler.bindAndSetParameters_(opt_isCube);
gl.uniform1i(location, i);
o3d.Param.texture_index_++;
};
diff --git a/o3d/samples/o3d-webgl/primitive.js b/o3d/samples/o3d-webgl/primitive.js
index 7c15ac2..dcf8959 100644
--- a/o3d/samples/o3d-webgl/primitive.js
+++ b/o3d/samples/o3d-webgl/primitive.js
@@ -132,6 +132,10 @@ o3d.Primitive.prototype.render = function() {
var field = stream.field;
var buffer = field.buffer;
+ if (gl_index == undefined) {
+ this.gl.client.error_callback('uknown semantic');
+ }
+
var stream_param = streams[semantic_index];
while (!stream_param.owner_.updateStreams &&
stream_param.inputConnection) {
@@ -147,6 +151,7 @@ o3d.Primitive.prototype.render = function() {
enabled_attribs.push(gl_index);
var kFloatSize = Float32Array.BYTES_PER_ELEMENT;
+
this.gl.vertexAttribPointer(
gl_index, field.numComponents, this.gl.FLOAT, false,
buffer.totalComponents * kFloatSize, field.offset_ * kFloatSize);
diff --git a/o3d/samples/o3d-webgl/sampler.js b/o3d/samples/o3d-webgl/sampler.js
index e4d6513..60f94c0 100644
--- a/o3d/samples/o3d-webgl/sampler.js
+++ b/o3d/samples/o3d-webgl/sampler.js
@@ -260,13 +260,19 @@ o3d.Sampler.defaultSampler_.magFilter = o3d.Sampler.POINT;
/**
* Binds the texture for this sampler and sets texParameters according to the
* states of the sampler.
+ * @param {boolean} opt_isCube Optional boolean indicating if this is a cube
+ * map, so we can use the right error texture.
*/
-o3d.Sampler.prototype.bindAndSetParameters_ = function() {
+o3d.Sampler.prototype.bindAndSetParameters_ = function(opt_isCube) {
var currentTexture = null;
if (this.texture) {
currentTexture = this.texture;
} else if (!this.gl.client.reportErrors_()) {
- currentTexture = this.gl.client.error_texture_;
+ if (opt_isCube) {
+ currentTexture = this.gl.client.error_texture_cube_;
+ } else {
+ currentTexture = this.gl.client.error_texture_;
+ }
} else {
currentTexture = this.gl.client.fallback_error_texture_;
this.gl.client.error_callback("Missing texture for sampler " + this.name);
diff --git a/o3d/samples/o3d-webgl/texture.js b/o3d/samples/o3d-webgl/texture.js
index b2ee1a2..ec35293 100644
--- a/o3d/samples/o3d-webgl/texture.js
+++ b/o3d/samples/o3d-webgl/texture.js
@@ -65,6 +65,8 @@ o3d.Texture = function() {
/**
* The associated GL texture target: TEXTURE_2D or TEXTURE_CUBE_MAP.
+ * This is the argument "target" to calls to bindTeture.
+ * NOT THE SAME THING AS the argument "target" to texImage2D.
* @type {number}
* @private
*/
@@ -156,6 +158,7 @@ o3d.Texture.prototype.generateMips =
function(source_level, num_levels) {
this.gl.bindTexture(this.texture_target_, this.texture_);
this.gl.generateMipmap(this.texture_target_);
+ this.levels = num_levels;
};
@@ -214,6 +217,46 @@ o3d.Texture.prototype.getGLTextureFormat_ = function() {
/**
+ * Helper function to determine the proper argument for the texture target
+ * This is either gl.TEXTURE_2D or gl.TEXTURE_CUBE_MAP_POSITIVE_X + face.
+ *
+ * @param {o3d.TextureCUBE.CubeFace} face The current face if applicable.
+ * @return {number} The proper argument for the texture target.
+ */
+o3d.Texture.prototype.getTexImage2DTarget_ = function(opt_face) {
+ if (this.texture_target_ == this.gl.TEXTURE_CUBE_MAP) {
+ return this.gl.TEXTURE_CUBE_MAP_POSITIVE_X + opt_face;
+ } else {
+ return this.gl.TEXTURE_2D;
+ }
+};
+
+
+/**
+ * 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.
+ */
+o3d.Texture.maxLevels_ = 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;
+};
+
+
+var g_counter = 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.
@@ -221,13 +264,13 @@ o3d.Texture.prototype.getGLTextureFormat_ = function() {
* @param {boolean} resize_to_pot Whether or not to resize to a power of two
* size.
* @param {boolean} generate_mips Whether or not to generate mips.
- *
+ * @param {o3d.TextureCUBE.CubeFace} opt_face The face number, if this is a
+ * cube map.
* @private
*/
o3d.Texture.prototype.setFromCanvas_ =
- function(canvas, resize_to_pot, flip, generate_mips, face) {
+ function(canvas, resize_to_pot, flip, generate_mips, opt_face) {
var gl = this.gl;
- gl.bindTexture(this.texture_target_, this.texture_);
if (resize_to_pot && (!o3d.Texture.isPowerOfTwo_(canvas.width) ||
!o3d.Texture.isPowerOfTwo_(canvas.height))) {
@@ -243,15 +286,15 @@ o3d.Texture.prototype.setFromCanvas_ =
canvas = scratch;
}
- var target = this.texture_target_;
- if (target == this.gl.TEXTURE_CUBE_MAP) {
- target = this.gl.TEXTURE_CUBE_MAP_POSITIVE_X + face;
- }
-
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flip);
- gl.texImage2D(
- target, 0 /*level*/, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas);
+
+ gl.bindTexture(this.texture_target_, this.texture_);
+ gl.texImage2D(this.getTexImage2DTarget_(opt_face), 0 /*level*/, gl.RGBA,
+ gl.RGBA, gl.UNSIGNED_BYTE, canvas);
+
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 0);
+
+
this.texture_width_ = canvas.width;
this.texture_height_ = canvas.height;
@@ -259,33 +302,158 @@ o3d.Texture.prototype.setFromCanvas_ =
// The texture target is already bound so why bind it again by calling
// this.generateMip.
this.gl.generateMipmap(this.texture_target_);
+ this.levels = o3d.Texture.maxLevels_(
+ this.texture_width_, this.texture_height_);
}
+
+ g_counter++;
+};
+
+
+/**
+ * Copy pixels from source bitmap to certain mip level.
+ * Scales if the width and height of source and dest do not match.
+ *
+ * @param {HTMLCanvas} source_img The source canvas.
+ * @param {number} source_x x-coordinate of the starting pixel in the
+ * source image.
+ * @param {number} source_y y-coordinate of the starting pixel in the
+ * source image.
+ * @param {number} source_width width of the source image to draw.
+ * @param {number} source_height Height of the source image to draw.
+ * @param {number} dest_mip on which mip level to draw to.
+ * @param {number} dest_x x-coordinate of the starting pixel in the
+ * destination texture.
+ * @param {number} dest_y y-coordinate of the starting pixel in the
+ * destination texture.
+ * @param {number} dest_width width of the dest image.
+ * @param {number} dest_height height of the dest image.
+ * @param {number} opt_face The face number if this is a cube map.
+ */
+o3d.Texture.prototype.drawImageFromCanvas_ =
+ function(source_canvas, source_x, source_y, source_width, source_height,
+ dest_mip, dest_x, dest_y, dest_width, dest_height, opt_face) {
+ var canvas = o3d.Bitmap.getScratchCanvas_();
+ canvas.width = dest_width;
+ canvas.height = dest_height;
+
+ // Get a scratch canvas and set its size to that of the source material.
+ // Set up transformation so that the draw into the canvas fill it with the
+ // source bitmap.
+ var context = canvas.getContext('2d');
+ context.save();
+
+ context.translate(-source_x, -source_y);
+ context.scale(dest_width / source_width,
+ dest_height / source_height);
+
+ // Draw the source image into the canvas, filling it.
+ context.drawImage(
+ source_canvas, 0, 0, source_canvas.width, source_canvas.height);
+
+ // Call texSubImage2D to upload the source image from the scratch canvas
+ // to the texture.
+ var gl = this.gl;
+ gl.bindTexture(this.texture_target_, this.texture_);
+ var format = this.getGLTextureFormat_();
+
+ //*/
+ // TODO(petersont): Replace this with a call to texSubImage2D once
+ // browsers support it.
+ gl.texImage2D(this.getTexImage2DTarget_(opt_face), dest_mip, gl.RGBA,
+ gl.RGBA, gl.UNSIGNED_BYTE, canvas);
+ /*/
+ gl.texSubImage2D(target, 0, dest_x, dest_y, dest_width, dest_height,
+ gl.RGBA, gl.UNSIGNED_BYTE, canvas);
+ //*/
+ this.texture_width_ = canvas.width;
+ this.texture_height_ = canvas.height;
+
+ context.restore();
};
/**
* Sets the values of the data stored in the texture.
*
- * @param {number} target The target to bind this texture to.
* @param {number} level the mip level to update.
* @param {number} values Values to be stored in the buffer.
+ * @param {o3d.TextureCUBE.CubeFace} opt_face The face to set if this is a cube
+ * texture.
* @private
*/
-o3d.Texture.prototype.setValues_ = function(target, level, values) {
+o3d.Texture.prototype.setValues_ = function(level, values, opt_face) {
var pixels = new Uint8Array(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_,
+ this.gl.bindTexture(this.texture_target_, this.texture_);
+
+ this.gl.texSubImage2D(this.getTexImage2DTarget_(opt_face),
+ level, 0, 0, this.texture_width_, this.texture_height_,
format, this.gl.UNSIGNED_BYTE, pixels);
};
/**
+ * Initializes this Texture2D object of the specified size and format and
+ * reserves the necessary resources for it.
+ *
+ * Note: If enable_render_surfaces is true, then the dimensions must be a
+ * power of two.
+ *
+ * @param {number} texture_target The apropriate value for texture_target.
+ * @param {number} width The width of the texture area in texels (max = 2048)
+ * @param {number} height The height of the texture area in texels (max = 2048)
+ * @param {o3d.Texture.Format} format The memory format of each texel
+ * @param {number} levels The number of mipmap levels. Use zero to create the
+ * compelete mipmap chain.
+ * @param {boolean} enable_render_surfaces If true, the texture object will
+ * expose RenderSurface objects through GetRenderSurface(...).
+ * @return {!o3d.Texture2D} The Texture2D object.
+ */
+o3d.Texture.prototype.initWithTarget_ =
+ function(texture_target, width, height, format, levels,
+ enable_render_surfaces, debug) {
+ this.width = width;
+ this.height = height;
+ this.format = format;
+ this.levels = levels;
+ this.texture_ = this.gl.createTexture();
+ this.texture_target_ = texture_target;
+
+ if (width != undefined && height != undefined) {
+ this.gl.bindTexture(this.texture_target_, 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 pixels = new Uint8Array(width * height * 4);
+
+ var canvas = o3d.Bitmap.getScratchCanvas_();
+ canvas.width = width;
+ canvas.height = height;
+
+ var numFaces = 1;
+ if (this.texture_target_ == this.gl.TEXTURE_CUBE_MAP) {
+ numFaces = 6;
+ }
+
+ for (var face = 0; face < numFaces; ++face) {
+ this.gl.texImage2D(this.getTexImage2DTarget_(face), 0, format, width,
+ height, 0, format, this.gl.UNSIGNED_BYTE, pixels);
+ }
+
+ this.texture_width_ = width;
+ this.texture_height_ = height;
+ }
+};
+
+
+/**
* A class for 2D textures that defines the interface for getting
* the dimensions of the texture, its memory format and number of mipmap levels.
*
@@ -319,6 +487,7 @@ 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.
@@ -337,26 +506,8 @@ o3d.ParamObject.setUpO3DParam_(o3d.Texture2D, 'height', 'ParamInteger');
*/
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;
-
- 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 pixels = new Uint8Array(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;
- }
+ this.initWithTarget_(this.gl.TEXTURE_2D,
+ width, height, format, levels, enable_render_surfaces);
};
@@ -408,8 +559,7 @@ o3d.Texture2D.prototype.getRenderSurface =
*/
o3d.Texture2D.prototype.set =
function(level, values) {
- var target = this.texture_target_;
- this.setValues_(target, level, values);
+ this.setValues_(level, values);
};
@@ -437,7 +587,6 @@ o3d.Texture2D.prototype.setRect =
var format = this.getGLTextureFormat_();
var numChannels = (format == this.gl.RGB ? 3 : 4);
var source_height = (values.length / numChannels) / source_width;
- var target = this.texture_target_;
// If completely clipped off, do nothing and return.
if (destination_x > this.width || destination_y > this.height ||
@@ -484,9 +633,9 @@ o3d.Texture2D.prototype.setRect =
var where_x = Math.max(destination_x, 0);
var where_y = this.height - (Math.max(destination_y, 0) + size_y);
- this.gl.bindTexture(target, this.texture_);
- this.gl.texSubImage2D(target, level, where_x, where_y, size_x, size_y,
- format, this.gl.UNSIGNED_BYTE, keptPixels);
+ this.gl.bindTexture(this.texture_target_, this.texture_);
+ this.gl.texSubImage2D(this.gl.TEXTURE_2D, level, where_x, where_y,
+ size_x, size_y, format, this.gl.UNSIGNED_BYTE, keptPixels);
};
@@ -516,7 +665,7 @@ o3d.Texture2D.prototype.getRect =
* @param {o3d.Bitmap} bitmap The bitmap to copy data from.
*/
o3d.Texture2D.prototype.setFromBitmap = function(bitmap) {
- // Whether resize the texture to power-of-two size
+ // Whether to resize the texture to power-of-two size.
var resize_to_pot = bitmap.defer_mipmaps_to_texture_;
this.setFromCanvas_(bitmap.canvas_,
resize_to_pot,
@@ -526,12 +675,11 @@ o3d.Texture2D.prototype.setFromBitmap = function(bitmap) {
/**
- * Copy pixels from source bitmap to certain mip level.
+ * Copy pixels from source bitmap to certain face and mip level.
* Scales if the width and height of source and dest do not match.
- * TODO(petersont): Takes optional arguments.
*
* @param {o3d.Bitmap} source_img The source bitmap.
- * @param {number} source_mip which mip from the source to copy from.
+ * @param {number} source_mip which mip of the source to copy from.
* @param {number} source_x x-coordinate of the starting pixel in the
* source image.
* @param {number} source_y y-coordinate of the starting pixel in the
@@ -543,35 +691,15 @@ o3d.Texture2D.prototype.setFromBitmap = function(bitmap) {
* destination texture.
* @param {number} dest_y y-coordinate of the starting pixel in the
* destination texture.
- * @param {number} dest_width width of the dest image.
- * @param {number} dest_height height of the dest image.
+ * @param {number} dest_width width of the destination image.
+ * @param {number} dest_height height of the destination image.
*/
o3d.Texture2D.prototype.drawImage =
function(source_img, source_mip, source_x, source_y, source_width,
- source_height, dest_mip, dest_x, dest_y, dest_width,
- dest_height) {
- var canvas = o3d.Bitmap.getScratchCanvas_();
- canvas.width = dest_width;
- canvas.height = dest_height;
-
- var context = canvas.getContext('2d');
-
- context.translate(-source_x, -source_y);
- context.scale(dest_width / source_width,
- dest_height / source_height);
-
- context.drawImage(source_img.canvas_,
- 0, 0, source_img.canvas_.width, source_img.canvas_.height);
-
- var gl = this.gl;
- gl.bindTexture(gl.TEXTURE_2D, this.texture_);
- // TODO(petersont): replace this with a call to texSubImage2D once
- // Firefox supports it.
- gl.texImage2D(
- gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas);
- // this.gl.texSubImage2D(this.gl.TEXTURE_2D, 0, 0, 0, canvas);
- this.texture_width_ = canvas.width;
- this.texture_height_ = canvas.height;
+ source_height, dest_mip, dest_x, dest_y, dest_width, dest_height) {
+ this.drawImageFromCanvas_(source_img.canvas_,
+ source_x, source_y, source_width, source_height, dest_mip,
+ dest_x, dest_y, dest_width, dest_height);
};
@@ -649,26 +777,9 @@ o3d.ParamObject.setUpO3DParam_(o3d.TextureCUBE, 'edgeLength', 'ParamInteger');
* @private
*/
o3d.TextureCUBE.prototype.init_ =
- function(edgeLength, format, levels, enableRenderSurfaces) {
- this.edgeLength = edgeLength;
- this.texture_ = this.gl.createTexture();
- this.texture_target_ = this.gl.TEXTURE_CUBE_MAP;
- this.texture_width_ = edgeLength;
- this.texture_height_ = edgeLength;
- this.format = format;
-
- this.gl.bindTexture(this.gl.TEXTURE_CUBE_MAP, this.texture_);
- // TODO(petersont): remove this allocation once Firefox supports
- // passing null as argument to this form of texImage2D.
- var t = new Uint8Array(edgeLength * edgeLength * 4);
- for (var ii = 0; ii < 6; ++ii) {
- this.gl.texImage2D(this.gl.TEXTURE_CUBE_MAP_POSITIVE_X + ii,
- 0, this.gl.RGBA, edgeLength, edgeLength, 0,
- this.gl.RGBA, this.gl.UNSIGNED_BYTE, t);
- }
-
- this.texture_width_ = edgeLength;
- this.texture_height_ = edgeLength;
+ function(edgeLength, format, levels, enable_render_surfaces, debug) {
+ this.initWithTarget_(this.gl.TEXTURE_CUBE_MAP,
+ edgeLength, edgeLength, format, levels, enable_render_surfaces, debug);
};
@@ -703,8 +814,7 @@ o3d.TextureCUBE.prototype.getRenderSurface =
*/
o3d.TextureCUBE.prototype.set =
function(face, level, values) {
- var target = this.gl.TEXTURE_CUBE_MAP_POSITIVE_X + face;
- this.setValues_(target, level, values);
+ this.setValues_(level, values, face);
this.faces_set_[face] = true;
};
@@ -764,20 +874,17 @@ o3d.TextureCUBE.prototype.getRect =
*/
o3d.TextureCUBE.prototype.setFromBitmap =
function(face, bitmap) {
-
var generate_mipmaps = bitmap.defer_mipmaps_to_texture_;
for (var f in this.faces_set_) {
generate_mipmaps = generate_mipmaps &&
- (this.faces_set_[f] || f==face);
+ (this.faces_set_[f] || f == face);
}
-
var resize_to_pot = bitmap.defer_mipmaps_to_texture_;
this.setFromCanvas_(bitmap.canvas_,
resize_to_pot,
false, // Never flip cube maps.
generate_mipmaps,
face);
-
this.faces_set_[face] = true;
};
@@ -808,7 +915,9 @@ o3d.TextureCUBE.prototype.drawImage =
function(source_img, source_mip, source_x, source_y, source_width,
source_height, face, dest_mip, dest_x, dest_y, dest_width,
dest_height) {
- o3d.notImplemented();
+ this.drawImageFromCanvas_(source_img.canvas_,
+ source_x, source_y, source_width, source_height, dest_mip,
+ dest_x, dest_y, dest_width, dest_height, face);
};
diff --git a/o3d/samples/o3djs/texture.js b/o3d/samples/o3djs/texture.js
index 8232d26..c299df0 100644
--- a/o3d/samples/o3djs/texture.js
+++ b/o3d/samples/o3djs/texture.js
@@ -212,7 +212,6 @@ o3djs.texture.createTextureFromBitmaps = function(
pack,
bitmaps,
opt_generateMips) {
-
if (bitmaps.length == 0) {
throw 'no bitmaps';
}
@@ -288,8 +287,7 @@ o3djs.texture.createCubeTextureFrom6Bitmaps = function(
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.setFromBitmap(ii, bitmap);
}
texture.generateMips(0, numMips - 1);
return texture;