如何将自定义ViewGroup绘制到CardboardView

时间:2015-07-19 18:16:14

标签: android opengl-es google-cardboard

所以我有一个自定义的ViewGroup,其中包含一堆我想在Google Cardboard的每只眼睛中显示的ImageView。到目前为止,我一直在将视图绘制为叠加层,但我想利用Cardboard提供的失真校正。

我的理解是我需要在OpenGL纹理中绘制视图,然后由Cardboard显示,但我遇到了很多麻烦。 mOverlayView是我想要添加到CardboardView的视图。

这是我的一些相关的CardboardActivity

public class TestActivity extends CardboardActivity implements CardboardView.StereoRenderer {

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.common_ui);
    final test cardboardView = (test) findViewById(R.id.cardboard_view);
    cardboardView.setRenderer(this);
    setCardboardView(cardboardView);

    ScreenParams f = cardboardView.getHeadMountedDisplay().getScreenParams();

    float IPD = cardboardView.getInterpupillaryDistance();
    float w = f.getWidthMeters();
    offset = (w / 2 - IPD) / 2;

    //this is how I have it now but I don't want to add as an overlay anymore!
    mOverlayView = (CardboardOverlayView) findViewById(R.id.overlay); 
}

@Override
public void onRendererShutdown(){
    Log.i(TAG, "onRendererShutdown");
}

@Override
public void onSurfaceChanged(int width, int height) {
    releaseSurface();
    mGlSurfaceTexture = createTexture();
    if (mGlSurfaceTexture > 0){
        //attach the texture to a surface.
        //It's a clue class for rendering an android view to gl level
        surfaceTexture = new SurfaceTexture(mGlSurfaceTexture);
        surfaceTexture.setDefaultBufferSize(mOverlayView.TEXTURE_WIDTH, mOverlayView.TEXTURE_HEIGHT);
        mOverlayView.surface = new Surface(surfaceTexture);
    }
    Log.i(TAG, "onSurfaceChanged");
}

public void releaseSurface(){
    if(mOverlayView.surface != null){
        mOverlayView.surface.release();
    }
    if(surfaceTexture != null){
        surfaceTexture.release();
    }
    mOverlayView.surface = null;
    surfaceTexture = null;

}

private int createTexture(){
    int[] textures = new int[1];

    // Generate the texture to where android view will be rendered
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glGenTextures(1, textures, 0);
    checkGlError("Texture generate");

    GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textures[0]);
    checkGlError("Texture bind");

    GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_LINEAR);
    GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
    GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
    GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);

    return textures[0];
}

public void checkGlError(String op)
{
    int error;
    while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
        Log.e(TAG, op + ": glError " + GLUtils.getEGLErrorString(error));
    }
}

@Override
public void onSurfaceCreated(EGLConfig config) {
    final String extensions = GLES20.glGetString( GLES20.GL_EXTENSIONS );
    Log.d( "GLES20Ext", extensions );

    Log.i(TAG, "onSurfaceCreated");
}

@Override
public void onDrawEye(Eye eye) {
    synchronized ( this ) {
        surfaceTexture.updateTexImage(); // Update texture
    }
}
}

然后在我的ViewGroup中,我有以下onDraw方法

@Override
protected void onDraw( Canvas canvas ) {
    if ( surface != null ) {
        // Requires a try/catch for .lockCanvas( null )
        try {
            final Canvas surfaceCanvas = surface.lockCanvas( null ); // Android canvas from surface
            super.onDraw( surfaceCanvas ); // Call the WebView onDraw targetting the canvas
            surface.unlockCanvasAndPost( surfaceCanvas ); // We're done with the canvas!
        } catch ( Surface.OutOfResourcesException excp ) {
            excp.printStackTrace();
        }
    }
}

我错过了什么?我已经看过许多例子,例如Sveder CardboardPassthrough,TreasureHunt Sample等等,但我似乎无法理解如何使其发挥作用。

0 个答案:

没有答案