Transparent background of android scene (6 posts)

Topic tags: transparent background
  • Profile picture of mrfluff mrfluff1p said 1 year ago:

    Hello,
    what is the preferred way of changing the background color of the jme scene to transparent? I put the code

    ctx = (OGLESContext) app.getContext();
    view = ctx.createView(this);
    view.setBackgroundColor(Color.TRANSPARENT);
    view.getHolder().setFormat(PixelFormat.TRANSPARENT);
    

    right before the view is added to the layout.
    But this always causes an exception:
    05-09 14:18:38.688: ERROR/AndroidRuntime(10724): FATAL EXCEPTION: GLThread 9
    05-09 14:18:38.688: ERROR/AndroidRuntime(10724): java.lang.RuntimeException: createWindowSurface failed: EGL_BAD_MATCH
    05-09 14:18:38.688: ERROR/AndroidRuntime(10724): at android.opengl.GLSurfaceView$EglHelper.throwEglException(GLSurfaceView.java:1077)
    05-09 14:18:38.688: ERROR/AndroidRuntime(10724): at android.opengl.GLSurfaceView$EglHelper.createSurface(GLSurfaceView.java:981)
    05-09 14:18:38.688: ERROR/AndroidRuntime(10724): at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1304)
    05-09 14:18:38.688: ERROR/AndroidRuntime(10724): at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1116)
    I guess this can be avoided when using other parameters on view.setEGLConfigChooser. (theres set 0 to opacity and i guess therefore it does not work)
    The problem is that I do not really understand where the OGLESContext comes from (I guess the origin is JmeSystem.newContext, but I am not shure) and to make any changes I probably have to recompile the Android lib of JMonkey.
    Is there any simple solution to set a transparent background?
    thx in advance

    edit:

    To be more accurate, I want to use the same settings that are shown in this example: -> mGLSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0)

    http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/TranslucentGLSurfaceViewActivity.html

    when I override the method getContext() from SimpleApplication and return my own Subclass of OGLESContext, which uses the settings I need, the scene is empty and I only see the camera image I positioned behind the GLSurfaceView (so maybe the background of the GLSurfaceView IS transparent now, but I do not see any models ^^ ).

  • Profile picture of larynx larynx27p said 1 year ago:

    The EGL config is set in OGLESContext:

        public GLSurfaceView createView(AndroidInput view)
        {
            this.view = view;
        	/*
        	 * Requesting client version from GLSurfaceView which is extended by
        	 * AndroidInput.
        	 * This is required to get OpenGL ES 2.0
        	 */
        	view.setEGLContextClientVersion(2);
    
            //RGB565, Depth16
            view.setEGLConfigChooser(5, 6, 5, 0, 16, 0);
            view.setFocusableInTouchMode(true);
            view.setFocusable(true);
            view.getHolder().setType(SurfaceHolder.SURFACE_TYPE_GPU);
    	view.setRenderer(this);
            return view;
        }

    createView gets called from the MainActivity

            logger.info("creating view ...");
            view = ctx.createView(input);
            logger.info("creating view ... done.");

    So you could do everything that is done in createView yourself in MainActivity,
    like setting the view of OGLESContext and setting OGLESContext as the renderer of the view.

  • Profile picture of mrfluff mrfluff1p said 1 year ago:

    This is what i hoped for as well, but some more changes need to be made to make this work.
    I just made it work this way:
    I created my own Subclass of OGLESContext and changed the createView method accordingly.
    Then I removed the call to super.start(contextType) in my SimpleApplication but copied the code from the Application.start(contextType) and changed the code where the context was assigned from JmeSystem.newContext(settings, contextType).
    I guess this needs to be done as the context variable is accessed in multiple ways and just assigning a “custom” GLSurfaceContext as the main view of the Android application is not enough, as JME will still render to the GLSurfaceView that was return by context.createView.
    At least I think so :) , now it works anyway.
    Thanks for your help.

  • Profile picture of mradam mradam said 2 months, 4 weeks ago:

    @mrfluff said:
    This is what i hoped for as well, but some more changes need to be made to make this work.
    I just made it work this way:
    I created my own Subclass of OGLESContext and changed the createView method accordingly.
    Then I removed the call to super.start(contextType) in my SimpleApplication but copied the code from the Application.start(contextType) and changed the code where the context was assigned from JmeSystem.newContext(settings, contextType).
    I guess this needs to be done as the context variable is accessed in multiple ways and just assigning a “custom” GLSurfaceContext as the main view of the Android application is not enough, as JME will still render to the GLSurfaceView that was return by context.createView.
    At least I think so :) , now it works anyway.
    Thanks for your help.

    Any chance you might post the code on how you did that?

  • Profile picture of mrfluff mrfluff1p said 2 months, 3 weeks ago:

    It’s been some time since I worked on the project but ill take a look at the source code this week.

  • Profile picture of mrfluff mrfluff1p said 2 months, 3 weeks ago:

    Here we go.

    I made a subclass of com.jme3.app.Application.

    In the start() method, i wrote the following code:

    context = new MyOGLESContext();
    context.setSystemListener(this);
    context.create(false);
    

    Thus, I replace the context of the JME3 application with my own context.

    My own implementation of the context looks like this:

    public class MyOGLESContext extends OGLESContext {
    
        public MyOGLESContext(){
        	super();
        }
    
        public GLSurfaceView createView(Activity activity){
            view = new MyAndroidInput(activity);
    
    	view.setEGLContextClientVersion(2);
    
          view.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
          view.setFocusableInTouchMode(true);
          view.setFocusable(true);
          view.setRenderer(this);
          view.getHolder().setFormat(PixelFormat.TRANSLUCENT);
          return view;
    
        }
    
    }
    

    Here is the class of MyAndroidInput:

    public class MyAndroidInput extends AndroidInput {
    
        public MyAndroidInput(Context ctx, AttributeSet attribs){
            super(ctx, attribs);
        }
    
        public MyAndroidInput(Context ctx){
            super(ctx);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent e) {
        	((FooActivity)getContext()).reactTotouchEvent((int)e.getX(), (int)e.getY());
        	return super.onTouchEvent(e);
        }
    }
    

    Please note that, in the end, I dropped JME3 for developing my mobile application as there were graphical artifacts when displaying animated 3D models. I cannot remember if these artifacts were introduced by using this context, though.

    I wrote about this in my master thesis but I could not gather more information about Android JME3 application development.
    There, the main focus was on using Augmented Reality running on Android devices.
    Finally I used JPCT to write the application.
    If you are interested in my findings about AR and Android have a look at http://www.koratien.at/blogentries/Massively_Multiplayer_Augmented_Reality_Games.htm

    Best regards