tags:

views:

604

answers:

2

Any idea whats wrong with my code? when i execute glCompressedTexImage2D() the program just crashes (comes the Windows XP crash message thing...)

Im trying to load DDS image without mipmaps, the image format is DDS DXT1

Am i missing some include file, or what did i do wrong? I downloaded the included files from: http://sourceforge.net/projects/glew/files/glew/1.5.1/glew-1.5.1-win32.zip/download

I have glew32.dll in the same folder as my .exe is.

The code below has only the parts i changed to be able to load DDS images:

#pragma comment(lib, "glew32.lib")
#include <GL\glew.h>
#include <GL\gl.h>


...


typedef struct {
    GLuint dwSize;
    GLuint dwFlags;
    GLuint dwFourCC;
    GLuint dwRGBBitCount;
    GLuint dwRBitMask;
    GLuint dwGBitMask;
    GLuint dwBBitMask;
    GLuint dwABitMask;
} DDS_PIXELFORMAT;

typedef struct {
    GLuint dwMagic;
    GLuint dwSize;
    GLuint dwFlags;
    GLuint dwHeight;
    GLuint dwWidth;
    GLuint dwLinearSize;
    GLuint dwDepth;
    GLuint dwMipMapCount;
    GLuint dwReserved1[11];
    DDS_PIXELFORMAT ddpf;
    GLuint dwCaps;
    GLuint dwCaps2;
    GLuint dwCaps3;
    GLuint dwCaps4;
    GLuint dwReserved2;
} DDS_HEADER;

DDS_HEADER DDS_headers;


...


FILE *fp = fopen("test.dds", "rb");
fread(&DDS_headers, 1, sizeof(DDS_headers), fp);

img_width = DDS_headers.dwWidth;
img_height = DDS_headers.dwHeight;

maxsize = (img_width*img_height)/2;
unsigned char *imgdata = (unsigned char *)malloc(maxsize);

fread(imgdata, 1, maxsize, fp);

fclose(fp);

GLuint texID;

glGenTextures(1, &texID);
glBindTexture(GL_TEXTURE_2D, texID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_PALETTE4_R5_G6_B5_OES, img_width, img_height, 0, maxsize, imgdata);
// NOTICE:
// Ive also tried with function:
// glCompressedTexImage2DARB();
// and internalformats: GL_COMPRESSED_RGB_S3TC_DXT1_EXT and all of the possible formats... its not a format error.
+1  A: 

The format argument that you're passing to glCompressedTexImage2D looks a bit odd:

glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_PALETTE4_R5_G6_B5_OES, img_width, img_height, 0, maxsize, imgdata);

I think this is neither a paletted texture, nor an OpenGL ES extension. Perhaps something like GL_COMPRESSED_RGB_S3TC_DXT1_EXT would work better.

prideout
i have tried with that too, and all the possible format types you can give there, every of them results in a crash.
Make sure your OpenGL implementation supports the DXT1 extension. You can do so by calling the glewIsSupported function and passing in the following string: "EXT_texture_compression_dxt1".
prideout
glewIsSupported("EXT_texture_compression_dxt1") returns false :/ what can i do to get this thing working?
Woops, I forgot the GL_ prefix; try GL_EXT_texture_compression_dxt1. If it still returns false, then your platform doesn't support DXT1 compression, so you'll need to convert your source data to some other format.
prideout
yeah still returns false, i dont quite understand how this is going to help me to make this DDS thing to work?what code you use to use DDS images in your applications? can you share it?my GFX card surely supports DDS, thats a fact.
A: 

I remember messing with the DDS loader in glew, I don't think the header information there is correct. I never could get it to work correctly.

