| Name |
| |
| OES_compressed_ETC1_RGB8_texture: |
| |
| Name Strings |
| |
| GL_OES_compressed_ETC1_RGB8_texture |
| |
| Contact |
| |
| Jacob Strom (jacob.strom 'at' ericsson.com) |
| |
| Notice |
| |
| Copyright (c) 2005-2013 The Khronos Group Inc. Copyright terms at |
| http://www.khronos.org/registry/speccopyright.html |
| |
| Specification Update Policy |
| |
| Khronos-approved extension specifications are updated in response to |
| issues and bugs prioritized by the Khronos OpenGL ES Working Group. For |
| extensions which have been promoted to a core Specification, fixes will |
| first appear in the latest version of that core Specification, and will |
| eventually be backported to the extension document. This policy is |
| described in more detail at |
| https://www.khronos.org/registry/OpenGL/docs/update_policy.php |
| |
| IP Status |
| |
| See Ericsson's "IP Statement" |
| |
| Status |
| |
| Ratified by the Khronos BOP, July 22, 2005. |
| |
| Version |
| |
| Last Modified Date: April 24, 2008 |
| |
| Number |
| |
| OpenGL ES Extension #5 |
| |
| Dependencies |
| |
| Written based on the wording of the OpenGL ES 1.0 specification |
| |
| Overview |
| |
| The goal of this extension is to allow direct support of |
| compressed textures in the Ericsson Texture Compression (ETC) |
| formats in OpenGL ES. |
| |
| ETC-compressed textures are handled in OpenGL ES using the |
| CompressedTexImage2D call. |
| |
| The definition of the "internalformat" parameter in the |
| CompressedTexImage2D call has been extended to support |
| ETC-compressed textures. |
| |
| |
| Issues |
| |
| Question: "How does the data format correspond to compressed files |
| created with tool etcpack?" |
| |
| If etcpack is used to convert a .ppm file to this format, the top |
| left pixel in the .ppm image will end up in the first block, which |
| in turn will end up at u=0, v=0 when sent to |
| glCompressedTexImage2D. Thus it works exactly the same way as just |
| sending the raw image data from the .ppm format directly to |
| glTexImage2D. |
| |
| New Procedures and Functions |
| |
| None |
| |
| |
| New Tokens |
| |
| Accepted by the <internalformat> parameter of CompressedTexImage2D |
| |
| ETC1_RGB8_OES 0x8D64 |
| |
| Additions to Chapter 2 of the OpenGL 1.3 Specification (OpenGL |
| Operation) |
| |
| None |
| |
| Additions to Chapter 3 of the OpenGL 1.3 Specification (Rasterization) |
| |
| Add to Table 3.17: Specific Compressed Internal Formats |
| |
| Compressed Internal Formats Base Internal Format |
| =========================== ==================== |
| ETC1_RGB8_OES RGB |
| |
| |
| Add to Section 3.8.3, Alternate Image Specification |
| |
| ETC1_RGB8_OES: |
| ============== |
| |
| If <internalformat> is ETC1_RGB8_OES, the compressed texture is an |
| ETC1 compressed texture. |
| |
| The texture is described as a number of 4x4 pixel blocks. If the |
| texture (or a particular mip-level) is smaller than 4 pixels in |
| any dimension (such as a 2x2 or a 8x1 texture), the texture is |
| found in the upper left part of the block(s), and the rest of the |
| pixels are not used. For instance, a texture of size 4x2 will be |
| placed in the upper half of a 4x4 block, and the lower half of the |
| pixels in the block will not be accessed. |
| |
| Pixel a1 (see Figure 3.9.0) of the first block in memory will |
| represent the texture coordinate (u=0, v=0). Pixel a2 in the |
| second block in memory will be adjacent to pixel m1 in the first |
| block, etc until the width of the texture. Then pixel a3 in the |
| following block (third block in memory for a 8x8 texture) will be |
| adjacent to pixel d1 in the first block, etc until the height of |
| the texture. Calling glCompressedTexImage2D to get an 8x8 texture |
| using the first, second, third and fourth block shown in Figure |
| 3.9.0 would have the same effect as calling glTexImage2D where the |
| bytes describing the pixels would come in the following memory |
| order: a1 e1 i1 m1 a2 e2 i2 m2 b1 f1 j1 n1 b2 f2 j2 n2 c1 g1 k1 o1 |
| c2 g2 k2 o2 d1 h1 l1 p1 d2 h2 l2 p2 a3 e3 i3 m3 a4 e4 i4 m4 b3 f3 |
| j3 n3 b4 f4 j4 n4 c3 g3 k3 o3 c4 g4 k4 o4 d3 h3 l3 p3 d4 h4 l4 p4. |
| |
| The number of bits that represent a 4x4 texel block is 64 bits if |
| <internalformat> is given by ETC1_RGB8_OES. |
| |
| The data for a block is a number of bytes, |
| |
| {q0, q1, q2, q3, q4, q5, q6, q7} |
| |
| where byte q0 is located at the lowest memory address and q7 at |
| the highest. The 64 bits specifying the block is then represented |
| by the following 64 bit integer: |
| |
| int64bit = 256*(256*(256*(256*(256*(256*(256*q0+q1)+q2)+q3)+q4)+q5)+q6)+q7; |
| |
| Each 64-bit word contains information about a 4x4 pixel block as |
| shown in Figure 3.9.1. There are two modes in ETC1; the |
| 'individual' mode and the 'differential' mode. Which mode is |
| active for a particular 4x4 block is controlled by bit 33, which |
| we call 'diffbit'. If diffbit = 0, the 'individual' mode is |
| chosen, and if diffbit = 1, then the 'differential' mode is |
| chosen. The bit layout for the two modes are different: The bit |
| layout for the individual mode is shown in Tables 3.17.1a and |
| 3.17.1c, and the bit layout for the differential mode is laid out |
| in Tables 3.17.1b and 3.17.1c. |
| |
| In both modes, the 4x4 block is divided into two subblocks of |
| either size 2x4 or 4x2. This is controlled by bit 32, which we |
| call 'flipbit'. If flipbit=0, the block is divided into two 2x4 |
| subblocks side-by-side, as shown in Figure 3.9.2. If flipbit=1, |
| the block is divided into two 4x2 subblocks on top of each other, |
| as shown in Figure 3.9.3. |
| |
| In both individual and differential mode, a 'base color' for each |
| subblock is stored, but the way they are stored is different in |
| the two modes: |
| |
| In the 'individual' mode (diffbit = 0), the base color for |
| subblock 1 is derived from the codewords R1 (bit 63-60), G1 (bit |
| 55-52) and B1 (bit 47-44), see Table 3.17.1a. These four bit |
| values are extended to RGB888 by replicating the four higher order |
| bits in the four lower order bits. For instance, if R1 = 14 = |
| 1110b, G1 = 3 = 0011b and B1 = 8 = 1000b, then the red component |
| of the base color of subblock 1 becomes 11101110b = 238, and the |
| green and blue components become 00110011b = 51 and 10001000b = |
| 136. The base color for subblock 2 is decoded the same way, but |
| using the 4-bit codewords R2 (bit 59-56), G2 (bit 51-48)and B2 |
| (bit 43-40) instead. In summary, the base colors for the subblocks |
| in the individual mode are: |
| |
| base col subblock1 = extend_4to8bits(R1, G1, B1) |
| base col subblock2 = extend_4to8bits(R2, G2, B2) |
| |
| In the 'differential' mode (diffbit = 1), the base color for |
| subblock 1 is derived from the five-bit codewords R1', G1' and |
| B1'. These five-bit codewords are extended to eight bits by |
| replicating the top three highest order bits to the three lowest |
| order bits. For instance, if R1' = 28 = 11100b, the resulting |
| eight-bit red color component becomes 11100111b = 231. Likewise, |
| if G1' = 4 = 00100b and B1' = 3 = 00011b, the green and blue |
| components become 00100001b = 33 and 00011000b = 24 |
| respectively. Thus, in this example, the base color for subblock 1 |
| is (231, 33, 24). The five bit representation for the base color |
| of subblock 2 is obtained by modifying the 5-bit codewords R1' G1' |
| and B1' by the codewords dR2, dG2 and dB2. Each of dR2, dG2 and |
| dB2 is a 3-bit two-complement number that can hold values between |
| -4 and +3. For instance, if R1' = 28 as above, and dR2 = 100b = |
| -4, then the five bit representation for the red color component |
| is 28+(-4)=24 = 11000b, which is then extended to eight bits to |
| 11000110b = 198. Likewise, if G1' = 4, dG2 = 2, B1' = 3 and dB2 = |
| 0, the base color of subblock 2 will be RGB = (198, 49, 24). In |
| summary, the base colors for the subblocks in the differential |
| mode are: |
| |
| base col subblock1 = extend_5to8bits(R1', G1', B1') |
| base col subblock2 = extend_5to8bits(R1'+dR2, G1'+dG2, B1'+dG2) |
| |
| Note that these additions are not allowed to under- or overflow |
| (go below zero or above 31). (The compression scheme can easily |
| make sure they don't.) For over- or underflowing values, the |
| behavior is undefined for all pixels in the 4x4 block. Note also |
| that the extension to eight bits is performed _after_ the |
| addition. |
| |
| After obtaining the base color, the operations are the same for |
| the two modes 'individual' and 'differential'. First a table is |
| chosen using the table codewords: For subblock 1, table codeword 1 |
| is used (bits 39-37), and for subblock 2, table codeword 2 is used |
| (bits 36-34), see Table 3.17.1. The table codeword is used to |
| select one of eight modifier tables, see Table 3.17.2. For |
| instance, if the table code word is 010b = 2, then the modifier |
| table [-29, -9, 9 29] is selected. Note that the values in Table |
| 3.17.2 are valid for all textures and can therefore be hardcoded |
| into the decompression unit. |
| |
| Next, we identify which modifier value to use from the modifier |
| table using the two 'pixel index' bits. The pixel index bits are |
| unique for each pixel. For instance, the pixel index for pixel d |
| (see Figure 3.9.1) can be found in bits 19 (most significant bit, |
| MSB), and 3 (least significant bit, LSB), see Table 3.17.1c. Note |
| that the pixel index for a particular texel is always stored in |
| the same bit position, irrespectively of bits 'diffbit' and |
| 'flipbit'. The pixel index bits are decoded using table |
| 3.17.3. If, for instance, the pixel index bits are 01b = 1, and |
| the modifier table [-29, -9, 9, 29] is used, then the modifier |
| value selected for that pixel is 29 (see table 3.17.3). This |
| modifier value is now used to additively modify the base |
| color. For example, if we have the base color (231, 8, 16), we |
| should add the modifier value 29 to all three components: (231+29, |
| 8+29, 16+29) resulting in (260, 37, 45). These values are then |
| clamped to [0, 255], resulting in the color (255, 37, 45), and we |
| are finished decoding the texel. |
| |
| ETC1 compressed textures support only 2D images without |
| borders. CompressedTexture2D will produce an INVALID_OPERATION if |
| <border> is non-zero. |
| |
| |
| Add table 3.17.1: Texel Data format for ETC1 compressed |
| textures: |
| |
| ETC1_RGB8_OES: |
| |
| a) bit layout in bits 63 through 32 if diffbit = 0 |
| |
| 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 |
| ----------------------------------------------- |
| | base col1 | base col2 | base col1 | base col2 | |
| | R1 (4bits)| R2 (4bits)| G1 (4bits)| G2 (4bits)| |
| ----------------------------------------------- |
| |
| 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 |
| --------------------------------------------------- |
| | base col1 | base col2 | table | table |diff|flip| |
| | B1 (4bits)| B2 (4bits)| cw 1 | cw 2 |bit |bit | |
| --------------------------------------------------- |
| |
| |
| b) bit layout in bits 63 through 32 if diffbit = 1 |
| |
| 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 |
| ----------------------------------------------- |
| | base col1 | dcol 2 | base col1 | dcol 2 | |
| | R1' (5 bits) | dR2 | G1' (5 bits) | dG2 | |
| ----------------------------------------------- |
| |
| 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 |
| --------------------------------------------------- |
| | base col 1 | dcol 2 | table | table |diff|flip| |
| | B1' (5 bits) | dB2 | cw 1 | cw 2 |bit |bit | |
| --------------------------------------------------- |
| |
| |
| c) bit layout in bits 31 through 0 (in both cases) |
| |
| 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 |
| ----------------------------------------------- |
| | most significant pixel index bits | |
| | p| o| n| m| l| k| j| i| h| g| f| e| d| c| b| a| |
| ----------------------------------------------- |
| |
| 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 |
| -------------------------------------------------- |
| | least significant pixel index bits | |
| | p| o| n| m| l| k| j| i| h| g| f| e| d| c | b | a | |
| -------------------------------------------------- |
| |
| |
| Add table 3.17.2: Intensity modifier sets for ETC1 compressed textures: |
| |
| table codeword modifier table |
| ------------------ ---------------------- |
| 0 -8 -2 2 8 |
| 1 -17 -5 5 17 |
| 2 -29 -9 9 29 |
| 3 -42 -13 13 42 |
| 4 -60 -18 18 60 |
| 5 -80 -24 24 80 |
| 6 -106 -33 33 106 |
| 7 -183 -47 47 183 |
| |
| |
| Add table 3.17.3 Mapping from pixel index values to modifier values for |
| ETC1 compressed textures: |
| |
| pixel index value |
| --------------- |
| msb lsb resulting modifier value |
| ----- ----- ------------------------- |
| 1 1 -b (large negative value) |
| 1 0 -a (small negative value) |
| 0 0 a (small positive value) |
| 0 1 b (large positive value) |
| |
| |
| |
| Add figure 3.9.0: Pixel layout for a 8x8 texture using four ETC1 |
| compressed blocks. Note how pixel a2 in the second block is |
| adjacent to pixel m in the first block. |
| |
| First block in mem Second block in mem |
| ---- ---- ---- ---- .... .... .... .... --> u direction |
| |a1 |e1 |i1 |m1 |a2 :e2 :i2 :m2 : |
| | | | | | : : : : |
| ---- ---- ---- ---- .... .... .... .... |
| |b1 |f1 |j1 |n1 |b2 :f2 :j2 :n2 : |
| | | | | | : : : : |
| ---- ---- ---- ---- .... .... .... .... |
| |c1 |g1 |k1 |o1 |c2 :g2 :k2 :o2 : |
| | | | | | : : : : |
| ---- ---- ---- ---- .... .... .... .... |
| |d1 |h1 |l1 |p1 |d2 :h2 :l2 :p2 : |
| | | | | | : : : : |
| ---- ---- ---- ---- ---- ---- ---- ---- |
| :a3 :e3 :i3 :m3 |a4 |e4 |i4 |m4 | |
| : : : : | | | | | |
| .... .... .... .... ---- ---- ---- ---- |
| :b3 :f3 :j3 :n3 |b4 |f4 |j4 |n4 | |
| : : : : | | | | | |
| .... .... .... .... ---- ---- ---- ---- |
| :c3 :g3 :k3 :o3 |c4 |g4 |k4 |o4 | |
| : : : : | | | | | |
| .... .... .... .... ---- ---- ---- ---- |
| :d3 :h3 :l3 :p3 |d4 |h4 |l4 |p4 | |
| : : : : | | | | | |
| .... .... .... .... ---- ---- ---- ---- |
| | Third block in mem Fourth block in mem |
| v |
| v direction |
| |
| Add figure 3.9.1: Pixel layout for a ETC1 compressed block: |
| |
| ---- ---- ---- ---- |
| |a |e |i |m | |
| | | | | | |
| ---- ---- ---- ---- |
| |b |f |j |n | |
| | | | | | |
| ---- ---- ---- ---- |
| |c |g |k |o | |
| | | | | | |
| ---- ---- ---- ---- |
| |d |h |l |p | |
| | | | | | |
| ---- ---- ---- ---- |
| |
| |
| Add figure 3.9.2: Two 2x4-pixel subblocks side-by-side: |
| |
| |
| subblock 1 subblock 2 |
| ---- ---- ---- ---- |
| |a e |i m | |
| | | | |
| | | | |
| |b f |j n | |
| | | | |
| | | | |
| |c g |k o | |
| | | | |
| | | | |
| |d h |l p | |
| | | | |
| ---- ---- ---- ---- |
| |
| |
| Add figure 3.9.3: Two 4x2-pixel subblocks on top of each other: |
| |
| ---- ---- ---- ---- |
| |a e i m | |
| | | |
| | | subblock 1 |
| |b f j n | |
| | | |
| ------------------- |
| |c g k o | |
| | | |
| | | subblock 2 |
| |d h l p | |
| | | |
| ---- ---- ---- ---- |
| |
| |
| Additions to Chapter 4 of the OpenGL 1.3 Specification (Per-Fragment |
| Operations and the Frame Buffer) |
| |
| None |
| |
| Additions to Chapter 5 of the OpenGL 1.3 Specification (Special |
| Functions) |
| |
| None |
| |
| |
| Additions to Chapter 6 of the OpenGL 1.3 Specification (State and |
| State Requests) |
| |
| None |
| |
| Additions to Appendix A of the OpenGL 1.3 Specification (Invariance) |
| |
| None |
| |
| Additions to the AGL/GLX/WGL Specification |
| |
| None |
| |
| GLX Protocol |
| |
| None |
| |
| Errors |
| |
| INVALID_OPERATION is generated by CompressedTexSubImage2D, |
| TexSubImage2D, or CopyTexSubImage2D if the texture image <level> |
| bound to <target> has internal format ETC1_RGB8_OES. |
| |
| New State |
| |
| The queries for NUM_COMPRESSED_TEXTURE_FORMATS and |
| COMPRESSED_TEXTURE_FORMATS include ETC1_RGB8_OES. |
| |
| |
| Revision History |
| 04/20/2005 0.1 (Jacob Strom) |
| - Original draft. |
| 04/26/2005 0.2 (Jacob Strom) |
| - Minor bugfixes. |
| 05/10/2005 0.3 (Jacob Strom) |
| - Minor bugfixes. |
| 06/30/2005 0.9 (Jacob Strom) |
| - Merged iPACKMAN and iPACKMANalpha. |
| 07/04/2005 0.92 (Jacob Strom) |
| - Changed name from iPACKMAN to Ericsson Texture Compression |
| 07/07/2005 0.98 (Jacob Strom) |
| - Removed alpha formats |
| 07/27/2005 1.00 (Jacob Strom) |
| - Added token value for ETC1_RGB8_OES |
| 07/28/2005 1.001 (Jacob Strom) |
| - Changed typos found by Eric Fausett |
| 10/25/2006 1.1 (Jacob Strom) |
| - Added clarification on small textures and endianess |
| 04/02/2008 1.11 (Jacob Strom) |
| - Added clarification on coordinate system orientation |
| 04/24/2008 1.12 (Jacob Strom) |
| - Improve error description |