java - 尝试以编程方式将 GLSurfaceView 添加到布局

标签 java android xml opengl-es canvas

好的,只是一些背景知识...我有一个使用 Canvas 绘图的功能齐全的游戏,我正在尝试学习并将绘图转换为 OpenGL ES 1.0。 (以保持兼容性。)

我一直在尝试做的是找出一种将 GLSurfaceView 和 Renderer 合并到程序中的方法,以便我可以逐个切换绘图。 (有很多 Sprite ,我需要经常更新,所以我不想花一个月的时间来发布下一个更新。)

有人建议我在当前的 SurfaceView 之上使用 GLSurfaceView,我已经做到了,但是我遇到了障碍。

我主要使用 LunarLander 示例并尝试添加一个简单的 OpenGL 渲染器,该渲染器在正方形上绘制纹理并进行渲染。目标是在 Canvas 上绘制正方形。

下面是Activity中的相关代码:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);



        setContentView(R.layout.lunar_layout);


        LinearLayout detailListView = (LinearLayout) findViewById(R.id.dets); // Find the layout where you want to add button

    Button button = new Button(this);
    button.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT));
    detailListView.addView(button);//add view to add



    mGLSV = new BasicGLSurfaceView(this);
    mGLSV.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT));
    detailListView.addView(mGLSV);

    //clipped

lunar_layout 文件如下所示:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"

    android:layout_width="match_parent"
    android:layout_height="match_parent">



    <com.example.android.lunarlander.LunarView
        android:id="@+id/lunar"
      android:layout_width="match_parent"
      android:layout_height="match_parent"/>

    <LinearLayout
       android:id="@+id/dets"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_alignParentLeft="true"
       android:layout_alignParentTop="true"
       android:layout_marginLeft="0dp"
       android:layout_marginTop="50dp"
       android:orientation="vertical" >

         <com.google.ads.AdView
             android:id="@+id/adView"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             ads:adSize="BANNER"
             ads:adUnitId="a14ecf8f2d9ef49"
             ads:loadAdOnCreate="true" >
         </com.google.ads.AdView>

    </LinearLayout>



     <RelativeLayout   
         android:id="@+id/relLayout"
         android:layout_width="match_parent"
         android:layout_height="match_parent" >

         <TextView
             android:id="@+id/text"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_centerInParent="true"
             android:gravity="center_horizontal"
             android:text="@string/lunar_layout_text_text"
             android:textColor="#88ffffff"
             android:textSize="24sp"
             android:visibility="visible" />

      </RelativeLayout>

</FrameLayout>

非常简单,我正在尝试使用 LinearLayout 在 Surface View 之上添加内容。请注意,我还添加了一个临时按钮,只是为了检查概念是否有效。 我最终得到的是 Canvas ,按钮正确显示,但没有 GLSurfaceView 的迹象。我做错了什么?

最佳答案

我建议您已经将 BasicGLSurfaceView 添加到您的 XML 框架布局中,并使用 findViewById(R.id.basicGLSurfaceView1) 获取它,而不是尝试以编程方式创建它:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.example.android.lunarlander.BasicGLSurfaceView 
        android:id="@+id/glSurfaceView1" 
        android:layout_width="match_parent" 
        android:layout_height="match_parent">
    </com.example.android.lunarlander.BasicGLSurfaceView>

    <com.example.android.lunarlander.LunarView
      android:id="@+id/lunar"
      android:layout_width="match_parent"
      android:layout_height="match_parent"/>

    <LinearLayout
       android:id="@+id/dets"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_alignParentLeft="true"
       android:layout_alignParentTop="true"
       android:layout_marginLeft="0dp"
       android:layout_marginTop="50dp"
       android:orientation="vertical" >

         <com.google.ads.AdView
             android:id="@+id/adView"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             ads:adSize="BANNER"
             ads:adUnitId="a14ecf8f2d9ef49"
             ads:loadAdOnCreate="true" >
         </com.google.ads.AdView>

    </LinearLayout>



     <RelativeLayout   
         android:id="@+id/relLayout"
         android:layout_width="match_parent"
         android:layout_height="match_parent" >

         <TextView
             android:id="@+id/text"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_centerInParent="true"
             android:gravity="center_horizontal"
             android:text="@string/lunar_layout_text_text"
             android:textColor="#88ffffff"
             android:textSize="24sp"
             android:visibility="visible" />

      </RelativeLayout>

