devIL and 0.96

Started by Nova_C, April 19, 2005, 17:32:42

Previous topic - Next topic

Nova_C

I posted before in the 0.96 thread and there is supposed to be no issue with devIL and 0.96 so the problem must be me. Probably along the lines of I'm a little rusty with Java and never really learned how to use devIL to load textures into OpenGL. So here goes. Please be patient with me.

basically, I'm just trying to display a .pcx image onscreen. Start simple, you know? I'm using a utility class called MyGraphics to store static graphic methods. Here's my init stuff:

Main class:
          DisplayMode mode = MyGraphics.getDisplayMode(1024, 768, 32, 60);
            Display.create();
            Display.setDisplayMode(mode);
            Display.setFullscreen(true);
            Display.update();
            Mouse.setGrabbed(true);
            Keyboard.create();
            MyGraphics.setGL2D(1024, 768);


Here's the appropriate methods in the MyGraphics class
(Except for getDisplayMode(...) as I know that works fine):
 public static void setGL2D(int xres, int yres)
  {
    org.lwjgl.opengl.GL11.glEnable(org.lwjgl.opengl.GL11.GL_TEXTURE_2D);
    org.lwjgl.opengl.GL11.glDisable(org.lwjgl.opengl.GL11.GL_DEPTH_TEST);
    org.lwjgl.opengl.glu.GLU.gluOrtho2D(0, xres, yres, 0);
    org.lwjgl.opengl.GL11.glMatrixMode(org.lwjgl.opengl.GL11.GL_PROJECTION);
    org.lwjgl.opengl.GL11.glLoadIdentity();
  }


That should properly set OpenGL to 2D mode. It worked with the space invaders example. The problem comes from trying to use devIL in place of the textureloader in space invaders.

Main class:
          int craftImage = MyGraphics.loadImage("craft.pcx");
            
            MyGraphics.setBuffer();
            MyGraphics.drawSprite(craftImage, 100, 100);
            Display.update();
            while(!Keyboard.isKeyDown(Keyboard.KEY_Q));
            Display.destroy();


Now I had troubles with no image being displayed before, but I can't even get that far anymore. Here's the problem method (Incomplete, I know):

 public static int loadImage(String location) throws org.lwjgl.LWJGLException
  {
      java.nio.IntBuffer set = org.lwjgl.BufferUtils.createIntBuffer(6);
      set.limit(1);
      org.lwjgl.devil.IL.ilGenImages(set);
      org.lwjgl.devil.IL.ilBindImage(set.get(0));
      if(!org.lwjgl.devil.IL.ilLoadImage(location))
          throw new org.lwjgl.LWJGLException("Error loading image file.");
      return 0;
  }


Now, as it stands, that method won't do anything, but I was just trying to get confirmation of the file being loaded. However, since going to 0.96, ANY devIL method causes this:

"An error report file with more information is saved as hs_err_pid3976.log"

I'm sure that I just simply don't understand how to use devIL. Any help would be much appreciated.

ordoc


Nova_C

What the-?

When I tried IL.create() before it gave me the same crash...now it doesn't....Oh man, why can't these things make sense?  :roll:

- Edit

Okay, something still isn't working. I'm trying to follow devIL's tutorial on accessing openGL and I'm getting the same JVM crash. Here's my new function (Without the two openGL commands, the image loads fine):

 public static int loadImage(String location) throws org.lwjgl.LWJGLException
  {
      java.nio.IntBuffer set = org.lwjgl.BufferUtils.createIntBuffer(6);
      set.limit(1);
      org.lwjgl.devil.IL.create();
      org.lwjgl.devil.IL.ilGenImages(set);
      org.lwjgl.devil.IL.ilBindImage(set.get(0));
      if(!org.lwjgl.devil.IL.ilLoadImage(location))
          throw new org.lwjgl.LWJGLException("Error loading image file.");
      org.lwjgl.devil.ILUT.ilutRenderer(org.lwjgl.devil.ILUT.ILUT_OPENGL); // Causes crash
      int image = org.lwjgl.devil.ILUT.ilutGLBindTexImage(); // Causes crash
      org.lwjgl.devil.IL.destroy();
      return image;
  }


Both commands marked cause a crash.

Nova_C

Okay, okay. Nevermind. Man, I didn't know I had to initialize each one individually. Didn't find that in any documentation I read.

I added ILUT.create(); Now it 'seems' to work.

I'm still having trouble with the Display.update() crashing, but I'll see what I can dig up.

Nova_C

Okay, guys. I'm ALMOST there. A couple things I haven't been able to resolve.

First, I succesfully have the image loading and displaying, but it's HUGE. The actual .pcx file is 64x64 but on a 1024x768 screen the onscreen image takes up about 80% of the screen.

Also, whenever I try to use glTranslatef(...), the image won't display at all anymore. Here's my display code:

     org.lwjgl.opengl.GL11.glPushMatrix();
      org.lwjgl.opengl.GL11.glBindTexture(org.lwjgl.opengl.GL11.GL_TEXTURE_2D, sprite);
      org.lwjgl.opengl.GL11.glTranslatef(xLocation, yLocation, 0.0f);
      org.lwjgl.opengl.GL11.glColor3f(1, 1, 1);
      org.lwjgl.opengl.GL11.glBegin(org.lwjgl.opengl.GL11.GL_QUADS);
      org.lwjgl.opengl.GL11.glTexCoord2f(0, 0);
      org.lwjgl.opengl.GL11.glVertex2f(0, 0);
      org.lwjgl.opengl.GL11.glTexCoord2f(1, 0);
      org.lwjgl.opengl.GL11.glVertex2f(1, 0);
      org.lwjgl.opengl.GL11.glTexCoord2f(1, 1);
      org.lwjgl.opengl.GL11.glVertex2f(1, 1);
      org.lwjgl.opengl.GL11.glTexCoord2f(0, 1);
      org.lwjgl.opengl.GL11.glVertex2f(0, 1);
      org.lwjgl.opengl.GL11.glEnd();
      org.lwjgl.opengl.GL11.glPopMatrix();


So, basically, I can't do anything with the image. As soon as I try to change where it is, it doesn't display anymore.

Orangy Tang

The code in set2DDisplay looks suspect:
   org.lwjgl.opengl.glu.GLU.gluOrtho2D(0, xres, yres, 0);
   org.lwjgl.opengl.GL11.glMatrixMode(org.lwjgl.opengl.GL11.GL_PROJECTION);
   org.lwjgl.opengl.GL11.glLoadIdentity();

IIRC, gluOrtho and gluPerspective both operate on the current matrix stack. You almost certainly want your gluOrtho2d call *after* the glLoadIdentity call ('cos at the moment you're overwriting the ortho setup with the identity matrix).

And then you'll want to change your quad drawing code, otherwise you'll get a single pixel quad.

Nova_C

Great, it works now. Thank you. I'm still having problems getting a texture size as glGetTexParameter or the FloatBuffer cause a crash when I try calling Display.update() or I simply end up with zeroes from teh glGetTexParameter function. This is not new, though. I've NEVER gotten that function to do anything.

- Edit: Nevermind. glGetTexParameter doesn't accept GL_TEXTURE_HEIGHT or WIDTH. I should've been using glGetTexLevelParameter. All my questions have been answered. Thank you all so much for helping.

tomjnsn

Nova_C, would you mind posting your final working code?  I'm going through the same exact thing.  I tried putting together what your final code looks like without luck.

Also, have you tried using the ILUT.ilutGLLoadImage(String) method to load up a texture which looks like it would streamline things a bit?

Thanks,

Tom

Nova_C

Woo hoo! I get to pass on knowledge instead of just begging off the people here!! :D

I never got the ilutGLLoadImage(String) to work. To simplify, I'll go through my entire process (Excluding setting up the display):

Basically, I create the display, then set the display mode. I then activate OpenGLs 2D mode:

   org.lwjgl.opengl.GL11.glEnable(org.lwjgl.opengl.GL11.GL_TEXTURE_2D);
    org.lwjgl.opengl.GL11.glDisable(org.lwjgl.opengl.GL11.GL_DEPTH_TEST);
    org.lwjgl.opengl.GL11.glMatrixMode(org.lwjgl.opengl.GL11.GL_PROJECTION);
    org.lwjgl.opengl.GL11.glLoadIdentity();
    org.lwjgl.opengl.glu.GLU.gluOrtho2D(0, xres, yres, 0); // xres and yres are the horizontal and vertical resolution respectively


I then load the graphics with the following function (The string is simply the file itself):

 public static int loadImage(String location) throws org.lwjgl.LWJGLException
  {
      org.lwjgl.devil.IL.create();
      org.lwjgl.devil.ILUT.create();
      java.nio.IntBuffer set = org.lwjgl.BufferUtils.createIntBuffer(5);
      set.put(0, 1);
      org.lwjgl.devil.IL.ilBindImage(set.get(0));
      org.lwjgl.devil.IL.ilLoadImage(location);
      org.lwjgl.devil.ILUT.ilutEnable(org.lwjgl.devil.ILUT.ILUT_OPENGL_CONV);
      org.lwjgl.devil.ILUT.ilutRenderer(org.lwjgl.devil.ILUT.ILUT_OPENGL);
      int image = org.lwjgl.devil.ILUT.ilutGLBindTexImage();
      org.lwjgl.devil.ILUT.destroy();
      org.lwjgl.devil.IL.destroy();
      return image;
  }


The int returned by the loadImage(String) function is the OpenGL reference. Every time you want to use that texture, you bind that int to OpenGL. It'll become more clear in a moment.

