android渲染是skia与egl,opengl-es - 为什么渲染位图时我的android native活动有时会显示错误的图像? - 堆栈内存溢出...

我正在尝试使用NDK在全屏上显示位图。 该要求迫使我使用完全本机代码进行开发。 我使用Skia绘制SkBitmap ,然后通过Opengl APIs将其显示。 当我的应用程序首次在真正的android设备上运行时,它始终可以正常运行。 但是,在我多次打开和关闭程序之后,它将显示出不好的图像。 为什么会这样?

功能engine_init_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_term_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_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;

}

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值