PDA

View Full Version : Fault with Compressed PBO texture loader



DWilson
05-26-2009, 06:39 PM
I am working with compressed textures, which i have loaded successfully using the pixel pointer with glCompressedTexImage2DARB, but unfortunately when I use the PBO texture upload, it comes up wrong :( .

Now I am working with PBO's. I have tried with this code

snip example code


void CreateTexture(Image* imagedata)
{
switch(imagedata->v_pixelformat)
{
case COMPRESSED_DXT1:
gl_internalformat=GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ;
gl_format=GL_RGBA;
break;
case COMPRESSED_DXT3:
gl_internalformat=GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ;
gl_format=GL_RGBA;
break;
case COMPRESSED_DXT5:
gl_internalformat=GL_COMPRESSED_RGBA_S3TC_DXT5_EXT ;
gl_format=GL_RGBA;
break;
}

glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);

glGenBuffersARB(1,&pBuf_GL);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pBuf_GL);
glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, imagedata->imageSize, NULL, GL_STATIC_DRAW_ARB);

glGenTextures(1,&ID);
glBindTexture(GL_TEXTURE_2D, ID);

iOffset = 0;

int iWidth = imagedata->GetWidth();
int iHeight = imagedata->GetHeight();
unsigned int iNumMipMaps = imagedata->num_mipmaps;

blockSize=(imagedata->v_pixelformat == V_COMPRESSED_DXT1) ? 8 : 16;

if(iNumMipMaps < 2)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
else
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}

for(Vuint i=0; i<iNumMipMaps; i++)
{
iSize = ((iWidth + 3) / 4) * ((iHeight + 3) / 4) * blockSize;
glCompressedTexImage2DARB(GL_TEXTURE_2D, i, gl_internalformat, iWidth, iHeight, 0, iSize, NULL);
iOffset += iSize;

iWidth /= 2;
iHeight /= 2;
}

unsigned char* tembuffer = glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB);
memcpy(tempbuffer,imagedata->pixels,
glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB);
}

void BindTexture(Image* imagedata)
{
glBindTexture (GL_TEXTURE_2D, ID);
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pBuf_GL);

int iOffset=0;
int iWidth = imagedata->GetWidth();
int iHeight = imagedata->GetHeight();
int iSize;

for(Vuint i = 0; i < texture->v_num_mipmaps; i++)
{
iSize = ((iWidth + 3) / 4) * ((iHeight + 3) / 4) * blockSize;
glCompressedTexSubImage2DARB(GL_TEXTURE_2D,i,0,0, iWidth, iHeight,gl_format, iSize,BUFFER_OFFSET(iOffset));

iOffset += iSize;
iHeight /= 2;
iHeight /= 2;
}
}

When I place...
glCompressedTexImage2DARB(GL_TEXTURE_2D, i, gl_internalformat, iWidth, iHeight, 0, iSize, pixels);
The texture comes out right, but if I PBO the texture (by leaving the pixel data pointer NULL) it comes with a bitmap dump.

I was wondering if it is how I have used the glCompressedTexSubImage function which most likely be faulty. Does anybody know where the fault is in this code...

Thank you

Dark Photon
05-27-2009, 06:38 PM
...unfortunately when I use the PBO texture upload, it comes up wrong...When I place...
glCompressedTexImage2DARB(GL_TEXTURE_2D, i, gl_internalformat, iWidth, iHeight, 0, iSize, pixels);
The texture comes out right, but if I PBO the texture (by leaving the pixel data pointer NULL) it comes with a bitmap dump.

IIRC, the spec doesn't allow for (and some vendors' implementation crashes/misbehaves when) passing a NULL pointer (http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Board=3&Number=159972) to glCompressedTexImage2D (http://www.opengl.org/sdk/docs/man/xhtml/glCompressedTexImage2D.xml), but you can get what you want by calling glTexImage2D (http://www.opengl.org/sdk/docs/man/xhtml/glTexImage2D.xml) with the right internal format and no buffer bound and a NULL pointer to force-allocate the MIPmaps, then call glCompressedTexSubImage2D to slap the compressed texel data in there. This NULL pointer is hopefully not a problem when a PBO is bound, but I mentioned this just in case. If none of the below fixes it, investigate this last.

Also, you've got that NULL (i.e. PBO offset 0) in a for loop to load all MIPmaps, no? So you're going to try to load all the MIPmap level texels from the DXT blocks at the front of the base map (level 0) only. Probably want BUFFER_OFFSET(iOffset) instead.

And the Map/memcpy/Unmap thing at the end puzzles me. Don't know what you're trying to accomplish there, but in the interests of pipelining, might want to stick a glBufferData( GL_PIXEL_UNPACK_BUFFER_ARB, pbo_size, 0, GL_STREAM_DRAW ); before it so GL can use another buffer.

Also, in your glCompressedTexSubImage2D (http://www.opengl.org/sdk/docs/man/xhtml/glCompressedTexSubImage2D.xml) call, your "format" parameter needs to be the actual format of the data. You're providing GL_RGBA (ambiguous and incorrect if your data is already DXT compressed), when you probably mean it to be GL_COMPRESSED_RGBA_S3TC_DXT?.

Also, your Map memcpy got chopped, but I'm not convinced you're not trashing your PBO contents right there.

Also, in your last subload loop, you're dividing iHeight by 2 twice, but not adjusting iWidth.

And try sticking some glGetError() checks in there -- you might find something.