Java-Gaming.org    
Featured games (91)
games approved by the League of Dukes
Games in Showcase (581)
games submitted by our members
Games in WIP (500)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  LWJGL 2D performance questions...  (Read 1206 times)
0 Members and 1 Guest are viewing this topic.
Offline Sparky83

Senior Member


Medals: 6
Projects: 1



« Posted 2012-12-08 14:41:12 »

Hello everyone!

This my first java-related post in here. Cheesy I have read a variety of other topics in hope to find some clues that help me solve my problems. But I couldn't find a solution to this one, so maybe you can help me out this time.  Smiley

A short version of the problem:
I am using LWJGL and slick-utils to program a 2D top down shooter. I have a spaceship, 4 enemy-spaceships for testing, a scrolling background made of tiles and a status screen with user interface. The main problem is that with the tiled background the performance is really breaking down. I am still testing, so the background isn't moving and I am drawing far too much of it. It consists of 500 tiles that come from a texture that i cut into regions so that I won't have to bind a texture that often. Of course these are the main work of the loop. If I stop drawing anything, then the avarage cycle takes 0.3 millisec. If I draw them, the cycle goes to 5 millisec. A tile is 24x28 pixels in size. The application runs in windowed mode and the resolution is at 720 x 680. Oddly...

I don't really have any idea what makes the rendering of the tileMap so time consuming. I am currently using VBOs for rendering, before that I used vertex arrays. I have around 60fps with my Core i3 M330 and AMD Radeon HD 5650M.

I might have forgotten something important. I will paste some of my code in here. First the game loop:
http://pastebin.java-gaming.org/6bfe88b2032

And here is the code for the tiles:
http://pastebin.java-gaming.org/bfe8b902231

I would be glad if someone had any idea what could be the problem. Are 500 textureRegions really that much? Am I doing something wrong.

Thank you for your help in advance! Smiley If something is missing or if you need more information, tell me please.
Offline matheus23

JGO Kernel


Medals: 98
Projects: 3


You think about my Avatar right now!


« Reply #1 - Posted 2012-12-08 15:01:52 »

You have to change your approach:

Put the sprite you use for the background into another seperate texture, and remove it from as TextureRegion.
Since texture regions are only for optimizing the number of
glBindTexture(GL_TEXTURE_2D, uniqueid);
calls and you only have to bind it once for the background, texture binding is no problem anymore.

When loading the texture and having it enabled, call:
1  
2  
3  
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_WRAP_T, GL_REPEAT);

This will make the texture repeat if you use texture UV's (texture coords) greater than 1. See this example image. In that image the UV's (0, 0) to (3, 3) were used.

When you did this, draw only 1 single fullscreen quad with the texture enabled and the UV's describing the number of times the texture should be repeated over the background. If you want the texture to be pixel-sized, you have to do this:

1  
2  
3  
4  
5  
public TexCoord getRepeatingTexCoords(int spriteWidth, int spriteHeight, int screenWidth, int screenHeight) {
    float u = (float) spriteWidth / (float) screenWidth;
    float v = (float) spriteHeight / (float) screenHeight;
    return new TexCoord(u, v);
}

(Untested. But pretty sure this should work!)

<edit>
With this you would only need 1 quad instead of 500. This means there are 3996 Vertices less moved over the BUS and 3996 Vertices less multiplied by 4x4 matrices in the vertex shader / graphics card processors.

In other words: It's now likely fill rate limited, not vertex limited Smiley
</edit>

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Offline Sparky83

Senior Member


Medals: 6
Projects: 1



« Reply #2 - Posted 2012-12-08 15:18:15 »

Thank you for your answer!

I have the feeling, that I didn't make quite clear, why I am using a tiled background. I don't have a big sprite that contains the whole background, but I construct it through the definition of a map in the map editor Tiled. So I have to have these little textureRegions.

I don't really get the point with the repeating texture. This could be good for a never ending background... cycling until the end of the level. But this is not what I want to do.

What I already did is extracting the tiles I am using into a single tilesheet-texture. This is what I meant with reducing texture binds.

Here is a screenshot of my program as far as I have it now. I have to mention, that I am currently using Tyrian images as placeholders.


Maybe there is something that I didn't get the way you meant it. I am still new to many of this stuff. Sorry for that. Wink
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline ClickerMonkey

JGO Coder


Medals: 20


Game Engineer


« Reply #3 - Posted 2012-12-08 15:23:11 »

It looks like you're clearing and drawing the VBO for each tile, try putting them all in one and draw it once. Hopefully I read your code completely, you missed how you were calling the draw tile method.

Offline Sparky83

Senior Member


Medals: 6
Projects: 1



« Reply #4 - Posted 2012-12-08 15:34:09 »