</FrameLayout>

您需要告诉 GLSurfaceView 开始渲染。 You have to call (or even override) GLSurfaceView.start() 在您的 GLSurfaceView 中。 或者,setRenderer 是公共(public)的,因此如果您在 Activity 中调用 mGLSV.setRenderer(myRenderer);,其中 myRenderer 是 MyRenderer implements GLSurfaceView.Renderer 的实例,那么它应该自动开始渲染,而无需触摸 start()

编辑:实际上,start() 是在布局 View 时调用的(即当您 setContentView() 或将其添加到您设置为内容 View 的任何布局时), 而不是在调用 setRenderer 时

这听起来从头到尾,但如果你只是想以标准的 android/opengl-es 方式渲染某些东西,那么实现 Renderer 是为了如果你真的想深入了解并编辑 android 的方式,那么扩展 GLSurfaceView渲染。事实上,我建议根本不要扩展 GLSurfaceView,而是尽可能多地在 GLSurfaceView.Renderer 中扩展。我在没有扩展 GLSurfaceView 的情况下编写了整个 3D 游戏。我的代码如下所示:

public class stackoverflowTest extends Activity {

MyGLSurfaceView glSurface;
MyRenderer myRenderer;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    myRenderer = new MyRenderer();

    //Get hold of our GLSurfaceView
    glSurface = (MyGLSurfaceView) findViewById(R.id.graphics_glsurfaceview1);
    // optional
    glSurface.setEGLConfigChooser(true);

    glSurface.setRenderer(myRenderer);
    //Set the renderer. setRenderer will call start() and start the GL thread, which then calls onSurfaceCreated, onDraw etc in the Renderer



}

    @Override
public void onPause(){
    super.onPause();
     glSurface.onPause();
}

@Override
public void onResume() {
       super.onResume();
       glSurface.onResume();
    }
}

}

渲染器:

public class MyRenderer implements Renderer {

@Override
public void onDrawFrame(GL10 gl) {
    // openGL drawing code goes here


}

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

    // etc


}

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    // etc


}

}

GLSurfaceView:

public class MyGLSurfaceView extends GLSurfaceView {

public MyGLSurfaceView(Context context) {
    super(context);

}

public MyGLSurfaceView(Context context, AttributeSet attribs) {
    super(context, attribs);

}

@Override
public void onPause(){
    super.onPause();
}

@Override
public void onResume(){
    super.onResume();
}

}

如果你能忍受升级到 android 2.1 (opengl-es 1.1) 你可以使用点 Sprite 而不是渲染纹理四边形或其他什么

关于java - 尝试以编程方式将 GLSurfaceView 添加到布局,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8494050/

相关文章:

java - 允许非 ssl 连接 : javax.net.ssl.SSLHandshakeException: 握手失败

xml - 将显示 XML 编码的 Linux 脚本

由于命名空间为空,Python XPath lxml 无法读取 SVG 路径元素?

java - Derby GRANT 语句用于向特定用户授予权限

android - 如何在 Android 中将溢出菜单项显示到操作栏

java - 运行两个流并从中创建一个对象

java - 使用可扩展 ListView 在我的 ImageView 中填充联系人图像

javascript - XML 到 JSON javascript 函数不起作用

java - 尝试创建并写入文件,但收到错误消息

java - HTTP 状态 500 - 实例化 servlet 类 com.Model 时出错