Need example how to recover opengl in native code after new onSurfaceCreated - android

I am almost done creating a game for android using a port of irrlicht 3d engine to android.
All code except a minimal frame work to make the native calls and play sounds is written in C++.
Even the opengles display is created in c++ code using eglGetDisplay and eglCreateWindowSurface
The problem I need to solve is that when home is pressed then relaunch the game the screen is all white.
From other answers I have found that the opengl context is lost then recreated when onSurfaceCreated is called. I thought that I could just reload textures but that seams to work for only some textures. Also the background color is changed which is not a resource.
It seams I would have to completely restart the game but this could be really annoying to a user.
the port of quake 3 has notes about this problem be has no solution.
Is there a example anywhere of a game written in native code which correctly handles this situation?

The way I handled the situation is to recreate everything. I made sure that all generated stuff like textures and buffers where deleted before recreating everything as if it happened for the first time.

Related

Cocos2dx C++ dealing with many textures

I am currently using Cocos2dx C++ version 2.0.1. I understand this is an older version of cocos2dx but I originally started using it and already made most of my game with it and I really would rather not switch versions at this time. The problem I am currently having is that my whole game has about 3 full songs, 6 sound effects, and LOTS of textures. I have about 4 sprite sheets using the .plist/.pvr approach that have about 70 frames each. Now I feel I must be doing something wrong because I feel like so many games have way more data then this and they can load up just fine. I have tried many ways to make this work efficiently. I will describe each approach and the problems I have had with each.
I made A load up screen on start of the application but I found out that there seems to be no way to load .plist/.pvr asynchronously so I had no choice but to load each .PNG image one by one and no longer use sprite sheets. I feel that this is a ridiculous way but I have no found another solution. so by using this approach the game does load up (it takes some time but it does work) and since all images are preloaded the game runs smoothly. The problem here is that when I hit the home button and tap on my game icon to resume It takes a lot of time to reload all the textures and I have a very long wait before the application resumes. To fix this I have tried the following approach: I learned about setPreserveEGLContextOnPause() and how I can make textures not be lost when pressing home button. So I finally figured out how to set that up and it actually fixed the problem but I tested this with using only about a fourth of my sprites just to see how much memory it was using and I saw that it was already using 345MB of RAM! This means my full game would probably make the phone run out of RAM.
After all the mishap with the first approach I am really convinced I am doing something terribly wrong because I have not seen one android game that has trouble with coming back after hitting home button. I understand I am using many sprites but I can only but them down so much. I would love to go back to using the .plist/.pvr approach but I can't seem to find a way to load these file types while presenting a loading screen.
I have also tried just simply loading each thing per scenes init method. This causes the same time delay between switching scenes also.
Overall I am really stuck. I feel like I must be doing something very wrong because my game is a very simple puzzle game that is not huge by any means. I also want to find a solution that will work for iphones as well as android phones. Any help would be highly appreciated. Thanks.
1* use .mp3 format for Sound.
2* load All texture in app delegate like that.
#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile( gsd->getFullPath("name.plist")->getCString() )
#endif
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile( "name.plist" );
#endif
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile( "name.plist" );
#endif

OpenGL ES difference for iOS and Android

