A little background: I'm working on my first game in java (using the LWJGL/OpenGL setup)When I made the game loop months ago, I was not aware of this "delta-time" business with a shifting frame rate. It's a little too late to implement it into this game.I worry a lot about efficiency. I try to keep the number of checks my game has to do down to a minimum.

I'm just kinda curious about how much OpenGL can handle. My framerate is arbitrarily fixed at 60 fps, and I'm drawing about 350-ish (2D) sprites at a time.Of those, About 300 all come from the same texture (a sprite sheet) which is bound once then drawn a lot. Another 50 of those objects also come from a single sprite sheet, and then about 5-20 other small sprites that each have their own texture.And then of course there are a load of other computations going into each step. Nothing crazy.

Given that the frame rate is unadjustable, should I drop it to something along the lines of 30 and half the speed of everything in the game? (Wouldn't be that hard)

Even though I'm a few thousand lines of source code into my game, only a few of those deal with movement. Is it worth it to go back in and put in a delta?

What are OpenGL's limits? Am I anywhere near them, or am I a ridiculous worrier?? What about players who have low end machines/netbooks?

I wouldn't worry about it. I can paint 160k transparent sprites from the same sprite sheet in less than 5ms. There was a thread about a year ago where people were trying to see how many bouncy balls they could paint in a frame and it was some kind of ridiculous number (much higher than my 160k).

I wouldn't worry about it. I can paint 160k transparent sprites from the same sprite sheet in less than 5ms. There was a thread about a year ago where people were trying to see how many bouncy balls they could paint in a frame and it was some kind of ridiculous number (much higher than my 160k).

Ultimately those numbers depend on the hardware and driver quality.

Depends on the pixel area they cover. For pixel sized stuff you can do at least 1 million, but on high-end hardware almost 10 million.

When using the GPU, it works in parallel with the CPU. Your CPU feeds the raw vertex data to the GPU, and the GPU then processes the vertices, constructs triangles out of them and colors the covered pixels. CPU-wise you need to feed the GPU data fast enough to keep it from stalling. If you don't, you get a CPU bottleneck where the GPU has to wait for more instructions. It's even easier to get a GPU bottleneck, since with just a single quad you can cover the whole screen, for example:

OpenGL is just as potent as DirectX, so you have the exact same GPU capabilities as any other game out there, including commercial ones. For 2D the real problem is CPU performance. OpenGL commands are actually pretty expensive though (Java ---> native call ---> driver ---> GPU), so it's important to as CPU efficiently as possible draw as much as possible.

Some tips: - Instead of using glBegin()-glEnd(), batch the sprite vertices together into a VBO and draw it with glDrawArrays(). - Texture binds make batching impossible since you need to do OpenGL calls in between to switch textures. Consider creating texture atlases (for example a tile set texture instead of individual tile textures) and picking out parts of it with texture coordinates.

Some GPU numbers to give you a general idea:Pixels:A low-end GPU can easily draw 5+ million pixels per frame (not including clearing the screen. glClear() is ridiculously fast). A high-end GPU can do over 40 million pixels per frame at 60 FPS. It does however depend on what operations you perform per pixel. Texturing and blending both have a small but noticeable cost.

Vertices:At least 1+ million for 2D. In other words don't worry about vertices.

TL;DR: frameTime = max(cpuTime, gpuTime), and in the case of 2D CPU time is almost always higher. Focus on optimizing it.

Some tips: - Instead of using glBegin()-glEnd(), batch the sprite vertices together into a VBO and draw it with glDrawArrays(). - Texture binds make batching impossible since you need to do OpenGL calls in between to switch textures. Consider creating texture atlases (for example a tile set texture instead of individual tile textures) and picking out parts of it with texture coordinates.

First, I'd like to thank all of you for such detailed responses(Also thanks for the glBegin() tip! I use that a lot. Looks like I have some research to do.)

Some tips: - Instead of using glBegin()-glEnd(), batch the sprite vertices together into a VBO and draw it with glDrawArrays(). - Texture binds make batching impossible since you need to do OpenGL calls in between to switch textures. Consider creating texture atlases (for example a tile set texture instead of individual tile textures) and picking out parts of it with texture coordinates.

First, I'd like to thank all of you for such detailed responses(Also thanks for the glBegin() tip! I use that a lot. Looks like I have some research to do.)

Well, I feel properly comforted. Thanks, guys!

There's no problem using glBegin()-glEnd() for some things like for example a fullscreen background. Switching to VBOs for the sake of 4 vertices covering hundreds of thousands of pixels does nothing for performance.

There's no problem using glBegin()-glEnd() for some things like for example a fullscreen background. Switching to VBOs for the sake of 4 vertices covering hundreds of thousands of pixels does nothing for performance.

Cas mentioned once that mixing VBOs and immediate mode did have an impact on the performance of VBOs (probably a driver issue)

Hi, appreciate more people! Σ ♥ = ¾Learn how to award medals... and work your way up the social rankings!

There's no problem using glBegin()-glEnd() for some things like for example a fullscreen background. Switching to VBOs for the sake of 4 vertices covering hundreds of thousands of pixels does nothing for performance.

Cas mentioned once that mixing VBOs and immediate mode did have an impact on the performance of VBOs (probably a driver issue)

There's no problem using glBegin()-glEnd() for some things like for example a fullscreen background. Switching to VBOs for the sake of 4 vertices covering hundreds of thousands of pixels does nothing for performance.

Cas mentioned once that mixing VBOs and immediate mode did have an impact on the performance of VBOs (probably a driver issue)

It's something "common" now... I use VBOs even for trivial examples.

I do too since I'm trying to embrace OpenGL 3+, but it's still annoying having to create a fragment+vertex shader, a VAO and 2 VBOs just to do a fullscreen quad. >_>

I use a little framework now to do all that crap for me. Worthwhile investing the time to make one I think.

Cas

Cas, did you write this yourself? I'd be interested to see it. I have been hearing about VBOs here and there ever since I've started working with LWJGL and Slick and I've wanted to find out more about what they are and how they increase performance.

EDIT: Just found out you founded LWJGL! It's an honor to be using your technology to develop my game in! I know it's changed a lot but it's been great having the chance to interface with OpenGL using Java in such a clean and easy manner!

I don't know much about OpenGL yet, but on the subject of using deltatime instead of a flatrate to update sprite-animations, I highly recommend it. Since I made the switch, I feel like I've gained so much control over the state of my animations and entities in general, and if you're already thinking about changing your FPS, you might as well take the leap.

Don't use immediate mode (glBegin/glEnd, excluding display lists)You should use a rendering method where you supply the vertex data only once, and modify it as little as possible. This allows the GPU to optimise the way it handles your vertices, because they are stored in the server memory (memory on the GPU) instead of in the client memory (memory on the CPU or RAM). Try using display lists or VBOs.

Call as little OpenGL functions and possibleTry minimizing the amount of OpenGL functions called. For example, constantly binding and unbinding textures can be a costly operation. When you call a function like glGet, the graphics card has to execute all the previously issues commands (it doesn't do most of them directly) before it can give you a correct value. The less synchronisation there has to be between the CPU and the GPU, the better.

I have found that in a real-game situation then 1000 sprites at 60fps is a reasonable goal that's achievable on a wide range of hardware. And by "real-game" I mean a realistic scenario with a large variety of sprite types, drawing modes, layers, multiple sprite sheets and render passes. Any more than that tends to become either fillrate limited or cpu bound shunting sprite data around.

You can get higher than that if you start requiring more recent hardware, or doing scene-specific optimisations, but I find 1k a good ballpark to aim for. Fortunately pretty much any game can be done in 1k sprites.

Not mine! Even lowly Titan Attacks uses something like 1500 sprites. Seeing as that's been running at 60Hz for 6 years even on lowly hardware from back in the day I think you can realistically aim for 2500 sprites per frame instead of a lowly 1000

Not mine! Even lowly Titan Attacks uses something like 1500 sprites. Seeing as that's been running at 60Hz for 6 years even on lowly hardware from back in the day I think you can realistically aim for 2500 sprites per frame instead of a lowly 1000

Cas

Yeah, that may be a little on the low side. It also doesn't count particle effects, as I think those should be special cased these days anyway.

I'm not, yet. Mostly just been eyeing up a friend's system after going over the high-level design with him. It's pretty vanilla really - a fixed size pool of particles with a life value incremented on cpu, and a stateless movement equation in the vertex shader.

I'm not, yet. Mostly just been eyeing up a friend's system after going over the high-level design with him. It's pretty vanilla really - a fixed size pool of particles with a life value incremented on cpu, and a stateless movement equation in the vertex shader.

!!!

So particles are just represented by a starting position and velocity and creation time, and then you calculate the current position with a parabola function using gravity or something?

I'm not, yet. Mostly just been eyeing up a friend's system after going over the high-level design with him. It's pretty vanilla really - a fixed size pool of particles with a life value incremented on cpu, and a stateless movement equation in the vertex shader.

!!!

So particles are just represented by a starting position and velocity and creation time, and then you calculate the current position with a parabola function using gravity or something?

Yup. And colours are done by indexing into a 2d texture (with life on one axis and a per-particle random value on the other). It's pretty old school really, but I'm only just getting around to doing a proper shader based 2d renderer, rather than FF.

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