diff options
-rw-r--r-- | o3d/plugin/idl/texture.idl | 209 | ||||
-rw-r--r-- | o3d/samples/o3djs/debug.js | 13 | ||||
-rw-r--r-- | o3d/samples/o3djs/primitives.js | 12 | ||||
-rw-r--r-- | o3d/samples/o3djs/simple.js | 6 | ||||
-rw-r--r-- | o3d/samples/o3djs/util.js | 3 | ||||
-rw-r--r-- | o3d/tests/selenium/javascript_unit_test_list.txt | 1 | ||||
-rw-r--r-- | o3d/tests/selenium/sample_list.txt | 15 | ||||
-rw-r--r-- | o3d/tests/selenium/tests/texture-set-test.html | 465 |
8 files changed, 660 insertions, 64 deletions
diff --git a/o3d/plugin/idl/texture.idl b/o3d/plugin/idl/texture.idl index 03dc49b..0f4614b 100644 --- a/o3d/plugin/idl/texture.idl +++ b/o3d/plugin/idl/texture.idl @@ -161,33 +161,67 @@ namespace o3d { [nocpp, userglue, include="core/cross/math_utilities.h"] void Set(int level, float[] values); + %[ + Sets a rectangular area of values in a texture. + + Does clipping. In other words if you pass in a 10x10 pixel array + and give it destination of (-5, -5) it will only use the bottom 5x5 + pixels of the array you passed in to set to set the top 5x5 pixels of the + texture. + + See o3d.Texture2D.set for details on formats. + + \param level the mip level to update. + \param destination_x The x coordinate of the area in the texture to effect. + \param destination_y The y coordinate of the area in the texture to effect. + \param source_width The width of the area to effect. The height is + determined bythe size of the array passed in. + \param values Values to be stored in the buffer. + \see o3d.Texture2D.set + %] + [nocpp, userglue, include="core/cross/math_utilities.h"] + void SetRect(int level, + int destination_x, + int destination_y, + int source_width, + float[] values); + + [verbatim=cpp_glue] %{ - void userglue_method_Set(o3d::Texture2D* self, - int level, - const std::vector<float>& values) { + void SetRectCheck(o3d::Texture2D* self, + int level, + int destination_x, + int destination_y, + int source_width, + const std::vector<float>& values, + bool check_needed) { if (level < 0 || level >= self->levels()) { O3D_ERROR(self->service_locator()) << "level (" << level << " out of range"; return; } - unsigned width = std::max(self->width() >> level, 1); - unsigned height = std::max(self->height() >> level, 1); - unsigned num_elements; + if (values.empty() || source_width <= 0) { + return; + } + unsigned num_values = values.size(); + unsigned texture_width = std::max(self->width() >> level, 1); + unsigned texture_height = std::max(self->height() >> level, 1); + unsigned num_components; unsigned swizzle[4] = {2, 1, 0, 3}; switch (self->format()) { case o3d::Texture::XRGB8: - num_elements = 3; + num_components = 3; break; case o3d::Texture::R32F: swizzle[0] = 0; - num_elements = 1; + num_components = 1; break; case o3d::Texture::ARGB8: case o3d::Texture::ABGR16F: - num_elements = 4; + num_components = 4; break; case o3d::Texture::ABGR32F: { - num_elements = 4; + num_components = 4; const o3d::Texture::RGBASwizzleIndices& indices = self->GetABGR32FSwizzleIndices(); for (int ii = 0; ii < 4; ++ii) { @@ -200,62 +234,128 @@ namespace o3d { << "Texture::Set not supported for this type of texture"; return; } - unsigned needed = num_elements * width * height; - if (values.size() != needed) { + if (num_values % num_components != 0) { O3D_ERROR(self->service_locator()) - << "needed " << needed << " values but " << values.size() - << " passed in."; + << "The number of elements passed in must be a multiple of " + << num_components; + } + unsigned num_elements = num_values / num_components; + if (num_elements % source_width != 0) { + O3D_ERROR(self->service_locator()) + << "The number of elements passed in must be a multiple of the " + << "width"; + return; + } + unsigned source_height = num_elements / source_width; + if (check_needed) { + unsigned needed = num_components * texture_width * texture_height; + if (num_values != needed) { + O3D_ERROR(self->service_locator()) + << "needed " << needed << " values but " << num_values + << " passed in."; + return; + } + } + + // clip + int source_x = 0; + int source_y = 0; + int copy_width = source_width; + int copy_height = source_height; + + if (destination_x < 0) { + copy_width += destination_x; + source_x -= destination_x; + destination_x = 0; + } + if (destination_x + copy_width > texture_width) { + copy_width -= destination_x + copy_width - texture_width; + } + + if (destination_y < 0) { + copy_height += destination_y; + source_y -= destination_y; + destination_y = 0; + } + if (destination_y + copy_height > texture_height) { + copy_height -= destination_y + copy_height - texture_height; + } + + if (copy_width <= 0 || copy_height <= 0) { return; } + void* data; if (!self->Lock(level, &data)) { O3D_ERROR(self->service_locator()) << "could not lock texture"; return; } + const float* source = + &values[0] + + (source_y * source_width + source_x) * num_components; + unsigned source_stride = (source_width - copy_width) * num_components; + unsigned destination_stride = + (texture_width - copy_width) * num_components; switch (self->format()) { case o3d::Texture::ABGR16F: { - unsigned short* destination = static_cast<unsigned short*>(data); - unsigned short* end = destination + width * height * num_elements; - const float* source = &values[0]; - while (destination < end) { - for (int element = 0; element < num_elements; ++element) { - destination[element] = Vectormath::Aos::FloatToHalf( - source[swizzle[element]]); + unsigned short* destination = + static_cast<unsigned short*>(data) + + (destination_y * texture_width + destination_x) * num_components; + while (copy_height > 0) { + for (int xx = 0; xx < copy_width; ++xx) { + for (int element = 0; element < num_components; ++element) { + destination[element] = Vectormath::Aos::FloatToHalf( + source[swizzle[element]]); + } + destination += num_components; + source += num_components; } - destination += num_elements; - source += num_elements; + destination += destination_stride; + source += source_stride; + --copy_height; } break; } case o3d::Texture::R32F: case o3d::Texture::ABGR32F: { - float* destination = static_cast<float*>(data); - float* end = destination + width * height * num_elements; - const float* source = &values[0]; - while (destination < end) { - for (int element = 0; element < num_elements; ++element) { - destination[element] = source[swizzle[element]]; + float* destination = + static_cast<float*>(data) + + (destination_y * texture_width + destination_x) * num_components; + while (copy_height > 0) { + for (int xx = 0; xx < copy_width; ++xx) { + for (int element = 0; element < num_components; ++element) { + destination[element] = source[swizzle[element]]; + } + destination += num_components; + source += num_components; } - destination += num_elements; - source += num_elements; + destination += destination_stride; + source += source_stride; + --copy_height; } break; } default: { - unsigned char* destination = static_cast<unsigned char*>(data); - unsigned char* end = destination + width * height * 4; - const float* source = &values[0]; - while (destination < end) { - destination[0] = static_cast<unsigned char>( - source[swizzle[0]] * 255.0f); - destination[1] = static_cast<unsigned char>( - source[swizzle[1]] * 255.0f); - destination[2] = static_cast<unsigned char>( - source[swizzle[2]] * 255.0f); - destination[3] = (num_elements == 4) ? - static_cast<unsigned char>(source[swizzle[3]] * 255.0f) : 255; - destination += 4; - source += num_elements; + destination_stride = (texture_width - copy_width) * 4; + uint8* destination = + static_cast<uint8*>(data) + + (destination_y * texture_width + destination_x) * 4; + while (copy_height > 0) { + for (int xx = 0; xx < copy_width; ++xx) { + destination[0] = static_cast<unsigned char>( + source[swizzle[0]] * 255.0f); + destination[1] = static_cast<unsigned char>( + source[swizzle[1]] * 255.0f); + destination[2] = static_cast<unsigned char>( + source[swizzle[2]] * 255.0f); + destination[3] = (num_components == 4) ? + static_cast<unsigned char>(source[swizzle[3]] * 255.0f) : 255; + destination += 4; + source += num_components; + } + destination += destination_stride; + source += source_stride; + --copy_height; } break; } @@ -264,6 +364,25 @@ namespace o3d { O3D_ERROR(self->service_locator()) << "could not unlock texture"; } } + void userglue_method_SetRect(o3d::Texture2D* self, + int level, + int destination_x, + int destination_y, + int source_width, + const std::vector<float>& values) { + SetRectCheck(self, + level, + destination_x, + destination_y, + source_width, + values, + false); + } + void userglue_method_Set(o3d::Texture2D* self, + int level, + const std::vector<float>& values) { + SetRectCheck(self, level, 0, 0, self->width(), values, true); + } %} }; // Texture2D diff --git a/o3d/samples/o3djs/debug.js b/o3d/samples/o3djs/debug.js index cc34b7a..8b1dc8d 100644 --- a/o3d/samples/o3djs/debug.js +++ b/o3d/samples/o3djs/debug.js @@ -387,7 +387,7 @@ o3djs.debug.createLineSphereVertices = function(radius, subdivisionsHeight, opt_matrix) { if (subdivisionsAxis <= 0 || subdivisionsHeight <= 0) { - throw RangeError('subdivisionAxis and subdivisionHeight must be > 0'); + throw Error('subdivisionAxis and subdivisionHeight must be > 0'); } // We are going to generate our sphere by iterating through its @@ -474,8 +474,19 @@ o3djs.debug.createLineSphere = function(pack, * this line belongs too. */ o3djs.debug.DebugLine = function(debugLineGroup) { + /** + * The DebugLineGroup this DebugLine is managed by. + * @private + * @type {!o3djs.debug.DebugLineGroup} + */ this.debugLineGroup_ = debugLineGroup; var pack = debugLineGroup.getPack(); + + /** + * The transform for this DebugLine. + * @private + * @type {!o3d.Transform} + */ this.transform_ = pack.createObject('Transform'); this.transform_.name = O3D_DEBUG_LINE_SHAPE_NAME; this.transform_.addShape(debugLineGroup.getLineShape()); diff --git a/o3d/samples/o3djs/primitives.js b/o3d/samples/o3djs/primitives.js index d3df686..52621d5 100644 --- a/o3d/samples/o3djs/primitives.js +++ b/o3d/samples/o3djs/primitives.js @@ -703,7 +703,7 @@ o3djs.primitives.createSphereVertices = function(radius, subdivisionsHeight, opt_matrix) { if (subdivisionsAxis <= 0 || subdivisionsHeight <= 0) { - throw RangeError('subdivisionAxis and subdivisionHeight must be > 0'); + throw Error('subdivisionAxis and subdivisionHeight must be > 0'); } // We are going to generate our sphere by iterating through its @@ -1016,7 +1016,7 @@ o3djs.primitives.createDiscVertices = function(radius, opt_stackPower, opt_matrix) { if (divisions < 3) { - throw RangeError('divisions must be at least 3'); + throw Error('divisions must be at least 3'); } var stacks = opt_stacks ? opt_stacks : 1; @@ -1148,11 +1148,11 @@ o3djs.primitives.createCylinderVertices = function(radius, verticalSubdivisions, opt_matrix) { if (radialSubdivisions < 1) { - throw RangeError('radialSubdivisions must be 1 or greater'); + throw Error('radialSubdivisions must be 1 or greater'); } if (verticalSubdivisions < 1) { - throw RangeError('verticalSubdivisions must be 1 or greater'); + throw Error('verticalSubdivisions must be 1 or greater'); } var vertexInfo = o3djs.primitives.createVertexInfo(); @@ -1417,7 +1417,7 @@ o3djs.primitives.createPrismVertices = function(points, depth, opt_matrix) { if (points.length < 3) { - throw RangeError('there must be 3 or more points'); + throw Error('there must be 3 or more points'); } var backZ = -0.5 * depth; @@ -1573,7 +1573,7 @@ o3djs.primitives.createPlaneVertices = function(width, subdivisionsDepth, opt_matrix) { if (subdivisionsWidth <= 0 || subdivisionsDepth <= 0) { - throw RangeError('subdivisionWidth and subdivisionDepth must be > 0'); + throw Error('subdivisionWidth and subdivisionDepth must be > 0'); } var vertexInfo = o3djs.primitives.createVertexInfo(); diff --git a/o3d/samples/o3djs/simple.js b/o3d/samples/o3djs/simple.js index a02e84d..8bb729b 100644 --- a/o3d/samples/o3djs/simple.js +++ b/o3d/samples/o3djs/simple.js @@ -421,10 +421,12 @@ o3djs.simple.SimpleInfo.prototype.createSphere = function(radius, * Loads a scene from a URL. * TODO: Implement * @param {string} url Url of scene to load. - * @return {!o3djs.simple.Scene} A Javascript object to manage th scene. + * @return {!o3djs.simple.Scene} A Javascript object to manage the scene. */ o3djs.simple.SimpleInfo.prototype.loadScene = function(url) { - throw('not implemented'); + if (true) { + throw('not implemented'); + } return null; }; diff --git a/o3d/samples/o3djs/util.js b/o3d/samples/o3djs/util.js index de283ba..b898a24 100644 --- a/o3d/samples/o3djs/util.js +++ b/o3d/samples/o3djs/util.js @@ -310,7 +310,7 @@ o3djs.util.requiredVersionAvailable = function(requiredVersion) { var haveParts = version.split('.'); var requiredParts = requiredVersion.split('.'); if (requiredParts.length > 4) { - throw RangeError('requiredVersion has more than 4 parts!'); + throw Error('requiredVersion has more than 4 parts!'); } for (var pp = 0; pp < requiredParts.length; ++pp) { var have = parseInt(haveParts[pp], 10); @@ -511,7 +511,6 @@ o3djs.util.getElementContentById = function(id) { throw 'getElementContentById does not no how to get content from a ' + node.tagName + ' element'; } - return node.value; }; /** diff --git a/o3d/tests/selenium/javascript_unit_test_list.txt b/o3d/tests/selenium/javascript_unit_test_list.txt index 9cfa199..fc3f287 100644 --- a/o3d/tests/selenium/javascript_unit_test_list.txt +++ b/o3d/tests/selenium/javascript_unit_test_list.txt @@ -69,6 +69,7 @@ small base-test small util-test small pixel-perfection screenshot pdiff_threshold(2500) pdiff_threshold_mac(3000) except(*iexplore) medium offscreen-test +medium texture-set-test screenshot small no-rendergraph screenshot small non-cachable-params screenshot pdiff_threshold(1700) small type-test diff --git a/o3d/tests/selenium/sample_list.txt b/o3d/tests/selenium/sample_list.txt index 699a888..136cd5a 100644 --- a/o3d/tests/selenium/sample_list.txt +++ b/o3d/tests/selenium/sample_list.txt @@ -59,28 +59,27 @@ medium 2d screenshot pdiff_threshold(41200) medium animation large animated-scene screenshot timeout(45000) pdiff_threshold(200) -large beachdemo/beachdemo screenshot timeout(120000) pdiff_threshold(15500) except(*iexplore) +large beachdemo/beachdemo screenshot timeout(120000) pdiff_threshold(100) downsample(1) except(*iexplore) medium canvas screenshot pdiff_threshold(4700) pdiff_threshold_mac(14600) medium canvas-fonts screenshot pdiff_threshold(1100) pdiff_threshold_mac(21900) medium canvas-texturedraw medium checkers screenshot pdiff_threshold(1100) medium convolution screenshot pdiff_threshold(200) -medium culling screenshot pdiff_threshold(3400) +medium culling screenshot pdiff_threshold(1000) downsample(1) medium debugging screenshot pdiff_threshold(2000) pdiff_threshold_mac(3000) medium displayfps -small generate-texture screenshot pdiff_threshold(30000) except(*iexplore) +small generate-texture screenshot pdiff_threshold(30000) except(*iexplore) medium hellocube screenshot pdiff_threshold(1000) -medium hellocube-colors screenshot pdiff_threshold(1000) +medium hellocube-colors screenshot pdiff_threshold(50) downsample(2) medium helloworld screenshot pdiff_threshold(900) medium hud-2d-overlay screenshot pdiff_threshold(11300) pdiff_threshold_win(39800) medium instance-override screenshot pdiff_threshold(10500) medium instancing screenshot pdiff_threshold(14300) -medium juggler screenshot -# NOTE: temporarily disabled while we investigate failures -# medium julia screenshot +medium juggler screenshot downsample(1) +medium julia screenshot small multiple-views screenshot pdiff_threshold(1900) medium particles screenshot pdiff_threshold(35500) -medium primitives screenshot pdiff_threshold(17200) pdiff_threshold_mac(20000) +medium primitives screenshot pdiff_threshold(17200) pdiff_threshold_mac(20000) colorfactor(.7) medium procedural-texture screenshot pdiff_threshold(1300) medium render-targets screenshot pdiff_threshold(1400) medium scatter-chart screenshot pdiff_threshold(10100) pdiff_threshold_mac(10600) diff --git a/o3d/tests/selenium/tests/texture-set-test.html b/o3d/tests/selenium/tests/texture-set-test.html new file mode 100644 index 0000000..88f8619 --- /dev/null +++ b/o3d/tests/selenium/tests/texture-set-test.html @@ -0,0 +1,465 @@ +<!-- +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. +--> + +<!-- +Texture set test. +--> +<!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> +Texture Set Test. +</title> +<script type="text/javascript" src="../../../samples/o3djs/base.js"></script> +<script type="text/javascript"> +o3djs.require('o3djs.util'); +o3djs.require('o3djs.math'); +o3djs.require('o3djs.rendergraph'); +o3djs.require('o3djs.primitives'); +o3djs.require('o3djs.effect'); + +// global variables +var g_o3d; +var g_math; +var g_client; +var g_pack; +var g_viewInfo; + +/** + * 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.util.makeClients(initStep2, 'FloatingPointTextures,NotAntiAliased'); +} + +/** + * 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 effectNames = [ + 'texture-only.shader', + 'luminance_alpha_texture.shader']; + + var effectInfos = { + texture_only: {name: 'texture_only'}, + one_channel_texture: {name: 'one_channel_texture'}}; + for (var key in effectInfos) { + var info = effectInfos[key]; + var effect = g_pack.createObject('Effect'); + effect.loadFromFXString(o3djs.util.getElementContentById(info.name)); + + // Create a Material for the effect. + var material = g_pack.createObject('Material'); + + // Set the material's drawList for transparent objects. + material.drawList = g_viewInfo.zOrderedDrawList; + + // Apply the effect to this material. + material.effect = effect; + + // Create the params that effect requires on the material. + effect.createUniformParameters(material); + + // Create a quad. + var shape = o3djs.primitives.createPlane(g_pack, + material, + 1, + 1, + 1, + 1); + info.shape = shape; + } + + // display our shape 5 times with 5 different textures + // by overriding the sampler on each instance. + for (var f = 0; f < 5; ++f) { + for (var s = 0; s < 5; ++s) { + // create a transform for an instance + var transform = g_pack.createObject('Transform'); + var x = s; + var z = f; + transform.translate(-180 + 32 + s * 70, 0, -180 + 32 + f * 70); + transform.scale(64, 1, 64); + 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.magFilter = g_o3d.Sampler.NONE; + sampler.minFilter = g_o3d.Sampler.NONE; + sampler.mipFilter = g_o3d.Sampler.NONE; + sampler.addressModeU = g_o3d.Sampler.CLAMP; + sampler.addressModeV = g_o3d.Sampler.CLAMP; + + // 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; + } + case 4: { // R32F + /** + * NOTE: GL and D3D do NOT share compatible 1 channel texture + * formats. + * + * In D3D the sampler will return + * + * R = channel 0 + * G = const 1 + * B = const 1 + * A = const 1 + * + * In GL the sampler will return + * + * R = channel 0 + * G = channel 0 + * B = channel 0 + * A = channel 0 + * + * What that means is only R works across platforms. G, B and A are + * undefined and if you use them you'll get the wrong results. + */ + transform.addShape(effectInfos.one_channel_texture.shape); + format = g_o3d.Texture.R32F; + for (var y = 0; y < 32; ++y) { + for (var x = 0; x < 32; ++x) { + var offset = (y * 32 + x); // r + var u = x / 32 * Math.PI * 0.5; + var v = y / 32 * Math.PI * 0.5; + pixels[offset + 0] = Math.cos(v * 16); // red + } + } + break; + } + } + var texture = g_pack.createTexture2D(32, 32, format, 1, false); + var tx = -16 + (f % 2) * 32; + var ty = -16 + Math.floor(f / 2) * 32; + if (f == 4) { + tx = 0; + ty = 0; + } + texture.setRect(0, tx, ty, 32, pixels); + sampler.texture = texture; + } + } + } + window.g_testResult = true; // for selenium testing. +} + +</script> +</head> +<body onload="init()"> +<h1>Texture Set Test</h1> +<br/> + +<!-- Start of O3D plugin --> +<div id="o3d" style="width: 400px; height: 400px;"></div> +<!-- End of O3D plugin --> +<script type="test/o3deffect" id="texture_only"> +/* + * 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. + */ + +float4x4 worldViewProjection : WORLDVIEWPROJECTION; + +// The texture sampler is used to access the texture bitmap in the fragment +// shader. +sampler texSampler0; + +// input parameters for our vertex shader +struct PixelShaderInput { + float4 position : POSITION; + float2 texcoord : TEXCOORD0; // Texture coordinates +}; + +// input parameters for our pixel shader +struct VertexShaderInput { + float4 position : POSITION; + float2 texcoord : TEXCOORD0; // Texture coordinates +}; + +/** + * Our vertex shader + */ +PixelShaderInput vertexShaderFunction(VertexShaderInput input) { + PixelShaderInput output; + output.position = mul(input.position, worldViewProjection); + output.texcoord = input.texcoord; + return output; +} + +/* Given the texture coordinates, our pixel shader grabs the corresponding + * color from the texture. + */ +float4 pixelShaderFunction(PixelShaderInput input): COLOR { + return tex2D(texSampler0, input.texcoord); +} + +// Here we tell our effect file *which* functions are +// our vertex and pixel shaders. +// #o3d VertexShaderEntryPoint vertexShaderFunction +// #o3d PixelShaderEntryPoint pixelShaderFunction +// #o3d MatrixLoadOrder RowMajor +</script> +<script type="test/o3deffect" id="one_channel_texture"> +/* + * 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. + */ + +float4x4 worldViewProjection : WORLDVIEWPROJECTION; + +// The texture sampler is used to access the texture bitmap in the fragment +// shader. +sampler texSampler0; + +// input parameters for our vertex shader +struct PixelShaderInput { + float4 position : POSITION; + float2 texcoord : TEXCOORD0; // Texture coordinates +}; + +// input parameters for our pixel shader +struct VertexShaderInput { + float4 position : POSITION; + float2 texcoord : TEXCOORD0; // Texture coordinates +}; + +/** + * Our vertex shader + */ +PixelShaderInput vertexShaderFunction(VertexShaderInput input) { + PixelShaderInput output; + output.position = mul(input.position, worldViewProjection); + output.texcoord = input.texcoord; + return output; +} + +/** + * Given the texture coordinates, our pixel shader grabs the corresponding + * color from the texture. + * + * NOTE: GL and D3D do NOT share compatible 1 channel texture formats. + * + * In D3D the sampler will return + * + * R = channel 0 + * G = const 1 + * B = const 1 + * A = const 1 + * + * In GL the sampler will return + * + * R = channel 0 + * G = channel 0 + * B = channel 0 + * A = channel 0 + * + * What that means is only R works across platforms. G, B and A are undefined + * and if you use them you'll get the wrong results. + */ +float4 pixelShaderFunction(PixelShaderInput input): COLOR { + // ** Use only valid channels. ** ---------+ + // | + // V + return tex2D(texSampler0, input.texcoord).rrrr; +} + +// Here we tell our effect file *which* functions are +// our vertex and pixel shaders. +// #o3d VertexShaderEntryPoint vertexShaderFunction +// #o3d PixelShaderEntryPoint pixelShaderFunction +// #o3d MatrixLoadOrder RowMajor +</script> +</body> +</html> |