Project

General

Profile

« Previous | Next » 

Revision 248a2782

Added by Leszek Koltunski over 7 years ago

Progress with "Around The World"

View differences:

src/main/java/org/distorted/examples/aroundtheworld/AroundTheWorldRendererPicker.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// Distorted is free software: you can redistribute it and/or modify                             //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Distorted is distributed in the hope that it will be useful,                                  //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

  
20
package org.distorted.examples.aroundtheworld;
21

  
22
import java.nio.ByteBuffer;
23
import java.nio.ByteOrder;
24
import java.nio.FloatBuffer;
25

  
26
import javax.microedition.khronos.egl.EGLConfig;
27
import javax.microedition.khronos.opengles.GL10;
28

  
29
import android.opengl.GLES20;
30
import android.opengl.GLSurfaceView;
31
import android.opengl.Matrix;
32

  
33
///////////////////////////////////////////////////////////////////////////////////////////////////
34

  
35
class AroundTheWorldRendererPicker implements GLSurfaceView.Renderer
36
  {
37
	private float[] mModelMatrix      = new float[16];
38
	private float[] mViewMatrix       = new float[16];
39
	private float[] mProjectionMatrix = new float[16];
40
	private float[] mMVPMatrix        = new float[16];
41

  
42
	private final FloatBuffer mTriangleVertices;
43

  
44
  private int mMVPMatrixHandle;
45
  private int mPositionHandle;
46
	private int mColorHandle;
47

  
48
	private final int mBytesPerFloat    = 4;
49
	private final int mStrideBytes      = 7 * mBytesPerFloat;
50
	private final int mPositionOffset   = 0;
51
	private final int mPositionDataSize = 3;
52
	private final int mColorOffset      = 3;
53
	private final int mColorDataSize    = 4;
54

  
55
///////////////////////////////////////////////////////////////////////////////////////////////////
56

  
57
	AroundTheWorldRendererPicker()
58
	  {
59
		final float[] triangle1VerticesData = {
60
				      -0.25f, 0.5f, 0.0f,      // x,y,z
61
	            1.0f, 1.0f, 1.0f, 1.0f,  // r,g,b
62

  
63
	            -0.25f, -0.5f, 0.0f,
64
	            0.0f, 0.0f, 0.0f, 1.0f,
65

  
66
	            0.559f, 0.0f, 0.0f,
67
	            0.3f, 0.3f, 0.0f, 1.0f };
68

  
69
		mTriangleVertices = ByteBuffer.allocateDirect(triangle1VerticesData.length * mBytesPerFloat).order(ByteOrder.nativeOrder()).asFloatBuffer();
70
    mTriangleVertices.put(triangle1VerticesData).position(0);
71
	  }
72

  
73
///////////////////////////////////////////////////////////////////////////////////////////////////
74

  
75
	@Override public void onSurfaceCreated(GL10 glUnused, EGLConfig config)
76
	  {
77
		GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
78

  
79
		final float eyeX = 0.0f;
80
		final float eyeY = 0.0f;
81
		final float eyeZ = 1.5f;
82

  
83
		final float lookX = 0.0f;
84
		final float lookY = 0.0f;
85
		final float lookZ = -5.0f;
86

  
87
		final float upX = 0.0f;
88
		final float upY = 1.0f;
89
		final float upZ = 0.0f;
90

  
91
		Matrix.setLookAtM(mViewMatrix, 0, eyeX, eyeY, eyeZ, lookX, lookY, lookZ, upX, upY, upZ);
92

  
93
		final String vertexShader =
94
			  "uniform mat4 u_MVPMatrix;                 \n"
95
		  + "attribute vec4 a_Position;                \n"
96
		  + "attribute vec4 a_Color;                   \n"
97
		  + "varying vec4 v_Color;                     \n"
98

  
99
		  + "void main()                               \n"
100
		  + "{                                         \n"
101
		  + "   v_Color = a_Color;                     \n"
102
		  + "   gl_Position = u_MVPMatrix* a_Position; \n"
103
		  + "}                                         \n";
104

  
105
		final String fragmentShader =
106
			  "precision mediump float;       \n"
107
		  + "varying vec4 v_Color;          \n"
108

  
109
		  + "void main()                    \n"
110
		  + "{                              \n"
111
		  + "   gl_FragColor = v_Color;     \n"
112
		  + "}                              \n";
113

  
114
		int vertexShaderHandle = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
115

  
116
		if (vertexShaderHandle != 0)
117
		  {
118
			GLES20.glShaderSource(vertexShaderHandle, vertexShader);
119
      GLES20.glCompileShader(vertexShaderHandle);
120

  
121
      final int[] compileStatus = new int[1];
122
			GLES20.glGetShaderiv(vertexShaderHandle, GLES20.GL_COMPILE_STATUS, compileStatus, 0);
123

  
124
			if (compileStatus[0] == 0)
125
  			{
126
				GLES20.glDeleteShader(vertexShaderHandle);
127
				vertexShaderHandle = 0;
128
	  		}
129
		  }
130

  
131
		if (vertexShaderHandle == 0)
132
		  {
133
			throw new RuntimeException("Error creating vertex shader.");
134
		  }
135

  
136
		int fragmentShaderHandle = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
137

  
138
		if (fragmentShaderHandle != 0)
139
		  {
140
			GLES20.glShaderSource(fragmentShaderHandle, fragmentShader);
141
      GLES20.glCompileShader(fragmentShaderHandle);
142

  
143
			final int[] compileStatus = new int[1];
144
			GLES20.glGetShaderiv(fragmentShaderHandle, GLES20.GL_COMPILE_STATUS, compileStatus, 0);
145

  
146
			if (compileStatus[0] == 0)
147
			  {
148
				GLES20.glDeleteShader(fragmentShaderHandle);
149
				fragmentShaderHandle = 0;
150
			  }
151
		  }
152

  
153
		if (fragmentShaderHandle == 0)
154
		  {
155
			throw new RuntimeException("Error creating fragment shader.");
156
		  }
157

  
158
		int programHandle = GLES20.glCreateProgram();
159

  
160
		if (programHandle != 0)
161
		  {
162
			GLES20.glAttachShader(programHandle, vertexShaderHandle);
163
      GLES20.glAttachShader(programHandle, fragmentShaderHandle);
164
			GLES20.glBindAttribLocation(programHandle, 0, "a_Position");
165
			GLES20.glBindAttribLocation(programHandle, 1, "a_Color");
166
			GLES20.glLinkProgram(programHandle);
167

  
168
			final int[] linkStatus = new int[1];
169
			GLES20.glGetProgramiv(programHandle, GLES20.GL_LINK_STATUS, linkStatus, 0);
170

  
171
			if (linkStatus[0] == 0)
172
			  {
173
				GLES20.glDeleteProgram(programHandle);
174
				programHandle = 0;
175
			  }
176
		  }
177

  
178
		if (programHandle == 0)
179
		  {
180
			throw new RuntimeException("Error creating program.");
181
		  }
182

  
183
    mMVPMatrixHandle = GLES20.glGetUniformLocation(programHandle, "u_MVPMatrix");
184
    mPositionHandle = GLES20.glGetAttribLocation(programHandle, "a_Position");
185
    mColorHandle = GLES20.glGetAttribLocation(programHandle, "a_Color");
186

  
187
    GLES20.glUseProgram(programHandle);
188
	  }
189

  
190
///////////////////////////////////////////////////////////////////////////////////////////////////
191

  
192
	@Override public void onSurfaceChanged(GL10 glUnused, int width, int height)
193
	  {
194
		GLES20.glViewport(0, 0, width, height);
195

  
196
		final float ratio = (float) width / height;
197
		final float left = -ratio;
198
		final float right = ratio;
199
		final float bottom = -1.0f;
200
		final float top = 1.0f;
201
		final float near = 1.0f;
202
		final float far = 10.0f;
203

  
204
		Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far);
205
	  }