The best way would be to use the header contstucts that are in DDraw.h here's what I was able to use for DXT1,3,and 5, which if I remember correctly are the only ones that can work in OpenGL.

    struct DDS_IMAGE_DATA
    {
           GLsizei  width;
            GLsizei  height;
            GLint    components;
            GLenum   format;
            int      numMipMaps;
            GLubyte *pixels;
    };

        DDS_IMAGE_DATA* CImage::loadDDSTextureFile( const char *filename )
        {
            DDS_IMAGE_DATA *pDDSImageData;
            DDSURFACEDESC2 ddsd;
            char filecode[4];
            FILE *pFile;
            int factor;
            int bufferSize;

            // Open the file
            pFile = fopen( filename, "rb" );

            if( pFile == NULL )
            { 
             #if DEBUG
             char str[255];
             printf( str, "loadDDSTextureFile couldn't find, or failed to load \"%s\"", filename );
             #endif
             return NULL;
            }

            // Verify the file is a true .dds file
            fread( filecode, 1, 4, pFile );

            if( strncmp( filecode, "DDS ", 4 ) != 0 )
            {
             #if DEBUG
             char str[255];
             printf( str, "The file \"%s\" doesn't appear to be a valid .dds file!", filename );
             #endif
             fclose( pFile );
             return NULL;
            }

            // Get the surface descriptor
            fread( &ddsd, sizeof(ddsd), 1, pFile );

            pDDSImageData = (DDS_IMAGE_DATA*) malloc(sizeof(DDS_IMAGE_DATA));

            memset( pDDSImageData, 0, sizeof(DDS_IMAGE_DATA) );

            //
            // This .dds loader supports the loading of compressed formats DXT1, DXT3 
            // and DXT5.
            //

            switch( ddsd.ddpfPixelFormat.dwFourCC )
            {
            case FOURCC_DXT1:
             // DXT1's compression ratio is 8:1
             pDDSImageData->format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
             factor = 2;
             break;

            case FOURCC_DXT3:
             // DXT3's compression ratio is 4:1
             pDDSImageData->format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
             factor = 4;
             break;

            case FOURCC_DXT5:
             // DXT5's compression ratio is 4:1
             pDDSImageData->format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
             factor = 4;
             break;

            default:

             #if DEBUG
             char str[255];
             printf( str, "The file \"%s\" doesn't appear to be compressed "
              "using DXT1, DXT3, or DXT5!", filename );
             #endif
             return NULL;
            }

            //
            // How big will the buffer need to be to load all of the pixel data 
            // including mip-maps?
            //

            if( ddsd.dwLinearSize == 0 )
            {
             #if DEBUG
             printf("dwLinearSize is 0!");
             #endif
            }

            if( ddsd.dwMipMapCount > 1 )
             bufferSize = ddsd.dwLinearSize * factor;
            else
             bufferSize = ddsd.dwLinearSize;

            pDDSImageData->pixels = (unsigned char*)malloc(bufferSize * sizeof(unsigned char));

            fread( pDDSImageData->pixels, 1, bufferSize, pFile );

            // Close the file
            fclose( pFile );

            pDDSImageData->width      = ddsd.dwWidth;
            pDDSImageData->height     = ddsd.dwHeight;
            pDDSImageData->numMipMaps = ddsd.dwMipMapCount;

            if( ddsd.ddpfPixelFormat.dwFourCC == FOURCC_DXT1 )
             pDDSImageData->components = 3;
            else
             pDDSImageData->components = 4;

            return pDDSImageData;
        }

void CImage::loadDDS(const char * szFilename, tTexture & texData)
{
    DDS_IMAGE_DATA *pDDSImageData = loadDDSTextureFile(szFilename);

    if( pDDSImageData != NULL )
    {
     texData.m_nHeight = pDDSImageData->height;
     texData.m_nWidth  = pDDSImageData->width;
     texData.m_nHeight = pDDSImageData->height;
     texData.m_eFormat = pDDSImageData->format;
     int nHeight = pDDSImageData->height;
     int nWidth = pDDSImageData->width;

     int nNumMipMaps = pDDSImageData->numMipMaps;
     int nBlockSize;

     if( pDDSImageData->format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT )
      nBlockSize = 8;
     else
      nBlockSize = 16;

     //glGenTextures( 1, &g_compressedTextureID );
     //glBindTexture( GL_TEXTURE_2D, g_compressedTextureID );

     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

     int nSize;
     int nOffset = 0;

     // Load the mip-map levels

     for( int i = 0; i < nNumMipMaps; ++i )
     {
      if( nWidth  == 0 ) nWidth  = 1;
      if( nHeight == 0 ) nHeight = 1;

      nSize = ((nWidth+3)/4) * ((nHeight+3)/4) * nBlockSize;

      glCompressedTexImage2DARB( GL_TEXTURE_2D,
       i,
       pDDSImageData->format,
       nWidth,
       nHeight,
       0,
       nSize,
       pDDSImageData->pixels + nOffset );

      nOffset += nSize;

      // Half the image size for the next mip-map level...
      nWidth  = (nWidth  / 2);
      nHeight = (nHeight / 2);
     }
    }

    if( pDDSImageData != NULL )
    {
     if( pDDSImageData->pixels != NULL )
      free( pDDSImageData->pixels );

     free( pDDSImageData );
    }
}

This particular bit of code makes a few assumptions of the DDS file we are trying to load, first that is is a compressed file, either DXT1,3, or 5, and that the DDS file has pre-generated mipmaps saved in it, hence we don't have to generate them ourselves.

I hope this was able to help you it took me some time to get it working correctly myself. If there's anything in this code snippet that seems unclear, let me know and I'll help you further.

Brandorf
Thanks for your help, but i've tested my headers and they are fine, i copied them from MSDN, and since i only use width/height in my code there cant be header related errors, plus i've tested with static numbers without using headers at all. I noticed your code has RGBA, so i tried with it too, but that didnt make any difference... I cant test your code because i dont have the needed type definitions: CImage, tTexture, DDSURFACEDESC2, FOURCC_DXT1, FOURCC_DXT3, FOURCC_DXT5. Anyways, cant i use DDS images unless i make miplevels in them?