Попытка добавить GLSurfaceView в макет программно - PullRequest
3 голосов
/ 13 декабря 2011

Хорошо, просто немного фона ... У меня есть полностью функционирующая игра, которая использует холст для рисования, и я пытаюсь изучить и преобразовать рисунок в OpenGL ES 1.0.(чтобы сохранить совместимость.)

То, что я пытался сделать, - это найти способ включить GLSurfaceView и Renderer в программу, чтобы я мог переключать рисование по кусочкам.(Существует много спрайтов, и мне нужно часто обновляться, поэтому я не хочу, чтобы на выпуск следующего обновления у меня уходил месяц.)

Было предложено использовать GLSurfaceView навершина текущего SurfaceView, и я добираюсь, но я наткнулся на препятствие.

Я в основном использую пример 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 для добавления объектов поверх Поверхностного вида.Обратите внимание, что я также добавляю кнопку «Скретч», просто чтобы проверить, работает ли концепция.В итоге я получаю холст и кнопку, которая отображается правильно, но без признаков GLSurfaceView.Что я делаю не так?

Ответы [ 3 ]

4 голосов
/ 14 декабря 2011

Я бы предложил, чтобы ваш 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 начать рендеринг. Вы должны вызвать (или даже переопределить) GLSurfaceView.start() в вашем GLSurfaceView. В качестве альтернативы setRenderer является общедоступным, поэтому, если вы вызываете mGLSV.setRenderer(myRenderer); в своей Активности, где myRenderer является экземпляром MyRenderer implements GLSurfaceView.Renderer, тогда он должен автоматически начать рендеринг, не касаясь start()

РЕДАКТИРОВАТЬ: На самом деле, start() вызывается, когда представление выложено (то есть, когда вы setContentView() или добавляете его в любой макет, который вы задали как представление содержимого), а не когда вызывается setRenderer

Звучитзадом наперед, но реализация Renderer предназначена для того, чтобы просто визуализировать что-либо стандартным способом android / opengl-es, тогда как расширение GLSurfaceView - для того, чтобы на самом деле захотеть проникнуть в суть и отредактировать способ рендеринга android.На самом деле, я бы порекомендовал вообще не расширять GLSurfaceView, а делать как можно больше в своем GLSurfaceView.Renderer.Я запрограммировал всю свою 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();
    }
}

}

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:

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) вы можете использовать точечные спрайты вместо рендеринга текстурированных четырехугольников или чего-либо еще

2 голосов
/ 14 декабря 2011

Разобрался сам. Несмотря на то, что SurfaceView является подклассом View, способ отображения SurfaceView через окно выглядит довольно забавно, в основном холст фактически проходит через вид поверхности, но находится позади него в Z-порядке. Из-за этого необходимо упорядочить несколько видов поверхности с помощью surfaceview.setZOrderOnTop (true);

Теперь мне просто нужно побеспокоиться о том, чтобы сделать GLSurfaceView Transparent прозрачным.

0 голосов
/ 04 сентября 2012

Взято из min3d, это должно работать на прозрачность GLSurfaceView

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