WEBGL_compress_texture
WebGL working group (public_webgl 'at' khronos.org)
Members of the WebGL working group
Last modified date: January 27, 2022
Revision: 4
WebGL extension #NN
Written against the WebGL API 1.0 specification.
This extension exposes compressed texture functionality to WebGL.
In WebGL we can not expose compressed texture formats directly to authors because web content is supposed to work everywhere. This proposal leaves the compression formats up to the WebGL implementation in an opaque way. The user provides hints to the implemenation on what kind of compression is appropriate and it is up to the WebGL implemenation to decide on a compression format or possibly no compression at all.
Because compression can be a slow the process of compression is handled asynchronously. The user provides that data as an image, video, canvas or ArrayBufferView. The implementation then compressed the image and returns a WebGLCompressedTexture object. That object can then be passed to the standard compressedTexImage2D function although with unneeded argements removed.
All forms are asynchronous. When compression is finished the callback
is called and passed a WebGLCompressedTexture
object which can then be used with compressedTexImage2D
.
compressTexture
takes 5 forms. The first form takes an ArrayBufferView
.
The width
, height
, format
, and type
arguments have the same meaning as they do in texImage2D
. They describe the format
of the pixels in the ArrayBufferView
.
The other 4 forms of compressTexture
take an ImageData
,
HTMLImageElement
, HTMLCanvasElement
, or an HTMLVideoElement
repsectively. As such they derive width, height, type and format from the element.
usage
is a kind of hint to the implementation to help it choose a
compression format. usage
is some logical OR of the following bits
PRESERVE_ALPHA
PRESERVE_TRANSPARENCY
PRESERVE_RGB
The implementation must choose a compression format that respects the usage
argument.
If no such compression format is available the implementation must choose an uncompressed format.
interface WebGLCompressedTexture : WebGLObject { readonly attribute long size; readonly attribute GLenum error; }; interface WEBGL_compress_texture { const GLenum PRESERVE_ALPHA = 0x0001; const GLenum PRESERVE_TRANSPARENCY = 0x0002; const GLenum PRESERVE_RGB = 0x0004; compressTexture(GLenum usage, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView pixels, Function callback); compressTexture(GLenum usage, ImageData pixels, Function callback); compressTexture(GLenum usage, HTMLImageElement image, Function callback); compressTexture(GLenum usage, HTMLCanvasElement canvas, Function callback); compressTexture(GLenum usage, HTMLVideoElement video, Function callback); compressedTexImage2D(GLenum target, GLint level, GLint border, WebGLCompressedTexture pixels); };
Errors are returned on the WebGLCompressedTexture object's error
attribute.
error
is set to INVALID_VALUE
if
width
or height
would generate an INVALID_VALUE
when calling
texImage2D.
error
is set to INVALID_ENUM
if type or format is not one of the types
or formats excepted by texImage2D.
error
is set to INVALID_OPERATION
if the size of the ArrayBufferView
is
not greater than or equal to the size of the data described by width, height, format and type.
Should the spec define what is acceptable compression? For example PRESERVE_TRANSPARENCY basically means use DXT1 where as PRESERVE_ALPHA means use DXT5 on systems that support those formats. On systems with no compression using 5_6_5 or 5_5_5_1 is also fine assuming PRESERVE_ALPHA is not requested. Is 5_6_5 okay for PRESERVE_RGB? Is 4_4_4_4 ok for PRESERVE_ALPHA?
The callback
is always called and passed a WebGLCompressedTexture
object. If there was an error
the error
attribute will be set to standard GL error value. Otherwise it is set to NO_ERROR
.
size
is the number of bytes used by the compressed texture. It will be 0 if there was an error.
Passing a WebGLCompressedTexture
who's error
attribute is not NO_ERROR
to compressTexImage2D
generates INVALID_OPERATION
.
compressedTexSubImage2D is not implemented.
texSubImage2D
and copyTexSubImage2D
must both fail on textures created with compressedTexImage2D
.
For consistency this is true even if the implementation did not actually compress the texture.
Rendering to a framebuffer object with an attached texture created by compressedTexImage2D
must fail
with INVALID_FRAMEBUFFER_OPERATION
even if the implemenation did not actually compress the texture.
compressTexture
must succeed for all valid dimensions defined by gl.getParameter(gl.MAX_TEXTURE_SIZE).
That means for example a 7x5 texture passed to compressTexture on a system who's texture compression
format requires textures that are a multiple of 4 or 8 in each dimension would choose not to compress
a 7x5 texture but instead provide it uncompressed or in some other format that can handle a 7x5 texture.
If both PRESERVE_ALPHA
and PRESERVE_TRANSPARENCY
are specified
PRESERVE_ALPHA
takes precedence. In other words the implemention must choose
a compression format with more than 1 bit of alpha.
Revision 1, 2011/04/04
Revision 2, 2011/04/05
Revision 3, 2012/01/03
Revision 4, 2022/01/27