Problem using Ericsson compression texture

I am developing an application which uses “Ericsson Texture Compression format” for texturing in OpenGL ES 1.1.

Unfortunately I always end up with “GL_INVALID_VALUE” error while I call “glCompressedTexImage2D”. I also tried varying the parameters but I was not successful.

The sample texture in ETC format was created using PVRTtools and also I am using licensed libraries.

The texture header is as below:

GLuint etc_texture[] = {
/* Header /
0x00000034, /
dwHeaderSize /
0x00000100, /
dwHeight /
0x00000100, /
dwWidth /
0x00000008, /
dwMipMapCount /
0x00000136, /
dwpfFlags /
0x0000aab8, /
dwDataSize /
0x00000004, /
dwBitCount /
0xffffffff, /
dwRBitMask /
0xffffffff, /
dwGBitMask /
0xffffffff, /
dwBBitMask /
0x00000000, /
dwAlphaBitMask /
0x21525650, /
dwPVR /
0x00000001, /
dwNumSurfs /
/
Data stream follows */
};

I call the below in my application which gives me “GL_INVALID_VALUE” error

glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_ETC1_RGB8_OES, 256, 256, 0, 0xaab8, (etc_texture + 52)); //52 being size of the header.

It would be very useful if anyone can help me solve the problem.

Thank you.

Either use “+13” instead of “+52” or “((GLubyte*)etc_texture) + 13”. Because etc_texture is an GLuint-array “etc_texture + 52” will return a pointer 208 (52*sizeof(etc_texture[0])) bytes past etc_texture. Pointer arithmetic in C/C++ operates in units of the datatype-size.

Thank you kusma for the reply.

Unfortunately that too doesn’t work.

I suppose you are checking that the device you are targeting actually supports OES_compressed_ETC1_RGB8_texture?

Apart from that, the size parameter you use is incorrect. The dwDataSize field in the header is the size of the entire mipmap chain, but what you need to pass to glCompressedTexImage2D is the size of a single mipmap level. The PVRTools library in the PowerVR SDK contains functions which will load textures in PVR format correctly.

However, in case you want to do it in your own code:

GLuint width = etc_texture[2];
GLuint height = etc_texture[1];
GLuint levels = etc_texture[3];
char* data = (char*) &etc_texture[13];
for (int level = 0; level < levels; ++level)
{
    // Calculate mipmap byte size based on 4x4 blocks, 8 bytes each
    GLuint size = 8 * ((width + 3) >> 2) * ((height + 3) >> 2);
    glCompressedTexImage2D(GL_TEXTURE_2D, level, GL_ETC1_RGB8_OES, width, height, 0, size, data);
    data += size;
    width = MAX(1, width >> 1);
    height = MAX(1, height >> 1;
}

Thank you very much for the solution.

The problem is solved.