在XML布局中使用Android GLSurfaceView

3
我正在尝试将GLSurfaceView和按钮放置在同一个xml布局中。但是每当我在设备上运行它时,我的应用程序会自动关闭。
有人能帮我并告诉我我错过了什么或者我的代码有什么问题吗?
以下是我的代码:
===================
<?xml version="1.0" encoding="utf-8"?>

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:id= "@+id/linearlayout1" >

    <Button
        android:id="@+id/buttonID"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dip"
        android:text="A Button" />

    <com.example.test2.MyGLSurfaceView
        android:id="@+id/glSurfaceViewID"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0.23" />

</LinearLayout>

================

package com.example.test2;

import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.Menu;
import android.view.MotionEvent;

public class MainActivity extends Activity {

    private GLSurfaceView mGLView;

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

        // Create a GLSurfaceView instance and set it
        // as the ContentView for this Activity
        mGLView = new MyGLSurfaceView(this);
        //setContentView(mGLView);
        setContentView(R.layout.activity_main);
    }

//    @Override
    protected void onPause() {
        super.onPause();
        mGLView = (MyGLSurfaceView)findViewById(R.id.glSurfaceViewID);
        mGLView.onPause();
    }
//
   @Override
   protected void onResume() {
        super.onResume();
        mGLView = (MyGLSurfaceView)findViewById(R.id.glSurfaceViewID);
        mGLView.onResume();
    }
}

class MyGLSurfaceView extends GLSurfaceView {

    private final MyGLRenderer mRenderer;

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

        // Create an OpenGL ES 2.0 context.
        setEGLContextClientVersion(2);

        // Set the Renderer for drawing on the GLSurfaceView
        mRenderer = new MyGLRenderer();
        setRenderer(mRenderer);

        // Render the view only when there is a change in the drawing data
        setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
    }

    private final float TOUCH_SCALE_FACTOR = 180.0f / 320;
    private float mPreviousX;
    private float mPreviousY;

    @Override
    public boolean onTouchEvent(MotionEvent e) {
        // MotionEvent reports input details from the touch screen
        // and other input controls. In this case, you are only
        // interested in events where the touch position changed.

        float x = e.getX();
        float y = e.getY();

        switch (e.getAction()) {
            case MotionEvent.ACTION_MOVE:

                float dx = x - mPreviousX;
                float dy = y - mPreviousY;

                // reverse direction of rotation above the mid-line
                if (y > getHeight() / 2) {
                  dx = dx * -1 ;
                }

                // reverse direction of rotation to left of the mid-line
                if (x < getWidth() / 2) {
                  dy = dy * -1 ;
                }

                mRenderer.mAngle += (dx + dy) * TOUCH_SCALE_FACTOR;  // = 180.0f / 320
                requestRender();
        }

        mPreviousX = x;
        mPreviousY = y;
        return true;
    }

}

谢谢您的选择。

===========================

感谢您的选择。
2个回答

7
在MainActivity.onCreate()中使用findViewById而不是创建新的View(就像你在onPause、onResume中所做的那样),并且只分配变量一次。
setContentView(R.layout.activity_main);
mGLView = (MyGLSurfaceView) findViewById(R.id.glSurfaceViewID);

请确保MyGLSurfaceView有带有AttributeSet的构造函数,以便可以从XML中膨胀。查看此stackoverflow文章以获取构造函数信息。

同时,在XML中更改Button和MyGLSurfaceView的顺序,因为现在Button将位于您的布局中MyGLSurfaceView的下方,所以您将无法看到它。


非常感谢您的建议。它有效了!耶!=)我很感激。 - AuroraBlaze

0

这是一个七年前的QA,现在使用Kotlin的方式如下:

import android.content.Context
import android.opengl.GLES20
import android.opengl.GLSurfaceView
import android.util.AttributeSet
import javax.microedition.khronos.egl.EGLConfig
import javax.microedition.khronos.opengles.GL10

class GameView
@JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
) : GLSurfaceView(context, attrs) {
    
    companion object{
        // Support OpenGL ES 2.0 
        private const val  OPEN_GLES_VERSION = 2
    }
    private val renderer: GameRenderer

    init {
        //create an OpenGL ES 2.0-compatible context.
        setEGLContextClientVersion(OPEN_GLES_VERSION)
        // Set the Renderer for drawing on the GLSurfaceView
        renderer = GameRenderer().apply {
            setRenderer(this)
        }
    }

    inner class GameRenderer : Renderer {
        override fun onSurfaceCreated(unused: GL10, config: EGLConfig) {
            // Set the background frame color
            GLES20.glClearColor(1.0f, 1.0f, 0.0f, 1.0f)
        }

        override fun onDrawFrame(unused: GL10) {
            // Redraw background color
            GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
        }

        override fun onSurfaceChanged(unused: GL10, width: Int, height: Int) {
            GLES20.glViewport(0, 0, width, height)
        }
    }
}

在XML中

<com.hiteshsahu.opengl.boilerplate.GameView
    android:id="@+id/glView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接