简体   繁体   English

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

[英]Trying to add GLSurfaceView to a layout programmatically

Ok, Just some background... I have a fully functioning game that uses the canvas to draw, and I'm in the process of trying to learn and convert the drawing over to OpenGL ES 1.0. 好吧,只是一些背景......我有一个功能齐全的游戏,使用画布绘制,我正在尝试学习并将绘图转换为OpenGL ES 1.0。 (to keep compatibility.) (为了保持兼容性。)

What I've been trying to do, Is figure out a way to incorporate the GLSurfaceView and Renderer into the program so that I can switch the drawing over piece by piece. 我一直试图做的是,找出一种方法将GLSurfaceView和Renderer合并到程序中,这样我就可以逐个切换绘图。 (There are a lot of sprites and I have needs to update often, so I don't want it to take me a month to release the next update.) (有很多精灵,我需要经常更新,所以我不想让它花一个月时间来发布下一次更新。)

It has been suggested that I Use the GLSurfaceView on top of the current SurfaceView, and i'm getting there but I've hit a snag. 有人建议我在当前的SurfaceView上使用GLSurfaceView,但是我到了那里但是我遇到了麻烦。

I'm basically using the LunarLander example and trying to add on a simple OpenGL renderer that draws a texture on a square and renders it. 我基本上使用的是LunarLander示例,并尝试添加一个简单的OpenGL渲染器,在一个正方形上绘制纹理并渲染它。 The goal would be to draw the square on top of the canvas. 目标是在画布上绘制正方形。

Here is the relevant code in the 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

The lunar_layout file looks like this: 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>

Pretty Simple, I'm trying to use that LinearLayout to add things on top of the Surface View. 非常简单,我正在尝试使用LinearLayout在Surface View上添加内容。 Notice I also add a scratch Button, just to check the concept works. 注意我还添加了一个临时按钮,只是为了检查概念的工作原理。 What I end up with is the canvas, and the button showing up correctly, but no sign of the GLSurfaceView. 我最终得到的是画布,按钮显示正确,但没有GLSurfaceView的迹象。 What am I doing wrong? 我究竟做错了什么?

I'd suggest you have your BasicGLSurfaceView already added to your framelayout in XML, and use findViewById(R.id.basicGLSurfaceView1) to get a hold of it, rather than trying to create it programatically: 我建议您已将BasicGLSurfaceView添加到XML中的framelayout中,并使用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>

You need to tell the GLSurfaceView to start rendering. 您需要告诉GLSurfaceView开始渲染。 You have to call (or even override) GLSurfaceView.start() in your GLSurfaceView. 您必须在 GLSurfaceView.start() 调用(或甚至覆盖) GLSurfaceView.start() Alternatively, setRenderer is public, so if you call mGLSV.setRenderer(myRenderer); 或者,setRenderer是公共的,所以如果你调用mGLSV.setRenderer(myRenderer); in your Activity where myRenderer is an instance of MyRenderer implements GLSurfaceView.Renderer then it should automatically start the rendering without you having to touch start() 在您的Activity中,myRenderer是MyRenderer的一个实例, MyRenderer implements GLSurfaceView.Renderer然后它应该自动启动渲染,而不必触摸start()

EDIT: Actually, start() is called when the view is laid out (ie when you setContentView() or add it to whatever layout you set as content view), not when setRenderer is called 编辑:实际上,在布局视图时调用start() (即当你setContentView()或将它添加到你设置为内容视图的任何布局时),而不是在调用setRenderer时

It sounds back-to-front but implementing Renderer is for if you just want to render something in the standard android/opengl-es way, whilst extending GLSurfaceView is if you actually want to get under the hood and edit the way android renders. 它听起来是前置的,但实现Renderer是为了你想要以标准的android / opengl-es方式呈现某些东西,同时扩展GLSurfaceView就是你真的想深入了解并编辑android呈现的方式。 In fact, I would recommend not extending GLSurfaceView at all but doing as much as possible in your GLSurfaceView.Renderer. 事实上,我建议不要在GLSurfaceView.Renderer中尽可能地扩展GLSurfaceView。 I have programmed my entire 3D game without extending GLSurfaceView. 我编写了我的整个3D游戏而没有扩展GLSurfaceView。 My code looks like this: 我的代码看起来像这样:

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

}

Renderer: 渲染:

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

}

If you can stand upgrading to android 2.1 (opengl-es 1.1) you can use point-sprites rather than rendering textured quads or whatever 如果你可以升级到android 2.1(opengl-es 1.1)你可以使用点精灵而不是渲染纹理四边形或其他

Figured it out myself. 自己搞清楚了。 Even though SurfaceView is a subclass of View, the way SurfaceView displays through the window is kinda funny, Basically The canvas actually goes through the surfaceview but is behind it in Z order. 即使SurfaceView是View的子类,SurfaceView在窗口中显示的方式也很有趣,基本上画布实际上是通过surfaceview但是在Z顺序后面。 Because of this Multiple surface views have to be ordered using surfaceview.setZOrderOnTop(true); 因此,必须使用surfaceview.setZOrderOnTop(true)来排序多个表面视图;

Now I just have to worry about making the GLSurfaceView Transparent. 现在我只需要担心GLSurfaceView透明化。

Taken from min3d, this should work on making the GLSurfaceView transparent 从min3d开始,这应该可以使GLSurfaceView透明化

_glSurfaceView.setEGLConfigChooser(8,8,8,8, 16, 0); 
_glSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM