Loading Images and Sounds?

Started by jediTofu, October 16, 2010, 13:38:34

Previous topic - Next topic

jediTofu

I am trying to figure out what to use to load images and sounds?

I read somewhere that DevIL is no longer being updated or something?  But I went to the website (http://openil.sourceforge.net/), and it seems to be up-to-date.  I haven't tried it yet, so don't know how easy it is to use with LWJGL.  I assume that I would have to use the JNI (or JNA) with their DLL's, which could be difficult.

For sound, I saw in the tutorials that LWJGL has WaveData, I believe?  What all file types are built into LWJGL for sound currently (without other libraries)?  Just wave?  I looked at FMOD, but it's only free for non-commercial software.  That's really most of what I plan on writing, but you never know.  I'd rather have something under the BSD or LGPL license.

Finally, I saw where people had suggested Slick.  I think that that is too much additional stuff that I don't need (adding memory and hassle to my life) if I just want to load images/sounds.  I thought about just going ahead and using their code for everything, but I don't really like how they do certain things.  Does anyone use Slick here?  Do you like it?  I could just do this if there is no other alternative.


Lastly, I could start a new project on Kenai.  I was thinking about calling it OpenLL (Open Loading Library).  There would be org.lwjgl.openll.* and org.lwjgl.openll.util.*.  Essentially, it would be for everything loading-wise for games (images, sounds, etc.).  There would be openll.ImageIO (different name to avoid conflicts, just saying this name for you to relate to) that would have a bunch of static methods for loading images, etc.  Then there would be stuff like openll.util.Image to store it in a class if you wanted it that way, with the x, y, width, height, etc.  I'm open for suggestions here obviously on anything.  It could be LWJGIO (lwjg input/output) or GIOL (gaming input/output library), whatever.  Since I'm kind of a novice at this, I'd probably just use javax.imageio.ImageIO and JOrbis and look at how Slick does things (even though I hate to do that).  Of course, people can add loaders in openll for all the different types of 3D files and add classes in openll.util for tile-based loaders, etc.  Bad idea or good idea?

And of course, LWJGL would be free to just copy and paste OpenLL or w/e into it so that it's already part of the package.
cool story, bro

kappa

Fmod and Devil were both removed for LWJGL2+, the recommended replacement is a library called slick-util (note different from slick2d). You should be able to load various texture and sound formats with it.

you can get it from http://slick.cokeandcode.com/downloads/util/ and the javadoc is located at http://slick.cokeandcode.com/javadoc-util/

Its pretty easy to use, just download the package and have a look at the examples included in the source code on how to use it.

jediTofu

Awesome, thanks!  This should be on the FAQ or something.  I never found this for some reason.
cool story, bro

kappa

Yeh, will put it in the faq on the wiki. I've been meaning to do a tutorial on it just not got round to it.

jediTofu

Hmmm, PNG images without any alpha load and draw fine, but if I set a color's alpha to 0 using IrfanView, it loads it fine but draws it all distorted.  But when I open the image using any of the image programs on my computer (IrfanView, GIMP, Windows image loader, etc.), the image is fine and the color is transparent.  I'm not even doing any alpha tests in the code yet; the image is just distorted for some reason.

//loading
Texture test = TextureLoader.getTexture("png",new FileInputStream("test.png"));
//drawing
test.bind();
glBegin(GL_QUADS);
glTexCoord2f(0,0);
glVertex2f(x,y);
glTexCoord2f(1,0);
glVertex2f(x + test.getTextureWidth(),y);
glTexCoord2f(1,1);
glVertex2f(x + test.getTextureWidth(),y + test.getTextureHeight());
glTexCoord2f(0,1);
glVertex2f(x,y + test.getTextureHeight());
glEnd();


I haven't messed with OpenGL in a long time, but back when I made a game in C++, I would just use an obscure purple color (rgb: 174,74,174), programmatically change the color's alpha to 0 (I didn't have IrfanView back then), and then draw it using OpenGL alpha tests.

I guess I will just save all my images without any alpha to 0, but how would I set my purple color to transparent using OpenGL?  Knowing it wouldn't work, I tried this anyway:

//init
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
//drawing
  //glColor4f(0.68f,0.29f,0.68f,0.0f);
  //or
  //glColor4b((byte)174,(byte)74,(byte)174,(byte)0);
cool story, bro

broumbroum

this is likely because no alpha  is RGB and with alpha is ARGB in java BufferedImage. color id 0 becomes alpha and 1 is red, blue is 2 green has id 3. check what is the store type used in opengl for 4 color components textures !

jediTofu

Sorry, I guess it was IrfanView's fault.  I did the same exact thing with GIMP, and it worked perfectly.   :-\

Still, I would like to know how to make a color transparent or translucent using OpenGL alone.  Do you guys know how to do this?  I guess any bitmaps will have to be converted to png's with GIMP, or I could just use texture.getTextureData() and add another byte, setting the desired color's alpha to 0 and hope that the byte array works with the OpenGL functions.  I know how to blend colors, but how would you make one color transparent and all the other colors opaque without changing the bytes?
cool story, bro

broumbroum

Well, loading textures supposes to load the entire buffered image into the RAM, i.e. in a Byte,Int,FloatBuffer. Right before you go on with glteximage2d, read and check all alpha values of the Buffer you've just loaded. Since LWJGL requires direct buffers, it should be quite fast to complete, and to code as well.
// load your buffer data 
IntBuffer bimg = loadTex("png");
IntBuffer colorVal;
while(bimg.position() < bimg.capacity()){
  // a good trick to retrieve a direct buffer as a view of the original
  colorVal = bimg.limit(bimg.position() + 4).slice(); 
  bimg.position(bimg.limit());
  // read and put as you like
  int blue = colorVal.get(0), green = colorVal.get(1), blue = colorVal.get(2);
  int alpha = colorVal.get(3);
  /* check for a PURPLE background in the png image */
  if(blue == Color.PURPLE.getBlue() && green ==Color.PURPLE.getGreen() && red == Color.PURPLE.getRed())
      alpha = 0;
   colorVal.put(0, blue); colorVal.put(1, green); colorVal.put(2, red); colorVal.put(3, alpha);
}

/* ready to load into glteximage2d !! */


This has not been tested yet, sorry for that ¨!

P.S : (About not changing the bytebuffer you asked in fine : this should lead to create a second png file that'll be the "mask". Ahead you will be able to use GL_STENCIL to do decals right before to display the png file that had no alpha mask  ;)8)

basil

that pretty cool actualy.
It'd give you decent lowlevel control over AA around blends and probably the most robust way to handle not/premultiplied images. with offline pre-rendering and other fancy effects, my fav. :)