3

I am trying to put a GLSurfaceView and a button into the same xml layout. But my application keep closing automatically whenever I run it on my device. Could someone please help me and tell what am I missing or what is wrong with my code?

here is my code

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

<?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;
    }

}

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

Thank you.

AuroraBlaze
  • 421
  • 2
  • 8
  • 25

2 Answers2

7

In MainActivity.onCreate() use findViewById instead of creating a new View.(like u did in onPause, onResume) and only assign the variable once.

setContentView(R.layout.activity_main);
mGLView = (MyGLSurfaceView) findViewById(R.id.glSurfaceViewID);

Make sure MyGLSurfaceView has constructors with AttributeSet so it could be inflated from XML. Check out this stackoverflow atricle for the constructors.

And aswell change the order of the Button and MyGLSurfaceView in the XML, because now Button will be below the MyGLSurfaceView in your layout so you won't be able to see it.

Community
  • 1
  • 1
Sipka
  • 2,291
  • 2
  • 27
  • 30
0

This is a 7 year old QA, this is how you do it now with 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)
        }
    }
}

In XML

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

enter image description here

Hitesh Sahu
  • 41,955
  • 17
  • 205
  • 154