DDS grainy at distance

Started by
9 comments, last by Lopez 18 years, 3 months ago
Hi there, i'm just getting started using dds's. I've got the nvidia photoshop plugin, and i'm loading the dds using the following:

UINT	CTextureManager::LoadDDS( char *strFileName ){

    // NOTE: Unlike "lena.bmp", "lena.dds" actually contains its own mip-map 
    // levels, which are also compressed.
    DDS_IMAGE_DATA *pDDSImageData = CreateTextureDDS( strFileName );

    if( pDDSImageData != NULL )
    {
        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, &m_texturecounter );
        glBindTexture( GL_TEXTURE_2D, m_texturecounter );

        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 );
    }
	return m_texturecounter;
}


it loads the dds and displays it fine (apart from the negated y), but the mip maps are all grainy when rendered. Image Hosted by ImageShack.us i'm using a DXT1 with 5 mipmap levels.
Advertisement
you arent using the mipmap levels when filtering, switch the min filter to one which does (I cant think of the token name off the top of my head, check your fav. opengl text book for it) and see if that helps
Quote:Original post by phantom
you arent using the mipmap levels when filtering, switch the min filter to one which does (I cant think of the token name off the top of my head, check your fav. opengl text book for it) and see if that helps


glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR) for trilinear.
just tried what OrangyTang said....

and all i get is black!!!!

The pic you show seems to be missing the mipmap with minfilter.
You may need to remove the mip level with less then 4 pixel.
that screenshot tells me nothing
also with mipmaps normally u have to generate mipmaps all the way down to 1x1 but with texture compresion the smallest size is 4x4 (IIRC)
DXTn are compressed in 4x4 blocks, but if the texture itself is smaller, only a part of the 4x4 block is actually used. So unless I'm mistaken, textures smaller than 4x4 are perfectly valid and should be included, or the mipmap set is incomplete.
heres my code, with compressed textures the samllest sized block is 4x4 thus u need something like if ( size < 16 ) size = 16;
for ( level = 0; level < num_mipmap_levels && ( w>=1 || h>=1 ); level++, w >>= 1, h >>= 1 )			{				if ( w < 1 ) w=1;				if ( h < 1 ) h=1;				int size = w * h;								if ( size < 16 )					size = 16;				if ( internal_format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT )					size /= 2;				if ( !pixels )	// only offset if theres some data else well run into trouble					size=0;									glCompressedTexImage2DARB( texture_target, level, internal_format, w, h, texture_border, size, (GLvoid *)(pixels+offset_size) );														if ( pixels )	// only offset if theres some data else well run into trouble					offset_size += size;
i've just loaded the dds into photoshop, and colored each mip level, and saved it off.

when the dds is being rendered, i'ts only using the first level.
if you've set your filter modes correctly then the problem is either with;

a) your DDS loading code
or
b) your texture data uploading code

All you have todo is rule one of them out [grin]

Try setting the filtering to LINEAR and uploading one of the mipmap levels as the base level, see if that works any better.

This topic is closed to new replies.

Advertisement