I know how to handle screen sizes, but it is quite a different matter when using OpenGL ES. The thing is that normally I would just get the size of the screen in pixels and using the numbers given I would align items to be displayed.
But, as I mentioned before, in OpenGL ES it is quite different. I want to draw a simple grid on the screen, but I want all the squares on all the devices to be the same size. That means that with bigger screens I would have more columns and rows instead of bigger squares. So the real question is how to convert screen size in pixels into OpenGL vertex system.
Actually, I was very stupid when asking this. After a bit of experimenting it turned out that the size of the squares of the grid will stay of the same size, because of the way opengl es vertices work. On bigger devices is the size the same as on smaller ones, because the scale stays the same, only the corner indices change accordingly.
Related
I'm developing a videogame in Android using OpenGL ES. I'm having some issues with the redimensioning of the textures.
I would like that my game could be compatible with any resolution, and for this, I created a constant with the relation between the game resolution and the screen resolution, like this:
Display display = getWindowManager().getDefaultDisplay();
KTE.SCREEN_WIDTH = display.getWidth();
KTE.SCREEN_HEIGHT = display.getHeight();
KTE.REDIMENSION_X = KTE.SCREEN_WIDTH/KTE.GAME_WIDTH;
KTE.REDIMENSION_Y = KTE.SCREEN_HEIGHT/KTE.GAME_HEIGHT;
Using this constant, I get the same result using differents screens sizes (with the redimensioning of all of the textures using the constant I calculated in the code before).
The problem is that I wanted to reduce the GAME resolution to make bigger all the textures, and now I get black pixels around the textures because my redimension constants are floats with a lot of decimals, and I guess all those black pixels are positions that are left during this calculations...
Anyone got this problem before? Any tip to redimensioning the game? I have tried a lot of things and I'm really stuck. Thanks.
It sounds like the "redimensioning" of the textures isn't working as expected. For instance, perhaps you are only resizing the data of the texture, but the texture itself is still the same size as before. This would account for black pixels at the boundary. Be sure you're creating your textures with your KTE.REDIMENSION_X/Y factor, and be sure when you're writing to your textures you're writing to the edges of them.
As for redimensioning the game, do you mean the screen size you render to? For this, it should be a simple change to glViewport(...) and perhaps the perspective frustrum's or orthos you create to view your scene. Changes to both of these are typically done when a screen size changes - changes to textures generally are not needed, except perhaps to bump up resolution (for instance for iOS retina displays that have 2x pixels).
I'm writing a simple 2D game for Android with a 300x200 play area with coords running from (0,0 to 299,199). I'd want this area to fill the screen as best as possible while maintaining its aspect ratio. e.g. if the GL view fills the full 800x480 of a device I could scale the area by 2.4x to 720x480 leaving 40 pixels of space either side.
I don't expect many devices would exactly scale in both dimensions so the code has to cope with a gap either in the horizontal or vertical.
So the question is how do I do this. My play area is 2D so I can use an orthgraphic projection. I just don't understand what values I need to plug in to set this up. I also suspect that because ES 2.0 has a heavy reliance on shaders that I might need to propagate some kind of scaling matrix to a vector shader to ensure objects are rendered to the right size.
Does anyone know of a good tutorial which perhaps talks in terms that make sense for my needs? Most tutorials I've seen seem content to dump a cube or square into the middle of the screen rather than rendering an area of exact dimensions.
These problem should be easy using the old and familiar Opengl functions, like glViewport and glProjection. GLM offers that for enviroments like Opengl ES, have a look
http://glm.g-truc.net/
We are to develop a scrolling/zooming scene in OpenGL ES on Android, very much like a level in Angry Birds but more like a level in World Of Goo. More like the latter as the world will not consist of repeated layers as featured in Angry Birds but of a large image. As the scene needs to scroll/zoom and therefore a lot of it will not be visible, I was wondering about the most efficient way to implement the rendering, focusing on the environment only (ie not the objects within the world but background layers).
We will be using an orthographic projection.
The first that comes to mind is creating a large 4 vertices rectangle at world size, which has the background texture mapped to it, and translate/scale this using glTranslatef / glScalef. However, I was wondering if the non visible area outside of the screens boundaries is still being rendered by OpenGL as it is not being culled (you would lose the visible area as well as there are only 4 vertices). Therefore, would it be more efficient to subdivide this rectangle, so non visible smaller rectangles can be culled?
Another option would be creating a 4 vertice rectangle that would fill the screen, then move the background by adjusting its texture coordinates. However, I guess we would run into problems when building bigger worlds, considering the texture size limit. It seems like a nice implementation for repeated backgrounds like AngryBirds has.
Maybe there is another way..?
If someone has an idea on how it might be done in AngryBirds / World of Goo, please share as I'd love to hear. They seem to have implemented a system that allows for the world to be moved and zoomed very (WorldOfGoo = VERY) smoothly.
This is probably your best bet for implementation.
In my experience, keeping a large texture in memory is very expensive on Android. I would get quite a few OutOfMemoryError exceptions for the background texture before I moved to tiling.
I think the biggest rendering bottleneck would be with memory transfer speeds and fill rate instead of any graphics computation.
Edit: Check out 53:28 of this presentation from Google I/O 2009.
You could split the background rectangle into smaller rectangles, so that OpenGL only renders the visible rectangles. You won't have a big ass rectangle with a big ass texture loaded but smallers rectangles with smaller textures that you could load/unload, depending on what is visible on screen...
Afaik there would be no performance drop due to large areas being rendered off-screen, subdividing and culling is normally done just to reduce vertex count, but you would actually be adding to it here.
Putting that aside for now; from the way you phrased the question I am unsure whether you have a large background texture or a small repeating one. If it is large, then you will need to subdivide because of texture size limitations anyway, so the question is moot! If it is small, then I would suggest the second method, fit a quad to the screen and move the background by changing the texture coordinates.
I feel like I may have missed something, though, as I am unsure why you mentioned the texture size limitation issue when talking about the the texture coordinate method and not the large quad method. Surely for both this is not a problem for repeating textures as you can use GL_REPEAT texture wrap mode...
But for both it is a problem for a single large texture unless you subdivide, which would make the texture coordinate tactic way more complicated than necessary. In this case subdividing the mesh along texture subdivisions would be best, and culling off-screen sections. Deciding which parts to cull should be trivial with this technique.
Cheers.
I currently have an OpenGL view that takes up nearly my entire screen. On tablets such as the Xoom and Galaxy Tab 10.1, there are two many pixels to fill, so since my fragment shader is quite large, my FPS goes way down on tablets. I was thinking that if I resized the view by 2, the shader would have to draw 1/4s of the pixels. But I still need the view to take up almost the whole screen.
So my question is, how do I make a View smaller, then scale it up so that each pixel actually takes up approximately 4 pixels of space?
I can currently make the OpenGL view smaller by using glSetViewport, but how can I scale it up without making the fragment shader do more work?
(Stretch to fill screen is not an option because I am not targeting a minimum of Android 3.2)
If OpenGL-ES 2 is available (if you're using shaders, it should be) then you can do your rendering to a texture in the color attachment of a framebuffer object in the smaller size (google for "render to texture FBO"). Then you draw this texture to a screen filling quad.
How to draw, say, a rectangle on the screen with it being proportional to the current device?
e.g. a rectangle, centered on the viewport, one pixel smaller than the screen on each border.
I can live with Orthogonal, but would like perspective (basically everything at Z=something should be proportional to the screen, and the upper parts of the elements being distorted by perspective)
I can calculate everything on my own if i know the relation... but i don't have a starting point.
I could experiment and get to a relation myself... i even resorted to that while coding for the Wii, but that's a really bad decision on Android and all the screen ratios/sizes out there...
seems that at z=1 you can fit in the screen all -1,-1-1,1 quads.