Index: conformance/textures/tex-image-with-format-and-type.html |
=================================================================== |
--- conformance/textures/tex-image-with-format-and-type.html (revision 0) |
+++ conformance/textures/tex-image-with-format-and-type.html (revision 0) |
@@ -0,0 +1,725 @@ |
+<!-- |
+Copyright (c) 2011 The Chromium Authors. All rights reserved. |
+Use of this source code is governed by a BSD-style license that can be |
+found in the LICENSE file. |
+ --> |
+<!DOCTYPE html> |
+<html> |
+<head> |
+<meta charset="utf-8"> |
+<link rel="stylesheet" href="../../resources/js-test-style.css"/> |
+<script src="../../resources/js-test-pre.js"></script> |
+<script src="../resources/pnglib.js"></script> |
+<script src="../resources/webgl-test.js"></script> |
+<script src="../resources/webgl-test-utils.js"></script> |
+ |
+<script> |
+var wtu = WebGLTestUtils; |
+var gl = null; |
+var textureLoc = null; |
+var successfullyParsed = false; |
+ |
+//---------------------------------------------------------------------- |
+// Harness |
+ |
+var testCases = []; |
+ |
+var DataMode = { |
+ IMAGE: 0, |
+ IMAGE_DATA: 1, |
+ |
+ NUM_HTML_MODES: 2, |
+ |
+ RAW_DATA: 2, |
+ |
+ // This must remain the last mode. |
+ NUM_MODES: 3 |
+}; |
+ |
+function init() |
+{ |
+ if (window.initNonKhronosFramework) { |
+ window.initNonKhronosFramework(true); |
+ } |
+ |
+ description('Verify texImage2D and texSubImage2D code paths taking both HTML and user-specified data with all format/type combinations'); |
+ |
+ var canvas = document.getElementById("example"); |
+ gl = wtu.create3DContext(canvas); |
+ var program = wtu.setupTexturedQuad(gl); |
+ |
+ gl.clearColor(0,0,0,1); |
+ gl.clearDepth(1); |
+ gl.disable(gl.BLEND); |
+ |
+ textureLoc = gl.getUniformLocation(program, "tex"); |
+ |
+ initializeTests(); |
+} |
+ |
+function initializeTests() |
+{ |
+ // Verify that uploading to packed pixel formats performs the |
+ // required conversion and associated loss of precision. |
+ for (var dataMode = 0; dataMode < DataMode.NUM_HTML_MODES; ++dataMode) { |
+ for (var useTexSubImage2D = 0; useTexSubImage2D < 2; ++useTexSubImage2D) { |
+ testCases.push({ |
+ dataMode: dataMode, |
+ useTexSubImage2D: !!useTexSubImage2D, |
+ width: 256, |
+ height: 1, |
+ generator: generateOpaqueGrayscaleRamp, |
+ premultiplyAlpha: false, |
+ format: gl.RGBA, |
+ type: gl.UNSIGNED_BYTE, |
+ verifier: allChannelsIncreaseByNoMoreThan, |
+ threshold: 1, |
+ numOccurrences: 1, |
+ description: "RGBA/UNSIGNED_BYTE should maintain full precision of data" |
+ }); |
+ testCases.push({ |
+ dataMode: dataMode, |
+ useTexSubImage2D: !!useTexSubImage2D, |
+ width: 256, |
+ height: 1, |
+ generator: generateOpaqueGrayscaleRamp, |
+ premultiplyAlpha: false, |
+ format: gl.RGBA, |
+ type: gl.UNSIGNED_SHORT_4_4_4_4, |
+ verifier: allChannelsIncreaseByAtLeast, |
+ threshold: 15, |
+ numOccurrences: 10, |
+ description: "RGBA/UNSIGNED_SHORT_4_4_4_4 must drop low four bits of precision" |
+ }); |
+ testCases.push({ |
+ dataMode: dataMode, |
+ useTexSubImage2D: !!useTexSubImage2D, |
+ width: 256, |
+ height: 1, |
+ generator: generateOpaqueGrayscaleRamp, |
+ premultiplyAlpha: false, |
+ format: gl.RGBA, |
+ type: gl.UNSIGNED_SHORT_5_5_5_1, |
+ verifier: allChannelsIncreaseByAtLeast, |
+ threshold: 7, |
+ numOccurrences: 20, |
+ description: "RGBA/UNSIGNED_SHORT_5_5_5_1 must drop low three bits of precision" |
+ }); |
+ testCases.push({ |
+ dataMode: dataMode, |
+ useTexSubImage2D: !!useTexSubImage2D, |
+ width: 256, |
+ height: 1, |
+ generator: generateOpaqueGrayscaleRamp, |
+ premultiplyAlpha: false, |
+ format: gl.RGB, |
+ type: gl.UNSIGNED_BYTE, |
+ verifier: allChannelsIncreaseByNoMoreThan, |
+ threshold: 1, |
+ numOccurrences: 1, |
+ description: "RGB/UNSIGNED_BYTE should maintain full precision of data" |
+ }); |
+ testCases.push({ |
+ dataMode: dataMode, |
+ useTexSubImage2D: !!useTexSubImage2D, |
+ width: 256, |
+ height: 1, |
+ generator: generateOpaqueGrayscaleRamp, |
+ premultiplyAlpha: false, |
+ format: gl.RGB, |
+ type: gl.UNSIGNED_SHORT_5_6_5, |
+ verifier: allChannelsIncreaseByAtLeast, |
+ threshold: 3, |
+ numOccurrences: 20, |
+ description: "RGB/UNSIGNED_SHORT_5_6_5 must drop low two or three bits of precision" |
+ }); |
+ testCases.push({ |
+ dataMode: dataMode, |
+ useTexSubImage2D: !!useTexSubImage2D, |
+ width: 256, |
+ height: 1, |
+ generator: generateTranslucentGrayscaleRamp, |
+ premultiplyAlpha: false, |
+ format: gl.ALPHA, |
+ type: gl.UNSIGNED_BYTE, |
+ verifier: alphaChannelIncreasesByNoMoreThan, |
+ threshold: 1, |
+ numOccurrences: 1, |
+ description: "ALPHA/UNSIGNED_BYTE should maintain full precision of data" |
+ }); |
+ testCases.push({ |
+ dataMode: dataMode, |
+ useTexSubImage2D: !!useTexSubImage2D, |
+ width: 256, |
+ height: 1, |
+ generator: generateOpaqueGrayscaleRamp, |
+ premultiplyAlpha: false, |
+ format: gl.LUMINANCE, |
+ type: gl.UNSIGNED_BYTE, |
+ verifier: allChannelsIncreaseByNoMoreThan, |
+ threshold: 1, |
+ numOccurrences: 1, |
+ description: "LUMINANCE/UNSIGNED_BYTE should maintain full precision of data" |
+ }); |
+ testCases.push({ |
+ dataMode: dataMode, |
+ useTexSubImage2D: !!useTexSubImage2D, |
+ width: 256, |
+ height: 1, |
+ generator: generateOpaqueGrayscaleRamp, |
+ premultiplyAlpha: false, |
+ format: gl.LUMINANCE_ALPHA, |
+ type: gl.UNSIGNED_BYTE, |
+ verifier: allChannelsIncreaseByNoMoreThan, |
+ threshold: 1, |
+ numOccurrences: 1, |
+ description: "LUMINANCE_ALPHA/UNSIGNED_BYTE should maintain full precision of data" |
+ }); |
+ } |
+ } |
+ |
+ // Verify that setting the UNPACK_PREMULTIPLY_ALPHA_WEBGL pixel |
+ // store parameter and sending down a zero alpha causes the color |
+ // channels to go to zero. |
+ for (var dataMode = 0; dataMode < DataMode.NUM_MODES; ++dataMode) { |
+ for (var useTexSubImage2D = 0; useTexSubImage2D < 2; ++useTexSubImage2D) { |
+ testCases.push({ |
+ dataMode: dataMode, |
+ useTexSubImage2D: !!useTexSubImage2D, |
+ width: 256, |
+ height: 1, |
+ generator: generateTransparentGrayscaleRamp, |
+ premultiplyAlpha: true, |
+ format: gl.RGBA, |
+ type: gl.UNSIGNED_BYTE, |
+ verifier: colorChannelsAreZero, |
+ description: "UNPACK_PREMULTIPLY_ALPHA_WEBGL with RGBA/UNSIGNED_BYTE" |
+ }); |
+ testCases.push({ |
+ dataMode: dataMode, |
+ useTexSubImage2D: !!useTexSubImage2D, |
+ width: 256, |
+ height: 1, |
+ generator: generateTransparentGrayscaleRamp, |
+ premultiplyAlpha: true, |
+ format: gl.RGBA, |
+ type: gl.UNSIGNED_SHORT_4_4_4_4, |
+ verifier: colorChannelsAreZero, |
+ description: "UNPACK_PREMULTIPLY_ALPHA_WEBGL with RGBA/UNSIGNED_SHORT_4_4_4_4" |
+ }); |
+ testCases.push({ |
+ dataMode: dataMode, |
+ useTexSubImage2D: !!useTexSubImage2D, |
+ width: 256, |
+ height: 1, |
+ generator: generateTransparentGrayscaleRamp, |
+ premultiplyAlpha: true, |
+ format: gl.RGBA, |
+ type: gl.UNSIGNED_SHORT_5_5_5_1, |
+ verifier: colorChannelsAreZero, |
+ description: "UNPACK_PREMULTIPLY_ALPHA_WEBGL with RGBA/UNSIGNED_SHORT_5_5_5_1" |
+ }); |
+ // The following few tests are invalid for the raw data |
+ // mode because there is either no alpha channel or no |
+ // separate alpha channel. |
+ if (dataMode != DataMode.RAW_DATA) { |
+ testCases.push({ |
+ dataMode: dataMode, |
+ useTexSubImage2D: !!useTexSubImage2D, |
+ width: 256, |
+ height: 1, |
+ generator: generateTransparentGrayscaleRamp, |
+ premultiplyAlpha: true, |
+ format: gl.RGB, |
+ type: gl.UNSIGNED_BYTE, |
+ verifier: colorChannelsAreZero, |
+ description: "UNPACK_PREMULTIPLY_ALPHA_WEBGL with RGB/UNSIGNED_BYTE" |
+ }); |
+ testCases.push({ |
+ dataMode: dataMode, |
+ useTexSubImage2D: !!useTexSubImage2D, |
+ width: 256, |
+ height: 1, |
+ generator: generateTransparentGrayscaleRamp, |
+ premultiplyAlpha: true, |
+ format: gl.RGB, |
+ type: gl.UNSIGNED_SHORT_5_6_5, |
+ verifier: colorChannelsAreZero, |
+ description: "UNPACK_PREMULTIPLY_ALPHA_WEBGL with RGB/UNSIGNED_SHORT_5_6_5" |
+ }); |
+ testCases.push({ |
+ dataMode: dataMode, |
+ useTexSubImage2D: !!useTexSubImage2D, |
+ width: 256, |
+ height: 1, |
+ generator: generateTransparentGrayscaleRamp, |
+ premultiplyAlpha: true, |
+ format: gl.ALPHA, |
+ type: gl.UNSIGNED_BYTE, |
+ verifier: colorChannelsAreZero, |
+ description: "UNPACK_PREMULTIPLY_ALPHA_WEBGL with ALPHA/UNSIGNED_BYTE" |
+ }); |
+ testCases.push({ |
+ dataMode: dataMode, |
+ useTexSubImage2D: !!useTexSubImage2D, |
+ width: 256, |
+ height: 1, |
+ generator: generateTransparentGrayscaleRamp, |
+ premultiplyAlpha: true, |
+ format: gl.LUMINANCE, |
+ type: gl.UNSIGNED_BYTE, |
+ verifier: colorChannelsAreZero, |
+ description: "UNPACK_PREMULTIPLY_ALPHA_WEBGL with LUMINANCE/UNSIGNED_BYTE" |
+ }); |
+ } |
+ testCases.push({ |
+ dataMode: dataMode, |
+ useTexSubImage2D: !!useTexSubImage2D, |
+ width: 256, |
+ height: 1, |
+ generator: generateTransparentGrayscaleRamp, |
+ premultiplyAlpha: true, |
+ format: gl.LUMINANCE_ALPHA, |
+ type: gl.UNSIGNED_BYTE, |
+ verifier: colorChannelsAreZero, |
+ description: "UNPACK_PREMULTIPLY_ALPHA_WEBGL with LUMINANCE_ALPHA/UNSIGNED_BYTE" |
+ }); |
+ } |
+ } |
+ |
+ // Produce data for all testcases. Because we load images, some of |
+ // these may generate their data asynchronously. |
+ generateTestData(); |
+} |
+ |
+function generateTestData() |
+{ |
+ for (var i = 0; i < testCases.length; i++) { |
+ var testCase = testCases[i]; |
+ var wrapper = null; |
+ switch (testCase.dataMode) { |
+ case DataMode.IMAGE: |
+ wrapper = new ImageWrapper(testCase.width, testCase.height); |
+ break; |
+ case DataMode.IMAGE_DATA: |
+ wrapper = new ImageDataWrapper(testCase.width, testCase.height); |
+ break; |
+ case DataMode.RAW_DATA: |
+ switch (testCase.type) { |
+ case gl.UNSIGNED_BYTE: |
+ switch (testCase.format) { |
+ case gl.RGBA: |
+ wrapper = new RGBA8DataWrapper(testCase.width, testCase.height); |
+ break; |
+ case gl.RGB: |
+ wrapper = new RGB8DataWrapper(testCase.width, testCase.height); |
+ break; |
+ case gl.ALPHA: |
+ wrapper = new A8DataWrapper(testCase.width, testCase.height); |
+ break; |
+ case gl.LUMINANCE: |
+ wrapper = new L8DataWrapper(testCase.width, testCase.height); |
+ break; |
+ case gl.LUMINANCE_ALPHA: |
+ wrapper = new LA8DataWrapper(testCase.width, testCase.height); |
+ break; |
+ } |
+ break; |
+ case gl.UNSIGNED_SHORT_4_4_4_4: |
+ wrapper = new RGBA4444DataWrapper(testCase.width, testCase.height); |
+ break; |
+ case gl.UNSIGNED_SHORT_5_5_5_1: |
+ wrapper = new RGBA5551DataWrapper(testCase.width, testCase.height); |
+ break; |
+ case gl.UNSIGNED_SHORT_5_6_5: |
+ wrapper = new RGB565DataWrapper(testCase.width, testCase.height); |
+ break; |
+ } |
+ } |
+ testCase.wrapper = wrapper; |
+ testCase.generator(wrapper); |
+ testCase.wrapper.generateData(); |
+ } |
+ |
+ // See whether we need to run the tests, in case all of them |
+ // generated their results synchronously. |
+ maybeRunTests(); |
+} |
+ |
+var ranTests = false; |
+ |
+function maybeRunTests() |
+{ |
+ if (!ranTests) |
+ for (var i = 0; i < testCases.length; ++i) |
+ if (!testCases[i].wrapper || !testCases[i].wrapper.data) |
+ return; |
+ |
+ ranTests = true; |
+ |
+ for (var i = 0; i < testCases.length; ++i) |
+ runOneTest(testCases[i]); |
+ |
+ finishTest(); |
+} |
+ |
+function testCaseToString(testCase) |
+{ |
+ var mode; |
+ switch (testCase.dataMode) { |
+ case DataMode.IMAGE: |
+ mode = "Image"; |
+ break; |
+ case DataMode.IMAGE_DATA: |
+ mode = "ImageData"; |
+ break; |
+ case DataMode.RAW_DATA: |
+ mode = "raw data"; |
+ break; |
+ } |
+ return (testCase.useTexSubImage2D ? "texSubImage2D" : "texImage2D") + |
+ " with " + mode + " at " + testCase.width + "x" + testCase.height; |
+} |
+ |
+function runOneTest(testCase) |
+{ |
+ debug("Testing " + testCaseToString(testCase)); |
+ var data = testCase.wrapper.data; |
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); |
+ var texture = gl.createTexture(); |
+ // Bind the texture to texture unit 0. |
+ gl.bindTexture(gl.TEXTURE_2D, texture); |
+ // Set up texture parameters. |
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); |
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); |
+ // Set up pixel store parameters. |
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, testCase.premultiplyAlpha); |
+ // Upload the image into the texture. |
+ if (testCase.useTexSubImage2D) { |
+ // Initialize the texture to black first. |
+ gl.texImage2D(gl.TEXTURE_2D, 0, testCase.format, testCase.width, testCase.height, 0, |
+ testCase.format, testCase.type, null); |
+ } |
+ switch (testCase.dataMode) { |
+ case DataMode.IMAGE: |
+ case DataMode.IMAGE_DATA: |
+ if (testCase.useTexSubImage2D) |
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, testCase.format, testCase.type, data); |
+ else |
+ gl.texImage2D(gl.TEXTURE_2D, 0, testCase.format, testCase.format, testCase.type, data); |
+ break; |
+ case DataMode.RAW_DATA: |
+ if (testCase.useTexSubImage2D) |
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, testCase.width, testCase.height, testCase.format, testCase.type, data); |
+ else |
+ gl.texImage2D(gl.TEXTURE_2D, 0, testCase.format, testCase.width, testCase.height, 0, testCase.format, testCase.type, data); |
+ break; |
+ } |
+ // Point the uniform sampler to texture unit 0. |
+ gl.uniform1i(textureLoc, 0); |
+ // Draw the triangles. |
+ gl.drawArrays(gl.TRIANGLES, 0, 6); |
+ // Clean up the texture. |
+ gl.deleteTexture(texture); |
+ |
+ // Read back the rendering results. |
+ buf = new Uint8Array(testCase.width * testCase.height * 4); |
+ gl.readPixels(0, 0, testCase.width, testCase.height, gl.RGBA, gl.UNSIGNED_BYTE, buf); |
+ // Run the verification routine. |
+ if (testCase.verifier(buf, testCase.threshold, testCase.numOccurrences)) |
+ testPassed(testCase.description); |
+ else |
+ testFailed(testCase.description); |
+} |
+ |
+//---------------------------------------------------------------------- |
+// Wrappers for programmatic construction of Image, ImageData and raw texture data |
+// |
+ |
+function ImageWrapper(width, height) |
+{ |
+ this.pngBuilder_ = new PNGlib(width, height, 256); |
+} |
+ |
+ImageWrapper.prototype.getWidth = function() { |
+ return this.pngBuilder_.width; |
+}; |
+ |
+ImageWrapper.prototype.getHeight = function() { |
+ return this.pngBuilder_.height; |
+}; |
+ |
+ImageWrapper.prototype.setPixel = function(x, y, r, g, b, a) { |
+ this.pngBuilder_.buffer[this.pngBuilder_.index(x, y)] = this.pngBuilder_.color(r, g, b, a); |
+}; |
+ |
+// Generates data into "data" property, possibly asynchronously. |
+ImageWrapper.prototype.generateData = function() { |
+ var that = this; |
+ var img = new Image(); |
+ img.onload = function() { |
+ that.data = img; |
+ maybeRunTests(); |
+ }; |
+ img.src = "data:image/png;base64," + this.pngBuilder_.getBase64(); |
+}; |
+ |
+function ImageDataWrapper(width, height) |
+{ |
+ if (!ImageDataWrapper.tempCanvas) { |
+ ImageDataWrapper.tempCanvas = document.createElement("canvas"); |
+ } |
+ this.imageData_ = ImageDataWrapper.tempCanvas.getContext("2d").createImageData(width, height); |
+} |
+ |
+ImageDataWrapper.tempCanvas = null; |
+ |
+ImageDataWrapper.prototype.getWidth = function() { |
+ return this.imageData_.width; |
+}; |
+ |
+ImageDataWrapper.prototype.getHeight = function() { |
+ return this.imageData_.height; |
+}; |
+ |
+ImageDataWrapper.prototype.setPixel = function(x, y, r, g, b, a) { |
+ var index = 4 * (this.imageData_.width * y + x); |
+ this.imageData_.data[index] = r; |
+ this.imageData_.data[index + 1] = g; |
+ this.imageData_.data[index + 2] = b; |
+ this.imageData_.data[index + 3] = a; |
+}; |
+ |
+ImageDataWrapper.prototype.generateData = function() { |
+ this.data = this.imageData_; |
+ maybeRunTests(); |
+}; |
+ |
+function TextureDataWrapper(width, height) |
+{ |
+ this.width_ = width; |
+ this.height_ = height; |
+} |
+ |
+TextureDataWrapper.prototype.getWidth = function() { |
+ return this.width_; |
+}; |
+ |
+TextureDataWrapper.prototype.getHeight = function() { |
+ return this.height_; |
+}; |
+ |
+TextureDataWrapper.prototype.generateData = function() { |
+ this.data = this.data_; |
+ maybeRunTests(); |
+}; |
+ |
+function RGBA8DataWrapper(width, height) |
+{ |
+ TextureDataWrapper.call(this, width, height); |
+ this.data_ = new Uint8Array(4 * width * height); |
+} |
+ |
+RGBA8DataWrapper.prototype = new TextureDataWrapper; |
+ |
+RGBA8DataWrapper.prototype.setPixel = function(x, y, r, g, b, a) { |
+ var index = 4 * (this.width_ * y + x); |
+ this.data_[index] = r; |
+ this.data_[index + 1] = g; |
+ this.data_[index + 2] = b; |
+ this.data_[index + 3] = a; |
+}; |
+ |
+function RGBA5551DataWrapper(width, height) |
+{ |
+ TextureDataWrapper.call(this, width, height); |
+ this.data_ = new Uint16Array(width * height); |
+} |
+ |
+RGBA5551DataWrapper.prototype = new TextureDataWrapper; |
+ |
+RGBA5551DataWrapper.prototype.setPixel = function(x, y, r, g, b, a) { |
+ var value = (((r & 0xF8) << 8) |
+ | ((g & 0xF8) << 3) |
+ | ((b & 0xF8) >> 2) |
+ | (a >> 7)); |
+ this.data_[this.width_ * y + x] = value; |
+}; |
+ |
+function RGBA4444DataWrapper(width, height) |
+{ |
+ TextureDataWrapper.call(this, width, height); |
+ this.data_ = new Uint16Array(width * height); |
+} |
+ |
+RGBA4444DataWrapper.prototype = new TextureDataWrapper; |
+ |
+RGBA4444DataWrapper.prototype.setPixel = function(x, y, r, g, b, a) { |
+ var value = (((r & 0xF0) << 8) |
+ | ((g & 0xF0) << 4) |
+ | (b & 0xF0) |
+ | (a >> 4)); |
+ this.data_[this.width_ * y + x] = value; |
+}; |
+ |
+function RGB8DataWrapper(width, height) |
+{ |
+ TextureDataWrapper.call(this, width, height); |
+ this.data_ = new Uint8Array(3 * width * height); |
+} |
+ |
+RGB8DataWrapper.prototype = new TextureDataWrapper; |
+ |
+RGB8DataWrapper.prototype.setPixel = function(x, y, r, g, b, a) { |
+ var index = 3 * (this.width_ * y + x); |
+ this.data_[index] = r; |
+ this.data_[index + 1] = g; |
+ this.data_[index + 2] = b; |
+}; |
+ |
+function RGB565DataWrapper(width, height) |
+{ |
+ TextureDataWrapper.call(this, width, height); |
+ this.data_ = new Uint16Array(width * height); |
+} |
+ |
+RGB565DataWrapper.prototype = new TextureDataWrapper; |
+ |
+RGB565DataWrapper.prototype.setPixel = function(x, y, r, g, b, a) { |
+ var value = (((r & 0xF8) << 8) |
+ | ((g & 0xFC) << 3) |
+ | ((b & 0xF8) >> 3)); |
+ this.data_[this.width_ * y + x] = value; |
+}; |
+ |
+function A8DataWrapper(width, height) |
+{ |
+ TextureDataWrapper.call(this, width, height); |
+ this.data_ = new Uint8Array(width * height); |
+} |
+ |
+A8DataWrapper.prototype = new TextureDataWrapper; |
+ |
+A8DataWrapper.prototype.setPixel = function(x, y, r, g, b, a) { |
+ this.data_[this.width_ * y + x] = a; |
+}; |
+ |
+function L8DataWrapper(width, height) |
+{ |
+ TextureDataWrapper.call(this, width, height); |
+ this.data_ = new Uint8Array(width * height); |
+} |
+ |
+L8DataWrapper.prototype = new TextureDataWrapper; |
+ |
+L8DataWrapper.prototype.setPixel = function(x, y, r, g, b, a) { |
+ this.data_[this.width_ * y + x] = r; |
+}; |
+ |
+function LA8DataWrapper(width, height) |
+{ |
+ TextureDataWrapper.call(this, width, height); |
+ this.data_ = new Uint8Array(2 * width * height); |
+} |
+ |
+LA8DataWrapper.prototype = new TextureDataWrapper; |
+ |
+LA8DataWrapper.prototype.setPixel = function(x, y, r, g, b, a) { |
+ var index = 2 * (this.width_ * y + x); |
+ this.data_[index] = r; |
+ this.data_[index + 1] = a; |
+}; |
+ |
+//---------------------------------------------------------------------- |
+// Color ramp generation functions |
+// |
+ |
+function generateOpaqueGrayscaleRamp(wrapper) |
+{ |
+ var width = wrapper.getWidth(); |
+ var height = wrapper.getHeight(); |
+ for (var x = 0; x < width; ++x) { |
+ var value = Math.round(255.0 * x / width); |
+ for (var y = 0; y < height; ++y) |
+ wrapper.setPixel(x, y, value, value, value, 255); |
+ } |
+} |
+ |
+function generateTranslucentGrayscaleRamp(wrapper) |
+{ |
+ var width = wrapper.getWidth(); |
+ var height = wrapper.getHeight(); |
+ for (var x = 0; x < width; ++x) { |
+ var value = Math.round(255.0 * x / width); |
+ for (var y = 0; y < height; ++y) |
+ wrapper.setPixel(x, y, value, value, value, value); |
+ } |
+} |
+ |
+function generateTransparentGrayscaleRamp(wrapper) |
+{ |
+ var width = wrapper.getWidth(); |
+ var height = wrapper.getHeight(); |
+ for (var x = 0; x < width; ++x) { |
+ var value = Math.round(255.0 * x / width); |
+ for (var y = 0; y < height; ++y) |
+ wrapper.setPixel(x, y, value, value, value, 0); |
+ } |
+} |
+ |
+//---------------------------------------------------------------------- |
+// Verification routines |
+// |
+ |
+function allChannelsIncreaseByNoMoreThan(array, threshold, numOccurrences) { |
+ var numFound = 0; |
+ for (var i = 4; i < array.length; i += 4) |
+ for (var j = 0; j < 4; j++) |
+ if (array[i + j] - array[i + j - 4] > threshold) |
+ ++numFound; |
+ |
+ return numFound < numOccurrences; |
+} |
+ |
+function alphaChannelIncreasesByNoMoreThan(array, threshold, numOccurrences) { |
+ var numFound = 0; |
+ for (var i = 7; i < array.length; i += 4) |
+ if (array[i] - array[i - 4] > threshold) |
+ ++numFound; |
+ |
+ return numFound < numOccurrences; |
+} |
+ |
+function allChannelsIncreaseByAtLeast(array, threshold, numOccurrences) { |
+ var numFound = 0; |
+ for (var i = 4; i < array.length; i += 4) |
+ for (var j = 0; j < 4; ++j) |
+ if (array[i + j] - array[i + j - 4] > threshold) |
+ ++numFound; |
+ |
+ return numFound > numOccurrences; |
+} |
+ |
+function colorChannelsAreZero(array, threshold, numOccurrences) { |
+ var passed = true; |
+ var numFailures = 0; |
+ |
+ for (var i = 4; i < array.length; i += 4) |
+ for (var j = 0; j < 3; ++j) |
+ if (array[i + j] != 0) { |
+ passed = false; |
+ if (++numFailures <= 5) |
+ debug(" array[" + (i + j) + "] should have been 0, was " + array[i + j]); |
+ } |
+ |
+ return passed; |
+} |
+ |
+</script> |
+</head> |
+<body onload="init()"> |
+<canvas id="example" width="256px" height="1px"></canvas> |
+<div id="description"></div> |
+<div id="console"></div> |
+</body> |
+</html> |
Property changes on: conformance/textures/tex-image-with-format-and-type.html |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |