How are .dds files loaded?

Newbie Spellweaver
Joined
Oct 22, 2008
Messages
53
Reaction score
0
How are the texture .dds files loaded onto models? If anyone could go ahead and grab the code where it loads the dds files onto the models, PM me it. I just need to study how they are loaded in C++ so I can use it for my Java FlyFF.
Don't go all screaming at me, I know they are probably completely different, but I understand some C++ so I'd probably be able to convert it.
-Thanks.
 
I can't speak for Java, but in C# with XNA you would define and load a DDS texture like
this.

PHP:
Texture2D.FromFile(graphics.GraphicsDevice, "Randomtexture.dds")


---------- Post added at 01:00 AM ---------- Previous post was at 12:58 AM ----------

Edit - after a bit of research I've discovered this


I skimmed it and it seems like it loads DDSFiles and displays them to the screen.
Hope this is what you were looking for.
 
Useing this in c++ opengl
Returns -1 if it couldnt load the file.
Load the whole file to a char array, and pass it to this function.

Code:
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glaux.h>
#include <ddraw.h>
#include "glext.h"

#define FOURCC_DXT1_REV  (MAKEFOURCC('1','T','X','D'))
#define FOURCC_DXT2_REV  (MAKEFOURCC('2','T','X','D'))
#define FOURCC_DXT3_REV  (MAKEFOURCC('3','T','X','D'))
#define FOURCC_DXT4_REV  (MAKEFOURCC('4','T','X','D'))
#define FOURCC_DXT5_REV  (MAKEFOURCC('5','T','X','D'))

GLuint loadCompressedTexture(const char *file)
{
	GLenum format=0;
    int nBlockSize=-1;

    GLuint tID = -1;
	char *puffer2=0, *p;
	bool compressed=false;
	int type;
	int a,r,g,b,c,d;

    if( (file[0]!='D')||(file[1]!='D')||(file[2]!='S') )
    {
        logger.log( "DDS header error\n");
        return -1;
    }

    DDSURFACEDESC2 &ddsd = *(DDSURFACEDESC2*)(&file[4]);
    int nHeight     = ddsd.dwHeight;
	int nWidth      = ddsd.dwWidth;
    int nNumMipMaps = ddsd.dwMipMapCount;

    switch( ddsd.ddpfPixelFormat.dwFourCC )
    {
        case FOURCC_DXT1:
		case FOURCC_DXT1_REV:
            format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
			nBlockSize = 8;
			compressed=true;
            break;

        case FOURCC_DXT3:
		case FOURCC_DXT3_REV:
            format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
			nBlockSize = 16;
			compressed=true;
            break;

        case FOURCC_DXT5:
		case FOURCC_DXT5_REV:
            format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
			nBlockSize = 16;
			compressed=true;
            break;
        default:
			nNumMipMaps=1;
    }

	GLubyte *pixels=(GLubyte*)&file[sizeof(ddsd)+4];

	if(format==0)
	{
		switch(ddsd.ddpfPixelFormat.dwRGBBitCount)
		{
		case 32:
			if(!compressed)format=GL_RGBA;
			else format = GL_RGBA8;
			nBlockSize = 4;
			type=GL_UNSIGNED_BYTE;
			break;
		case 24:
			if(!compressed)format=GL_RGB;
			else format = GL_RGB8;
			type=GL_UNSIGNED_BYTE;
			nBlockSize = 3;
			break;
		case 16:
			if(compressed)
			{
				return -1;
			}
			else
			{
				int rmask=ddsd.ddpfPixelFormat.dwRBitMask;
				int gmask=ddsd.ddpfPixelFormat.dwGBitMask;
				int bmask=ddsd.ddpfPixelFormat.dwBBitMask;
				a=rmask & gmask & bmask;
				if(a<65535)
				{
					puffer2=new char[nWidth*nHeight*4];
					format=GL_RGBA;
					nBlockSize = 4;
					type=GL_UNSIGNED_BYTE;

				}else
				{
					puffer2=new char[nWidth*nHeight*3];
					format=GL_RGB;
					nBlockSize = 3;
					type=GL_UNSIGNED_BYTE;
				}
				d=0;
				int rdiv=0,rmult=0;
				for(a=rmask;(a&1)==0;a>>=1)rdiv++;
				for(;(a&128)==0;a<<=1)rmult++;
				int gdiv=0,gmult=0;
				for(a=gmask;(a&1)==0;a>>=1)gdiv++;
				for(;(a&128)==0;a<<=1)gmult++;
				int bdiv=0,bmult=0;
				for(a=bmask;(a&1)==0;a>>=1)bdiv++;
				for(;(a&128)==0;a<<=1)bmult++;
				int amask=~(rmask & gmask & bmask);

				for(a=0;a<(nWidth*nHeight*2);a+=2)
				{
					c=*(short*)&pixels[a];
					r=c&rmask;
					g=c&gmask;
					b=c&bmask;

					r>>=rdiv;
					g>>=gdiv;
					b>>=bdiv;

					r<<=rmult;
					g<<=gmult;
					b<<=bmult;
					if((nBlockSize==4)&&((c&amask)!=0))c=255;else c=0;
					puffer2[d]=r;
					puffer2[d+1]=g;
					puffer2[d+2]=b;
					if(nBlockSize==4)puffer2[d+3]=c;

					d+=nBlockSize;
				}
			}
			break;
		default:
			logger.log(" unknown format %d", ddsd.ddpfPixelFormat.dwRGBBitCount);
		}
	}


	if(nBlockSize==-1)
	{
		logger.log("error unknonw pixelformat %08x", format);
		return -1;
	}


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

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

	int nSize;
	int nOffset = 0;
	
	if(nNumMipMaps<1)nNumMipMaps=1;
	for( int i = 0; i < nNumMipMaps; ++i )
	{
		if( nWidth  == 0 ) nWidth  = 1;
		if( nHeight == 0 ) nHeight = 1;
		if(compressed)nSize = ((nWidth+3)/4) * ((nHeight+3)/4) * nBlockSize;
		else nSize=nWidth*nHeight*nBlockSize;

		if(!compressed)
		{
			p=(char*)pixels;
			if(puffer2!=0)p=puffer2;
			glTexImage2D( GL_TEXTURE_2D, 0, nBlockSize, nWidth, nHeight, 0, format, type, p );
		}
		else glCompressedTexImage2DARB( GL_TEXTURE_2D, i, format, nWidth, nHeight, 0, nSize, &pixels[nOffset] );
		nOffset += nSize;
		nWidth  = (nWidth  / 2);
		nHeight = (nHeight / 2);
	}
	
    delete[] puffer2;
    return tID;
}

Loading uncompressed files is like loading bmp files.
For compressed ones you can use glCompressedTexImage2DARB function.
 
Last edited:
Back