206

  
207
///////////////////////////////////////////////////////////////////////////////////////////////////
208

  
209
	@Override public void onDrawFrame(GL10 glUnused)
210
	  {
211
		GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
212

  
213
    Matrix.setIdentityM(mModelMatrix, 0);
214

  
215
    mTriangleVertices.position(mPositionOffset);
216
    GLES20.glVertexAttribPointer(mPositionHandle, mPositionDataSize, GLES20.GL_FLOAT, false, mStrideBytes, mTriangleVertices);
217
    GLES20.glEnableVertexAttribArray(mPositionHandle);
218

  
219
    mTriangleVertices.position(mColorOffset);
220
    GLES20.glVertexAttribPointer(mColorHandle, mColorDataSize, GLES20.GL_FLOAT, false, mStrideBytes, mTriangleVertices);
221
    GLES20.glEnableVertexAttribArray(mColorHandle);
222

  
223
		Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);
224
    Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);
225
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
226
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
227
	  }
228
  }
src/main/java/org/distorted/examples/aroundtheworld/AroundTheWorldSurfaceViewPicker.java
20 20
package org.distorted.examples.aroundtheworld;
21 21

  
22 22
import android.content.Context;
23
import android.graphics.Canvas;
23
import android.opengl.GLSurfaceView;
24
import android.os.Build;
24 25
import android.util.AttributeSet;
25 26
import android.view.MotionEvent;
26
import android.view.SurfaceHolder;
27
import android.view.SurfaceView;
28 27

  
29 28
///////////////////////////////////////////////////////////////////////////////////////////////////
30 29

  
31
class AroundTheWorldSurfaceViewPicker extends SurfaceView implements SurfaceHolder.Callback
30
class AroundTheWorldSurfaceViewPicker extends GLSurfaceView
32 31
{
33
    private static final int FRAME_INTERVAL = 70;
34

  
35
    private boolean refreshScreen = true;
36
    private boolean mFinishedBooting=false;
37
    private int scrWidth, scrHeight;
38
    private GraphicsThread mThread;
39
    private int mX, mY;
40

  
41
///////////////////////////////////////////////////////////////////////////////////////////////////
42

  
43
    private class GraphicsThread extends Thread
44
      {
45
      private SurfaceHolder mSurfaceHolder;
46
      private AroundTheWorldSurfaceViewPicker mPicker;
47
      private boolean mRun = false;
48

  
49
      /////////////////////////////////////////////////////////////////////////////////////
50

  
51
      GraphicsThread(SurfaceHolder surfaceHolder, AroundTheWorldSurfaceViewPicker p)
52
        {
53
        mSurfaceHolder = surfaceHolder;
54
        mPicker = p;
55
        }
56

  
57
      /////////////////////////////////////////////////////////////////////////////////////
58

  
59
      void setRunning(boolean run)
60
        {
61
        mRun = run;
62
        }
63

  
64
      /////////////////////////////////////////////////////////////////////////////////////
65

  
66
      public void run()
67
        {
68
        Canvas c;
69
        long time;
70

  
71
        while (mRun)
72
          {
73
          c = null;
74
          time = 0;
75

  
76
          if( refreshScreen && mFinishedBooting )
77
            {
78
            refreshScreen=false;
79
            time = System.currentTimeMillis();
80

  
81
            try
82
              {
83
              c = mSurfaceHolder.lockCanvas(null);
84
              synchronized (mSurfaceHolder) { mPicker.draw(c); }
85
              }
86
            finally
87
              {
88
              if (c != null)  mSurfaceHolder.unlockCanvasAndPost(c);
89
              }
90

  
91
            time = System.currentTimeMillis() -time;
92
            }
93

  
94
          if( time<FRAME_INTERVAL )
95
            {
96
            try { Thread.sleep(FRAME_INTERVAL-time); }
97
            catch(InterruptedException ex) {}
98
            }
99
          }
100
        }
101
    }
32
    private AroundTheWorldRendererPicker mRenderer;
102 33

  
103 34
///////////////////////////////////////////////////////////////////////////////////////////////////
104 35

  
......
106 37
      {
107 38
      super(c, attrs);
108 39

  
109
      mX = -100;
110
      mY = -100;
111

  
112
      getHolder().addCallback(this);
113
      setFocusable(true);
114
      setFocusableInTouchMode(true);
115

  
116
      mFinishedBooting=true;
117
      }
118

  
119
///////////////////////////////////////////////////////////////////////////////////////////////////
120

  
121
    public void surfaceCreated(SurfaceHolder holder)
122
      {
123
      android.util.Log.e( "Picker", "surfaceCreated");
124

  
125
      mThread = new GraphicsThread(getHolder(), this);
126
      mThread.setRunning(true);
127
      mThread.start();
128
      }
129

  
130
///////////////////////////////////////////////////////////////////////////////////////////////////
131

  
132
    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h)
