#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, если это имело значение, но это все еще не работает.