2011-02-14 18 views
23

Android için bir Bilgi Görselleştirme API'si yazıyorum ve özel bir GLSurfaceView'un iki birimini bir Mizanpaja yerleştirmeye çalışırken bir sorunla karşılaştım. Bu noktada Özel GLSurfaceView, özel yöntemlerin neden olduğu olası hataları ortadan kaldırmak için GLSurfaceView'un bir uzantısıdır.Birden çok GLSurfaceView bileşenini aynı Düzen'de nasıl kullanabilirim?

Her iki bileşenin de düzeni eklediğimde ve uygulamayı başlattığımda çalışır. Ama hiçbir şey çizilmez, sonsuz bir döngüye girmiş gibi görünür. Çünkü Renderers içindeki hata ayıklama mesajları LogCat'a yazdırılır. Ancak, yalnızca özel GLSurfaceView bileşenlerinden birini kullanırsam, gayet iyi çalışır.

Birden Faaliyetlerde GLSurfaceView kullanmada bir sorun olduğunu okumak ve aynı anda bu bileşenlerin iki kullanırken aynı zamanda geçerlidir varsayalım. Ben here gönderilen geçici çözüm denedim ama işe yarayacak gibi görünmüyor.

Herhangi bir yardım için minnettarım. Daha iyi bir performans için openGL kullanmayı tercih ediyorum, ancak birden fazla bileşeni aynı anda kullanamıyorsam, bunun yerine Canvas kullanmam gerektiğini düşünüyorum.

şöyle tezahür görünür: Aktivite itibaren

<?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> 

kod şu şekildedir:

@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(); 
} 

ben belirgin bir şey eksik? Ya da birisi neden çalışmadığını açıklayabilir mi?

+1

Bana atlayan ilk şey, iç içe geçmiş LinearLayout öğenizin fill_parent olarak ayarlanmış olmasıdır. GLSurfaceView'larınızın her ikisinin de sıfır olmayan yükseklikle yerleştirildiğinden emin olmak için kontrol ederdim. Her ikisinin de çiziminde olduğu, ancak birinin 0 piksel yüksekliğinde olduğu ve bu nedenle görünmez olduğu durum söz konusu olabilir. –

+0

İki "GLSurfaceViews" yerine, bir GL iş parçacığı ve bağlamı oluşturmak/yönetmek için daha iyi olabilir, bunu iki "SurfaceViews" (GLSurfaceViews) öğesine uygulamayın). [Fadden'ın tartışması ve Grafika'ya bağlantı] konusuna bakın (http://stackoverflow.com/a/22746240/199364). – ToolmakerSteve

cevap

0

GLContext'in yönetimi de dahil olmak üzere GLSurfaceView'ın arkasında bir çok şey var, bunu yapamayacağınızdan eminsiniz, daha sonra daha beklenmedik sorunlarla karşılaşabilirsiniz. Bu yüzden doğru uygulama mimarisi olmadığını düşünüyorum.

8

[UPDATE: Bu yanıt artık Android 5.0 (Lollipop)'dan itibaren doğru değil. Bir tartışma ve bağlantılar için fadden's answer'a bakın. It was also incorrect as of Android 2.0, and apparently was only an issue for OVERLAPPING surfaces even before then.]

tek bir Faaliyet içine 2 SurfaceViews (SV) yerleştiremem. SV'lerin nasıl çalıştığını neden bilmeniz gerektiğini anlamak için.

bunu ve aslında doesnt aktivitesi üzerine yer yaratmak

yerine o etkinlikte oluşturulan "şeffaf" görüntüsü mevcut faaliyet arkasında oluşturulacak, aktivite (veya bunun üstüne) yerleştirilir.

Android 4.0'da (API 14) TextureView adı verilen yeni Görünüm var Eski platformlarda bu gibi bir şey oluşturmanın bir yolu yok.

+1

Bundan emin misin? Sadece sınırlamanın, onları üst üste koyamayacağınız veya üst üste koyamayacağınızı düşündüm. Görünüşe göre, bir video görüntülemenin bir videosu gösterilemediği söylenebilir, bu da video görüntülemenin yüzey görünümünü genişletir ... – WarrenFaith

+0

Evet, eminim. SV'nin yalnızca bir örneğini zamanında kullanabilirsiniz. – pepyakin

+0

Eğer bir tane varsa, bir kaynak verebilir misiniz? Tam SV konusuyla çok ilgileniyorum. Teşekkürler! – WarrenFaith

0

Sen altı döşeme tam ekran GLSurfaceView kullanarak ekranın 'doğru' alanında Modellerinizin/bindirilirken araştırmak isteyebilirsiniz olabilir. Bunu daha basit hale getirmek için ya da belki de tam ekran GLSurfaceView'de birden fazla Viewport kullanmak için bir çeşit düzen çerçevesini bir araya getirmek isteyebilirsiniz. Bunları OpenGL ES'de denemedim, ancak genellikle bu yöntemlerden biri, birden çok GLContexts kullanmak yerine, bir masaüstü sistemde tek bir uygulamada aynı veya çok sayıda farklı modelin çoklu görünümlerini oluşturmak için kullanılırdı (eğer durum böyle ise). sahnelerin ardında devam ediyor).

2

CoordinateSystemRenderer için uygulama nedir?

Aynı gereksinimi bugün karşıladım ve denedim, aslında bu demektir, 2 GLSurfaceView'u aynı etkinliğe koyabilirsiniz.

şey onSurfaceChanged çağrıldığında, oluşturulması iplik 2 olacak, 2 GLSurfaceView ile görünümünüzü

  • boyutlandırmak, bu nedenle sorunun oluştuğu edilecektir senkronize olmalıdır, GLRender yılında

    1. , fark edilmesi gerekir. Bu, uygulamanıza bağlıdır.

    Sen olabilir 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; 
    } 
    
  • +0

    Bu kod nasıl ilgili? İki GLSurfaceViews göstermiyor. Sadece iki küp çizerek tek bir manzara gösterir. – ToolmakerSteve

    -1

    Android API demosunu kullanmak için hızlı bir test yoktur çoklu GLSurfaceViews etkin olduğundan ve Aktivite görünür. Her görünüm kendi GL içeriğini alır.

    +0

    OPS iki GLSurfaceViews kullanmak için TRIED ve çalışmak için bir sorun yaşıyor. Bu "cevap" nasıl yardımcı olur? – ToolmakerSteve

    0

    İşte bunu yapmanın alternatif bir yolu. Örneği Android dokümanlarından indirin: http://developer.android.com/shareables/training/OpenGLES.zip Bu zip dosyasında 2 proje göreceksiniz. Projeyi açın: HelloOpenGLES20 ve 'MyGLRenderer' Sınıfını aşağıda listelenmiş olanla değiştirin ve projeyi çalıştırın. Anladığım kadarıyla

    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 sadece biri görünümü ama potansiyel çoklu Render hedeflerle kullanmak üzere tasarlanmıştır. Yönetici olmam gerekiyor olsa da, yapmaya çalıştığınız şeyin yanlış olduğundan emin değilim. OpenGLES’in kendime bir yenisi var. Bitbucket'te OpenGL açık kaynak kütüphanem var. Ondan bazı fikirler alabilirsiniz: https://bitbucket.org/warwick/hacergestov2, bir jest kütüphanesi.

    +0

    Lütfen açıklayınız - bu "nasıl yapmanın alternatif bir yolu"? OP tarafından tartışılan "it", GL'yi bir düzen içindeki iki farklı görünüme dönüştürür. Alternatif bir çözüm olarak ne öneriyorsunuz? – ToolmakerSteve

    İlgili konular