I have an OpenGL ES app that works both on iOS and Android. Most of the code was written ages ago by another person and now I have to maintain it. OpenGL usage seems fairly simple (the game is 2D and uses only textured sprites in a simple manner). But I see two major differences in graphics code realization for iOS and Android:
1) iOS code contains this code:
glGenFramebuffersOES(1, &m_defaultFramebuffer);
glGenRenderbuffersOES(1, &m_colorRenderbuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_defaultFramebuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, m_colorRenderbuffer);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, m_colorRenderbuffer);
and Android's one does not.
2) When Android app goes to background, all OpenGL textures are destroyed (glDeleteTextures) and EGL is shutdowned using eglTerminate. When app returns from sleep, EGL is re-initialized and textures are re-created.
iOS code does not do these things. It just pauses rendering loop by calling [m_displayLink setPaused:YES];
Other OpenGL-related code is the same for iOS and Android.
Everything works well on both platforms, but I want to have a full understanding of what's going on. Can anybody explain me a rationale behind these two differences?
1)
This is just a difference in the APIs. On iOS, you create your own framebuffer to render in to when the App starts. On Android the framebuffer is created automatically in GLSurfaceView, so the App doesn't need to create its own.
2)
On iOS, when your App goes to the background, the OpenGL context is preserved, which means all your textures and buffers are still there when you return it to the foreground.
Older versions of Android had only a single OpenGL context, so it was destroyed whenever your App went to the background (so that other Apps could then make use of it).
Later versions of Android do have the option to behave more like iOS by calling setPreserveEGLContextOnPause. However for this to work, the Android version has to be 3.x or above (API 11) and the device must support it also.
When it is not used or supported, the App must delete and re-create all it's OpenGL resources when going between background and foreground, which is what your App appears to be doing.

GLSurfaceView device orientation change, black screen

Im porting an iOS game to Android.
Im using as template the GL2JNI example from the latest NDK, and have added inside GL2JNIActivity.java/onCreate mView.setPreserveEGLContextOnPause( true ); to preserve the EGL context but it as soon the device orientation change the screen is all black.
I've research on this and some suggests to reload all textures, shaders, geometry etc... But that is not an option for me (too slow to reload).
Is there any way to handle like on iOS multiple devices orientation using on OpenGLES2 view on Android? If yes how can it be done without reloading everything. I've seen like Unity games doing it... so it must be possible right?
TIA!

Deal with OpenGL context restoration in Android 2.x libgdx?

I read somewhere that OpenGL context can be restored automatically by libgdx framework. And in my case, everything is OK with the real phone 4.0.3. But when I test with Android 2.x, it doesn't work well, just return me a white blank:((.
Isn't it true that i can leave restoring OpenGL context to libgdx? Could you please share your experiences with this? Or libgdx just can't work with Android versions lower than 4.x?( I use Opengl 1.0).
See http://www.badlogicgames.com/wordpress/?p=1073. The post is from 2010, and so it talks in about some future features that are now current (TextureAtlas and TextureRegion), and the point of the article is about how dynamically generated textures cannot be automatically managed by libGDX, but implicitly it describes the texture management problem, and how libGDX can be used to solve it in certain cases (basically libGDX needs to know how/where to reload your texture from).
libGDX should work fine on Android 2.x or 4.x.
Are you sure the underlying process is hanging around in both the 4.x and 2.x Android cases? Texture lossage is only a problem when an Activity exits and the Application stays alive until the Activity is restarted. If the Application exits, everything is re-initialized.

Getting an android app to keep it's OpenGL Context after hitting the home button

First a bit of context: I'm developing a video game for both the Android and iPhone platforms. The way the iPhone works, when a user hits the home button and returns to the game later, in most circumstances the game will pick up RIGHT where it left off with no hicups. I immediately jump back into my rendering and game loop. Setting this up on the iOS platform was absolutely easy for me to do. Accomplishing this on the Android has left me in a fit of rage after hours of wrestling with google results :P
I have my own OpenGL setup for both the iPhone and Android, and everything has been working great. The root of the problem, I believe, is that I need a SurfaceHolder to create an OpenGL Context. Here's the sucky part, when the screen loses focus of the game (ie the home button was hit), Android calls surfaceDestroyed in my SurfaceView class and basically KILLS my opengl context. I could recreate a new one with a new SurfaceHolder when surfaceCreated is called, but then I need to reload all of my art assets which defeats the purpose of everything I'm trying to accomplish.
Can I somehow prevent the Android OS from killing my surface holder, is there some sort of custom view I can use to get this to work? Is there some setting in the Manifest that can help me out here (I doubt it as I have thoroughly tested most of the flags)? I know this is possible because Angry Birds does this perfectly on the Android OS.

Categories

Resources