If I draw something with coordinations like -80 and -90 will it affect performance same way as if it was actually drawn inside?
Is it actually worth it checking if the final image will appear on screen?
(and not drawing it if won't)
If I draw something with coordinations like -80 and -90 will it affect performance same way as if it was actually drawn inside?
Somewhat, but not nearly as much as if it is inside the screen.
Is it actually worth it checking if the final image will appear on screen? (and not drawing it if won't)
It's practically never worth implementing your own culling/clipping in a library where drawing out of bounds isn't an error/access violation, since the library would already have to make that check to avoid writing to memory out of bounds, and it would generally be wise to bet that the library's way of checking this is smart and fast.
So if you were to add your own basic check on top, now you're just making the regular, on-screen drawing perform two of such checks (your own on top of whatever is going on under the hood), and for off-screen cases, it would be likely that your check would actually be slower (or at least no better) than the library's.
Now I have to place emphasis on basic culling/clipping here. By basic, I mean checking for each shape you draw on a per-shape basis. There you'll just more likely damage performance.
Acceleration Structures and Clipping/Culling in Bulk
Yet there are cases where you might have a data structure to do efficient culling of thousands of triangles at once with a single bounding box check to see if it's in the frustum, for example, in a 3D case with structures like bounding volume hierarchies. Games use these types of data structures to massively reduce the amount of drawing requests required per frame with very few checks, and there you do gain a potentially massive performance benefit. A more basic version of this is simply check if the object/mesh containing the triangles has a bounding box that is inside the screen, eliminating potentially thousands of triangles from being culled individually with a single bounding box check.
In 2D with clipping, you might be able to use something like a quad tree or fixed grid to only selectively draw what's on the screen (and also accelerate collision detection or click-detection, e.g.). There you might actually get a performance boost if you can eliminate many superfluous drawing calls with a single check. But again, that's using a data structure that eliminates a boatload of unnecessary drawing calls with a single check. These are spatial partitioning structures whose sole point is to avoid checking things on a per-shape basis.
For a more basic 2D example, if you have say, a 2D "widget" which, in order to draw it, involves drawing dozens of different shapes to the screen, you might be able to squeeze a performance gain if you can avoid requesting to draw dozens of shapes with a single check to see if the rectangle encompassing the entire widget is in the screen. Again, there you're doing one check to eliminate many drawing calls. You won't get a performance gain on a level playing field where you're doing that check on a per-shape basis, but if you can turn many checks into a single check, then you have a chance.
According to the Graphics implementation for most common draws/fills (i.e. drawRectangle see: source of Graphics on grepcode.com they start with checking if the width and height are bigger then zero and then are doing more operations, therefore doing check for x,y < 0 are in doing the same number of operations in worst case.
Keep in mind that a rectangle starting at -80 and -90 as you said but width and height i.e. 200 will be displayed on screen.
Yes it will still affect the performance as it still does exist within the program, it's just not visible on the screen
Related
I am attempting to draw two textures to 3D space that containing transparency. When they do not overlap they work fine:
However when one texture overlaps the other the the transparency means that you can see through the one behind:
I use GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA when initialising blending.
You need to either depth sort or use alpha testing:
glEnable(GL_ALPHA_TEST);
glAlphaTest(GL_GREATER, 0.0f);
which will only draw pixels that have an alpha value of more than 0f. However, this doesn't work for blending transparent pixels. Andon's solution is the one that I use, although I work in 2D and I have to have transparency for smoke effects.
One possibility is to use the discard keyword in the fragment shader, as the alpha test is no longer with us. This has the disadvantage of having aliased edges of objects.
Another possibility is to depth-sort the objects and draw back to front. Obvious disadvantage is having to perform the transformations and the sorting in the first place. This can be sometimes avoided if the order of the objects can be determined statically (when the camera doesn't change much). Another disadvantage is overdrawing of the shaded pixels by something different, therefore throwing away performance.
Finally, you can use alpha-to-coverage, where the antialiassing hardware is employed to take care of the transparency. This doesn't require sorting and makes the edges of the objects smooth. The disadvantage is that this is enabled per rendering context and may not be available everywhere.
I've been trying various ways of creating a two-dimensional tile-based game for a few months now. I have always had each tile be a separate object of a 'Tile' class. The tile objects are stored in a two-dimensional array of objects. This has proven to be extremely impractical, mostly in terms of performance with many tiles being rendered at once. I have aided in this by only allowing tiles within a certain distance of the player being rendered, but this isn't that great either. I have also had problems with the objects returning a null-pointer exception when I try to edit the tile's values in-game. This has to do with the objects in the 2D array not being properly initialized.
Is there any other, simpler way of doing this? I can't imagine every tile-based game uses this exact way, I must be overlooking something.
EDIT: Perhaps LWJGL just isn't the correct library to use? I am having similar problems with implementing a font system with LWJGL... typing out more than a sentence will bring down the FPS by 100 or even more.
For static objects (not going anywhere, staying where they are) 1 tile = 1 object is OK. That's how it was done in Wolf3d. For moving objects you have multiple options.
You can, if you really really want to, store object sub-parts in adjacent cells/tiles when an object isn't contained fully within just one of them and crosses one or more cell/tile boundaries. But that may be not quite handy as you'd need to split your objects into parts on the fly.
A more reasonable approach is to not store moving objects in cells/tiles at all and process them more or less independently of the static objects. But then you will need to have some code to determine object visibility. Actually, in graphics the most basic performance problems come from unnecessary calculations and rendering. Generally, you don't want to even try to render what's invisible. Likewise, if some computations (especially complex ones) can be moved outside of the innermost loops, they should be.
Other than that it's pretty hard to give any specific advice given so little details about what you're doing, how you're doing it and seeing the actual code. You should really try to make your questions specific.
A two-dimensional array of Tile objects should be fine........ this is what most 2D games use and you should certainly be able to get good enough performance out of OpenGL / LWJGL to render this at a good speed (100FPS+).
Things to check:
Make sure you are clipping to only deisplay the visible set of tiles (According to the screen width and height and the player's position)
Make sure the code to draw each tile is fast... ideally you should be drawing just one textured square for each tile. In particular, you shouldn't be doing any complex operations on a per-tile basis in your rendering code.
If you're clever, you can draw multiple tiles in one OpenGL call with VBOs / clever use of texture coordinates etc. But this is probably unnecessary for a tile-based game.
I am writing a game on Android, and it is coming along well enough. I am trying to keep everything as efficient as possible, so I am storing as much as I can in Vertex Buffer Objects to avoid unnecessary CPU overhead. However the simple act of drawing lots of unrelated primitives, or even a varying length string of sprites efficiently (such as drawing text to the screen) is escaping me.
The purpose of these primitives is menus and buttons, as well as text.
For drawing the menus, I could just make a vertex array for each element (menu background, buttons, etc), but since they are all just quads, this feels very inefficient. I could also create a sort of drawQuad() function that lets me just transparently load a single saved vertex array with data for xy/height&width/color/texture/whatever. However, reloading each element of the array with the new coordinates and other data each time, to copy it to the Float Buffer (For C++ guys, this is a special step you have to do in Java to pass the data to GL) so I can resend it to the GPU also feels lacking in efficiency, though I don't know how else I could do it. (One boost in efficiency I could see is setting the quad coordinates to be a unit square and then using Uniforms to scale it, but this seems unscalable).
For text it is even worse since I don't know how long the text will be and don't want to have to create larger buffers for larger text (causing the GC to randomly fire later). The alternate is to draw each letter with a independent draw command, but this also seems very inefficient for even a hundred letters on the screen (Since I read that you should try to have as few draw commands as possible).
It is also possible that I am looking way too deep into the necessary optimization of openGL, but I don't want to back myself into a corner with some terrible design early on.
You should try looking into the idea of interleaving data for your glDrawArrays calls.
Granted this link is for iphone, but there is a nice graphic at the bottom of the page that details this concept. http://iphonedevelopment.blogspot.com/2009/06/opengl-es-from-ground-up-part-8.html
I'm going to assume for drawing your characters that you are specifying some vertex coords and some texture coords into some sort of font bitmap to pick the correct character.
So you could envision your FloatBuffer as looking like
[vertex 1][texcoord 1][vertex 2][texcoord 2][vertex 3][texcoord 3]
[vertex 2][texcoord 2][vertex 3][texcoord 3][vertex 4][texcoord 4]
The above would represent a single character in your sentence if you're using GL_TRIANGLES, and you could expand on this idea to have vertices 5 - 8 to represent the second character and so on and so forth. Now you could draw all of your text on screen with a single glDrawArrays call. Now you might be worried about having redundant data in your FloatBuffer, but the savings will be huge. For example, in rendering a teapot with 1200 vertices and having this redundant data in my buffer, I was able to get a very visible speed increase over calling glDrawArrays for each individual triangle maybe something like 10 times better.
I have a small demo on sourceforge where I use data interleaving to render the teapot I mentioned earlier.
Its the ShaderProgramTutorial.rar. https://sourceforge.net/projects/androidopengles/files/ShaderProgram/
Look in teapot.java in the onDrawFrame function to see it.
On a side note you might find some of the other things on that sourceforge page helpful in your future Android OpenGL ES 2.0 fun!
So I'm writing a sort of particle simulator, like a "falling sand game" if you know what that is, and I've kind of hit a roadblock now. The way I'm doing this is I have a particle object that basically as of now has an position (int x, int y) and that's it. The way I'm drawing/moving them, is with a thread and the onDraw event for an android panel. Each time onDraw is called I loop through all the particles, move them down one pixel unless they hit the bottom and then draw them, this is pretty smooth until I get to about 200 particles, then the fps drops significantly. I know this is computation heavy the way I'm doing it, there's no debate about it, but is there any way I could do this to allow a lot more particles to be drawn and with less lag?
Thanks in advance.
I take it you're using an individual-pixel drawing function for this? That would indeed be slow.
I see a couple ways to improve it. First is to put the pixels into an in-memory bitmap then draw the whole bitmap at the same time. Second, since particles are always just going down one pixel, you can scroll part of the bitmap instead of replotting everything. If Android doesn't have a scroll then just draw the bitmap one pixel down and start a new bitmap for the particles above the scroll. You'll have to fix up the particles on the bottom, but there are fewer of those.
I've never done things like this before, but I have done some complex cellular automata. Sorry if this is too vague.
The basic idea here is to mark all particles that should "keep falling" or "not move" and exclude them from complex processing (with a special short/fast processor for the "falling" list - all you need to do is drop each one by a pixel).
The acceleration for non-moving particles - static particles (I'll call them S particles), is that they don't move. Mark it for all non-moving regions (like a gravity-immune "wall" or "bowl" that a user might make. Mark particles above it S if they are stable, so for example for liquid, if it has S particles under, and to both sides of itself, it will not move. For something like sand that forms piles, if it has an S in each of the three spots under it, it makes a pile, you'll get nice 45-degree piles like this, I'm sure you can change it to make some things form steeper, or less-steep piles. Do S mapping bottom-up.
The acceleration for particles with no particle under them is falling - F particles. Particles with an F particle under them are also F particles. Mark these bottom-up as well.
Particles unmarked F or S are complex, they may start falling, stop falling, or roll, use the slow processor, which you already have, to deal with them, there shouldn't be many.
In the end what you will have is many many fast particles. Those in a pile/lake and those raining down. The leftover particles are those on the edge of slopes, on the top of lakes, or in other complex positions. There shouldn't be nearly as many as there will be fast particles.
Visually mark each kind of particle with some colour, complex particles being bright red. Find cases where it is still slow, and see what other kinds of fast processors you should make. For example you may find that making lots of piles of sand creates lots of red areas along slopes, you may want to invest in speeding up "rolling zones" along the slopes of piles.
Hope it makes sense. Don't forget to come back and edit once you've figured something out!
You may want to look into OpenGL ES hardware acceleration and renderscript. It doesn't give you a more efficient solution code wise (see the other answers for that). It does open up a lot more processing power for you to use however. You can even run the entire simulation on the GPU (possibly, don't know your implementation details).
Edit
Also, if you still decide to do the processing in java, you should look at Method Profiling in DDMS. This will help you visualize where your performance bottlenecks are.
If you blur your image a bit, then you could just move half particule at a time, maybe one fourth only and print them all.. that would cut computation and the user wouldn't see it, getting the feeling all particules move.
But what ever you choose, I think you should be put a strong limit, not all users have powerfull android devices.
Regards,
stéphane
I think if particles are close each other, you can create objects that represent 3 or more particles.
When displaying several particles on screen, sets of grains maybe gets unnoticed.
I'm trying to develop side scrolling game for android involving many many textures so I was thinking if I could create a separate layer, all a single unique color (very similar to a green screen effect) make a collidable and make it invisible to the player.
(foreground layer) visual Image
(2nd layer)collidable copy of foreground layer with main character
(3rd layer)Background image
I not sure if this is possible or how to implement it efficiently, the idea just came to me randomly one day.
Future regards, Thanks
I assume your game is entirely 2D, using either bit-blits or quads (two 3D triangles always screen-aligned) as sprites. Over the years there have been lots of schemes for doing collision detection using the actual image data, whether from the background or the sprite definition itself. If you have direct access to video RAM, reading one pixel position can quickly tell if you've collided or not, giving pixel-wise accuracy not possible with something like bounding boxes. However, there are issues greatly complicating this: figuring out what you've collided with, or if your speed lands you many pixels into a graphical object, or if it is thin and you pass through it, or how to determine an angle of deflection, etc.
Using 3D graphics hardware and quads, you could potentially change render states, rendering in monochrome to an off-screen texture, yielding the 2nd collidable layer you described. Yet that texture is then resident in graphics memory, which isn't freely/easily accessible like your system memory is. And getting that data back/forth over the bus is slow. It's also costly, requiring an entire additional render pass (worst case, halving your frame rate) plus you have all that extra graphics RAM used up... all just to do something like collision-detect. Much better schemes exist, especially using data structures.
It's better to use bounding boxes, or even a hierarchy of sub-bounding boxes. After that, you can determine if you've landed on the other side of, say, a sloped line, requiring only division/addition operations. Your game already manages all the sprites you're moving, so integrate some data structures to help your collision detection. For instance, I just suggested in another thread the use of linked lists to limit the objects you must collision-detect against one another.
Ideas like yours might not always work, but your continual creative thinking will lead to ones that do. Sometimes you just have to try coding them to find out!