My question is How could I print the maximum OpenGL ES version supported by a physical device by implementing GLSurfaceView.EGLContextFactory ?
I was following a tutorial here on how to setup the environment in an Android application using OpenGL ES.
The way I structure my code is exactly like the tutorial tells me.
My Main Activity is setup like this
class MainActivity: Activity()wherebyActivityis fromandroid.app.Activitypackage.Inside
MainActivitythere is an instance ofGLSurfaceViewfromandroid.opengl.GLSurfaceViewpackage.A class named
MyGLSurfaceViewis created to implement or inherits fromGLSurfaceView. Inside it, it has an instance ofGLSurfaceView.Renderer.A class named
MyGLRendereris created to implement or inherits fromGLSurfaceView.Renderer.A class named
Modelis created in the same package with the requiredOpenGL ESclass to create the environment.
so, Model class needs to access Android Context from android.content.Context package to do some work, like to access a file.
In here, it tells me to write:
private const val EGL_CONTEXT_CLIENT_VERSION = 0x3098
private const val glVersion = 3.0
private class ContextFactory : GLSurfaceView.EGLContextFactory {
override fun createContext(egl: EGL10, display: EGLDisplay, eglConfig: EGLConfig):
EGLContext {
Log.w(TAG, "creating OpenGL ES $glVersion context")
return egl.eglCreateContext(
display,
eglConfig,
EGL10.EGL_NO_CONTEXT,
intArrayOf(EGL_CONTEXT_CLIENT_VERSION, glVersion.toInt(), EGL10.EGL_NONE)
) // returns null if 3.0 is not supported
}
}
But, I still do not understand how to implement this code. Because, I already created OpenGL ES context inside the constructor of MyGLSurfaceView like so:
init {
// Create an OpenGL ES 2.0 context
setEGLContextClientVersion(2)
renderer = MyGLRenderer(context)
// Set the Renderer for drawing on the GLSurfaceView
setRenderer(renderer)
}
It says there, in the documentation that I must create the OpenGL ES context first before
reading the version that the device can support, like the maximum version it can run.
The problem is GLSurfaceView.EGLContextFactory is a static interface which means it is a
global or shared object and need to be implemented first, i.e inherits from that class and overriding the createContext() method and destroyContext().
How should I implement GLSurfaceView.EGLContextFactory? should I declare it as nested class of MyGLSurfaceView.
I have tried like this by creating a nested class called ContextFactory which implements the interface GLSurfaceView.EGLContextFactory:
private const val EGL_CONTEXT_CLIENT_VERSION=0x3098
private const val glVersion=3.0
const val TAG="ContextFactory"
class MyGLSurfaceView(context: Context):GLSurfaceView(context) {
private val renderer: MyGLRenderer
init {
// Create an OpenGL ES 2.0 context
setEGLContextClientVersion(2)
renderer = MyGLRenderer(context)
//renderMode = GLSurfaceView.RENDERMODE_WHEN_DIRTY
// Set the Renderer for drawing on the GLSurfaceView
setRenderer(renderer)
glGetString(glVersion.toInt())
//I am assuming `ContextFactory` has already been instantiated since it implements
//a `static interface` so, I do not need to create another instance of it here in
// the constructor. So, I just directly trying to read `maximum OpenGL ES version`
//supported in my device.
}
but in the logcat inside warn category it says:
Rcall to OpenGL ES API with no current context (logged once per thread)
Reading a NULL string not supported here.
MyGLSurfaceView class looks like this:
import android.content.Context
import android.opengl.GLES20.glGetString
import android.opengl.GLSurfaceView
import android.util.Log
import javax.microedition.khronos.egl.EGL10
import javax.microedition.khronos.egl.EGLConfig
import javax.microedition.khronos.egl.EGLContext
import javax.microedition.khronos.egl.EGLDisplay
private const val EGL_CONTEXT_CLIENT_VERSION=0x3098
private const val glVersion=3.0
const val TAG="ContextFactory"
class MyGLSurfaceView(context: Context):GLSurfaceView(context) {
private val renderer: MyGLRenderer
init {
setEGLContextClientVersion(2)
renderer = MyGLRenderer(context)
setRenderer(renderer)
glGetString(glVersion.toInt())
}
private class ContextFactory: GLSurfaceView.EGLContextFactory{
override fun createContext(egl: EGL10?, display: EGLDisplay?, eglConfig:
EGLConfig?): EGLContext? {
Log.w(TAG, "creating OpenGL ES $glVersion context")
if (egl != null) {
return egl.eglCreateContext(
display,
eglConfig,
EGL10.EGL_NO_CONTEXT,
intArrayOf(EGL_CONTEXT_CLIENT_VERSION, glVersion.toInt(),
EGL10.EGL_NONE)
)
}
return null
}
override fun destroyContext(p0: EGL10?, p1: EGLDisplay?, p2: EGLContext?) {
TODO("Not yet implemented")
}
}
}
First create a class that inherits from
GLSurfaceView.EGLContextFactoryinterface like so:in
MyGLSurfaceViewclass:if the program crashes, it means, it doesn't support the current version that was specified in the
ContextFactoryclass. If it can run smoothly, it means it supports the currently specified version.One more thing
GLSurfaceView.EGLContextFactoryis actually a normal interface, not astaticorglobalinterface when I thought previously.