LWJGL for my 2D Game

I’ve decided I want to use LWJGL for my game, but I need some help doing it. The game is a top-down 2D game, and well it’s really about finished, but for it to stand on its own as a PC game I need it to work quite a bit faster as Java2D just can’t cut it when it comes to translating translucent images all over the place. Even just plain tiling opaque images is too slow for my hopes.

Also, I want good sound, so I’m currently working through the OpenAL tutorials for this library and developing a tool to help me do that and it’s going very well.

What ISN’T going well is me figuring out how to use OpenGL for my game. Any set of example code I can find to use LWJGL for 2D is overwhelming to me, and I feel funny going through tutorials at NeHe because I’m never going to use anything I learn there with drawing 3D objects and wave transforms for them and all that. I just want a faster way to draw my sprites.

I have my game done in Java2D and Graphics2D.drawImage() calls all over the place. Now I want to be able to flip a toggle and go from that rendering method to an OpenGL rendering method, where I can draw all my sprites like I do but using all the speed advantages OpenGL can give me. Can someone help me out? I’m afraid I’m going to have to write a separate game just to get OpenGL rendering to work, when I just want it to be an augmentation of the working game I already have.

Thanks for any help or advice you guys can give me. If you want to check out the current stage of the game in an Applet form, go here (controls are listed in the Options menu):
http://www.gamelizard.com/test/rimscape.html

ava.lang.ClassNotFoundException: com.gamelizard.util.GLApplet

  at sun.applet.AppletClassLoader.findClass(Unknown Source)

  at java.lang.ClassLoader.loadClass(Unknown Source)

  at sun.applet.AppletClassLoader.loadClass(Unknown Source)

  at java.lang.ClassLoader.loadClass(Unknown Source)

  at sun.applet.AppletClassLoader.loadCode(Unknown Source)

  at sun.applet.AppletPanel.createApplet(Unknown Source)

  at sun.plugin.AppletViewer.createApplet(Unknown Source)

  at sun.applet.AppletPanel.runLoader(Unknown Source)

  at sun.applet.AppletPanel.run(Unknown Source)

  at java.lang.Thread.run(Unknown Source)

Caused by: java.io.IOException: open HTTP connection failed.

  at sun.applet.AppletClassLoader.getBytes(Unknown Source)

  at sun.applet.AppletClassLoader.access$100(Unknown Source)

  at sun.applet.AppletClassLoader$1.run(Unknown Source)

  at java.security.AccessController.doPrivileged(Native Method)

  ... 10 more

You cannot run LWJGL in an applet - you have to use Java Webstart. As for using LWJGL in 2D mode, look at org.lwjgl.examples.spaceinvaders

It worked fine for me! Plus it runs really smooth.

To do 2D graphics you need to learn all the 3D stuff because for 2D you would draw all your sprites onto quads with no depth. Your game is still in the 3D world. There are some orthographic functions that you might want to look into though.

I checked out the LWJGL Space Invaders game and understood the source fine, so that was very helpful to learn about how LWJGL would work in comparison to how I have my game set up. I also found a tutorial that illustrated using Sprites that would be created and drawn using whatever the selected rendering option was, with the choices being JOGL, LWJGL, and Java2D. It was very insightful and made great sense, but still, for me to implement the idea felt like an overwhelming project.

I make a LOT of calls to the Graphics2D class throughout my game, only about half of them being to the drawImage() method. So while I saw how I can draw sprites using LWJGL, there is a lot more going on my game that I don’t know how to compensate for. I really want to be able to toggle between Java2D mode and OpenGL mode, but I don’t know what to do because I have so much I’m doing with the Graphics2D class and making my code work for both Java2D and OpenGL is just overwhelming. Especially since for the majority of what I do I don’t know of the GL options I have for doing the same thing.

I need help :stuck_out_tongue: Can someone give me some hope on this project? I’ve spent two full days of code crunching trying to match ideas to make both methods work, and I’ve had almost completely 0 success. I’m in need of some serious help.

