所以我有一个自定义的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等等,但我似乎无法理解如何使其发挥作用。