2011-02-14 77 views
23

我正在爲Android編寫一個信息可視化API,並遇到了一個問題,試圖將兩個單元的自定義GLSurfaceView放入佈局中。自定義GLSurfaceView此時只是GLSurfaceView的擴展,以消除由自定義方法導致的可能故障。如何在同一個佈局中使用多個GLSurfaceView組件?

當我在佈局中添加了兩個組件並啓動它運行的應用程序時。但沒有任何東西被繪製,似乎它進入了一個無限循環。因爲Renderer中的調試消息被打印到LogCat中。但是,如果我僅使用定製的GLSurfaceView組件之一,則它工作得很好。

,我讀了有多個活動使用GLSurfaceView一個問題,我想在同一時間使用兩種這些組件時,它也同樣適用。我已經嘗試過發佈here的解決方法,但似乎無法使其工作。

我將不勝感激任何幫助。我選擇使用openGL來獲得更好的性能,但是如果我不能一次使用多個組件,我想我必須改用Canvas。

清單如下所示:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 
    <TextView android:text="@string/hello" android:id="@+id/TextView01" 
     android:layout_width="wrap_content" 
      android:layout_height="wrap_content" /> 

    <com.syntronic.vtadlib.VisualizationView android:id="@+id/glview" 
     android:layout_width="fill_parent" android:layout_height="300px" /> 


    <TextView android:text="@string/hello" android:id="@+id/TextView02" 
     android:layout_width="wrap_content" 
      android:layout_height="wrap_content" /> 

    <LinearLayout 
     android:orientation="vertical" android:layout_width="fill_parent" 
     android:layout_height="fill_parent"> 

     <com.syntronic.vtadlib.VisualizationView android:id="@+id/glview2" 
      android:layout_width="fill_parent" android:layout_height="fill_parent" /> 

    </LinearLayout> 

</LinearLayout> 

從活動的代碼是這樣的:

@Override 
public void onCreate(Bundle savedInstanceState) { 

    super.onCreate(savedInstanceState); 

    setContentView(R.layout.main); 

    mSurfaceView = (VisualizationView) findViewById(R.id.glview); 
    mSurfaceView2 = (VisualizationView) findViewById(R.id.glview2); 

    //Enables debug flags for Errors 
    //mSurfaceView.setDebugFlags(GLSurfaceView.DEBUG_CHECK_GL_ERROR); 
    //mSurfaceView2.setDebugFlags(GLSurfaceView.DEBUG_CHECK_GL_ERROR); 

    mSurfaceView.setRenderer(new CoordinateSystemRenderer()); 
    mSurfaceView2.setRenderer(new CoordinateSystemRenderer()); 

} 

@Override 
protected void onPause() { 
    // TODO Auto-generated method stub 
    super.onPause(); 
    mSurfaceView.onPause(); 
    mSurfaceView2.onPause(); 
} 

@Override 
protected void onResume() { 
    // TODO Auto-generated method stub 
    super.onResume(); 
    mSurfaceView.onResume(); 
    mSurfaceView2.onResume(); 
} 

我失去了一些東西明顯?或者有人可以解釋爲什麼它不起作用?

+1

跳出來的第一件事就是你的嵌套LinearLayout被設置爲fill_parent。我會檢查以確保您的兩個GLSurfaceViews都以非零高度佈置。可能情況是,它們都在繪製,但其中一個具有0像素的高度,因此是不可見的。 – 2012-01-25 03:11:42

+0

而不是兩個`GLSurfaceViews`,可能會更好地創建/管理GL線程和上下文,將它應用於兩個`SurfaceViews`(而不是``GLSurfaceViews`)。參見[fadden的討論和鏈接到Grafika](http://stackoverflow.com/a/22746240/199364)。 – ToolmakerSteve 2017-01-05 03:12:58

回答

0

有很多要去的GLSurfaceView包括管理GLContext後面,我敢肯定,你將不能夠讓它工作,即使你成功了,你可能會爲更多的意想不到的問題以後。所以我真的相信這不是正確的應用程序架構。

8

[更新:這個答案不再正確,因爲Android 5.0(Lollipop)。請參閱fadden's answer進行討論和鏈接。 It was also incorrect as of Android 2.0, and apparently was only an issue for OVERLAPPING surfaces even before then.]

您不能將2個SurfaceViews(SV)放置到一個Activity中。 瞭解爲什麼你應該知道SVs是如何工作的。

當你創建它,並在它實際上犯規活動場所將被放置在活動(或它的上面),而是將與該活動創建「透明」鑑於當前活動的背後創建。

在Android 4.0(API 14)中有新的視圖叫做TextureView 有沒有辦法在舊平臺上創建類似的視圖。

+1

你確定嗎?我只認爲限制是,你不能把它們放在彼此之上或重疊。被稱爲你不能在視圖上顯示視頻視圖,因爲videoview擴展了視圖視圖... – WarrenFaith 2012-04-03 21:24:20

+0

是的,我確定。您只能在一次使用SV的一個實例。 – pepyakin 2012-04-04 13:23:45

+0

你能否提供一個源代碼?我對完整的SV主題非常感興趣。謝謝! – WarrenFaith 2012-04-04 13:44:39

0

您可能可能要調查覆蓋/下鋪設採用全屏GLSurfaceView你的機型在屏幕上的「正確」的區域。您可能希望將某種佈局框架放在一起以使其更簡單,或者可以在全屏GLSurfaceView上使用多個視口。在OpenGL ES還沒有嘗試過這些,但通常這些方法之一將是用來呈現在桌面系統上的單個應用程序相同,甚至很多不同型號的多個視圖,而不是使用多個GLContexts(如果那是什麼在這裏幕後)。

2

什麼是對CoordinateSystemRenderer執行?

我今天遇到同樣的要求,試過了,它實際上是這樣的意思,你可以把2 GLSurfaceView放到同一個活動中。

東西需要被注意,

  1. GLRender,當調用onSurfaceChanged,你必須調整你的視
  2. 隨着2 GLSurfaceView,渲染線程爲2,那麼同步會發生問題。這取決於您執行。

有一個快速測試使用Android API演示在SDK GLSurfaceViewActivity

/* 
* Copyright (C) 2007 The Android Open Source Project 
* 
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at 
* 
*  http://www.apache.org/licenses/LICENSE-2.0 
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed under the License is distributed on an "AS IS" BASIS, 
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License. 
*/ 

package com.example.android.apis.graphics; 

import javax.microedition.khronos.egl.EGLConfig; 
import javax.microedition.khronos.opengles.GL10; 

import android.opengl.GLSurfaceView; 

/** 
* Render a pair of tumbling cubes. 
*/ 

public class CubeRenderer implements GLSurfaceView.Renderer 
{ 
    boolean isReverse = false; 

    public CubeRenderer(boolean useTranslucentBackground, boolean isReverse) 
    { 
     mTranslucentBackground = useTranslucentBackground; 
     mCube = new Cube(); 
     this.isReverse = isReverse; 
    } 

    public CubeRenderer(boolean useTranslucentBackground) 
    { 
     this(useTranslucentBackground, false); 
    } 

    public void onDrawFrame(GL10 gl) 
    { 
     /* 
     * Usually, the first thing one might want to do is to clear the screen. The most efficient way of doing this is 
     * to use glClear(). 
     */ 

     gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); 

     /* 
     * Now we're ready to draw some 3D objects 
     */ 

     gl.glMatrixMode(GL10.GL_MODELVIEW); 
     gl.glLoadIdentity(); 
     gl.glTranslatef(0, 0, -3.0f); 
     gl.glRotatef(mAngle, 0, 1, 0); 
     gl.glRotatef(mAngle * 0.25f, 1, 0, 0); 

     gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 
     gl.glEnableClientState(GL10.GL_COLOR_ARRAY); 

     mCube.draw(gl); 

     gl.glRotatef(mAngle * 2.0f, 0, 1, 1); 
     gl.glTranslatef(0.5f, 0.5f, 0.5f); 

     mCube.draw(gl); 

     if (isReverse) 
     { 
      mAngle -= 1.2f; 
     } 
     else 
     { 
      mAngle += 1.2f; 
     } 
    } 

    public void onSurfaceChanged(GL10 gl, int width, int height) 
    { 
     System.out.println("Joey's Log width : " + width + " height : " + height); 
     gl.glViewport(0, 0, width, height); 

     /* 
     * Set our projection matrix. This doesn't have to be done each time we draw, but usually a new projection needs 
     * to be set when the viewport is resized. 
     */ 

     float ratio = (float) width/height; 
     gl.glMatrixMode(GL10.GL_PROJECTION); 
     gl.glLoadIdentity(); 
     gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10); 
    } 

    public void onSurfaceCreated(GL10 gl, EGLConfig config) 
    { 
     /* 
     * By default, OpenGL enables features that improve quality but reduce performance. One might want to tweak that 
     * especially on software renderer. 
     */ 
     gl.glDisable(GL10.GL_DITHER); 

     /* 
     * Some one-time OpenGL initialization can be made here probably based on features of this particular context 
     */ 
     gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST); 

     if (mTranslucentBackground) 
     { 
      gl.glClearColor(0, 0, 0, 0); 
     } 
     else 
     { 
      gl.glClearColor(1, 1, 1, 1); 
     } 
     gl.glEnable(GL10.GL_CULL_FACE); 
     gl.glShadeModel(GL10.GL_SMOOTH); 
     gl.glEnable(GL10.GL_DEPTH_TEST); 
    } 

    private boolean mTranslucentBackground; 

    private Cube mCube; 

    private float mAngle; 
} 


------------------------------------------------------------------------------------------ 
/* 
* Copyright (C) 2007 The Android Open Source Project 
* 
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at 
* 
*  http://www.apache.org/licenses/LICENSE-2.0 
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed under the License is distributed on an "AS IS" BASIS, 
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License. 
*/ 

package com.example.android.apis.graphics; 

import javax.microedition.khronos.egl.EGLConfig; 
import javax.microedition.khronos.opengles.GL10; 

import android.opengl.GLSurfaceView; 

/** 
* Render a pair of tumbling cubes. 
*/ 

public class CubeRenderer implements GLSurfaceView.Renderer { 
    boolean isReverse = false; 
    public CubeRenderer(boolean useTranslucentBackground,boolean isReverse) { 
     mTranslucentBackground = useTranslucentBackground; 
     mCube = new Cube(); 
     this.isReverse = isReverse; 
    } 

    public CubeRenderer(boolean useTranslucentBackground) 
    { 
     this(useTranslucentBackground, false); 
    } 

    public void onDrawFrame(GL10 gl) { 
     /* 
     * Usually, the first thing one might want to do is to clear 
     * the screen. The most efficient way of doing this is to use 
     * glClear(). 
     */ 

     gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); 

     /* 
     * Now we're ready to draw some 3D objects 
     */ 

     gl.glMatrixMode(GL10.GL_MODELVIEW); 
     gl.glLoadIdentity(); 
     gl.glTranslatef(0, 0, -3.0f); 
     gl.glRotatef(mAngle,  0, 1, 0); 
     gl.glRotatef(mAngle*0.25f, 1, 0, 0); 

     gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 
     gl.glEnableClientState(GL10.GL_COLOR_ARRAY); 

     mCube.draw(gl); 

     gl.glRotatef(mAngle*2.0f, 0, 1, 1); 
     gl.glTranslatef(0.5f, 0.5f, 0.5f); 

     mCube.draw(gl); 

     if (isReverse) 
     { 
      mAngle -= 1.2f; 
     } 
     else 
     { 
      mAngle += 1.2f; 
     } 
    } 

    public void onSurfaceChanged(GL10 gl, int width, int height) { 
     System.out.println("Joey's Log width : " + width + " height : " + height); 
     gl.glViewport(0, 0, width, height); 

     /* 
      * Set our projection matrix. This doesn't have to be done 
      * each time we draw, but usually a new projection needs to 
      * be set when the viewport is resized. 
      */ 

     float ratio = (float) width/height; 
     gl.glMatrixMode(GL10.GL_PROJECTION); 
     gl.glLoadIdentity(); 
     gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10); 
    } 

    public void onSurfaceCreated(GL10 gl, EGLConfig config) { 
     /* 
     * By default, OpenGL enables features that improve quality 
     * but reduce performance. One might want to tweak that 
     * especially on software renderer. 
     */ 
     gl.glDisable(GL10.GL_DITHER); 

     /* 
     * Some one-time OpenGL initialization can be made here 
     * probably based on features of this particular context 
     */ 
     gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, 
       GL10.GL_FASTEST); 

     if (mTranslucentBackground) { 
      gl.glClearColor(0,0,0,0); 
     } else { 
      gl.glClearColor(1,1,1,1); 
     } 
     gl.glEnable(GL10.GL_CULL_FACE); 
     gl.glShadeModel(GL10.GL_SMOOTH); 
     gl.glEnable(GL10.GL_DEPTH_TEST); 
    } 
    private boolean mTranslucentBackground; 
    private Cube mCube; 
    private float mAngle; 
} 
-1

你可以有多個GLSurfaceViews活躍,並在活動中可見。每個視圖都有自己的GL上下文。

0

這是另一種方法。從Android文檔下載示例:http://developer.android.com/shareables/training/OpenGLES.zip 在此zip文件中,您將看到2個項目。打開項目:HelloOpenGLES20,用下面列出的項目替換「MyGLRenderer」類,然後運行該項目。

package com.example.android.opengl; 

import javax.microedition.khronos.egl.EGLConfig; 
import javax.microedition.khronos.opengles.GL10; 

import android.opengl.GLES20; 
import android.opengl.GLSurfaceView; 
import android.opengl.Matrix; 
import android.util.Log; 

public class MyGLRenderer implements GLSurfaceView.Renderer { 

    private static final String TAG = "MyGLRenderer"; 
    private Triangle[] mTriangle = new Triangle[2]; 
    private final float[] mMVPMatrix = new float[16]; 
    private final float[] mProjectionMatrix = new float[16]; 
    private final float[] mViewMatrix = new float[16]; 
    private final float[] mRotationMatrix = new float[16]; 

    private float mAngle; 

    @Override 
    public void onSurfaceCreated(GL10 unused, EGLConfig config) { 

     GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 
     mTriangle[0] = new Triangle(); 
     mTriangle[1] = new Triangle(); 

    } 

    @Override 
    public void onDrawFrame(GL10 unused) { 

     final float[] scratch = new float[16]; 

     GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); 

     Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f); 

     Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0); 

     for(int i = 0; i < 2; i++) { 

      if(i % 2 == 0) { 

       Matrix.setRotateM(mRotationMatrix, 0, mAngle/2f, 0, 0, 1.0f); 

      } 
      else { 

       Matrix.setRotateM(mRotationMatrix, 0, mAngle/4f, 0, 0, 1.0f); 

      } 

      Matrix.multiplyMM(scratch, 0, mMVPMatrix, 0, mRotationMatrix, 0); 

      mTriangle[i].draw(scratch); 

     }//End for(int i = 0; i < 2; i++) 

    }//End public void onDrawFrame(GL10 unused) 

    @Override 
    public void onSurfaceChanged(GL10 unused, int width, int height) { 

     GLES20.glViewport(0, 0, width, height); 
     float ratio = (float) width/height; 
     Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7); 

    } 

    public static int loadShader(int type, String shaderCode){ 

     int shader = GLES20.glCreateShader(type); 
     GLES20.glShaderSource(shader, shaderCode); 
     GLES20.glCompileShader(shader); 

     return shader; 

    } 

    public static void checkGlError(String glOperation) { 

     int error; 

     while((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) { 

      Log.e(TAG, glOperation + ": glError " + error); 
      throw new RuntimeException(glOperation + ": glError " + error); 

     } 

    } 

    public float getAngle() { 
     return mAngle; 
    } 


    public void setAngle(float angle) { 
     mAngle = angle; 
    } 

} 

據我所知,OpenGLES被設計爲只使用一個視圖,但可能使用多個Render目標。雖然我必須管理員,但我不確定你想做什麼是錯的或不是。我自己對OpenGLES有一點新鮮感。我在bitbucket中有一個OpenGL開源庫。您可以從中獲得一些想法:https://bitbucket.org/warwick/hacergestov2,這是一個手勢庫。

相關問題