Funny thing is, what you need to complete this is something like J2DA (http://j2da.sf.net). However, I’d pretty mcuh decided this was a dead idea. The problem is if you try to support Java 2D and OpenGL you end up supporting only the lowest common denominator. While this is fine with most types of abstraction (daabases etc) for visuals this doesn’t cut the mustard. If you want nice effects just choose the rendering technology you’re going to use and stick to that.

Just my opinion of course,

Kev

the effects I pretty much already have. All of the requests of my designer have been plenty possible with Java 2D, and they’re done. The game looks good, and it’s clean looking. I don’t need any other effects, I just want the speed advantage.

[quote]I make a LOT of calls to the Graphics2D class throughout my game, only about half of them being to the drawImage() method. So while I saw how I can draw sprites using LWJGL, there is a lot more going on my game that I don’t know how to compensate for.
[/quote]
What else do you need?

You can draw lines by passing GL_LINES to glBegin().


glBegin(GL_LINES)
//line vertices
glEnd()

Other shapes, like sircles, you have to draw yourself by using line segments.

can I create Sprites on the fly and store them? I do quite a bit of work onto BufferedImages, and I’d like to be able to create one, hold onto it, and draw it as much as I want on the screen. That would let me do my Graphics2D tricks (primitive drawing and GradientPaint usage) and not have to worry about finding OpenGL ways to do it as well. So far the only management I’ve found with Sprites has been by letting the library construct it from a file name and never letting you have any more access than that. Even still, would it be at all efficient to be creating a Sprite object very often with its Texture components when all I really want to do is blit a new BufferedImage to the screen?

I also do a lot of work in terms of drawing with the AffineTransform class. I assume there are fast counterparts to the transformation work I’d need to do for OpenGL right?

Also, what about regular computers without 3D graphics cards? Will the OpenGL drivers still be able to draw my sprites faster than Java2D can?

[quote]can I create Sprites on the fly and store them?
[/quote]
Yes you can. You have to read up on textures. What you are after are GLU.gluBuild2DMipmaps(…) or GL11.glTexImage2D(…).

[quote]Even still, would it be at all efficient to be creating a Sprite object very often with its Texture components when all I really want to do is blit a new BufferedImage to the screen?
[/quote]
Not sure I understand, can you explain more. Creating or updating textures are slow, if thats what you are asking.

[quote]I also do a lot of work in terms of drawing with the AffineTransform class. I assume there are fast counterparts to the transformation work I’d need to do for OpenGL right?
[/quote]
Of course. In opengl there is a matrix stack that contains the current transform.

[quote]Also, what about regular computers without 3D graphics cards? Will the OpenGL drivers still be able to draw my sprites faster than Java2D can?
[/quote]
LWJGL won’t work unless the computer has hardware accelerated opengl. I think JOGL supports software mode, but I don’t think it will be faster than Java2D.

You need to read the red book. (There is a link to a pdf and html version at the bottom of the page).

In the interest of a slow and steady conversion to being able to use LWJGL, I was thinking I’d take it one step at a time, just converting what I needed to, instead of spending half an hour altering code and hoping it would all work at the same time.

So I made a Sprite constructor that would take a BufferedImage and do the same operations to create the Sprite as the regular Sprite constructor that takes a string for the file name.

I kept my game the same, except each loop I rendered my game to a BufferedImage, and I created a Sprite using it, and let LWJGL render that to the screen. It took about half a second to do every frame. That wasn’t cool.

I know when I have the rest of it working I’ll be mostly using pre-made Sprites, but still, I would really like to keep drawing my BufferedImages. All the menu’s are just fine and dandy and really don’t have a need for converting. I could just draw them to a BufferedImage, and have whatever active renderer that is working draw the BufferedImage on top of the game. The actual game, away from menu’s, is where I care about speed and FPS.

Do I have any good options for doing what I’m trying to do? I couldn’t figure out how to use glTexImage2D() and the Red Book didn’t help give me any ideas. It’s like me looking up a Spanish word in a Spanish dictionary. I just get more Spanish words :slight_smile:

Per default, LWJGL refuses to run on software OpenGL, but if you use


 -Dorg.lwjgl.opengl.Window.allowSoftwareOpenGL=true

on the command line, you can override this behaviour. As for your BufferedImage troubles, I can’t help you (other than saying “convert it all to OpenGL”, but that won’t help you).

  • elias

if I really did just convert all my Graphics2D calls into OpenGL calls, and my game ran on a computer that didn’t support OpenGL and had to have it work in software mode, would lwjgl handle that and still make it run as fast as it does now with Java2D?

[quote]if I really did just convert all my Graphics2D calls into OpenGL calls, and my game ran on a computer that didn’t support OpenGL and had to have it work in software mode, would lwjgl handle that and still make it run as fast as it does now with Java2D?
[/quote]
I highly doubt it - OpenGL is dog-slow in software mode (at least the standard Windows implementation).

if your clever enough, you could abstract the rendering bits from your code. That way, you can check if they have an OpenGL able card and use OpenGL, if not, use Java2D.

So you would have the exact same methods in your renderer for both Java2D and OpenGL, e.g. draw(TriMesh t). In java2D, that would be a polygon made up of triangles using the drawPolygon method. in OpenGL you would use a triangleStrip.

Hope that helps, DP

true, but one thing I do now is create BufferedImages and hold on to them and only change them when stuff in the menu changes. This makes the speed MUCH faster when menu’s are working (important for key response as well as the game running in the background). If I take out that optimization, the Java2D version will be very slow. However, if I leave it, the OpenGL version will be very slow. Even abstracting the Graphics class wouldn’t be able to handle that.

The only way I can think to manage that one would just be a whole bunch of if statements checking the draw method and deciding whether or not to do something.

ok as far as how much of the CPU is involved in rendering, and considering the advantage I have of storing BufferedImages for menu portions so I don’t have to re-create them, OpenGL isn’t going to be THAT helpful. A lot of the advantage of my storing them is that I don’t have to recalculate a lot of stuff. In that area of the game it’s not all rendering speed, it’s a lot of other calculation work. If I can’t store those pieces as BufferedImages and use them efficiently, then I guess OpenGL is out for me.

That’s really confusing though… I can recreate a BufferedImage every frame if I wanted to and draw it with unaccelerated translucency and it’s still SOOO much faster than creating a Sprite and drawing it with OpenGL. Why is that? It doesn’t make sense to me that Java2D would be so much faster at just drawing a BufferedImage to the screen. Is there NO other option for having OpenGL do that?

How about the new Java 5 feature for enabling the OpenGL pipeline for Java2D calls? Is there any way to use OpenGL drivers to take advantage of that? I can run AlienFlux just fine because my graphics card supports OpenGL. However it doesn’t support all the exact picky things Java needs to enable the OpenGL pipeline with the System property -Djava.sun.opengl. It seems like if some extra drivers is all I need to get AlienFlux doing all its crazy 3D things with OpenGL, that I could use them for the same purpose in enabling this pipeline. Any ideas there? It seems like I’m coming to the end of my options with OpenGL here and I might just have to toss it and stick with Java2D.

I’m not sure why you need to render anything to a bufferedimage and cache it in the first place?

Under GL, just draw everything - every frame.

Cas :slight_smile:

What I was trying to say was that some times deciding what needs to be drawn and how takes a lot of decision making and calculations and then scaling and color saturation before doing a draw. Even if I’m doing this every frame with OpenGL, the biggest expense here is all of the calculating. That’s why I store a BufferedImage, so that I don’t have to redo all of the calculations every frame. I want to still have this advantage

“What to draw” and “how to draw it” are two different concepts. Work out what you want to draw once and stash that somewhere. Then when asked to draw it, it should be a simple matter of blitting quads and such. It’s a bit like optimising the drawing of a quadtree landscape. The quadtree is what you want to render; whenever the viewpoint changes you work out what to draw and stuff that in an intermediate structure that knows how to draw itself fast. Same here with your menus.

GL even has a few tricks up its sleeve which might even make it easier, such as display lists.

Cas :slight_smile: