In the past I’ve developed two iOS games using Cocos2D, but now I want to switch to Cocos2d-x to use the same engine for my iOS games, Android games AND Android Live Wallpapers. That said, I’m a total newbie with Cocos2d-x.
So far I’ve managed to create and run the default android project. Now I’m trying to change the code to use it inside a live wallpaper. The lifecycle changes a lot because instead of an Activity I must use a WallpaperService.Engine class. However it should be possible to reuse the Cocos2dxGLSurfaceView class inside the WallpaperService.Engine class. I’ve took the idea from ‘approach one’ of this blog post: http://www.learnopengles.com/how-to-use-opengl-es-2-in-an-android-live-wallpaper/
Also I’m trying to reuse Cocos2dxHelper and Cocos2dxRenderer classes. In essence I’m moving initialization code from Cocos2dxActivity to my custom WallpaperService.Engine subclass.
So far the code looks like this:
public class MyWallpaperService extends WallpaperService
{
static
{
System.loadLibrary("game");
}
@Override
public Engine onCreateEngine()
{
return new MyWallpaperEngine();
}
// Based on: http://www.learnopengles.com/how-to-use-opengl-es-2-in-an-android-live-wallpaper/
protected class MyWallpaperEngine extends Engine implements Cocos2dxHelperListener
{
protected class MyGLSurfaceView extends Cocos2dxGLSurfaceView
{
MyGLSurfaceView(Context context)
{
super(context);
}
@Override
public SurfaceHolder getHolder()
{
return getSurfaceHolder();
}
public void onDestroy()
{
super.onDetachedFromWindow();
}
}
private MyGLSurfaceView mGLSurfaceView;
@Override
public void onCreate(SurfaceHolder surfaceHolder)
{
super.onCreate(surfaceHolder);
mGLSurfaceView = new MyGLSurfaceView(MyWallpaperService.this);
mGLSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
mGLSurfaceView.setCocos2dxRenderer(new Cocos2dxRenderer());
Cocos2dxHelper.init(MyWallpaperService.this, this);
}
@Override
public void onVisibilityChanged(boolean visible)
{
super.onVisibilityChanged(visible);
if (visible)
{
Cocos2dxHelper.onResume();
mGLSurfaceView.onResume();
}
else
{
Cocos2dxHelper.onPause();
mGLSurfaceView.onPause();
}
}
@Override
public void onDestroy()
{
super.onDestroy();
Cocos2dxHelper.end();
mGLSurfaceView.onDestroy();
}
@Override
public void showDialog(String pTitle, String pMessage)
{
}
@Override
public void showEditTextDialog(String pTitle, String pMessage, int pInputMode, int pInputFlag, int pReturnType, int pMaxLength)
{
}
@Override
public void runOnGLThread(Runnable pRunnable)
{
mGLSurfaceView.queueEvent(pRunnable);
}
}
}
As you can see no Cocos2dxEditText class is present and showDialog and showEditTextDialog implementations are left empty.
First time I run the project and pick the wallpaper nothing happens, just a black screen and the usual Cocos logging. Second time still a black screen but the log window is filled with OpenGL 0x0501 error messages
Any ideas? Someone here has managed to implement a Cocos2d-x based wallpaper?
Did you over-ride any of the draw functions in cocos2d-x for custom rendering?
I think this error shows up when you use opengl calls directly instead of using cocos2d-x wrappers.
Also i think you missed the adding renderer part of the tutorial?
There you go fixed it for you…
PS: Thanks for the boilerplate code… wouldn’t have done if it wasn’t available.
I have been searching for an example for months. Thank you very much for providing what you have. When I try to use the code however the results are somewhat random. Sometimes it works perfect but other times I get a black screen and a load of opengl 0x0501 errors. The pattern seems to be if you try to show the wallpaper twice - e.g. Open up the Live Wallpapers screen - choose the wallpaper - it shows (sometimes), press set wallpaper and I get a black screen with opengl errors. Turn off phone, turn back on so the wallpaper has only been loaded once and it works fine.
Did you see this error? Do you have any idea how this can be fixed? I have been playing with the lifecycle to no avail.
Hi guys! I would like to now how is going with your live wallpaper implementation. I’m also trying to do that, using cocos2d-x 2.2 version, but the result is very unstable. So, what about you?
I’ve used cocos2d-2.1beta3-x-2.1.0 and works fine for me.
have not tried out with the newer versions
Also it would help if you can post the stack trace.
Sandro Italiano wrote:
One of my logcat errors is:
[…]
then the wallpaper crashs.
Some times instead, setting as wallpaper, it works well or doesn’t crash but the screen is black.
Ok! On my Nexus 7, settiing my project as wallpaper, the screen turns black, but if I rotate the device then cocos2d reloads all textures so the wallpaper is visible. Here is the stack trace…
11-06 10:22:01.238: W/WindowManager(434): Force-removing child win Window{42936af8 u0 com.sandro.lwptest.MyWallpaperService} from container Window{428c6e10 u0 com.android.wallpaper.livepicker/com.android.wallpaper.livepicker.LiveWallpaperPreview}
11-06 10:22:01.238: E/BufferQueue(121): [com.sandro.lwptest.MyWallpaperService] dequeueBuffer: BufferQueue has been abandoned!
11-06 10:22:01.238: W/nvwsi(5830): dequeueBuffer failed, error -19
11-06 10:22:01.238: W/WindowManager(434): Force-removing child win Window{4290e6a0 u0 Media:com.android.wallpaper.livepicker/com.android.wallpaper.livepicker.LiveWallpaperPreview} from container Window{428c6e10 u0 com.android.wallpaper.livepicker/com.android.wallpaper.livepicker.LiveWallpaperPreview}
11-06 10:22:01.248: D/cocos2d-x debug info(5830): OpenGL error 0x0506 in C:/Dev/cocos2d-x-2.2.0/projects/LwpTest/proj.android/../../../cocos2dx/sprite_nodes/CCSprite.cpp draw 584
11-06 10:22:01.248: D/cocos2d-x debug info(5830): OpenGL error 0x0506 in C:/Dev/cocos2d-x-2.2.0/projects/LwpTest/proj.android/../../../cocos2dx/textures/CCTextureAtlas.cpp drawNumberOfQuads 686
11-06 10:22:01.248: D/cocos2d-x debug info(5830): OpenGL error 0x0506 in C:/Dev/cocos2d-x-2.2.0/projects/LwpTest/proj.android/../../../cocos2dx/textures/CCTextureAtlas.cpp drawNumberOfQuads 686
11-06 10:22:01.248: D/cocos2d-x debug info(5830): OpenGL error 0x0506 in C:/Dev/cocos2d-x-2.2.0/projects/LwpTest/proj.android/../../../cocos2dx/textures/CCTextureAtlas.cpp drawNumberOfQuads 686
11-06 10:22:01.248: W/GLThread(5830): eglSwapBuffers failed: EGL_BAD_SURFACE
11-06 10:22:01.258: W/WindowManager(434): Failed looking up window
11-06 10:22:01.258: W/WindowManager(434): java.lang.IllegalArgumentException: Requested window android.os.BinderProxy@42886e88 does not exist
11-06 10:22:01.258: W/WindowManager(434): at com.android.server.wm.WindowManagerService.windowForClientLocked(WindowManagerService.java:7608)
11-06 10:22:01.258: W/WindowManager(434): at com.android.server.wm.WindowManagerService.windowForClientLocked(WindowManagerService.java:7599)
11-06 10:22:01.258: W/WindowManager(434): at com.android.server.wm.WindowManagerService.removeWindow(WindowManagerService.java:2305)
11-06 10:22:01.258: W/WindowManager(434): at com.android.server.wm.Session.remove(Session.java:181)
11-06 10:22:01.258: W/WindowManager(434): at android.view.IWindowSession$Stub.onTransact(IWindowSession.java:197)
11-06 10:22:01.258: W/WindowManager(434): at com.android.server.wm.Session.onTransact(Session.java:125)
11-06 10:22:01.258: W/WindowManager(434): at android.os.Binder.execTransact(Binder.java:388)
11-06 10:22:01.258: W/WindowManager(434): at dalvik.system.NativeStart.run(Native Method)
11-06 10:22:01.268: D/MyWallpaperService(5830): onDestroy
11-06 10:22:01.278: W/WindowManager(434): Failed looking up window
11-06 10:22:01.278: W/WindowManager(434): java.lang.IllegalArgumentException: Requested window android.os.BinderProxy@42566df0 does not exist
11-06 10:22:01.278: W/WindowManager(434): at com.android.server.wm.WindowManagerService.windowForClientLocked(WindowManagerService.java:7608)
11-06 10:22:01.278: W/WindowManager(434): at com.android.server.wm.WindowManagerService.windowForClientLocked(WindowManagerService.java:7599)
11-06 10:22:01.278: W/WindowManager(434): at com.android.server.wm.WindowManagerService.removeWindow(WindowManagerService.java:2305)
11-06 10:22:01.278: W/WindowManager(434): at com.android.server.wm.Session.remove(Session.java:181)
11-06 10:22:01.278: W/WindowManager(434): at android.view.IWindowSession$Stub.onTransact(IWindowSession.java:197)
11-06 10:22:01.278: W/WindowManager(434): at com.android.server.wm.Session.onTransact(Session.java:125)
11-06 10:22:01.278: W/WindowManager(434): at android.os.Binder.execTransact(Binder.java:388)
11-06 10:22:01.278: W/WindowManager(434): at dalvik.system.NativeStart.run(Native Method)
On my Samsung Galaxy ACE instead…
11-06 10:27:40.117: D/cocos2d-x debug info(32016): OpenGL error 0x0502 in C:/Dev/cocos2d-x-2.2.0/projects/LwpTest/proj.android/../../../cocos2dx/sprite_nodes/CCSprite.cpp draw 584
11-06 10:27:40.117: D/cocos2d-x debug info(32016): OpenGL error 0x0502 in C:/Dev/cocos2d-x-2.2.0/projects/LwpTest/proj.android/../../../cocos2dx/textures/CCTextureAtlas.cpp drawNumberOfQuads 686
11-06 10:27:40.117: D/cocos2d-x debug info(32016): OpenGL error 0x0502 in C:/Dev/cocos2d-x-2.2.0/projects/LwpTest/proj.android/../../../cocos2dx/textures/CCTextureAtlas.cpp drawNumberOfQuads 686
11-06 10:27:40.117: D/cocos2d-x debug info(32016): OpenGL error 0x0502 in C:/Dev/cocos2d-x-2.2.0/projects/LwpTest/proj.android/../../../cocos2dx/textures/CCTextureAtlas.cpp drawNumberOfQuads 686
11-06 10:27:40.265: D/MyWallpaperService(32016): onVisibilityChanged ::true
11-06 10:27:40.265: I/GLThread(32016): onResume tid=14
11-06 10:27:40.281: D/cocos2d-x debug info(32016): reload all texture
11-06 10:27:40.382: I/GLThread(32016): noticed surfaceView surface lost tid=10
11-06 10:27:40.382: W/EglHelper(32016): destroySurface() tid=10
11-06 10:27:40.382: D/BRCM_EGL(32016): eglMakeCurrent(NULL) Thread: 32024
11-06 10:27:40.382: D/BRCM_EGL(32016): eglDestroySurface() surface: 0x1e06e0, android window 0x1d8698, Thread: 32024
11-06 10:27:40.382: D/MyWallpaperService(32016): onDestroy
11-06 10:27:40.390: W/EglHelper(32016): finish() tid=10
11-06 10:27:40.390: D/BRCM_EGL(32016): eglDestroyContext() context: 0x1d8678, VC context: 1, Thread 32024
11-06 10:27:40.664: I/GLThread(32016): sending render notification tid=14
11-06 10:27:40.835: E/(32016): Unable to Find Phys Addr for 1f5170
11-06 10:27:40.835: E/(32016): Unable to Find Phys Addr for 1f5170
11-06 10:27:40.835: E/(32016): Unable to Find Phys Addr for 1f5170
11-06 10:27:40.875: E/(32016): Unable to Find Phys Addr for 1f5170
11-06 10:27:40.875: E/(32016): Unable to Find Phys Addr for 1f5170
11-06 10:27:40.875: E/(32016): Unable to Find Phys Addr for 1f5170
11-06 10:27:40.968: E/(32016): Unable to Find Phys Addr for 1f5170
11-06 10:27:40.976: E/(32016): Unable to Find Phys Addr for 1f5170
11-06 10:27:40.976: E/(32016): Unable to Find Phys Addr for 1f5170
11-06 10:27:41.078: E/(32016): Unable to Find Phys Addr for 1f5170
11-06 10:27:41.078: E/(32016): Unable to Find Phys Addr for 1f5170
11-06 10:27:41.078: E/(32016): Unable to Find Phys Addr for 1f5170
11-06 10:27:41.179: E/(32016): Unable to Find Phys Addr for 1f5170
11-06 10:27:41.179: E/(32016): Unable to Find Phys Addr for 1f5170
11-06 10:27:41.179: E/(32016): Unable to Find Phys Addr for 1f5170
11-06 10:27:41.281: E/(32016): Unable to Find Phys Addr for 1f5170
11-06 10:27:41.281: E/(32016): Unable to Find Phys Addr for 1f5170
11-06 10:27:41.281: E/(32016): Unable to Find Phys Addr for 1f5170
11-06 10:27:41.382: E/(32016): Unable to Find Phys Addr for 1f5170
11-06 10:27:41.382: E/(32016): Unable to Find Phys Addr for 1f5170