OpenGL ES2... many questions - Printable Version
+- iDevGames Forums (http://www.idevgames.com/forums)
+-- Forum: Development Zone (/forum-3.html)
+--- Forum: Graphics & Audio Programming (/forum-9.html)
+--- Thread: OpenGL ES2... many questions (/thread-9280.html)
OpenGL ES2... many questions - vunterslaush - Aug 18, 2011 10:09 AM
I'm trying to study now OpenGL ES 2 for iOS games, and I want to create a sprite engine, and before I start- I want to ask what would be the best way to do it, for performance, app size, quality and ease of use.
What I want to be able to do is to draw a texture and easily modify it's position, scale (both horizontal and vertical), angle, and color/alpha.
I looked at lot's of examples, and read a lot, but still I don't understand a lot.
I'm pretty stuck...
NOTE: I realize that's a lot of questions, I don't expect someone to answer and explain everything, even giving me links or telling me what to google would be very appreciated. I'm trying to study after all
If I'm using ES 2, do I have to use shaders? (Generally and specifically to achieve what I described earlier).
What would be the most efficient way to handle textures? From what I understood using texture atlases is a good idea, so would you suggest putting as many sprites as possible on a single texture file?
Should I try minimizing calls to glDrawElements/glDrawArrays?
I mean- let's say draw all the sprites of texture1 in a single call, then all sprites of texture2, etc...
What is PVR? How Important is it to use that? Or is it fine to just stick to PNG's?
What is the best way to handle z-ordering? Is it possible to set up the projection so it will sorta "ignore" distance from the camera (objects in the distance still render at the same size) and then use the y/z/whatever to control the order of rendering?
Thanks for your help!
RE: OpenGL ES2... many questions - ThemsAllTook - Aug 18, 2011 10:38 AM
I'm by no means an OpenGL expert, but I can at least repeat the advice I've heard from people more experienced than me... One thing to keep in mind is not to prematurely optimize. In many cases, something which seems like it'll be a performance problem in your head won't actually be one in the real world, so you can often save yourself a lot of time and complexity by implementing it the slow way first and only changing it if it proves to be an actual bottleneck.
(Aug 18, 2011 10:09 AM)vunterslaush Wrote: If I'm using ES 2, do I have to use shaders? (Generally and specifically to achieve what I described earlier).
Yes. ES2 has no fixed function pipeline, so there isn't any way to draw stuff with it without using shaders.
(Aug 18, 2011 10:09 AM)vunterslaush Wrote: What would be the most efficient way to handle textures? From what I understood using texture atlases is a good idea, so would you suggest putting as many sprites as possible on a single texture file?
That's the usual recommendation. Texture changes can be expensive, so using atlases to minimize them makes sense if you can't get enough performance out of separate textures. Again, though, no need to prematurely optimize if it's simpler not to use a texture atlas.
(Aug 18, 2011 10:09 AM)vunterslaush Wrote: Should I try minimizing calls to glDrawElements/glDrawArrays?
Generally speaking, the fewer calls to OpenGL the better, as long as it doesn't require your program to do an inordinate amount of extra work.
(Aug 18, 2011 10:09 AM)vunterslaush Wrote: What is PVR? How Important is it to use that? Or is it fine to just stick to PNG's?
PVRTC is a lossy compression alternative to PNG. It produces smaller files and may net you some performance gains, at the cost of image quality. There are various tricks for dealing with/hiding the loss of quality. I've heard of people using a PVRTC-compressed image at a higher resolution than they would if they used a PNG, and getting reasonably good results while still keeping the benefits of smaller compressed size; as well as using lossy textures for in-between frames in animation that the player will only see for a split second, and lossless textures for the frames that stay onscreen for longer.
I seem to recall that PVRTC can be uploaded directly to OpenGL without a decoding step, eliminating the CPU time that would be spent unpacking a PNG to a pixel array, but I don't know the details of doing this.
(Aug 18, 2011 10:09 AM)vunterslaush Wrote: What is the best way to handle z-ordering? Is it possible to set up the projection so it will sorta "ignore" distance from the camera (objects in the distance still render at the same size) and then use the y/z/whatever to control the order of rendering?
Yep! An orthographic projection (using glOrtho or equivalent) has no foreshortening, so everything will render at the same size regardless of distance. You can also leave depth testing off and simply draw your sprites in the order you want them to appear, but if you're sorting by depth, you of course won't be able to sort by texture...
Hope this helps. Someone else may be able to chime in to fill in more specifics.
RE: OpenGL ES2... many questions - vunterslaush - Aug 18, 2011 11:26 AM
Thanks a lot for the detailed answer!
So I guess I'll start with png and if it would be costly I'll change to PVR...
About the atlases that's not a problem because I'm creating the graphics anyway so I can just use minimum texture atlases.
About the depth thing- using the orthographic sounds better because then I'll be able to sort by texture and minimize swapping calls.
BTW, what's the best way to sort the objects? A sorting algorithm, holding them in a self sorting data structure (AVL)...?
Damn, it's all theory but in practice I don't know how to do anything. The template is confusing me like hell, and the word "shader" makes me shiver.
I just wanna draw a sprite on the screen... Is that too much to ask?
Where do I begin?
RE: OpenGL ES2... many questions - ThemsAllTook - Aug 18, 2011 12:09 PM
(Aug 18, 2011 11:26 AM)vunterslaush Wrote: BTW, what's the best way to sort the objects? A sorting algorithm, holding them in a self sorting data structure (AVL)...?
There isn't any one best way to do it, but I usually find myself using insertion sort for this sort of thing. It's very easy to implement and reasonably speedy for an application like this.
(Aug 18, 2011 11:26 AM)vunterslaush Wrote: Damn, it's all theory but in practice I don't know how to do anything. The template is confusing me like hell, and the word "shader" makes me shiver.
Honestly, I'd begin with desktop OpenGL. It's much more forgiving when you can lean on the fixed function pipeline and immediate mode to get something working before bothering with shaders, VBOs, etc. It sounds like you might already have a pretty good grasp on it and just need to transition to ES2, though?
Shaders are a bit daunting, but I think that's mostly due to the complexity of the code you have to write before you can get anything at all on the screen and start messing with it. However, Xcode's OpenGL ES template provides you with an already-working example you can modify. There is certainly a lot of stuff in the template, and it's worth reading up on each thing it does at some point to understand it, but that's doesn't need to be a requirement for modifying the drawing code to make it do what you want.
A good first step might be to modify the template to load an image, create a texture from it, and apply that texture to the quad it draws. You'd need to add a new attribute to the vertex shader for texture coordinates (or replace the one that's used for color), add a varying to pass it to the fragment shader (or, again, repurpose the color one), then use that varying to look up the texture color in a sampler with the texture bound to it. Here are vertex and fragment shaders I use that have both texturing and color, in case they're useful to reference.
I learned about shaders from this book. I haven't found any free/online resources that are particularly good, but I imagine they exist somewhere.
RE: OpenGL ES2... many questions - vunterslaush - Aug 19, 2011 05:02 AM
Thanks a lot for your help!!!
Actually I have no background with OpenGL at all, but I did read a lot because I want to learn, but I have expirience with Flash programming.
So I think my plan is to try and modify the template to work with textures, and then use it to make a sprite engine, that will support texture atlases, and draw the sprites sorted by texture, with the orthogonal projection or whatever it's called.
BTW, if I use glDrawElements I would be able to draw all the sprites of the same texture in one call, right? (But then I would have to use triangle list instead of strips?)
RE: OpenGL ES2... many questions - Skorche - Aug 19, 2011 08:54 AM
Yes, you'll have to transform the sprite's geometry yourself and generate triangle lists.
You could generate triangle strips with degenerate geometry -- repeating vertexes to join things with triangles that have no area, but I don't think that will be faster in this case. You'll just end up outputting the same amount of redundant geometry when joining quads as you would by splitting each one into two separate triangles.
RE: OpenGL ES2... many questions - vunterslaush - Aug 20, 2011 05:59 PM
Hey again, so I'm playing around with a tutorial I downloaded, and I'm trying to understand a few things. What exactly is a VBO? Do I have to use those?
I want to know what I'm doing before I'm jumping into implementation.
I thought about having a loop that updates logic and graphics (maybe separate it to consider lag and stuff) and when I update the graphics I'll have to do this-
-Sort sprites by texture
-Create a VBO per texture, calculating the vertices of every sprite of that texture in the CPU considering my rotations and scales etc
-glDrawElements for that texture
Is that the right way to do it?
What do you guys do? What's the best way to make this sort of thing?
RE: OpenGL ES2... many questions - Mattonaise - Aug 20, 2011 08:47 PM
Just to ask in, would you be using a Texture2d class for sprites? It was originally from Apple used in their Lunar Lander example, and it's supposed to be very good, however i'm not sure if that is used in OpenGL ES 2 or if thats up to date.
RE: OpenGL ES2... many questions - vunterslaush - Aug 21, 2011 05:34 AM
No, I'm not using Texture2D but I have no idea if it's working with ES2 or not... Currently I'm trying to understand what's going on... I'm just modifying an example file I've found-
Anyways can anyone help with my last post?
RE: OpenGL ES2... many questions - vunterslaush - Aug 22, 2011 12:38 PM
(Aug 20, 2011 05:59 PM)vunterslaush Wrote: Hey again, so I'm playing around with a tutorial I downloaded, and I'm trying to understand a few things. What exactly is a VBO? Do I have to use those?
I'm using an ortho projection and the z values for depth, I have depth test enabled, but sometimes I get that my transparent sprites are "cutting" sprites behind it:
I have this going on my init:
Also, I've noticed then in specific ordering of calls, it works correctly, but I don't want to depend on ordering... (If it's possible)
Because I want to order by texture...
RE: OpenGL ES2... many questions - ThemsAllTook - Aug 22, 2011 01:45 PM
What you're seeing is a fundamental difficulty when dealing with transparent objects, and the source of many headaches for graphics programmers. What happens is that when you draw a quad with a partially-transparent texture in the foreground, the entire quad is written to the depth buffer, so anything subsequently rendered behind it will fail the depth test and not get rasterized.
Unfortunately, there isn't much choice but to sort your drawing so that you go farthest to nearest for transparent objects (if you see the term "depth sorting", that's what it's about). You can render fully-opaque objects in any order, but transparent objects with depth testing on have to be special cased. Yes, this means you can't sort by texture. This is one of the places where texture atlases come in handy, since if you can fit all of your transparent objects onto one atlas, you can draw them in depth-sorted order without having to change textures.
RE: OpenGL ES2... many questions - vunterslaush - Aug 22, 2011 02:09 PM
Dang. My graphics are going to be mostly transparent... So if I have to sort them all by depth, seems like I can ditch the whole projection and depth testing, right?
So what would be the way to go? Game loop wise...
VBO per texture is no longer possible... What I'm currently thinking is:
-Sort by depth
-Group consecutive sprites of the same texture atlas
-Create VBO per group, (considering the group's inner order), and call glDrawElements
But then I lost control over the number of glDrawElements calls... Is it worth the trouble or should I just use a vbo per sprite?
BTW, another question- Only for testing purposes, I took a pretty large .png file as my texture, and rendered it a lot smaller, and it looks pretty bad... Not smooth. I am using GL_LINEAR but I honestly have no idea if it has anything to do with that.
And one last question- I am determined to learn and use OpenGL because I understand that it's the only way to maximize the iPhone's resources, and that's the way the best games are made. But when I just started (which is not too long ago... ) I used UIImageView's to make a little test game, and everything worked perfectly, without any OpenGL headache, and I used PNG's with transparencies and all. The catch is, it only has like 3-4 sprites on the screen at once. If I'll add lot's of sprites what would happen? The FPS will go to the floor? Because this whole OpenGL gets really frustrating...
RE: OpenGL ES2... many questions - Mattonaise - Aug 22, 2011 09:24 PM
Well i've heard Core Animation can get pretty slow with many sprites. Core Animation is really used best with effect-like animations where you describe the animation beforehand and tell it to run and watch the magic. But it's not very powerful when it comes to fast ramerates with many movements. I'm not an OpenGL expert or anything, but if your game's 2d (which im assuming it is) do you really need to use depth sorting? Is it easier to simply specify which things are behind others and draw them in that order? That may only work for certain types of games and yours may be different but im not sure depth testing is entirely neccessary for 2d games. Though I could be completely wrong im no expert or even close to one. And also im not sure, but do you really need vertex buffer objects for a 2d game? If everything is sprites then im guessing your using quads out of 2 triangles, but is there really any performance benifit that is noticeable or even needed with that simple geometry? I could still be wrong but it's just my input...
RE: OpenGL ES2... many questions - vunterslaush - Aug 23, 2011 05:07 AM
(Aug 22, 2011 09:24 PM)Mattonaise Wrote: I'm not an OpenGL expert or anything, but if your game's 2d (which im assuming it is) do you really need to use depth sorting? Is it easier to simply specify which things are behind others and draw them in that order? That may only work for certain types of games and yours may be different but im not sure depth testing is entirely neccessary for 2d games.
I'm trying to think of the most generic case... Like if I'll make an isometric game I would probably have to use depth sorting.
Anyways, specify which things are behind others, is also depth sorting... don't you think?
Anyways the first game that I want to make is a side scroller so I was going to do something similar-
What I had in mind was making some sort of linked list with key objects that represents "layers of depth" (hud, foreground, player, enemies, background, something like that) and implement methods like addInFront, addInBack, addBefore:someobject, addAfter:someobject, and then it would be pretty easy to manage it, and also I won't have to run a sorting alogrithm every frame. How does that sound?
(Aug 22, 2011 09:24 PM)Mattonaise Wrote: Though I could be completely wrong im no expert or even close to one. And also im not sure, but do you really need vertex buffer objects for a 2d game? If everything is sprites then im guessing your using quads out of 2 triangles, but is there really any performance benifit that is noticeable or even needed with that simple geometry? I could still be wrong but it's just my input...
That's what I'm asking... I don't know anything I'm just playing with example projects and modify it...
BTW- So depth test is completely useless with transparent textures?
RE: OpenGL ES2... many questions - Mattonaise - Aug 23, 2011 10:47 AM
Oh I think I understand what your trying to do. So you want to use depth testing to actually put objects behind others, so you can draw objects using the same texture at the same time to minimize texture changes without having objects be drawn in front of other objects simply because they're using a specific texture. But OpenGL is cutting parts of other sprites, even though you should technically be able to see them because the sprite in front is partly transparent, because of the depth testing. I would suggest that unless there's another solution, to not use depth testing and simply draw things to the screen in the order you want even if you have to do some more texture changes, and hopefully the sprites wont be cut off.
However, texture atlases would probably help you epecially if it was a side scroller. Your solution should work, however you can probably take it a bit further and use multiple "layers" and sprite atlases for specific layers. I'm assuming it's a 2d tile-based side scroller like the Mario Brothers kind of thing, and if it is then you could split up your world into layers. What I mean by that is instead of having on large array to hold all your game objects and whatnot, you could have multiple arrays that would hold specific kinds of objects. One array would be the level, another the items, then enemies, then player, then whatever else, then HUD, and so on, and you would also draw the arrays/layers in a specific order. You could then make it a bit more effecient by making texture atlases that correspond to a specific layer, for example by grouping the enemy sprites into one atlas, so you would really only need to swap textures when you start drawing a different layer. The ordering of objects with this solution may not be as flexible as your solution, but may be more efficient with texture changes and should be perfectly fine with simple side-scrollers. But that's really just how I would do it, but the thing is if you really need all that optimization. If your game still runs fine with your method of sorting it then you should stick with that.
And about the VBO's I really dont know, I just thought if you were using textured quads then you wouldn't have different meshes you would really only need one. I'm just not sure if VBO's actually effect how fast the meshes are rendered, or the speed at which OpenGL can switch between different meshes, because if it's the latter then VBO's aren't neccessary with only one type of mesh. However, I would suggest to simply use a vertex array to define a quad instead of a VBO because i'm not sure if you really need to use them as they can be much more complex then a simple vertex array. Basically you really shouldn't try to optimize things beforehand because you may waste a lot of time doing something you may not even need. Thats just what I think and I havent actually used OpenGL before i'm just gathering from what I hear.