views:

344

answers:

1

I am trying to create a simple 3-D app for android that will have an additional view layered on top of the OpenGL view (much like the SurfaceViewOverlay example in the API demos). I'm running into an issue trying to implement that method with an extended GLSurfaceView class. I've set up an example where I'm trying to do a combination of this demo with the API Oerlay demo. If I try to cast to a Martin's VortexView object like this (replace lines 44-46 in the API demo)

VortexView glSurfaceView=
     (VortexView) findViewById(R.id.glsurfaceview);

I get a ClassCastException error (which is understandable, as I assume casting is fairly specific) so I guess I'm looking for a method to transfer the view from a GLSurfaceView instance to a new subclass or a way to set the rendering surface to an XML defined view for a subclass after it has been created.

EDIT: I've made some progress trying to get this to work- in the API example the view XML uses (from ApiDemos/res/layout/surface_view_overlay.xml)

        <android.opengl.GLSurfaceView android:id="@+id/glsurfaceview"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

If I change that element to a
com.domain.project.VortexView it will do the casting correctly with the above code but generates Null Pointer Exceptions when it hits the surfaceCreated and surfaceChanged routines (I think it's the called methods in the GLThread class based on the line number) inside the GLSurfaceView class. So maybe I should change the question- How can I implement an extension for GLSurfaceView without generating NullPointerExceptions on surfaceCreated and surfaceChanged, or how can I debug them without having the source for GLSurfaceView.java?

A: 

Here's how I got it to work:

in the XML file (mine is main.xml) use the extended class spec

        <com.domain.project.VortexView android:id="@+id/vortexview"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" />

In your activity class:

    setContentView(R.layout.main);
    VortexRenderer _renderer=new VortexRenderer();         // setup our renderer
    VortexView glSurface=(VortexView) findViewById(R.id.vortexview); // use the xml to set the view
   glSurface.setRenderer(_renderer); // MUST BE RIGHT HERE, NOT in the class definition, not after any other calls (see GLSurfaceView.java for related notes)
   glSurface.showRenderer(_renderer); // allows us to access the renderer instance for touch events, etc

The view definition (VortexView.java):

public class VortexView extends GLSurfaceView {
    public VortexRenderer _renderer; // just a placeholder for now

public VortexView(Context context) { // default constructor
    super(context);
}


public VortexView(Context context, AttributeSet attrs) { /*IMPORTANT - this is the constructor that is used when you send your view ID in the main activity */
    super(context, attrs);
}

public void showRenderer(VortexRenderer renderer){ // sets our local object to the one created in the main activity, a poor man's getRenderer
    this._renderer=renderer;        
}

public boolean onTouchEvent(final MotionEvent event) { // An example touchevent from the vortex demo
    queueEvent(new Runnable() {
        public void run() {
           _renderer.setColor(event.getX() / getWidth(), event.getY() / getHeight(), 1.0f);
        }
    });
    return true;
}

}

the VortexRenderer.java just has typical onSurfaceXXXXX calls.

Anyway this seems to allow me to stack other XML defined views over my extended GLSurface which is what I wanted in the first place.

Cheers!

T. Markle