Android OpenGL ES Context lost
Posted: Fri Oct 25, 2013 1:48 am
Hi,
I'm currently trying to port an irrlicht project to android but I have problems with the context loss when pressing the home button.
After reading http://irrlicht.sourceforge.net/forum// ... 61#p265961 I tried to implement a recreate method (contains basically all important stuff from the constructors) for the COGLES2Driver:
Recreate method for COGLES2Texture:
The method gets called on the APP_CMD_RESUME event.
I've tried it with a modified version of the UserInterface Example:
But after pressing home and returning to the app the gui is no longer visible (but reacts on input):
I've already spent days trying to fix this with no success. Can anybody help me please?
Thank you very much in advance.
I'm currently trying to port an irrlicht project to android but I have problems with the context loss when pressing the home button.
After reading http://irrlicht.sourceforge.net/forum// ... 61#p265961 I tried to implement a recreate method (contains basically all important stuff from the constructors) for the COGLES2Driver:
Code: Select all
void COGLES2Driver::recreate(const SIrrlichtCreationParameters& params,
const SExposedVideoData& data, io::IFileSystem* io
#if defined(_IRR_COMPILE_WITH_IPHONE_DEVICE_)
, CIrrDeviceIPhone* device
#endif
){
ExposedData = data;
#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_)
EglWindow = (NativeWindowType)data.OpenGLWin32.HWnd;
HDc = GetDC((HWND)EglWindow);
EglDisplay = eglGetDisplay((NativeDisplayType)HDc);
#elif defined(_IRR_COMPILE_WITH_X11_DEVICE_)
EglWindow = (NativeWindowType)ExposedData.OpenGLLinux.X11Window;
EglDisplay = eglGetDisplay((NativeDisplayType)ExposedData.OpenGLLinux.X11Display);
#elif defined(_IRR_COMPILE_WITH_IPHONE_DEVICE_)
Device = device;
#elif defined(_IRR_COMPILE_WITH_ANDROID_DEVICE_)
EglWindow = ((struct android_app *)(params.PrivateData))->window;
EglDisplay = EGL_NO_DISPLAY;
//mustRecreate = false;
#endif
//changed:
//COGLES2ExtensionHandler Konstruktor
EGLVersion= 0; Version = 0; MaxTextureUnits = 0; MaxSupportedTextures = 0; MaxAnisotropy = 1; MaxTextureSize = 1; MaxIndices = 0xffff; MaxTextureLODBias = 0.f; StencilBuffer = false;
for (u32 i=0; i<IRR_OGLES2_Feature_Count; ++i)
FeatureAvailable[i] = false;
CurrentRenderMode = ERM_NONE;
ResetRenderStates = true;
Transformation3DChanged = true;
AntiAlias = params.AntiAlias;
BridgeCalls = 0;
RenderTargetTexture = 0;
CurrentRendertargetSize = core::dimension2d<u32>(0, 0);
ColorFormat = ECF_R8G8B8;
#ifdef EGL_VERSION_1_0
EglDisplay = EGL_NO_DISPLAY;
#endif
//stuff from Null Device Constructor
setTextureCreationFlag(ETCF_ALWAYS_32_BIT, true);
setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, true);
memset(&ExposedData, 0, sizeof(ExposedData));
for (u32 i=0; i<video::EVDF_COUNT; ++i)
FeatureEnabled[i]=true;
InitMaterial2D.AntiAliasing=video::EAAM_OFF;
InitMaterial2D.Lighting=false;
InitMaterial2D.ZWriteEnable=false;
InitMaterial2D.ZBuffer=video::ECFN_DISABLED;
InitMaterial2D.UseMipMaps=false;
for (u32 i=0; i<video::MATERIAL_MAX_TEXTURES; ++i)
{
InitMaterial2D.TextureLayer[i].BilinearFilter=false;
InitMaterial2D.TextureLayer[i].TextureWrapU=video::ETC_REPEAT;
InitMaterial2D.TextureLayer[i].TextureWrapV=video::ETC_REPEAT;
}
OverrideMaterial2D=InitMaterial2D;
//HWBufferLinks:
HWBufferMap.clear();
//changed end
#ifdef EGL_VERSION_1_0
if (EglDisplay == EGL_NO_DISPLAY)
{
os::Printer::log("Getting OpenGL-ES2 display.");
EglDisplay = eglGetDisplay((NativeDisplayType) EGL_DEFAULT_DISPLAY);
}
if (EglDisplay == EGL_NO_DISPLAY)
{
os::Printer::log("Could not get OpenGL-ES2 display.");
}
EGLint majorVersion, minorVersion;
if (!eglInitialize(EglDisplay, &majorVersion, &minorVersion))
{
os::Printer::log("Could not initialize OpenGL-ES2 display.");
}
else
{
char text[64];
sprintf(text, "EglDisplay initialized. Egl version %d.%d\n", majorVersion, minorVersion);
os::Printer::log(text);
}
EGLint attribs[] =
{
EGL_RED_SIZE, 5,
EGL_GREEN_SIZE, 5,
EGL_BLUE_SIZE, 5,
EGL_ALPHA_SIZE, params.WithAlphaChannel ? 1 : 0,
EGL_BUFFER_SIZE, params.Bits,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
//EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER,
EGL_DEPTH_SIZE, params.ZBufferBits,
EGL_STENCIL_SIZE, params.Stencilbuffer,
EGL_SAMPLE_BUFFERS, params.AntiAlias ? 1 : 0,
EGL_SAMPLES, params.AntiAlias,
#ifdef EGL_VERSION_1_3
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
#endif
EGL_NONE, 0
};
EGLint contextAttrib[] =
{
#ifdef EGL_VERSION_1_3
EGL_CONTEXT_CLIENT_VERSION, 2,
#endif
EGL_NONE, 0
};
EGLConfig config;
EGLint num_configs;
u32 steps=5;
while (!eglChooseConfig(EglDisplay, attribs, &config, 1, &num_configs) || !num_configs)
{
switch (steps)
{
case 5: // samples
if (attribs[19]>2)
{
--attribs[19];
}
else
{
attribs[17]=0;
attribs[19]=0;
--steps;
}
break;
case 4: // alpha
if (attribs[7])
{
attribs[7]=0;
if (params.AntiAlias)
{
attribs[17]=1;
attribs[19]=params.AntiAlias;
steps=5;
}
}
else
--steps;
break;
case 3: // stencil
if (attribs[15])
{
attribs[15]=0;
if (params.AntiAlias)
{
attribs[17]=1;
attribs[19]=params.AntiAlias;
steps=5;
}
}
else
--steps;
break;
case 2: // depth size
if (attribs[13]>16)
{
attribs[13]-=8;
}
else
memset(&ExposedData, 0, sizeof(ExposedData));
for (u32 i=0; i<video::EVDF_COUNT; ++i)
FeatureEnabled[i]=true;
InitMaterial2D.AntiAliasing=video::EAAM_OFF;
InitMaterial2D.Lighting=false;
InitMaterial2D.ZWriteEnable=false;
InitMaterial2D.ZBuffer=video::ECFN_DISABLED;
InitMaterial2D.UseMipMaps=false;
for (u32 i=0; i<video::MATERIAL_MAX_TEXTURES; ++i)
{
InitMaterial2D.TextureLayer[i].BilinearFilter=false;
InitMaterial2D.TextureLayer[i].TextureWrapU=video::ETC_REPEAT;
InitMaterial2D.TextureLayer[i].TextureWrapV=video::ETC_REPEAT;
}
OverrideMaterial2D=InitMaterial2D; --steps;
break;
case 1: // buffer size
if (attribs[9]>16)
{
attribs[9]-=8;
}
else
--steps;
break;
default:
os::Printer::log("Could not get config for OpenGL-ES2 display.");
return;
}
}
if (params.AntiAlias && !attribs[17])
os::Printer::log("No multisampling.");
if (params.WithAlphaChannel && !attribs[7])
os::Printer::log("No alpha.");
if (params.Stencilbuffer && !attribs[15])
os::Printer::log("No stencil buffer.");
if (params.ZBufferBits > attribs[13])
os::Printer::log("No full depth buffer.");
if (params.Bits > attribs[9])
os::Printer::log("No full color buffer.");
os::Printer::log(" Creating EglSurface with nativeWindow...");
EglSurface = eglCreateWindowSurface(EglDisplay, config, EglWindow, NULL);
if (EGL_NO_SURFACE == EglSurface)
{
os::Printer::log("FAILED\n");
EglSurface = eglCreateWindowSurface(EglDisplay, config, NULL, NULL);
os::Printer::log("Creating EglSurface without nativeWindows...");
}
else
os::Printer::log("SUCCESS\n");
if (EGL_NO_SURFACE == EglSurface)
{
os::Printer::log("FAILED\n");
os::Printer::log("Could not create surface for OpenGL-ES2 display.");
}
else
os::Printer::log("SUCCESS\n");
#ifdef EGL_VERSION_1_2
if (minorVersion>1)
eglBindAPI(EGL_OPENGL_ES_API);
#endif
os::Printer::log("Creating EglContext...");
EglContext = eglCreateContext(EglDisplay, config, EGL_NO_CONTEXT, contextAttrib);
if (EGL_NO_CONTEXT == EglContext)
{
os::Printer::log("FAILED\n");
os::Printer::log("Could not create Context for OpenGL-ES2 display.");
}
eglMakeCurrent(EglDisplay, EglSurface, EglSurface, EglContext);
if (testEGLError())
{
os::Printer::log("Could not make Context current for OpenGL-ES2 display.");
}
genericDriverInit(params.WindowSize, params.Stencilbuffer);
// set vsync
if (params.Vsync)
eglSwapInterval(EglDisplay, 1);
#elif defined(GL_ES_VERSION_2_0)
glGenFramebuffers(1, &ViewFramebuffer);
glGenRenderbuffers(1, &ViewRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, ViewRenderbuffer);
#if defined(_IRR_COMPILE_WITH_IPHONE_DEVICE_)
ExposedData.OGLESIPhone.AppDelegate = Device;
Device->displayInitialize(&ExposedData.OGLESIPhone.Context, &ExposedData.OGLESIPhone.View);
#endif
GLint backingWidth;
GLint backingHeight;
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth);
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight);
glGenRenderbuffers(1, &ViewDepthRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, ViewDepthRenderbuffer);
GLenum depthComponent = GL_DEPTH_COMPONENT16;
if (params.ZBufferBits >= 24)
depthComponent = GL_DEPTH_COMPONENT24_OES;
glRenderbufferStorage(GL_RENDERBUFFER, depthComponent, backingWidth, backingHeight);
glBindFramebuffer(GL_FRAMEBUFFER, ViewFramebuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, ViewRenderbuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, ViewDepthRenderbuffer);
core::dimension2d<u32> WindowSize(backingWidth, backingHeight);
CNullDriver::ScreenSize = WindowSize;
CNullDriver::ViewPort = core::rect<s32>(core::position2d<s32>(0,0), core::dimension2di(WindowSize));
genericDriverInit(WindowSize, params.Stencilbuffer);
#endif
//Recreate Textures
for (u32 i=0; i<Textures.size(); ++i)
((COGLES2Texture*)(Textures[i].Surface))->recreate();
}
Code: Select all
void COGLES2Texture::recreate(){
glGenTextures(1, &TextureName);
uploadTexture(true, NULL);
regenerateMipMapLevels();
}
I've tried it with a modified version of the UserInterface Example:
But after pressing home and returning to the app the gui is no longer visible (but reacts on input):
I've already spent days trying to fix this with no success. Can anybody help me please?
Thank you very much in advance.