I have an issue with my code on Android.
I'm trying to use glGenProgramPipelines on my OnePlus 3, with OpenGL ES 3.1 and sady during calling this method, the app is crashing.
So my question is: Should these methods be available in OpenGL ES 3.1 or do I still need "ARB_separate_shader_objects" extension to use these?
If the extension is required, could you recommend me any Android phone which may have this extension?
Thanks!
Related
I need to write a small opengl ES 2 application for android 8+, but I just want to write a proof of concept with kotlin before deploying it on a phone.
Are there code samples for the specifics of OpenGL ES2 on android and GLsurface?
Is it possible to not use android studio on windows since it's pretty heavy to use on a small laptop?
This is the basics:
Overview
Basic setup
You're effectively setting up your GlSurface and giving it a Renderer that you've created, which has a few callbacks where you do setup (e.g. onSurfaceChanged) and drawing (onDrawFrame, which gets called every frame in a loop). That's where you do your standard OpenGL ES calls, so if you're writing some generic Kotlin code, you could call it from these.
Android also creates a renderer thread for you, and all your Renderer calls happen on that thread (and it also has the OpenGL context), so that's something to keep in mind if you want to communicate with it.
I recently switched from using glBufferData to glMapBufferRange which gives me direct access to GPU memory rather than copying the data from CPU to GPU every frame.
This works just fine and in OpenGL ES 3.0 I do the following per frame:
Get a pointer to my GPU buffer memory via glMapBufferRange.
Directly update my buffer using this pointer.
Use glUnmapBuffer to unmap the buffer so that I can render.
But some Android devices may have at least OpenGL ES 3.1 and, as I understand it, may also have the EXT_buffer_storage extension (please correct me if that's the wrong extension ?). Using this extension it's possible to set up persistent buffer pointers which do not require mapping/unmapping every frame using the GL_MAP_PERSISTENT_BIT flag. But I can't figure out or find much online in the way of how to access these features.
How exactly do I invoke glMapBufferRange with GL_MAP_PERSISTENT_BIT set in OpenGL ES 3.1 on Android ?
Examining glGetString(GL_EXTENSIONS) does seem to show the extension is present on my device, but I can't seem to find GL_MAP_PERSISTENT_BIT anwhere, e.g. in GLES31 or GLES31Ext, and I'm just not sure how to proceed.
The standard Android Java bindings for OpenGL ES only expose extensions that are guaranteed to be supported by all implementations on Android. If you want to expose less universally available vendor extensions you'll need to roll your own JNI bindings, using eglGetProcAddress() from native code compiled with the NDK to fetch the entry points.
For this one you want the extension entry point glBufferStorageEXT().
I am writing an Android app and am trying to maximize device support as much as possible. This means (for me at least) supporting both OpenGL ES 1.0 and OpenGL ES 2.0, depending on which is available.
Shader compiler support in OpenGL ES 2.0 is optional, but required for my app (unless I use OpenGL ES 1.0, of course), and so far I haven't been able to find any information about availability. So, I need to check whether compiler support is available and, if not, fall back to OpenGL ES 1.0.
The problem is that if I call GLES20.glGetIntegerv(GLES20.GL_SHADER_COMPILER, ...) to check for support before my onSurfaceCreated(...) method is called, it returns GL_FALSE (if I call it inside onSurfaceCreated, it returns GL_TRUE).
This means I need to create my GL20 Renderer and commit my GLSurfaceView to use GL20 via setEGLContextClientVersion(2) and setRenderer(myGL20Renderer) before I can figure out whether that's really what I want to do.
Is there any way around this other than throwing all that setup away again and basically starting over or accepting the fact that my app might crash on systems that say they support GL 2.0, but don't offer shader compilation?
I'm trying to port an iOS project to Android (java). I've however encountered a few ES 2.0 extension functions (OES), which do not appear in the Android GLES20 API:
glGenVertexArraysOES
glBindVertexArrayOES
glDeleteVertexArraysOES
It appears I have to call these functions from NDK, dynamically bind the extensions at runtime and check for support od devices. Not something I'd love to do.
While googling I found these functions in the GLES30 api. So my question is:
- is it possible to mix GLES20 and GLES30 calls?
- are these functions basically calls to the same api or is this completely different?
- any other sugggestions?
Just looking at the API entry points, ES 3.0 is a superset of ES 2.0. So the transition is mostly smooth. You request API version 3 when making the GLSurfaceView.setEGLContextClientVersion() call, and your ES 2.0 code should still work. Then you can start using methods from GLES30 on top of the GLES20 methods.
There are some very subtle differences, e.g. related to slight differences in cube map sampling, but you're unlikely to run into them. If you want details, see appendix F.2 of the spec document. Some features like client side vertex arrays have been declared legacy, but are still supported.
The only thing you're likely to encounter are differences in GLSL. You can still use ES 2.0 shaders as long as you keep the #version 100 in the shader code. But if you want to use the latest GLSL version (#version 300 es), there are incompatible changes. The necessary code changes are simple, it's mostly replacing attribute and varying with in and out, and not using the built-in gl_FragColor anymore. You have to switch over to the new GLSL version if you want to take advantage of certain new ES 3.0 features, like multiple render targets.
The downside of using ES 3.0 is of course that you're much more restricted in the devices your software runs on. While the latest higher-end devices mostly support ES 3.0, there are still plenty of devices out there that only support 2.0, and will stay at that level. According to the latest data from Google (http://developer.android.com/about/dashboards/index.html), 18.2% of all devices support ES 3.0 as of July 7, 2014.
As #vadimvolk explained, you will need to check whether OpenGL driver supports OES_vertex_array_object extension. More info here:
http://www.khronos.org/registry/gles/extensions/OES/OES_vertex_array_object.txt
If you just stick to use OpenGL ES 3.0, you can use these methods after checking that you've got OpenGL ES 3.0 context. In Android, you can mix calls to GLES20 and GLES30 because these APIs are backwards-compatible.
All you need is to create OpenGL ES 2.0 context and check if returned context version is 3.0 by reading GL_VERSION string. If it is 3.0, you can use mix both GLES20 and GLES30 functions. Additional info: https://plus.google.com/u/0/+RomainGuy/posts/iJmTjpUfR5E
Functions are same. In GLES20 they are exists only on some devices as not mandatory extensions.
In GLES30 they are mandatory.
If you use them from GLES30 your application will work only on devices supports GLES30 (only devices made for android 4.4).
I found some ways to speed up glReadPixels by OpenGL ES 3.0, but I am not sure if it works or not.
specifies the fifth argument of glReadPixels() as GL_BGRA to avoid unnecessary swizzle.
use PBO as this mentioned.
In order to verify, I updated to the latest Android SDK and ADT, and try to use OpenGL ES 3.0. However, I can't find GL_BGRA definition as I expected, and I don't know how to use glMapBuffer(). Am I missing something?
To summarize,
Is there any other faster way to access framebuffer than using glReadPixels() ?
How to use GL_BGRA and PBO by OpenGL ES 3.0 on Android?
If anyone knows, please point me out. Some code snippets would be better.
Thanks in advance.
Not really. I don't know whether you would get performance gains by using BGRA format, but it's worth a try. In ES 2.0, GL_BGRA is only available through extension: EXT_read_format_bgra, so you would need to use the enum GL_BGRA_EXT, and apparently it's the same in OpenGL ES 3.0 too.
Yes, glMapBufferRange is the way to go on OpenGL ES 3.0. It looks like your call is correct, as per your comment. According to spec and man page, glMapBufferRange should not generate GL_INVALID_ENUM errors, so I think something else is wrong here. Make sure the error is not generated by an earlier call.