Android:如何将此应用程序从 GLES1 移植到 GLES3
Android: How can I port this app from GLES1 to GLES3
我的任务是将 android 应用从 GLES1 转换为 GLES3。该应用程序在 JNI 中执行所有 OpenGL 调用,在线程中执行 运行s,并调用 Java 到 运行 基本功能,例如:
InitOpenGL();
MakeContextCurrent();
GLSwapBuffer();
该应用维护自己的时钟等——所以基本上,该应用的主循环看起来像这样(简化)。
JavaBridge->InitOpenGL();
while (stillRunning())
{
SleepUntilRightTime();
UpdateEverything();
if (shouldDraw())
{
JavaBridge->MakeContextCurrent();
DrawEverything();
JavaBridge->GLSwapBuffers();
}
}
因此,为了实现这一点,应用程序拥有自己的 OpenGL 工厂,用于初始化 OpenGL1.1。
为了简洁起见,我会尽量删掉所有不必要的内容,这是基础知识(删除了所有错误检查以保持简短):
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);
}
}
这一切都很完美,应用程序 运行 在它的线程中,并在它认为合适的时候绘制屏幕(这是一个游戏,顺便说一句,这就是为什么不断循环)。
现在:我希望将其转换为 OpenGL3.0 上下文,我只会说“嘿请求版本号”或类似的东西。我已经尝试了一些没有成功的事情(在带有 createcontext 的属性列表中设置 GL_VERSION,确保链接了正确的库,修复了清单等等等等)但是无论我做什么,openGL JNI 中的调用要么什么都不做,要么使程序崩溃。
我什至无法让 glClear 工作,除非我将所有内容恢复原状。有人有任何建议可以将这个东西变成支持 3.0 的环境吗?
好的,设法解决了这个问题。对于使用现代 android 的任何人,您会发现未定义 EG10.EGL_CONTEXT_CLIENT_VERSION。似乎使用 EGL_VERSION 可以替代,但事实并非如此。
为什么 EGL_CONTEXT_CLIENT_VERSION 没有定义?它贬值了吗?它被回避了吗?我们永远不会知道。但是我们确实知道,如果它被定义了,它将是 0x3098。
所以,让这一切神奇地工作就像说:
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);
这样做有危险吗?大概。我会做更多的研究。如果我从不 return 编辑它,那么我找不到真正的答案是或否。
我的任务是将 android 应用从 GLES1 转换为 GLES3。该应用程序在 JNI 中执行所有 OpenGL 调用,在线程中执行 运行s,并调用 Java 到 运行 基本功能,例如:
InitOpenGL();
MakeContextCurrent();
GLSwapBuffer();
该应用维护自己的时钟等——所以基本上,该应用的主循环看起来像这样(简化)。
JavaBridge->InitOpenGL();
while (stillRunning())
{
SleepUntilRightTime();
UpdateEverything();
if (shouldDraw())
{
JavaBridge->MakeContextCurrent();
DrawEverything();
JavaBridge->GLSwapBuffers();
}
}
因此,为了实现这一点,应用程序拥有自己的 OpenGL 工厂,用于初始化 OpenGL1.1。 为了简洁起见,我会尽量删掉所有不必要的内容,这是基础知识(删除了所有错误检查以保持简短):
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);
}
}
这一切都很完美,应用程序 运行 在它的线程中,并在它认为合适的时候绘制屏幕(这是一个游戏,顺便说一句,这就是为什么不断循环)。
现在:我希望将其转换为 OpenGL3.0 上下文,我只会说“嘿请求版本号”或类似的东西。我已经尝试了一些没有成功的事情(在带有 createcontext 的属性列表中设置 GL_VERSION,确保链接了正确的库,修复了清单等等等等)但是无论我做什么,openGL JNI 中的调用要么什么都不做,要么使程序崩溃。
我什至无法让 glClear 工作,除非我将所有内容恢复原状。有人有任何建议可以将这个东西变成支持 3.0 的环境吗?
好的,设法解决了这个问题。对于使用现代 android 的任何人,您会发现未定义 EG10.EGL_CONTEXT_CLIENT_VERSION。似乎使用 EGL_VERSION 可以替代,但事实并非如此。
为什么 EGL_CONTEXT_CLIENT_VERSION 没有定义?它贬值了吗?它被回避了吗?我们永远不会知道。但是我们确实知道,如果它被定义了,它将是 0x3098。
所以,让这一切神奇地工作就像说:
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);
这样做有危险吗?大概。我会做更多的研究。如果我从不 return 编辑它,那么我找不到真正的答案是或否。