簡體   English   中英

嘗試以編程方式將GLSurfaceView添加到布局中

[英]Trying to add GLSurfaceView to a layout programmatically

好吧,只是一些背景......我有一個功能齊全的游戲,使用畫布繪制,我正在嘗試學習並將繪圖轉換為OpenGL ES 1.0。 (為了保持兼容性。)

我一直試圖做的是,找出一種方法將GLSurfaceView和Renderer合並到程序中,這樣我就可以逐個切換繪圖。 (有很多精靈,我需要經常更新,所以我不想讓它花一個月時間來發布下一次更新。)

有人建議我在當前的SurfaceView上使用GLSurfaceView,但是我到了那里但是我遇到了麻煩。

我基本上使用的是LunarLander示例,並嘗試添加一個簡單的OpenGL渲染器,在一個正方形上繪制紋理並渲染它。 目標是在畫布上繪制正方形。

以下是活動中的相關代碼:

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上添加內容。 注意我還添加了一個臨時按鈕,只是為了檢查概念的工作原理。 我最終得到的是畫布,按鈕顯示正確,但沒有GLSurfaceView的跡象。 我究竟做錯了什么?

我建議您已將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>

您需要告訴GLSurfaceView開始渲染。 您必須在 GLSurfaceView.start() 調用(或甚至覆蓋) GLSurfaceView.start() 或者,setRenderer是公共的,所以如果你調用mGLSV.setRenderer(myRenderer); 在您的Activity中,myRenderer是MyRenderer的一個實例, MyRenderer implements GLSurfaceView.Renderer然后它應該自動啟動渲染,而不必觸摸start()

編輯:實際上,在布局視圖時調用start() (即當你setContentView()或將它添加到你設置為內容視圖的任何布局時),而不是在調用setRenderer時

它聽起來是前置的,但實現Renderer是為了你想要以標准的android / opengl-es方式呈現某些東西,同時擴展GLSurfaceView就是你真的想深入了解並編輯android呈現的方式。 事實上,我建議不要在GLSurfaceView.Renderer中盡可能地擴展GLSurfaceView。 我編寫了我的整個3D游戲而沒有擴展GLSurfaceView。 我的代碼看起來像這樣:

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)你可以使用點精靈而不是渲染紋理四邊形或其他

自己搞清楚了。 即使SurfaceView是View的子類,SurfaceView在窗口中顯示的方式也很有趣,基本上畫布實際上是通過surfaceview但是在Z順序后面。 因此,必須使用surfaceview.setZOrderOnTop(true)來排序多個表面視圖;

現在我只需要擔心GLSurfaceView透明化。

從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