This is a good point there, didn't think of this as a possibility. You see, I am new to it. Smiley Thanks very much for the hint! I will report about the changes asap.
Offline davedes
« Reply #5 - Posted 2012-12-08 18:24:35 »

You need to write a sprite batcher; something that will accumulate all of the sprite data and only render them when necessary, i.e. in large batches. Ideally you will then end up with a single VBO draw call per frame.

I'd also recommend getting used to GL_TRIANGLES since quads are deprecated.

Here is an example of what a sprite batcher looks like:
https://github.com/mattdesl/lwjgl-basics/blob/master/src/mdesl/graphics/SpriteBatch.java

It uses vertex arrays for simplicity (and because they are sometimes faster), but it should be easy enough to extend to vertex buffer objects.

Furthermore, you should part from the old school SlickUtil and learn to write your own texture loaders. It will potentially be more performant, and definitely be more flexible. I recently started writing a tutorial series on this subject, which you might find useful. It's still a work in progress, but you can find it here:
https://github.com/mattdesl/lwjgl-basics/wiki


EDIT: Regarding your game loop, where is Display.sync and Display.update? Huh

Offline Sparky83

Senior Member


Medals: 6
Projects: 1



« Reply #6 - Posted 2012-12-08 20:36:40 »

As promised, here is my report about the changes!

ClickerMonkey, I thank you very much! It was no complicated thing, but I just didn't have the idea to put all the quads in one buffer and then let them be rendered. Now I put the tilerendering in the Map class where all tiles are put in one buffer. Et voilá!!
It works like a charm, now the FPS is back to 400! Which is really awesome and exactly what I aimed for!

@davedes: thank you for your help!
Quote from: davedes
You need to write a sprite batcher; something that will accumulate all of the sprite data and only render them when necessary, i.e. in large batches. Ideally you will then end up with a single VBO draw call per frame.
Ahhh, interesting! This reminds me of libGDX. There is also a SpriteBatch. Well I have seen now what happens if I don't use batching and the difference in performance is really huge. So this is a point I will definitly take advantage of.

Quote
I'd also recommend getting used to GL_TRIANGLES since quads are deprecated.
Is this really true?! I didn't know that...

Quote
Furthermore, you should part from the old school SlickUtil and learn to write your own texture loaders.
This is something that I wanted to do sometime but is not important enough to me right now. You know, I like figuring out how things work inside and this is another nice challenge. I will then definitly take a closer look at your tutorials, they look really great!

So again, thanks for your help and now I have new motivation! I am looking forward to finishing my little programming project.

EDIT: Ah, I forgot!
Quote
EDIT: Regarding your game loop, where is Display.sync and Display.update? Huh
I have no Display.sync, but update is hidden in render().
Offline Sparky83

Senior Member


Medals: 6
Projects: 1



« Reply #7 - Posted 2012-12-25 23:58:20 »

Furthermore, you should part from the old school SlickUtil and learn to write your own texture loaders. It will potentially be more performant, and definitely be more flexible. I recently started writing a tutorial series on this subject, which you might find useful. It's still a work in progress, but you can find it here:
https://github.com/mattdesl/lwjgl-basics/wiki
I have now read your tutorial regarding the loading of textures. It is a really good read and covers all the needed information as far as I can tell. I have implemented it with some adjustments in style and attributes. And what surprised me: it worked at the first attempt! I didn't try or debug anything. This is the way it has to be! Wink

I just wanted to say thank you!   Smiley
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

xsi3rr4x (58 views)
2014-04-15 18:08:23

BurntPizza (56 views)
2014-04-15 03:46:01

UprightPath (69 views)
2014-04-14 17:39:50

UprightPath (52 views)
2014-04-14 17:35:47

Porlus (69 views)
2014-04-14 15:48:38

tom_mai78101 (95 views)
2014-04-10 04:04:31

BurntPizza (155 views)
2014-04-08 23:06:04

tom_mai78101 (250 views)
2014-04-05 13:34:39

trollwarrior1 (206 views)
2014-04-04 12:06:45

CJLetsGame (213 views)
2014-04-01 02:16:10
List of Learning Resources
by SHC
2014-04-18 03:17:39

List of Learning Resources
by Longarmx
2014-04-08 03:14:44

Good Examples
by matheus23
2014-04-05 13:51:37

Good Examples
by Grunnt
2014-04-03 15:48:46

Good Examples
by Grunnt
2014-04-03 15:48:37

Good Examples
by matheus23
2014-04-01 18:40:51

Good Examples
by matheus23
2014-04-01 18:40:34

Anonymous/Local/Inner class gotchas
by Roquen
2014-03-11 15:22:30
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!