133
      {
134
      android.util.Log.e( "Picker", "surfaceChanged: width="+w+" height="+h);
135

  
136
      scrWidth = w;
137
      scrHeight= h;
138
      refreshScreen = true;
139
      }
140

  
141
///////////////////////////////////////////////////////////////////////////////////////////////////
142

  
143
    public void surfaceDestroyed(SurfaceHolder holder)
144
      {
145
      android.util.Log.e( "Picker", "surfaceDestroyed");
146

  
147
      stopThread();
148
      }
149

  
150
///////////////////////////////////////////////////////////////////////////////////////////////////
151

  
152
    private void stopThread()
153
      {
154
      if( mThread!=null )
40
      if(!isInEditMode())
155 41
        {
156
        boolean retry = true;
157
        mThread.setRunning(false);
42
        setEGLContextClientVersion(2);
158 43

  
159
        while (retry)
44
        if( Build.FINGERPRINT.startsWith("generic") )
160 45
          {
161
          try
162
            {
163
            mThread.join();
164
            retry = false;
165
            }
166
          catch (InterruptedException e) { android.util.Log.e( "Picker", "Joining thread interrupted!"); }
46
          setEGLConfigChooser(8, 8, 8, 8, 16, 0);
167 47
          }
168 48

  
169
        mThread=null;
49
        mRenderer = new AroundTheWorldRendererPicker();
50
        setRenderer(mRenderer);
170 51
        }
171 52
      }