I use the following function to 'clear' the buffer so I can draw a new frame. It could probably use work as I've learned about a zillion things since I wrote this little function.

 public static void setBuffer()
  {
    org.lwjgl.opengl.GL11.glClear(org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT | org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT);
    org.lwjgl.opengl.GL11.glMatrixMode(org.lwjgl.opengl.GL11.GL_MODELVIEW);
    org.lwjgl.opengl.GL11.glLoadIdentity();    
  }


Finally, we get to the meat of the issue. Here is my actual drawing routine. I've changed from Quads to Triangles so when I rotate the image, it spins in place instead of rotating around the 0,0 upper left co-ordinate (Think of a square with an X inside it. The center of the X is where the origin of the object is):

 public static void drawSprite(int sprite, int xLocation, int yLocation, int angle)
  {
      org.lwjgl.opengl.GL11.glPushMatrix();
      org.lwjgl.opengl.GL11.glBindTexture(org.lwjgl.opengl.GL11.GL_TEXTURE_2D, sprite);
      java.nio.FloatBuffer set = org.lwjgl.BufferUtils.createFloatBuffer(6);
      set.limit(6);
      set.position(0);
      org.lwjgl.opengl.GL11.glGetTexLevelParameter(org.lwjgl.opengl.GL11.GL_TEXTURE_2D, 
              0, org.lwjgl.opengl.GL11.GL_TEXTURE_WIDTH, set);
      set.position(1);
      org.lwjgl.opengl.GL11.glGetTexLevelParameter(org.lwjgl.opengl.GL11.GL_TEXTURE_2D, 
              0, org.lwjgl.opengl.GL11.GL_TEXTURE_HEIGHT, set);
      set.rewind();
      int width = (int)set.get() / 2;
      int height = (int)set.get() / 2;
      org.lwjgl.opengl.GL11.glTranslatef(xLocation + width, yLocation + width, 0.0f); //Because of the four triangle setup, this allows proper placement, using the function as if it was navigating from the upper left corner.
      org.lwjgl.opengl.GL11.glColor3f(1, 1, 1);
      org.lwjgl.opengl.GL11.glRotatef((float)angle + 90, 0.0f, 0.0f, 1.0f);
      org.lwjgl.opengl.GL11.glBegin(org.lwjgl.opengl.GL11.GL_TRIANGLES);
      
      org.lwjgl.opengl.GL11.glTexCoord2f(0.0f, 0.0f); 
      org.lwjgl.opengl.GL11.glVertex2i(width - (width * 2), height); 
      org.lwjgl.opengl.GL11.glTexCoord2f(1.0f, 0.0f); 
      org.lwjgl.opengl.GL11.glVertex2i(width - (width * 2), height - (height * 2)); 
      org.lwjgl.opengl.GL11.glTexCoord2f(0.5f, 0.5f);
      org.lwjgl.opengl.GL11.glVertex2i(0, 0);
      
      org.lwjgl.opengl.GL11.glTexCoord2f(1.0f, 0.0f); 
      org.lwjgl.opengl.GL11.glVertex2i(width - (width * 2), height - (height * 2)); 
      org.lwjgl.opengl.GL11.glTexCoord2f(1.0f, 1.0f); 
      org.lwjgl.opengl.GL11.glVertex2i(width, height - (height * 2)); 
      org.lwjgl.opengl.GL11.glTexCoord2f(0.5f, 0.5f); 
      org.lwjgl.opengl.GL11.glVertex2i(0, 0); 

      org.lwjgl.opengl.GL11.glTexCoord2f(1.0f, 1.0f); 
      org.lwjgl.opengl.GL11.glVertex2i(width, height - (height * 2)); 
      org.lwjgl.opengl.GL11.glTexCoord2f(0.0f, 1.0f); 
      org.lwjgl.opengl.GL11.glVertex2i(width, height); 
      org.lwjgl.opengl.GL11.glTexCoord2f(0.5f, 0.5f); 
      org.lwjgl.opengl.GL11.glVertex2i(0, 0); 

      org.lwjgl.opengl.GL11.glTexCoord2f(0.0f, 1.0f); 
      org.lwjgl.opengl.GL11.glVertex2i(width, height); 
      org.lwjgl.opengl.GL11.glTexCoord2f(0.0f, 0.0f); 
      org.lwjgl.opengl.GL11.glVertex2i(width - (width * 2), height); 
      org.lwjgl.opengl.GL11.glTexCoord2f(0.5f, 0.5f); 
      org.lwjgl.opengl.GL11.glVertex2i(0, 0); 
      
      org.lwjgl.opengl.GL11.glEnd();
      org.lwjgl.opengl.GL11.glPopMatrix();
  }

(I was just reviewing this and found I totally missed the simple method. It really isn't all that important but replace width - (width * 2) with width * -1. Don't ask me why I didn't do that in the first place)

I'm terrible for commenting, so if there is anything confusing in there (And there probably is), just ask me to clarify.

tomjnsn

Thanks!  That was enough info to get rolling.