kotlin 如何在Android应用程序中实现GLSurfaceView.EGLContextFactory来创建OpenGL ES上下文,以便我们可以检查OpenGL ES版本?

qoefvg9y  于 12个月前  发布在  Kotlin
关注(0)|答案(1)|浏览(122)

我的问题是如何通过实现GLSurfaceView.EGLContextFactory打印物理设备支持的最大OpenGL ES version
我正在学习一个教程here,介绍如何使用OpenGL ES在Android应用程序中设置环境。
我构造代码的方式完全像教程告诉我的那样。
1.我的主要活动是这样设置class MainActivity: Activity(),其中Activity来自android.app.Activity包。
1.在MainActivity中有一个来自android.opengl.GLSurfaceView包的GLSurfaceView示例。
1.创建名为MyGLSurfaceView的类来实现或继承GLSurfaceView。在它内部,它有一个GLSurfaceView.Renderer的示例。
1.创建名为MyGLRenderer的类来实现或继承GLSurfaceView.Renderer
1.一个名为Model的类与创建环境所需的OpenGL ES类在同一个包中创建。
所以,Model类需要从android.content.Context包访问Android Context来做一些工作,比如访问一个文件。
here中,它告诉我这样写:

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
    }
}

字符串
但是,我仍然不明白如何实现这段代码。因为,我已经在MyGLSurfaceViewconstructor中创建了OpenGL ES上下文,如下所示:

init {

    // Create an OpenGL ES 2.0 context
    setEGLContextClientVersion(2)

    renderer = MyGLRenderer(context)
    
    // Set the Renderer for drawing on the GLSurfaceView
    setRenderer(renderer)
    }


它在文档中说,在阅读设备可以支持的版本(比如它可以运行的最大版本)之前,我必须首先创建OpenGL ES上下文。
问题是GLSurfaceView.EGLContextFactory是一个static interface,这意味着它是一个globalshared对象,需要首先实现,即从该类继承并覆盖createContext()方法和destroyContext()
如何实现GLSurfaceView.EGLContextFactory?我应该把它声明为MyGLSurfaceView的嵌套类吗?
我尝试过这样做,创建了一个名为ContextFactory的嵌套类,它实现了接口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.
    }


但在logcat inside warn类别中,它说:
Rcall to OpenGL ES API with no current context (logged once per thread)Reading a NULL string not supported here.
MyGLSurfaceView类看起来像这样:

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")
        }
    }
}

pdsfdshx

pdsfdshx1#

首先创建一个继承自GLSurfaceView.EGLContextFactory接口的类,如下所示:

import android.opengl.GLSurfaceView
import android.util.Log
import javax.microedition.khronos.egl.EGL10 //make sure to import from 
//javax not from `android.opengles.*` package
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.3

class ContextFactory : GLSurfaceView.EGLContextFactory {
    override fun createContext(egl: EGL10, display: EGLDisplay, eglConfig: 
        EGLConfig): EGLContext {
         // returns null if 3.0 is not supported
        Log.w("OpenGl version", "creating OpenGL ES $glVersion context")
        return egl.eglCreateContext(
            display,
            eglConfig,
            EGL10.EGL_NO_CONTEXT,
            intArrayOf(EGL_CONTEXT_CLIENT_VERSION, glVersion.toInt(), 
            EGL10.EGL_NONE)
        ) //
    }

    override fun destroyContext(egl: EGL10, display: EGLDisplay, context: 
        EGLContext) {
        egl.eglDestroyContext(display, context)
    }
}

字符串
MyGLSurfaceView类中:

class MyGLSurfaceView(context: Context) : GLSurfaceView(context) {
     private val renderer: MyGLRenderer
     private var previousX: Float = 0f
     private var previousY: Float = 0f

init {
    //setEGLContextClientVersion(2)
    setEGLContextFactory(ContextFactory()) //need to use this function 
    //instead of the above one
    renderer = MyGLRenderer(context)
    setRenderer(renderer)
}


如果程序崩溃,这意味着它不支持ContextFactory类中指定的当前版本。如果它可以顺利运行,则意味着它支持当前指定的版本。
还有一件事,GLSurfaceView.EGLContextFactory实际上是一个普通的接口,而不是我以前认为的staticglobal接口。

相关问题