Optimizing the OpenGL ES settings for 2D drawing - android

I'm experimenting with using OpenGL ES to draw rather complicated paths, as I was running into severe performance problems when using the generic Android drawing functions. So far using OpenGL directly seems to be significantly faster, but I'm wondering about the difference between drawing in 2D as compared to 3D.
I'm using the example from the Google Tutorial on OpenGL, and modified it a bit to remove the third dimension from my vertices. Just omitting the z coordinate in glVertexAttribPointer and passing 2 as the size parameter seems to work. This seems to be an obvious and easy optimization, and it also makes the code a bit clearer. But I'm wondering at which other places OpenGL ES just assumes 3D, and does unnecessary work.
For example, I don't need any depth testing, but from what I read it isn't clear to me if just never explicitly enabling it is enough, or if I need to disable any settings?
I'm not looking for microoptimizations, but for general settings that remove assumptions that I'm working in 3D and simplify or remove calculations that just are not necessary in 2D. What are other things I should do when I'm working in pure 2D, and not in 3D?

Related

What are the various ways of creating OpenGl ES graphics on Android?

I have done some reading on OpenGl ES for Android. I know that I could make a game with the canvas API, but I would like to experiment with OpenGl ES first.
From here I can see two options: Use a game engine or develop my OpenGl ES from the ground up.
The coder/math person that I am is pushing me to the harder option(second option). The way I want to start on this journey is by creating a mesh and manipulating it with various transformations. I will worry about the textures later on. I've learned that I could develop my mesh using outside software such as Blender or LibGdx. However, I would like to learn to develop it with the android API. Do you think this is possible? Will it be very taxing for the android system to process many meshes and transform them? I think It will.
Should I just stick to the game engine way, and forget the "from the ground up mindset".
I also just found out about the replica island source code. Perhaps, I should start reading it and tweaking it on my own.
One more thing, from what I see, I have several options when developing graphics on android using OpenGl ES. Create the 3D model meshes or use sprites(such as replica island). Are there any other ways of doing this?
It all depends on the complexity of the game.
If it's on the simpler side, you could very well 'start from scratch'. I'm pretty sure, you'll end up creating something similar to replica island. For a complex game, you'll be near (as we're from moon) unity on the other extreme. We're talking about hundreds of thousands of man-hours.
As far as creating the meshes is concerned, OpenGL(ES) can only render the meshes.
Unless it's a very primitive mesh or one which can be modelled mathematically with a few equations (less likely for a game), you'll have to create them in blender, maya etc.
For a first timer, I suggest reusing an existing game/engine.
The transition from rendering meshes, then applying textures, then using lighting and shadows etc has a decent learning curve.
Trust me, even with this approach the coder/Math person will have enough on his plate.

OpenGL ES or android.graphics?

I'm developing a client for LBS service and I need to implement some 2D and 3D graphics.
As I read, standard package android.graphics is better for 2D grahics and drawing simple objects, and opengl es is better for 3D and it works faster. Unfortunatelly, I did'n find anything alse about their differences. Does anybody konow more about differences between drawing with OpenGL ES and with android.graphics?
OpenGL will give you full control over the graphics that you are using. You will not have many limitations long term on what you would like to do. You can make a good 3D game on an Android using OpenGL, as you can render large amounts of polys and overlay 2D graphics on top of those. It is a great deal of work, though.
Regular old OpenGL is my favorite, and I'd hate to have to use any of the frameworks mentioned in other answers, but I've been working with 3D graphics for many years. I can see why others would recommend them.
If you haven't done 3D graphics before, you have a steep learning curve in front of you. If you don't take the time to learn the underlying math and rendering concepts, you will struggle with it long term.
I love the reference pages from Khronos
Also, the Android developer site has some nice reference.
The main difference is that OpenGL is much faster compared to Canvas (The Android 2D graphics drawing surface). Although hardware acceleration is enabled for Canvas since honeycomb, it is a bit tricky to use it effectively.
Canvas does make life easier though. It's easy to use and simple to understand even for someone new to Computer Graphics.
In the end it will depend on what you need to do. If you need the fancy stuff like Geometry, Lighting etc then you should definitely go for OpenGL. Besides, If you need 3D then OpenGL is your only option since Canvas only supports 2D graphics.
Bare bones OpenGL is very tedious to use in my opinion so I would suggest a framework such as the ones mentioned here.
Hope this helps.

Rendering SVG with OpenGL (and OpenGL ES)

I am currently investigating the possibility of rendering vector graphics from an SVG file using OpenGL and OpenGL ES. I intend to target Windows and Android. My ideal solution would be to have a minimal C library that generates a polygon triangulation from a given SVG file. This would then generate standard OpenGL or OpenGL ES calls, and use a display list or vbo for optimization when redrawing. I would simply draw a display list to draw the vector image after translating and rotating, allowing me to mix this with other OpenGL calls.
So far I see that the suggestions are to firstly use QT or Cairo. - This is not an option given that I wish to manage my own OpenGL context without bloated libraries (in the context of what I am trying to achieve). Nor is this suitable for Android.
Second option is to use libraries that render to a texture. While this might be ok for static vector graphics, it's not an efficient or feasible option for games where scaling and rotations occur frequently.
Thirdly there is the possibility of using OpenVG. There are some opensource implementations of the OpenVG specification (ShivaVG etc), but I am yet to find a library that is capable of generating the appropriate OpenVG calls from a given SVG file at runtime, and I can't see how to optimize this as we might wish to with a display list or vbo.
All three methods suffer limitations. I think the most promising option is using an OpenVG implementation if no other solution exists. So my question is, are there any libraries out there that do what I want, or close to what I want? If not, is there a good reason why not? And would it be better to attempt to do this from the ground up instead?
My answer is going to about displaying vector graphics wtih OpenGL in general, because all solutions for this problem can support rather trivially SVG in particular, although none support animated SVGs (SMIL). Since there was nothing said about animation, I assume the question implied static SVGs only.
First, I would not bother with anything OpenVG, not even with MonkVG, which is probably the most modern, albeit incomplete implementation. The OpenVG committee has folded in 2011 and most if not all implementations are abandonware or at best legacy software.
Since 2011, the state of the art is Mark Kilgard's baby, NV_path_rendering, which is currently only a vendor (Nvidia) extension as you might have guessed already from its name. There are a lot of materials on that:
https://developer.nvidia.com/nv-path-rendering Nvidia hub, but some material on the landing page is not the most up-to-date
http://developer.download.nvidia.com/devzone/devcenter/gamegraphics/files/opengl/gpupathrender.pdf Siggraph 2012 paper
http://on-demand.gputechconf.com/gtc/2014/presentations/S4810-accelerating-vector-graphics-mobile-web.pdf GTC 2014 presentation
http://www.opengl.org/registry/specs/NV/path_rendering.txt official extension doc
You can of course load SVGs and such https://www.youtube.com/watch?v=bCrohG6PJQE. They also support the PostScript syntax for paths. You can also mix path rendering with other OpenGL (3D) stuff, as demoed at:
https://www.youtube.com/watch?v=FVYl4o1rgIs
https://www.youtube.com/watch?v=yZBXGLlmg2U
NV_path_rendering is now used by Google's Skia library behind the scenes, when available. (Nvidia contributed the code in late 2013 and 2014.) One of the cairo devs (who is an Intel employee as well) seems to like it too http://lists.cairographics.org/archives/cairo/2013-March/024134.html, although I'm not [yet] aware of any concrete efforts for cairo to use NV_path_rendering.
NV_path_rendering has some minor dependencies on the fixed pipeline, so it can a bit of nuisance to use in OpenGL ES. This issue documented in the official extension doc linked above. For a workaround see for example what Skia/Chromium has done: https://code.google.com/p/chromium/issues/detail?id=344330
An upstart having even less (or downright no) vendor support or academic glitz is NanoVG, which is currently developed and maintained. (https://github.com/memononen/nanovg) Given the number of 2D libraries over OpenGL that have come and gone over time, you're taking a big bet using something not supported by a major vendor, in my humble opinion.
Check out MonkVG an OpenVG like API implementation on top of OpenGL ES.
Also, for SVG rendering on top of OpenVG (MonkVG) checkout MonkSVG.
MonkVG has been built for iOS, OSX, and Android platforms.
I'm the author of both libraries and would be happy to answer any questions.
It needs to be said that rendering SVG or OpenVG with OpenGL or OpenGL ES is fundamentally a bad idea. There are reasons the OpenVG implementations are all so slow and largely abandoned. The process of tessellating paths (the foundation of all SVG/OpenVG rendering) into triangle lists as required by OpenGL is fundamentally slow and inefficient. It basically requires inserting a sort/search algorithm into the 3D rendering pipeline, which cripples performance. There is also the problem that a dynamic memory allocation scheme is required because the size of the data set is unknown since SVG places no limits on the complexity of the path geometry. A really poor design.
SVG and OpenVG were created by developers who had little understanding of how modern 3D graphics hardware engines actually work (triangle lists). They were created to be an open alternative to Adobe Flash, which also has the same flawed architecture that has made Flash reviled in the industry for unpredictable performance.
My advice is to rethink your design and use OpenGL triangle lists directly. You may have to write more code, but your app will perform about a thousand times better and you can more easily debug your code than someone elses.
I am currently investigating the possibility of rendering vector graphics from an SVG file > using OpenGL and OpenGL ES. I intend to target Windows and Android. My ideal solution
would be to have a minimal C library that generates a polygon triangulation from a given
SVG file. This would then generate standard OpenGL or OpenGL ES calls, and use a display
list or vbo for optimization when redrawing. I would simply draw a display list to draw
the vector image after translating and rotating, allowing me to mix this with other OpenGL > calls.
If you only want to transform SVG vector shapes into OpenGL|ES, then I suggest to do the parser and the logic yourself. Note that SVG is a huge spec, with different features like paint servers (gradients, patterns ...), references, filters, clipping, font handling, animations, scripting, linking, etc, etc.
If you want full svg support, then there's a library on http://code.google.com/p/enesim called egueb (and particularly esvg) which uses enesim (a rendering library that has software and opengl backends) for the drawing. In most cases it uses shaders and everything is rendered into a texture, the library is very flexible allowing you to adapt to your particular needs like modifying the rendered scene, transform it, etc. Because the gl drawing is done always into a texture.
So far I see that the suggestions are to firstly use QT or Cairo. - This is not an option
given that I wish to manage my own OpenGL context without bloated libraries (in the
context of what I am trying to achieve). Nor is this suitable for Android.
Second option is to use libraries that render to a texture. While this might be ok for
static vector graphics, it's not an efficient or feasible option for games where scaling
and rotations occur frequently.
In the particular case of the gl backend, enesim does not create a GLX (or any other window dependent context), you have to provide it, so it adapts perfectly to your situation as it only uses GL calls.
The only drawback is that the library is not complete yet in terms of gl support or full SVG spec support, but depending on your needs, seems to me like a good option.
From http://shivavg.svn.sourceforge.net/viewvc/shivavg/trunk/src/shPipeline.c?revision=14&view=markup :
static void shDrawVertices(SHPath *p, GLenum mode)
{
int start = 0;
int size = 0;
/* We separate vertex arrays by contours to properly
handle the fill modes */
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, sizeof(SHVertex), p->vertices.items);
while (start < p->vertices.size) {
size = p->vertices.items[start].flags;
glDrawArrays(mode, start, size);
start += size;
}
glDisableClientState(GL_VERTEX_ARRAY);
}
So it does use a VBO. So I'd suggest making your own SVG parser / use a pre-made one, and forward the calls to ShivaVG.
You still have the problem that ShivaVG is in C (and not in Java) and creates an opengl context (and not opengles, if I read the code correctly). So even if you compile it using Android's NDK, you'll have to modify the code ( for instance, I've seen a few glVertex3f around, but they don't seem to be much needed... hope for the best). The other option, of course, it to port the code from C to Java. Maybe not as painful as you could imagine.
Good luck !
You can have a look at AmanithVG, they seem to have implemented a good paths -> triangles pipeline. I've tried the iOS GL tiger example, and it seems that triangulation is not a real bottleneck.

Android: Deciding between SurfaceView and OpenGL (GLSurfaceView)

Is there a way to decide up front based on the expected complexity of a game/app in the planning phase whether to use regular Canvas drawing in a SurfaceView or to go with OpenGL?
I've been playing around with a Canvas and only need 2D movement, and on a fairly new phone I'm getting pretty decent performance with a bunch of primitive objects and a few bitmaps running around the screen on a solid background.
Is it fair to say that if I'm going to be drawing background images and increasing the number of objects being moved and drawn on top of them that I should go straight to OpenGL?
All I can say is that it depends on how many sprites you're gonna use. Chris Pruett from Google has also documented this part very well.
Google I/O 2009 and Google I/O 2010.
Below is a picture from one of his slides that are related to your topic:
With that knowledge, you should go with OpenGL using the draw_texture extension. Remember to query out the string and check if draw_texture is supported on the actual device.
For further information that are related to game development in general, see this.
SurfaceView
A GLSurfaceView is a SurfaceView that you can render into with OpenGL.
Choosing between them is simple:
If you're familiar with OpenGL and need what it provides, use a
GLSurfaceView. Otherwise, use a SurfaceView. OpenGL is low-level. If
you're not already familiar with it, it's an undertaking to learn. If
you only need 2D drawing, SurfaceView uses the high-level, reasonably
high-performance Canvas. It's very easy to work with.
Unless you have a strong reason to use a GLSurfaceView, you should use
a regular SurfaceView. I would suggest that if you don't already know
that you need GL, then you probably don't.
OpenGL
OpenGL would be able to handle the rotations and scaling easily.
Honestly, you would probably need to learn a lot of OpenGL to do this,
specifically related to the topics of:
Geometry Lighting (or just disabling it) Picking (selecting geometry
to draw on it) Pixel Maps Texture Mapping Mipmapping Also, learning
OpenGL for this might be overkill, and you would have to be pretty
good at it to make it efficient.
Instead, I would recommend using the graphic components of a game
library built on top of openGL, such as:
Cocos2d
libgdx
Any of the engines listed here
Source
Difference between SurfaceView and GLSurfaceView in Android
Android: Canvas vs OpenGL

Differences and advantages of SurfaceView vs GLSurfaceView on Android?

I'm currently playing around with 2D graphics in android and have been using a plain old SurfaceView to draw Drawables and Bitmaps to the screen. This has been working alright, but there's a little stutter in the sprite movement, and I'm wondering the feasibility to do a real time (but not terrible fast) game with this.
I know GLSurfaceView exists which uses OpenGL, but I'm curious as to the extent to which this makes a difference. Is a plain SurfaceView hardware accelerated, or do I need to use OpenGL? What type of speed difference could I expect from switching to OpenGL, and how much altering of code would it require to switch (the game logic is all in a separate object that provides an ordered array of drawables to the SurfaceView)?
As far as I can tell, you have to use openGL to get HW acceleration. But don't take is for granted and wait for other answers ^^
If it really is the case, the speedup should be quite important. Any 2D application should work at at very least 20 fps (generally less polygons than 3D applications)
it would take a substantial amount of code, but 1) as a first attempt, you could try with only 1 square VBO and change the matrix each time and 2) your rendering seems already quite encapsulated so it should simplify things a lot.
SurfaceView is not hardware accelerated in default.
if you want to get HW acceleration
use GLSurfaceView, which use opengl and is hardware accelerated.
Hardware acceleration is possible for a regular SurfaceView since 3.0.
http://developer.android.com/guide/topics/graphics/hardware-accel.html

Categories

Resources