I am writing an app for Android, using OpenGL ES 1.x, but I would like answers which include iOS devices and OpenGL ES 2.x.
I am confused as to whether I should use GL_FLOAT or GL_FIXED, the priority being performance regarding GPU operations(does GL_FIXED need to be converted etc. ex: GL_FIXED fits EXACTLY with the precision I need but if it is converted to a float then using it is pointless).
This book seems to say that it is ALWAYS preferable to use GL_FIXED for vertices: "The major exception is with vertex data, which should never be given in floating point..."
Here (paragraph right above the subtitle "Vertex data")
But I have seen others saying floating point is better..
For all iOS devices, GL_FIXED has no redeeming value. It is useful on many lower-end Android devices which do not have a floating point unit in the CPU, but iOS devices have always shipped with full floating point support. On iOS, FIXED data is converted to Float32 before any other processing is done. I do not know what happens for Android.
Related
I want to fetch depth from tile local memory with OpenGL ES.
That is needed to make soft particles effect and color-only deferred decals in a videogame.
ARM_shader_framebuffer_fetch_depth_stencil extension works great and gives direct access to depth value.
Now I want to achieve same result with ARM_shader_framebuffer_fetch and EXT_shader_framebuffer_fetch.
In GDC talk Bringing Fortnite to Mobile with Vulkan and OpenGL ES I see that one possible solution is writing depth value to alpha.
This approach doesn't work for me because of major precision loss, my alpha is 8 bits only.
I consider adding second attachment with enough precision and writing to it with MRT.
The question is: is MRT a way to go, or I miss some important trick?
Implementations that support ARM_shader_framebuffer_fetch do not guarantee to support MRT at all. If they do support it, then only the color of attachment zero can be retrieved. There are also some restrictions around color format; e.g. it only supports unorm color formats, so likely cannot have enough precision for depth even if you put the depth info in attachment zero.
Using EXT_shader_framebuffer_fetch is more generic and adds full MRT support, but not all tile-based GPUs support it.
Let's say I wanted to write my own software for Android that would benchmark rendering performance. Something along the lines of 3Dmark basically. What sorts of factors should the different test cases measure? Would it simply be rendering a ton of verts? Running a ton of textures?
Are there any resources out there that are either books or online guides that might help with developing specific test cases that would exercise specific portions of a phone/tablet's GPU?
Thanks,
Besides vertex count and texture sizes, the other major variables you should cover in an OpenGL ES benchmark are the display resolution and the complexity of the shader programs. You might also want to evaluate the compatibility of the OpenGL ES and EGL drivers, including extensions. There is a real need for that on Android.
I need to write to the depth buffer on an android device (OpenGL ES 2.0). Since gl_FragDepth is not writable under OGL ES 2.0, I have to find a workaround. I actually want to render spheres via raycasting, similar to this: http://www.sunsetlakesoftware.com/2011/05/08/enhancing-molecules-using-opengl-es-20 .
However, the solution explained on this website (offscreen render pass writing the depth using a special glBlendEquation) is only working on Apple devices, not on Android, because GL_MIN_EXT-blending is not supported.
On my Tegra3 tablet I was able to implement this method: Android GLES20.glBlendEquation not working? (btw, I recommend using linearized depth values, they give better results!)
It works quite good, but of course this is only available on Nvidia GPUs.
In theory, there is the extension GL_EXT_frag_depth (see Can an OpenGL ES fragment shader change the depth value of a fragment?), but it is not available on Android devices as well.
Finally, you could of course write the depth buffer for just one sphere (in an offscreen render pass), then write the depth buffer for the next sphere in a second render pass and combine the two in a third render pass. In doing so, you would have 2*n+1 render passes for n spheres - which seems to be quite inefficient!
So since I am running out of ideas, my question is: Can you think of another, generic way/workaround to write the depth buffer on an OpenGL ES 2.0 Android device?
Well, you are sure running out of options here. I don't know of any further workaround because I don't know Opengl ES soooo well.
The only thing that comes into my mind would be combining the brute-force multi-pass approach with some preprocessing:
Sort your spheres into groups where the atoms are not overlapping each other. It should be possible to sort all your spheres from proteins in less then ten groups. Then render all spheres of each group in one pass. The vertex-depth is sufficient here, because the spheres do not overlap. Then you can "depth-blend" the results.
This requires some preprocessing which could be a problem.
From what I've read, it appears that OpenGL ES 2.0 isn't anything like OpenGL 2.1, which is what I assumed from before.
What I'm curious to know is whether or not OpenGL 3 is comparable to OpenGL ES 2.0. In other words, given that I'm about to make a game engine for both desktop and Android, are there any differences I should be aware of in particular regarding OpenGL 3.x+ and OpenGL ES 2.0?
This can also include OpenGL 4.x versions as well.
For example, if I start reading this book, am I wasting my time if I plan to port the engine to Android (using NDK of course ;) )?
From what I've read, it appears that OpenGL ES 2.0 isn't anything like OpenGL 2.1, which is what I assumed from before.
Define "isn't anything like" it. Desktop GL 2.1 has a bunch of functions that ES 2.0 doesn't have. But there is a mostly common subset of the two that would work on both (though you'll have to fudge things for texture image loading, because there are some significant differences there).
Desktop GL 3.x provides a lot of functionality that unextended ES 2.0 simply does not. Framebuffer objects are core in 3.x, whereas they're extensions in 2.0 (and even then, you only get one destination image without another extension). There's transform feedback, integer textures, uniform buffer objects, and geometry shaders. These are all specific hardware features that either aren't available in ES 2.0, or are only available via extensions. Some of which may be platform-specific.
But there are also some good API convenience features available on desktop GL 3.x. Explicit attribute locations (layout(location=#)), VAOs, etc.
For example, if I start reading this book, am I wasting my time if I plan to port the engine to Android (using NDK of course ;) )?
It rather depends on how much work you intend to do and what you're prepared to do to make it work. At the very least, you should read up on what OpenGL ES 2.0 does, so that you can know how it differs from desktop GL.
It's easy to avoid the actual hardware features. Rendering to texture (or to multiple textures) is something that is called for by your algorithm. As is transform feedback, geometry shaders, etc. So how much you need it depends on what you're trying to do, and there may be alternatives depending on the algorithm.
The thing you're more likely to get caught on are the convenience features of desktop GL 3.x. For example:
layout(location = 0) in vec4 position;
This is not possible in ES 2.0. A similar definition would be:
attribute vec4 position;
That would work in ES 2.0, but it would not cause the position attribute to be associated with the attribute index 0. That has to be done via code, using glBindAttribLocation before the program is linked. Desktop GL also allows this, but the book you linked to doesn't do it. For obvious reasons (it's a 3.3-based book, not one trying to maintain compatibility with older GL versions).
Uniform buffers is another. The book makes liberal use of them, particularly for shared perspective matrices. It's a simple and effective technique for that. But ES 2.0 doesn't have that feature; it only has the per-program uniforms.
Again, you can code to the common subset if you like. That is, you can deliberately forgo using explicit attribute locations, uniform buffers, vertex array objects and the like. But that book isn't exactly going to help you do it either.
Will it be a waste of your time? Well, that book isn't for teaching you the OpenGL 3.3 API (it does do that, but that's not the point). The book teaches you graphics programming; it just so happens to use the 3.3 API. The skills you learn there (except those that are hardware based) transfer to any API or system you're using that involves shaders.
Put it this way: if you don't know graphics programming very much, it doesn't matter what API you use to learn. Once you've mastered the concepts, you can read the various documentation and understand how to apply those concepts to any new API easily enough.
OpenGL ES 2.0 (and 3.0) is mostly a subset of Desktop OpenGL.
The biggest difference is there is no legacy fixed function pipeline in ES. What's the fixed function pipeline? Anything having to do with glVertex, glColor, glNormal, glLight, glPushMatrix, glPopMatrix, glMatrixMode, etc... in GLSL using any of the variables that access the fixed function data like gl_Vertex, gl_Normal, gl_Color, gl_MultiTexCoord, gl_FogCoord, gl_ModelViewMatrix and the various other matrices from the fixed function pipeline.
If you use any of those features you'll have some work cut out for you. OpenGL ES 2.0 and 3.0 are just plain shaders. No "3d" is provided for you. You're required to write all projection, lighting, texture references, etc yourself.
If you're already doing that (which most modern games probably do ) you might not have too much work. If on the other hand you've been using those old deprecated OpenGL features which from my experience is still very very common (most tutorials still use that stuff). Then you've got a bit of work cut out for you as you try to reproduce those features on your own.
There is an open source library, regal, which I think was started by NVidia. It's supposed to reproduce that stuff. Be aware that whole fixed function system was fairly inefficient which is one of the reasons it was deprecated but it might be a way to get things working quickly.
I just caught a little quirk in my fledgling application's GL interfaces. On desktop GL things like glShaderSource() take a GLchar*, but on the mobile GLES interfaces they take a plain char*.
Now, this is really a very trivial thing to fix. Since GLchar is a typedef of char anyway, one can just use char* on desktop GL and be alright everywhere.
However, seeing this issue raises concerns in me about coming across other compatibility issues in the GL vs GLES realm. Of course I know that GLES 2.0 is basically a stripped down OpenGL 2.0, and that I'll have to suffer the loss of things like the fixed function pipeline. But will it get any worse that that? I was hoping that the interfaces which GLES 2.0 did leave for me would at least work identically to their desktop GL counterparts. But is this indeed the case? I sure do hope so.
But is this indeed the case?
No.
For example, glTexSubImage2D doesn't work in ES 2.0 like it does in desktop GL. The internal format and pixel format parameters take entirely different values, values that would not be legal in most cases with desktop GL.
You should not expect ES 2.0 code to run without changes on desktop GL.