Jump to content

  • Log In with Google      Sign In   
  • Create Account


Problem loading compressed DDS without pre-generated mipmaps


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
4 replies to this topic

#1 Jean-Claude   Members   -  Reputation: 103

Like
0Likes
Like

Posted 26 February 2013 - 12:57 PM

Hi everyone, 

 

I am currently working at rendering bitmap fonts. For that I want to load dds textures. Now the program I use creates these dds files without any mipmaps, but the dds-loader I used before for some model textures seems to only work with pre-generated mipmaps.  

 

This is my loader:

 

 

 

    //    structures for reading and information variables
    char magic[4];
    unsigned char header[124];
    unsigned int width, height, linearSize, mipMapCount, fourCC;
    unsigned char* dataBuffer;
    unsigned int bufferSize;


    fstream file(path, ios::in|ios::binary);


    //    read magic and header
    if (!file.read((char*)magic, sizeof(magic))){
        cerr<< "File " << path << " not found!"<<endl;
        return false;
    }


    if (magic[0]!='D' || magic[1]!='D' || magic[2]!='S' || magic[3]!=' '){
        cerr<< "File does not comply with dds file format!"<<endl;
        return false;
    }


    if (!file.read((char*)header, sizeof(header))){
        cerr<< "Not able to read file information!"<<endl;
        return false;
    }


    //    derive information from header
    height = *(int*)&(header[8]);
    width = *(int*)&(header[12]);
    linearSize = *(int*)&(header[16]);
    mipMapCount = *(int*)&(header[24]);
    fourCC = *(int*)&(header[80]);


    //    determine dataBuffer size
    bufferSize = mipMapCount > 1 ? linearSize * 2 : linearSize;
    dataBuffer = new unsigned char [bufferSize*2];


    //    read data and close file
    if (file.read((char*)dataBuffer, bufferSize/1.5))
        cout<<"Loading texture "<<path<<" successful"<<endl;
    else{
        cerr<<"Data of file "<<path<<" corrupted"<<endl;
        return false;
    }


    file.close();


    //    check pixel format
    unsigned int format;


    switch(fourCC){
    case FOURCC_DXT1:
        format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
        break;
    case FOURCC_DXT3:
        format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
        break;
    case FOURCC_DXT5:
        format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
        break;
    default:
        cerr << "Compression type not supported or corrupted!" << endl;
        return false;
    }


    glGenTextures(1, &ID);


    glBindTexture(GL_TEXTURE_2D, ID);
    glPixelStorei(GL_UNPACK_ALIGNMENT,1);
    //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAX_LEVEL,0);


    unsigned int blockSize = (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) ? 8 : 16;
    unsigned int offset = 0;


    /* load the mipmaps */
    for (unsigned int level = 0; level < mipMapCount && (width || height); ++level) {
        unsigned int size = ((width+3)/4)*((height+3)/4)*blockSize;
        glCompressedTexImage2D(GL_TEXTURE_2D, level, format, width, height,
                            0, size, dataBuffer + offset);


        offset += size;
        width  /= 2;
        height /= 2;
    }




    textureType = DDS_TEXTURE;


    return true;
 

Now if there are no mipmaps, mipMapCount is equal to 0, and the loop does not start. I tried to set the glTexParameter and increased mipMapCount manually, but didn't really work(it showed only the "d" of "Hello World!" for some reason XD). So I'm kinda stuck now. 

 

I think somewhere I have to manually create the mipmaps with glGenerateMipmap but I'm not sure where and in what why the loop still works then.

 

I hope someone can help me out here. 
 

Thanks in advance. 



Sponsor:

#2 blueshogun96   Crossbones+   -  Reputation: 888

Like
0Likes
Like

Posted 27 February 2013 - 07:36 AM

Well, glCompressedTexImage2D has to get called one way or another.  Try this:

 

for (unsigned int level = 0; level < (mipMapCount+1) && (width || height); ++level) {

 

This way, the top level mipmap level always gets set.  Textures that don't use/need mipmaps still need level 0 accounted for.  It appears that you were setting every mip level except for the last.  Keep in mind that the mipMapCount represents the mipmap levels "besides" the top level, which is always 0.  Try this and make sure it works. ^^

 

Shogun.


Follow Shogun3D on the official website: http://shogun3d.net

 

blogger.png twitter.png tumblr_32.png facebook.png


#3 Jean-Claude   Members   -  Reputation: 103

Like
0Likes
Like

Posted 27 February 2013 - 09:21 AM

Thanks for your answer. 

 

Well this kind of works. Somehow only a few of my chars get drawn then, others are just invisible/(black if no transparency) so the texture is not loaded correctly there. 



#4 Jean-Claude   Members   -  Reputation: 103

Like
0Likes
Like

Posted 27 February 2013 - 04:48 PM

Okay I solved it. 

 

In case the texture had no pre-generated mipmaps, the data was only read partly because the bufferSize was devided by 1.5, which is needed for the case with mipmaps.

The solution was therefore to replace this code

 

 

 

//    determine dataBuffer size
    bufferSize = mipMapCount > 1 ? linearSize * 2 : linearSize;
    dataBuffer = new unsigned char [bufferSize*2];


    //    read data and close file
    if (file.read((char*)dataBuffer, bufferSize/1.5))
        cout<<"Loading texture "<<path<<" successful"<<endl;
 

by this code

 

 

 

//    determine dataBuffer size
    bufferSize = mipMapCount > 1 ? linearSize * 2 : linearSize * 1.5;
    dataBuffer = new unsigned char [bufferSize*2];


    //    read data and close file
    if (file.read((char*)dataBuffer, bufferSize/1.5))
        cout<<"Loading texture "<<path<<" successful"<<endl;
 

Thanks for your help.



#5 blueshogun96   Crossbones+   -  Reputation: 888

Like
0Likes
Like

Posted 28 February 2013 - 02:03 AM

My pleasure.  And thank you for posting this.  Even I learned something today!

 

Shogun


Follow Shogun3D on the official website: http://shogun3d.net

 

blogger.png twitter.png tumblr_32.png facebook.png





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS