Use Pre-Compressed DDS in OpenGL – glut

screen_shot8-300x252 This sample program shows us to use pre-compressed dds file with OpenGL. With pre-compressed textures, on the one hand we could reduce the file size on the disk; on the other hand we could improve the texture processing time and better visual quality. We could create mipmaps and do some other quality control settings during pre-compress process. The compressed texture format that should be support by our 3D card.

Let dive into the source code and to see how OpenGL handle those textures that are compressed with DXT1 for ample:

// Missing mipmaps won’t be a problem anymore.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, GLint(m_NbMipmaps) – 1);

// Upload each mipmaps
size_t Offset = 0;
size_t Width = m_Width;
size_t Height = m_Height;

for (size_t i = 0; (i < m_NbMipmaps) && ((Width != 0) || (Height != 0)); ++i) {

    size_t BufSize = ((Width + 3) / 4) * ((Height + 3) / 4) * m_BlockSize;

    glCompressedTexImage2D(GL_TEXTURE_2D, GLint(i), 
        m_Format, GLsizei(Width), GLsizei(Height), 
        0, GLsizei(BufSize), &m_Pixels[Offset]);

    Offset += BufSize;
    if ((Width /= 2) == 0) Width = 1;
    if ((Height /= 2) == 0) Height = 1;
}

As you see from the above code, you set the mip map level and upload the compressed mip map into 3d card. Before this you need to load the compressed dxt1 dds file, load it’s full image content. Here you need to take care of how those mipmap size computed. Obviously, it is not the same way as you computed a normal texture size with texture width, height and bits of each pixel.The whole compressed texture is coded with blocks, you need to figure out how many blocks for the current mipmap.

 

On windows, actually functions glCompressedTexImage2D is not a native function that provided some libraries. Such functions are OpenGL extensions. You could use following code to check whether a given kind of extension is support by your system or not:

char *ext = (char*)glGetString( GL_EXTENSIONS );
// check to whether the 3d card support some texture compression format
if ( strstr( ext, “GL_EXT_texture_compression_s3tc” ) == NULL )
{
// if not, you need do some handling work here
}
if( strstr( ext, “ARB_texture_compression” ) == NULL )
{
// if not, you need to some handling work here
}

 

After that, you could get the function address by the following code:

// Init function pointers
glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) wglGetProcAddress(“glCompressedTexImage2D”);

The reason why we need to some something special on windows is not MS already have D3D, and they do not want to support OpenGL after an certain time.

 

For textures coordinates, OpenGL will take the original (0, 0) at the bottom left corner, but DirectX will place it at the top left corner.  So you may come across some problem, the texture mapping effect appears OK in DirectX, but when come to the OpenGL, you find that textures upside-down. In the downloadable full source package there is a document that will state this problem and figure out how to address it. The main ideas are swapping the blocks in the textures and also swapping pixels in the each texture block.

 

One thing that need to notice is that, this program could not load dds files that compressed by DirectX Texture Tool. I tried to use NVDIA nvcompress tool, it works very well.

 

The full source code could be downloaded frome here. To compile and run this project you need to install VS2008.

posted @ 2012-08-24 07:41  opencoder  阅读(395)  评论(0编辑  收藏  举报