Как мне объединить OpenGL с макетами?

#java #android #eclipse #opengl-es

#java #Android #eclipse #opengl-es

Вопрос:

Итак, я хочу либо иметь возможность размещать кнопки и другие виджеты поверх моего открытого GL-представления, либо я хочу, чтобы мой Open GL и layouts разделяли пространство экрана. Я получил несколько ответов, таких как создание макета, а затем подключение к нему из основного и установка поверхности GL в качестве вида внутри макета, например:

 myGL = new MySurface(this); 
FrameLayout frame = (FrameLayout)findViewById(R.id.myframelayout);
frame.addView(myGL, 0);
  

но это сопровождается исключением NullPointerException, на которое оно указывает:

 frame.addView(myGL, 0);
  

Но frame или myGL равны нулю. Такого рода проблемы у меня были в прошлом с помещением определенного кода в onCreate (), а также вопрос, который я указал в своем профиле (без ответа). Затем я попытался создать представление OpenGLSurface с помощью xml-файла следующим образом:

 <com.example.escape.MainActivity.MySurface
android:id="@ id/visualizer"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
  

Это также создает ошибку, говорящую:

Исключение, возникшее во время рендеринга: загрузчик (экземпляр com / android / ide / eclipse / adt / internal / resources / manager / ProjectClassLoader): попытка дублирования определения класса для имени: «com / example / escape / MainActivity $ MySurface» Сведения об исключении регистрируются в окне> Показать просмотр> Журнал ошибок

На случай, если вы хотите знать: com.example.escape — это путь к моему MainActivity.java

Я также не хочу делать то, что говорят другие, и создавать прямоугольник в OpenGL, который постоянно остается перпендикулярным экрану, действуя как кнопка.

Вот мой основной код:

    public class MainActivity extends Activity {

GLSurfaceView myGL;

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

    myGL=new MySurface(this);
    setContentView(R.layout.activity_main);

}... 
  

Моя поверхность GL и код рендеринга:

 class MySurface extends GLSurfaceView
{

private MyRenderer myRend;

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

    myRend=new MyRenderer();
    setEGLContextClientVersion(2);
    setRenderer(myRend);
    setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}
}

Square mSquare;
float [] mViewMatrix=new float[16];
float [] mMVPMatrix=new float[16];
float [] mProjectionMatrix=new float[16];
private float[] mRotationMatrix=new float[16];

class MyRenderer implements GLSurfaceView.Renderer
{
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1f);

        mSquare=new Square();
}

@Override
public void onDrawFrame(GL10 gl) {
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

     Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
     Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);

    mSquare.draw(mMVPMatrix);

}

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
    GLES20.glViewport(0, 0, width, height);

    float ratio = (float) width / height;
    Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 2, 10);

}   

}
  

Комментарии:

1. MySurface Определяется как локальный класс внутри MainActivity ? Похоже, что это не из кода, но то, как вы используете его в своем layout xml ( com.example.escape.MainActivity.MySurface ), должно было бы быть. Кроме того, когда вы пытались использовать findViewById() , вы вызывали это после setContentView() ?

2. Да, MySurface определен в MainActivity, я просто разделил его, потому что хотел, чтобы код был легче читаемым. Что касается функции findViewById (), я пробовал ее до и после setContentView(). Связано ли это с тем фактом, что я установил contentView (R.layout.activity_main); но я нахожу VIEWBYID (R.id.myLayout); который является относительным макетом в моем fragment_main?

3. @RetoKoradi Я пытался поместить свой Surface View в другой макет, отличный от Realtive, если это имело значение, но это все еще не работает.