172

  
173 53
///////////////////////////////////////////////////////////////////////////////////////////////////
174 54

  
175
    public void draw(Canvas c)
55
    public AroundTheWorldRendererPicker getRenderer()
176 56
      {
177
      if( c!=null )
178
        {
179

  
180
        }
57
      return mRenderer;
181 58
      }
182 59

  
183 60
///////////////////////////////////////////////////////////////////////////////////////////////////
184 61

  
185
    public void setRepaint()
62
    @Override public boolean onTouchEvent(MotionEvent event)
186 63
      {
187
      refreshScreen=true;
188
      }
189

  
190
///////////////////////////////////////////////////////////////////////////////////////////////////
64
      int x = (int)event.getX();
65
      int y = (int)event.getY();
191 66

  
192
    public boolean onTouchEvent(MotionEvent event)
193
      {
194
      mX = (int)event.getX();
195
      mY = (int)event.getY();
196

  
197
      android.util.Log.e( "Picker", "onTouchEvent: x="+mX+" y="+mY);
198

  
199
      setRepaint();
67
      android.util.Log.e("Picker", "touched at x="+x+" y="+y);
200 68

  
201 69
      return true;
202 70
      }
203 71
}
72

  
src/main/res/layout/aroundtheworldlayout.xml
10 10
        android:layout_height="0dp"
11 11
        android:layout_weight="1" />
12 12

  
13
    <Space
14
        android:layout_width="match_parent"
15
        android:layout_height="5dp"/>
16

  
17 13
    <org.distorted.examples.aroundtheworld.AroundTheWorldSurfaceViewPicker
18 14
        android:id="@+id/aroundTheWorldSurfaceViewPicker"
19 15
        android:layout_width="fill_parent"

Also available in: Unified diff