简体   繁体   中英

Android: How can I port this app from GLES1 to GLES3

I'm tasked with converting an android app from GLES1 to GLES3. The app does all its OpenGL calls in JNI, runs in a thread, and calls into Java to run basic functions like:

InitOpenGL();
MakeContextCurrent();
GLSwapBuffer();

The app maintains its own clock, etc-- so basically the main loop of the app looks something like this (simplified).

JavaBridge->InitOpenGL();
while (stillRunning())
{
   SleepUntilRightTime();
   UpdateEverything();
   if (shouldDraw())
   {
      JavaBridge->MakeContextCurrent();
      DrawEverything();
      JavaBridge->GLSwapBuffers();
   }
}

So, to accomplish this, the app has its own OpenGL factory, which initializes OpenGL1.1. I'll try to cut out everything unncessary for brevity, here are the basics (removed all error checking to keep it short):

public class GLView extends SurfaceView implements SurfaceHolder.Callback
{
   EGL10 m_GL;
   EGLContext m_GLContext;
   EGLDisplay m_GLDisplay=null;
   EGLSurface m_GLSurface=null;
   EGLConfig m_GLConfig=null;
   
   public void InitOpenGL()
   {
      m_GL = (EGL10) EGLContext.getEGL();
      m_GLDisplay = m_GL.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
      m_GL.eglInitialize(m_GLDisplay, null);
      EGLConfig[] configs = new EGLConfig[1];
      int[] config_count = new int[1];
      int[] specs = { EGL10.EGL_ALPHA_SIZE, 8, EGL10.EGL_DEPTH_SIZE, 16, EGL10.EGL_STENCIL_SIZE, 8, EGL10.EGL_NONE };
      m_GL.eglChooseConfig(m_GLDisplay, specs, configs, 1, config_count);
      m_GLContext = m_GL.eglCreateContext(m_GLDisplay, m_GLConfig, EGL10.EGL_NO_CONTEXT, null);
      SurfaceHolder h = getHolder();
      m_GLSurface = m_GL.eglCreateWindowSurface(m_GLDisplay, m_GLConfig, h, null);
      m_GL.eglMakeCurrent(m_GLDisplay, m_GLSurface, m_GLSurface, m_GLContext);
      m_GL = (EGL10) EGLContext.getEGL();
   } 
   public void MakeContextCurrent() 
   {
      m_GL.eglMakeCurrent(m_GLDisplay, m_GLSurface, m_GLSurface,    m_GLContext);
   }
   public void SwapBuffers() 
   {
      m_GL.eglSwapBuffers(m_GLDisplay, m_GLSurface);
   }
}

This all works beautifully, the app runs in its thread and paints the screen whenever it deems fit (it's a game, btw, that's why the constant loop).

Now: I was hoping that to turn this into an OpenGL3.0 context, I'd just say "hey request version number" or something like that. I've tried a few things without success (setting GL_VERSION in an attrib list with createcontext, making sure the right libraries are linked, fixed manifest, etc, etc, on and on) but no matter what I do, openGL calls in the JNI either do nothing, or crash the program.

I can't even get glClear to work unless I just revert everything back to square one. Anyone have any advice on offer to turn this thing into a 3.0 capable context?

Okay, managed to figure this out. For anyone using modern android, you'll find that EG10.EGL_CONTEXT_CLIENT_VERSION is not defined. It seems like using EGL_VERSION would be the substitute, but it's not.

Why isn't EGL_CONTEXT_CLIENT_VERSION defined? Is it depreciated? Is it shunned? We'll never know. But we DO know that if it WAS defined it would be 0x3098.

So, making this all magically work was as simple as saying:

        int[] attrib_list=new int[]{0x3098,3,EGL10.EGL_NONE};
        m_GLContext = m_GL.eglCreateContext(m_GLDisplay, m_GLConfig, EGL10.EGL_NO_CONTEXT,attrib_list);

Is it dangerous to do this? Probably. I'll do a little more research into it. If I never return to edit this, then I found no real answer yea or nay.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM