2011-02-14 45 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,这是一个手势库。

相关问题