Android GLSurfaceView.Renderer是否可以在onDrawFrame()中多次交换缓冲区?

Android GLSurfaceView.Renderer是否可以在onDrawFrame()中多次交换缓冲区?,android,opengl-es,glsurfaceview,egl,Android,Opengl Es,Glsurfaceview,Egl,在我的openGL游戏中,我通常使用onDrawFrame()中的GLSurfaceView.Renderer类绘制场景。但是,当我显示加载屏幕时,我希望在加载每个数据项后强制屏幕绘制,以便可以显示加载条 在这个draw调用过程中是否可以强制进行缓冲区交换?我唯一的选择是在多个帧之间错开加载,这意味着大量的返工 我想我试图调用的是eglSwapBuffers(),但我找不到从GLSurfaceView或GLSurfaceView.Renderer访问egl上下文的方法 谢谢您的时间。不,您不能(

在我的openGL游戏中,我通常使用onDrawFrame()中的GLSurfaceView.Renderer类绘制场景。但是,当我显示加载屏幕时,我希望在加载每个数据项后强制屏幕绘制,以便可以显示加载条

在这个draw调用过程中是否可以强制进行缓冲区交换?我唯一的选择是在多个帧之间错开加载,这意味着大量的返工

我想我试图调用的是eglSwapBuffers(),但我找不到从GLSurfaceView或GLSurfaceView.Renderer访问egl上下文的方法

谢谢您的时间。

不,您不能(或不应该)在渲染器的onDraw方法中强制交换缓冲区


您应该做的是在单独的线程中加载数据。您的onDraw方法仍将定期调用,这将允许您向加载线程询问加载了多少项以相应地显示进度条/消息

答案被接受已经有一段时间了,但是您可以(并且没有理由不应该)强制交换渲染器的onDrawFrame()方法中的缓冲区

我在OpenGL应用程序中遇到了完全相同的问题——我需要在加载数据时渲染加载屏幕。下面是我在加载期间调用eglSwapBuffers()的伪代码示例(我使用JNI):

MyJNILib本机伪代码:

#include <EGL\egl.h>

...

void render()
{
    ...

    while (loading)
    {
        // Do loading stuff
        ...
        eglSwapBuffers( eglGetCurrentDisplay(), eglGetCurrentSurface( EGL_DRAW ) );
    }

    ...
}
#包括
...
void render()
{
...
同时(装载)
{
//装东西
...
eglSwapBuffers(eglGetCurrentDisplay(),eglGetCurrentSurface(EGL_DRAW));
}
...
}

您还可以将此方法添加到GLSurfaceView.Renderer类中:

import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.egl.EGLSurface;

public void swapBuffers()
{
    EGL10 curEgl = (EGL10)EGLContext.getEGL();

    EGLDisplay curDisplay = curEgl.eglGetCurrentDisplay();
    if (curDisplay == EGL10.EGL_NO_DISPLAY) { Log.e("myApp","No default display"); return; }    

    EGLSurface curSurface = curEgl.eglGetCurrentSurface(EGL10.EGL_DRAW);
    if (curSurface == EGL10.EGL_NO_SURFACE) { Log.e("myApp","No current surface"); return; }

    curEgl.eglSwapBuffers(curDisplay, curSurface);
}

与OpenUserX03的答案基本相同,只是在Java中。

强制解决方案是使自定义版本的GLSurfaceView类基于

在源代码中,您可以找到名为
swap
的方法:

/**
 * Display the current render surface.
 * @return the EGL error code from eglSwapBuffers.
 */
public int swap() {
    if (! mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) {
        return mEgl.eglGetError();
    }
    return EGL10.EGL_SUCCESS;
}
这应该是你想要的。然而,不幸的是,它是一个名为
EglHelper
private内部类的方法

/**
 * An EGL helper class.
 */

private static class EglHelper {
因此,在您的自定义GLSurfaceView类(从谷歌的源代码复制)中,将此
EglHelper
classpublic,您可以使用
EglHelper.swap
方法

public static class EglHelper {

在单独的线程上加载数据需要从加载线程(glGenTextures等)调用gl。据我所知,这不是我应该做的事情..?如果同步onDraw方法,您的glGenTexture调用将在渲染过程之外进行,因此这不是问题。我通过在单独的线程上加载所有图像数据来实现这一点。为了保证安全,在加载数据后,我实际上调用了渲染器线程上的所有gl函数,如glGenTextures。这工作非常出色,我现在有一个动画加载栏!
public static class EglHelper {