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?
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With