From: <dom...@so...> - 2003-06-24 09:36:39
|
Hi all, I'm trying to use compressed DDS files in my program. I started by writing my own DDS file reader, referencing nVidia's tutorial (http://developer.nvidia.com/view.asp?IO=OpenGL_S3TC_tutorial) together with the source code of DevIL, and information on MSDN. I can now load the file successfully, and I've checked that all the data loaded are correct (where I verify the header items one-by-one, and sampling the image data for correctness). The problem is, after loading the data into the texture object using glCompressedTexImage2D, I see nothing on there screen (where a simple triangle is rendered). I've double checked that the rendering code is correct (if I map a .tga texture using the tga loader, the triangle is displayed with texture mapped). So I have no idea what's the problem for now. I suspected that I'm not using the correct data type for the data array, but after trying all possible choice I still got nothing on the screen. Could anyone please give me some hints about this? Thank you. Regards, Dominic The source code I used for loading the DDS file are listed below. Currently I'm only handling file compressed by the DXT3 format. // This class represents the header of a DDS file. public class DDSFormatDescriptor { public static final int DDSD_CAPS = 0x00000001; public static final int DDSD_HEIGHT = 0x00000002; public static final int DDSD_WIDTH = 0x00000004; public static final int DDSD_PITCH = 0x00000008; public static final int DDSD_PIXELFORMAT = 0x00001000; public static final int DDSD_MIPMAPCOUNT = 0x00020000; public static final int DDSD_LINEARSIZE = 0x00080000; public static final int DDSD_DEPTH = 0x00800000; public static final int DDPF_ALPHAPIXELS = 0x00000001; public static final int DDPF_FOURCC = 0x00000004; public static final int DDPF_RGB = 0x00000040; public static final int DDSCAPS_COMPLEX = 0x00000008; public static final int DDSCAPS_TEXTURE = 0x00001000; public static final int DDSCAPS_MIPMAP = 0x00400000; public char [] signature = new char[4]; public int size; public int flags; public int height; public int width; public int linearSize; public int depth; public int mipMapCount; public int alphaBitDepth; public int [] reserved1 = new int[10]; public int size2; public int flags2; public char [] fourCC = new char[4]; public int rgbBitCount; public int rBitMask; public int gBitMask; public int bBitMask; public int rgbaAlphaBitMask; public int ddsCaps1; public int ddsCaps2; public int ddsCaps3; public int ddsCaps4; public int textureStage; }; // This is the file object. Consisted of the header, and the data array. public class DDSFile { public DDSFormatDescriptor ddsfd; public byte [][] data; } // This class actually load the dds file from this. public class DDSHandler { public DDSHandler() { } public int readIntSwapped(DataInputStream dataInputStream) { try { int a, b, c, d; a = dataInputStream.read(); b = dataInputStream.read(); c = dataInputStream.read(); d = dataInputStream.read(); return (((d & 0xff) << 24) | ((c & 0xff) << 16) | ((b & 0xff) << 8) | (a & 0xff)); } catch (Exception e) { return (-1); } } public DDSFile load(String fileName) { try { File file = new File(fileName); FileInputStream in = new FileInputStream(file); DataInputStream din = new DataInputStream(in); DDSFormatDescriptor ddsfd = new DDSFormatDescriptor(); ddsfd.signature[0] = (char) din.readUnsignedByte(); ddsfd.signature[1] = (char) din.readUnsignedByte(); ddsfd.signature[2] = (char) din.readUnsignedByte(); ddsfd.signature[3] = (char) din.readUnsignedByte(); ddsfd.size = readIntSwapped(din); ddsfd.flags = readIntSwapped(din); ddsfd.height = readIntSwapped(din); ddsfd.width = readIntSwapped(din); ddsfd.linearSize = readIntSwapped(din); ddsfd.depth = readIntSwapped(din); ddsfd.mipMapCount = readIntSwapped(din); ddsfd.alphaBitDepth = readIntSwapped(din); for (int i = 0; i < 10; i++) { ddsfd.reserved1[i] = readIntSwapped(din); } ddsfd.size2 = readIntSwapped(din); ddsfd.flags2 = readIntSwapped(din); for (int i = 0; i < 4; i++) { ddsfd.fourCC[i] = (char) din.readUnsignedByte(); } ddsfd.rgbBitCount = readIntSwapped(din); ddsfd.rBitMask = readIntSwapped(din); ddsfd.gBitMask = readIntSwapped(din); ddsfd.bBitMask = readIntSwapped(din); ddsfd.rgbaAlphaBitMask = readIntSwapped(din); ddsfd.ddsCaps1 = readIntSwapped(din); ddsfd.ddsCaps2 = readIntSwapped(din); ddsfd.ddsCaps3 = readIntSwapped(din); ddsfd.ddsCaps4 = readIntSwapped(din); ddsfd.textureStage = readIntSwapped(din); DDSFile ddsFile = new DDSFile(ddsfd); int mipMapCount = ddsfd.mipMapCount; ddsFile.data = new byte[mipMapCount][]; int mipMapWidth = ddsfd.width; int mipMapHeight = ddsfd.height; for (int i = 0; i < mipMapCount; i++) { int size = (mipMapWidth / 4) * (mipMapHeight / 4) * 16; int bufferSize = size; if (size < 16) { bufferSize = 16; } ddsFile.data[i] = new byte[bufferSize]; for (int j = 0; j < bufferSize; j++) { ddsFile.data[i][j] = (byte) din.readUnsignedByte(); // I use this line to verify that my data is correct. System.out.println(ddsFile.data[i][j]); } mipMapWidth /= 2; mipMapHeight /= 2; } return (ddsFile); } catch (Exception e) { e.printStackTrace(); return (null); } } public static void main(String[] args) { new DDSHandler().load("c:/test.dds"); } } // Finally, the code in the GLEventListener for loading the texture, and render it. // Started with something else... DDSFile ddsFile = ddsHandler.load("c:/data/skybox/bluedream_negx.dds"); gl.glGenTextures(1, compressedTextureID); gl.glBindTexture(GL_TEXTURE_2D, compressedTextureID[0]); int width = ddsFile.getWidth(); int height = ddsFile.getHeight(); for (int i = 0; i < 1; i++) { gl.glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, width, height, 0, ddsFile.data[i].length, ddsFile.data[i]); width /= 2; height /= 2; } // And then in the rendering loop... gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); gl.glLoadIdentity(); gl.glTranslatef(-1.0f, 0.0f, -10.0f); gl.glColor3f(1.0f, 1.0f, 1.0f); gl.glEnable(gl.GL_TEXTURE_2D); gl.glPushMatrix(); gl.glBindTexture(GL_TEXTURE_2D, compressedTextureID); gl.glBegin(GL_TRIANGLES); gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f(0.0f, 0.0f, 0.0f); gl.glTexCoord2f(10.0f, 0.0f); gl.glVertex3f(1.0f, 0.0f, 0.0f); gl.glTexCoord2f(0.0f, 10.0f); gl.glVertex3f(0.0f, 1.0f, 0.0f); gl.glEnd(); gl.glPopMatrix(); glDrawable.repaint(); |