[SOLVED] Texture inverted when PNG or JPG but not BMP!!!

Started by MarneusCalgarXP, September 04, 2006, 22:16:38

Previous topic - Next topic

MarneusCalgarXP

Hello, I'm new on this forum, in LWJGL, in OpenGL, and in Devil :wink:

I'm currently making tests with LWJGL, Devil and OpenGL. I've got a problem: I'm using a texture, and when I load it in BMP format, no problem, the texture is mapped ok on a plane or on a GLU Sphere, but when I load the same texture in PNG or JPG format, the texture is upside down !!!

The whole code is the NeHe Lesson 18


code to load texture
IL.create();

...

private int[] loadTexture(String path) {
        IntBuffer image = ByteBuffer.allocateDirect(4).order(ByteOrder.nativeOrder()).asIntBuffer();
        IL.ilGenImages(image);
        IL.ilBindImage(image.get(0));
        IL.ilLoadImage(path);
        //IL.ilConvertImage(IL.IL_RGB, IL.IL_BYTE);
        ByteBuffer scratch = ByteBuffer.allocateDirect(IL.ilGetInteger(IL.IL_IMAGE_WIDTH) * IL.ilGetInteger(IL.IL_IMAGE_HEIGHT) * 3);
        IL.ilCopyPixels(0, 0, 0, IL.ilGetInteger(IL.IL_IMAGE_WIDTH), IL.ilGetInteger(IL.IL_IMAGE_HEIGHT), 1, IL.IL_RGB, IL.IL_BYTE, scratch);

        // Create A IntBuffer For Image Address In Memory
        IntBuffer buf = ByteBuffer.allocateDirect(12).order(ByteOrder.nativeOrder()).asIntBuffer();
        GL11.glGenTextures(buf); // Create Texture In OpenGL

        GL11.glBindTexture(GL11.GL_TEXTURE_2D, buf.get(0));
        // Typical Texture Generation Using Data From The Image

        // Create Nearest Filtered Texture
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, buf.get(0));
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
        GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, IL.ilGetInteger(IL.IL_IMAGE_WIDTH), 
                IL.ilGetInteger(IL.IL_IMAGE_HEIGHT), 0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, scratch);

        // Create Linear Filtered Texture
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, buf.get(1));
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
        GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, IL.ilGetInteger(IL.IL_IMAGE_WIDTH), 
                IL.ilGetInteger(IL.IL_IMAGE_HEIGHT), 0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, scratch);

        // Create MipMapped Texture
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, buf.get(2));
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR_MIPMAP_NEAREST);
        GLU.gluBuild2DMipmaps(GL11.GL_TEXTURE_2D, 3, IL.ilGetInteger(IL.IL_IMAGE_WIDTH), 
                IL.ilGetInteger(IL.IL_IMAGE_HEIGHT), GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, scratch);

      return new int[]{ buf.get(0), buf.get(1), buf.get(2) };     // Return Image Addresses In Memory
    }


The texture is from the Celestia project, i've uploaded in the 3 versions here:
Here are the results when using BMP texture:


And when using the same texture, in PNG or JPG format:


Do somebody have any idea to solve this problem ?
Dark Skull Software
http://www.darkskull.net

xindon


MarneusCalgarXP

Thank you for the function, I didn't knew about it !!!

But I still don't understand why some picture formats are loaded "normally" and some others are loaded "upside down"... Will I have to make a test like this ? (pseudo code)

switch (format) {
  case JPG:
  case PNG: 
       // image upside down, reverse it
       iluFlipImage();
       break;
  default: // image OK, do nothing !
}
Dark Skull Software
http://www.darkskull.net

aldacron

Quote from: "MarneusCalgarXP"But I still don't understand why some picture formats are loaded "normally" and some others are loaded "upside down"...

It has to do with OpenGL texture coordinates and the origin (0,0) of the image. OpenGL treats the origin of a texture as the lower left corner, whereas most graphics programs that you work with treat the origin as the upper left corner. While most file formats support both origin types (upper left and lower left), some formats commonly use one type over the other.

Quote
Will I have to make a test like this ? (pseudo code)

switch (format) {
  case JPG:
  case PNG: 
       // image upside down, reverse it
       iluFlipImage();
       break;
  default: // image OK, do nothing !
}

That would not be the most reliable method to use since the origin of the image is usually not dependent upon the file format. Instead, add the following after your call to IL.ilCreate:

IL.ilOriginFunc(IL.IL_ORIGIN_LOWER_LEFT);
IL.ilEnable(IL.IL_ORIGIN_SET);


Depending on how you are specifying texture coordidates, that may or may not work. If it causes all of your textures to be upside down, then change the first line to il.ilOriginFunc(IL.IL_ORIGIN_UPPER_LEFT). The point is it causes DevIL to load all of your texture images with a common origin regardless of how they are stored on disk.

MarneusCalgarXP

Thank you a lot, it's exactly what I was looking for !!!!
Dark Skull Software
http://www.darkskull.net