Opengl es 为什么我的android本机活动在渲染位图时有时会显示坏图像?

Opengl es 为什么我的android本机活动在渲染位图时有时会显示坏图像?,opengl-es,android-ndk,native-activity,skia,Opengl Es,Android Ndk,Native Activity,Skia,我正在尝试使用NDK在全屏上显示位图。这个需求迫使我使用完全本地的代码进行开发。我使用Skia绘制SkBitmap,然后通过openglapi显示它。当我的应用程序第一次在真正的android设备上运行时,它总是运行良好。但是,在我多次打开和关闭程序后,它将显示一个坏的图像。为什么会发生这种情况 函数engine\u init\u display用于初始化OpenGL ES和EGL,创建位图并加载纹理 static int engine_init_display(struct engine* e

我正在尝试使用
NDK
在全屏上显示位图。这个需求迫使我使用完全本地的代码进行开发。我使用
Skia
绘制
SkBitmap
,然后通过
openglapi
显示它。当我的应用程序第一次在真正的android设备上运行时,它总是运行良好。但是,在我多次打开和关闭程序后,它将显示一个坏的图像。为什么会发生这种情况

函数
engine\u init\u display
用于初始化OpenGL ES和EGL,创建位图并加载纹理

static int engine_init_display(struct engine* engine){
// initialize OpenGL ES and EGL

/*
 * Here specify the attributes of the desired configuration.
 * Below, we select an EGLConfig with at least 8 bits per color
 * component compatible with on-screen windows
 */
const EGLint attribs[] = {
        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
        EGL_DEPTH_SIZE, 16,
        EGL_BLUE_SIZE, 8,
        EGL_GREEN_SIZE, 8,
        EGL_RED_SIZE, 8,
        EGL_NONE
};
EGLint w, h, dummy, format;
EGLint numConfigs;
EGLConfig config;
EGLSurface surface;
EGLContext context;

EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(display, 0, 0);

/* Here, the application chooses the configuration it desires. In this
 * sample, we have a very simplified selection process, where we pick
 * the first EGLConfig that matches our criteria */
eglChooseConfig(display, attribs, &config, 1, &numConfigs);

/* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is
 * guaranteed to be accepted by ANativeWindow_setBuffersGeometry().
 * As soon as we picked a EGLConfig, we can safely reconfigure the
 * ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */
eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);

ANativeWindow_setBuffersGeometry(engine->app->window, 0, 0, format);
surface = eglCreateWindowSurface(display, config, engine->app->window, NULL);
context = eglCreateContext(display, config, NULL, NULL);

if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) {
    LOGW("Unable to eglMakeCurrent");
    return -1;
}

eglQuerySurface(display, surface, EGL_WIDTH, &w);
eglQuerySurface(display, surface, EGL_HEIGHT, &h);

engine->display = display;
engine->context = context;
engine->surface = surface;
engine->width = w;
engine->height = h;
engine->state.angle = 0;
engine->format=format;
// Initialize GL state.

glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
glEnable(GL_CULL_FACE);
glShadeModel(GL_SMOOTH);
glDisable(GL_DEPTH_TEST);
SkBitmap bitmap;
GLvoid* bitmapBuffer;
createBitmap(bitmap,bitmapBuffer,width,height);
drawBitmap(bitmap,width,height);
glEnable(GL_TEXTURE_2D);
glGenTextures(1,&sTexture);
glBindTexture(GL_TEXTURE_2D,sTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)bitmapBuffer);
glDisable(GL_TEXTURE_2D);
glFinish();
clearBitmapBuffer(bitmap,bitmapBuffer);
//engine_draw_frame(engine);
return 0;
}
函数
render
用于显示位图

void render(struct engine* engine, int width, int height){

glViewport((engine->width-width)/2, (engine->height-height)/2, width, height);
glClearColorx((GLfixed)(0.1f * 65536),(GLfixed)(0.2f * 65536),(GLfixed)(0.3f * 65536), 0x10000);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindTexture(GL_TEXTURE_2D,sTexture);
glFrontFace(GL_CW);
glTexCoordPointer(2, GL_FLOAT, 0, textureCoords);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glFlush();
eglSwapBuffers(engine->display, engine->surface);
}
当窗口关闭时,将调用
engine\u term\u display

static void engine_term_display(struct engine* engine) {
if (engine->display != EGL_NO_DISPLAY) {
    eglMakeCurrent(engine->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    if (engine->context != EGL_NO_CONTEXT) {
        eglDestroyContext(engine->display, engine->context);
    }
    if (engine->surface != EGL_NO_SURFACE) {
        eglDestroySurface(engine->display, engine->surface);
    }
    eglTerminate(engine->display);
}
engine->display = EGL_NO_DISPLAY;
engine->context = EGL_NO_CONTEXT;
engine->surface = EGL_NO_SURFACE;
}
更新

android\u main
是我本机应用程序的主要入口点。我发现当这个主函数返回时,整个应用程序仍在运行

void android_main(struct android_app* state) {
struct engine engine;

// Make sure glue isn't stripped.
app_dummy();
memset(&engine, 0, sizeof(engine));
state->userData = &engine;
state->onAppCmd = engine_handle_cmd;
state->onInputEvent = engine_handle_input;
engine.app = state;
ANativeActivity_setWindowFlags(engine.app->activity, AWINDOW_FLAG_FULLSCREEN, 0);

if (state->savedState != NULL) {
    // We are starting with a previous saved state; restore from it.
    engine.state = *(struct saved_state*)state->savedState;
}
while(1){
    int ident;
    int events;
    struct android_poll_source* source;
    if((ident=ALooper_pollAll(-1, NULL, &events,(void**)&source))>=0){
      // Process this event.
       if (source != NULL) {
           source->process(state, source);
       }
       if (state->destroyRequested != 0) {
           engine_term_display(&engine);
           return;
       }
  }
}
}

我自己修复它,使用
exit(0)
而不是
return
完全完成活动

if (state->destroyRequested != 0) {
       engine_term_display(&engine);
       exit(0);
   }

我自己修复它,使用
exit(0)
而不是
return
完全完成活动

if (state->destroyRequested != 0) {
       engine_term_display(&engine);
       exit(0);
   }

讨厌。你基本上把虚拟机从膝盖上砍掉了,这样做会毁掉你的整个过程。你基本上把虚拟机从膝盖上砍掉了,这样做会毁掉你的整个过程。