Project

General

Profile

Download (9.46 KB) Statistics
| Branch: | Revision:

examples / src / main / java / org / distorted / examples / plainmonalisa / RenderThread.java @ 107e4b72

1 bc0a685b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
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 862fcd79 Leszek Koltunski
package org.distorted.examples.plainmonalisa;
21
22
import android.graphics.Bitmap;
23
import android.graphics.BitmapFactory;
24
import android.opengl.EGL14;
25
import android.opengl.EGLSurface;
26 41a85bb7 Leszek Koltunski
import android.opengl.GLES31;
27 862fcd79 Leszek Koltunski
import android.os.Looper;
28
import android.util.Log;
29
import android.view.Surface;
30
import android.view.SurfaceHolder;
31
import android.view.SurfaceView;
32
33 1f218177 Leszek Koltunski
import org.distorted.library.effect.MatrixEffectMove;
34
import org.distorted.library.effect.MatrixEffectScale;
35
import org.distorted.library.effect.VertexEffectDistort;
36 01782e85 Leszek Koltunski
import org.distorted.library.main.Distorted;
37
import org.distorted.library.main.DistortedEffects;
38
import org.distorted.library.main.DistortedScreen;
39 107e4b72 Leszek Koltunski
import org.distorted.library.mesh.MeshFlat;
40 01782e85 Leszek Koltunski
import org.distorted.library.main.DistortedTexture;
41 7bf107f7 Leszek Koltunski
import org.distorted.library.type.Dynamic3D;
42 7589635e Leszek Koltunski
import org.distorted.library.type.Static3D;
43
import org.distorted.library.type.Static4D;
44 862fcd79 Leszek Koltunski
import org.distorted.examples.R;
45
46
import java.io.IOException;
47
import java.io.InputStream;
48
49
///////////////////////////////////////////////////////////////////////////////////////////////////
50 bc0a685b Leszek Koltunski
51 f6d884d5 Leszek Koltunski
class RenderThread extends Thread
52 862fcd79 Leszek Koltunski
  {
53
  private static final String TAG = "RenderThread";
54
55
  // Object must be created on render thread to get correct Looper, but is used from
56
  // UI thread, so we need to declare it volatile to ensure the UI thread sees a fully
57
  // constructed object.
58
  private volatile RenderHandler mHandler;
59
60
  // Used to wait for the thread to start.
61 ee76cb8f Leszek Koltunski
  private final Object mStartLock = new Object();
62 862fcd79 Leszek Koltunski
  private boolean mReady = false;
63
  private volatile SurfaceHolder mSurfaceHolder;  // may be updated by UI thread
64
  private EglCore eglCore;
65
  private EGLSurface eglSurface;
66
67 d04a4886 Leszek Koltunski
  private DistortedEffects mEffects;
68 c126aa85 leszek
  private DistortedTexture mTexture;
69 5f2a53b6 leszek
  private MeshFlat mMesh;
70 d218d64e leszek
  private DistortedScreen mScreen;
71 862fcd79 Leszek Koltunski
  private int bmpHeight, bmpWidth;
72 f6d884d5 Leszek Koltunski
  private SurfaceView mView;
73 c126aa85 leszek
  private static boolean resourcesCreated = false;
74 1f218177 Leszek Koltunski
  private Static3D mMove, mScale;
75 862fcd79 Leszek Koltunski
76
///////////////////////////////////////////////////////////////////////////////////////////////////
77 bc0a685b Leszek Koltunski
78 f6d884d5 Leszek Koltunski
  RenderThread(SurfaceHolder holder, SurfaceView view)
79 862fcd79 Leszek Koltunski
    {
80
    mSurfaceHolder = holder;
81
    mView = view;
82
83 f6d884d5 Leszek Koltunski
    Static3D pLeft = new Static3D( 90, 258, 0);
84
    Static3D pRight= new Static3D(176, 255, 0);
85 862fcd79 Leszek Koltunski
86 f6d884d5 Leszek Koltunski
    Static4D rLeft = new Static4D(-10,-10,25,25);
87
    Static4D rRight= new Static4D( 10, -5,25,25);
88 862fcd79 Leszek Koltunski
89 f6d884d5 Leszek Koltunski
    Dynamic3D dLeft = new Dynamic3D(1000,0.0f);
90
    Dynamic3D dRight= new Dynamic3D(1000,0.0f);
91 7bf107f7 Leszek Koltunski
92
    dLeft.add( new Static3D(  0,  0,0) );
93
    dLeft.add( new Static3D(-20,-20,0) );
94
95
    dRight.add( new Static3D(  0,  0,0) );
96
    dRight.add( new Static3D( 20,-10,0) );
97 f6d884d5 Leszek Koltunski
98 d04a4886 Leszek Koltunski
    mEffects = new DistortedEffects();
99 1f218177 Leszek Koltunski
    mEffects.apply( new VertexEffectDistort(dLeft , pLeft , rLeft ) );
100
    mEffects.apply( new VertexEffectDistort(dRight, pRight, rRight) );
101
102
    mMove = new Static3D(0,0,0);
103
    mScale= new Static3D(1,1,1);
104
    mEffects.apply(new MatrixEffectMove(mMove));
105
    mEffects.apply(new MatrixEffectScale(mScale));
106 392e16fd Leszek Koltunski
107 e4330c89 Leszek Koltunski
    mScreen = new DistortedScreen();
108 f6d884d5 Leszek Koltunski
    }
109
110 c126aa85 leszek
///////////////////////////////////////////////////////////////////////////////////////////////////
111
112
  static void setResourcesCreated()
113
    {
114
    resourcesCreated = false;
115
    }
116
117 f6d884d5 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
118
119
  private static void checkGlError(String op)
120
    {
121 41a85bb7 Leszek Koltunski
    int error = GLES31.glGetError();
122 f6d884d5 Leszek Koltunski
123 41a85bb7 Leszek Koltunski
    if (error != GLES31.GL_NO_ERROR)
124 f6d884d5 Leszek Koltunski
      {
125
      String msg = op + ": glError 0x" + Integer.toHexString(error);
126
      Log.e(TAG, msg);
127 1f218177 Leszek Koltunski
//    throw new RuntimeException(msg);
128 f6d884d5 Leszek Koltunski
      }
129 862fcd79 Leszek Koltunski
    }
130
131
///////////////////////////////////////////////////////////////////////////////////////////////////
132 bc0a685b Leszek Koltunski
133 862fcd79 Leszek Koltunski
  @Override
134
  public void run()
135
    {
136
    Looper.prepare();
137
    mHandler = new RenderHandler(this);
138
    eglCore = new EglCore(null, EglCore.FLAG_RECORDABLE | EglCore.FLAG_TRY_GLES3);
139
140
    synchronized (mStartLock)
141
      {
142
      mReady = true;
143
      mStartLock.notify();    // signal waitUntilReady()
144
      }
145
146
    Looper.loop();
147
    Log.d(TAG, "looper quit");
148
149
    checkGlError("releaseGl start");
150
151
    if (eglSurface != null)
152
      {
153
      eglCore.releaseSurface(eglSurface);
154
      eglSurface = EGL14.EGL_NO_SURFACE;
155
      }
156
157
    checkGlError("releaseGl done");
158
159
    eglCore.makeNothingCurrent();
160
    eglCore.release();
161
162
    synchronized (mStartLock)
163
      {
164
      mReady = false;
165
      }
166
    }
167
168
///////////////////////////////////////////////////////////////////////////////////////////////////
169 bc0a685b Leszek Koltunski
170 f6d884d5 Leszek Koltunski
  void waitUntilReady()
171 862fcd79 Leszek Koltunski
    {
172
    synchronized (mStartLock)
173
      {
174
      while (!mReady)
175
        {
176
        try
177
          {
178
          mStartLock.wait();
179
          }
180 bc0a685b Leszek Koltunski
        catch (InterruptedException ie) {  }
181 862fcd79 Leszek Koltunski
        }
182
      }
183
    }
184
185
///////////////////////////////////////////////////////////////////////////////////////////////////
186 bc0a685b Leszek Koltunski
187 862fcd79 Leszek Koltunski
  void shutdown()
188
    {
189
    Log.d(TAG, "shutdown");
190
    Looper.myLooper().quit();
191
    }
192
193
///////////////////////////////////////////////////////////////////////////////////////////////////
194 bc0a685b Leszek Koltunski
195 f6d884d5 Leszek Koltunski
  RenderHandler getHandler()
196 bc0a685b Leszek Koltunski
    {
197
    return mHandler;
198
    }
199 862fcd79 Leszek Koltunski
200
///////////////////////////////////////////////////////////////////////////////////////////////////
201 bc0a685b Leszek Koltunski
202 862fcd79 Leszek Koltunski
  void surfaceCreated()
203
    {
204 c126aa85 leszek
    Log.d(TAG, "surfaceCreated");
205
206 862fcd79 Leszek Koltunski
    Surface surface = mSurfaceHolder.getSurface();
207
208
    eglSurface = eglCore.createWindowSurface(surface);
209
    eglCore.makeCurrent(eglSurface);
210
211 c126aa85 leszek
    createResources();
212
    }
213
214
///////////////////////////////////////////////////////////////////////////////////////////////////
215
216
  void surfaceChanged(int width, int height)
217
    {
218
    Log.d(TAG, "surfaceChanged " + width + "x" + height);
219
220 67c3a83b leszek
    if( (float)bmpHeight/bmpWidth > (float)height/width )
221
      {
222
      int w = (height*bmpWidth)/bmpHeight;
223
      float factor = (float)height/bmpHeight;
224
225 1f218177 Leszek Koltunski
      mMove.set((width-w)/2,0,0);
226
      mScale.set( factor,factor,factor );
227 67c3a83b leszek
      }
228
    else
229
      {
230
      int h = (width*bmpHeight)/bmpWidth;
231
      float factor = (float)width/bmpWidth;
232
233 1f218177 Leszek Koltunski
      mMove.set(0,(height-h)/2,0);
234
      mScale.set( factor,factor,factor );
235 67c3a83b leszek
      }
236 c126aa85 leszek
237
    mScreen.resize(width, height);
238
    }
239
240
///////////////////////////////////////////////////////////////////////////////////////////////////
241
242 1f218177 Leszek Koltunski
  private void createResources()
243 c126aa85 leszek
    {
244
    resourcesCreated = true;
245
246 862fcd79 Leszek Koltunski
    InputStream is = mView.getContext().getResources().openRawResource(R.raw.monalisa);
247
    Bitmap bmp;
248
249
    try
250
      {
251
      bmp = BitmapFactory.decodeStream(is);
252
      }
253
    finally
254
      {
255
      try
256
        {
257
        is.close();
258
        }
259
      catch(IOException io) {}
260
      }
261
262 e8b6aa95 Leszek Koltunski
    bmpHeight = bmp.getHeight();
263
    bmpWidth  = bmp.getWidth();
264
265 c126aa85 leszek
    if( mTexture==null ) mTexture = new DistortedTexture(bmpWidth,bmpHeight);
266
    mTexture.setTexture(bmp);
267 862fcd79 Leszek Koltunski
268 5f2a53b6 leszek
    if( mMesh==null ) mMesh = new MeshFlat(9,9*bmpHeight/bmpWidth);
269
270 fe59d375 Leszek Koltunski
    mScreen.detachAll();
271 5f2a53b6 leszek
    mScreen.attach(mTexture,mEffects,mMesh);
272 862fcd79 Leszek Koltunski
273 885b9cca leszek
    VertexEffectDistort.enable();
274 6637d0f2 Leszek Koltunski
275 862fcd79 Leszek Koltunski
    try
276
      {
277 76f9798b Leszek Koltunski
      Distorted.onCreate(mView.getContext());
278 862fcd79 Leszek Koltunski
      }
279
    catch(Exception ex)
280
      {
281 ee76cb8f Leszek Koltunski
      Log.e("PlainMonaLisa", ex.getMessage() );
282 862fcd79 Leszek Koltunski
      }
283
    }
284
285
///////////////////////////////////////////////////////////////////////////////////////////////////
286
287 f6d884d5 Leszek Koltunski
  void doFrame(long frameTimeNs)
288 862fcd79 Leszek Koltunski
    {
289 c126aa85 leszek
    // We can still get here after onPaused - ignore such calls.
290 e52f9d96 Leszek Koltunski
    if( PlainMonaLisaSurfaceView.isPaused() )
291
      {
292
      android.util.Log.e("Thread", "Got here after onPaused- ignoring frame draw call!!");
293
      return;
294
      }
295
296 c126aa85 leszek
    // This will happen if we just briefly went into the background (press 'POWER')
297
    // Then surfaceCreated/changed is not called
298
    if( !resourcesCreated )
299
      {
300
      Log.e("Thread", "resources not created!!");
301
      createResources();
302
      }
303
304 862fcd79 Leszek Koltunski
    eglCore.makeCurrent(eglSurface);
305 855ba24e leszek
    mScreen.render( frameTimeNs/1000000 );  // 1 nanosecond = 1 millisecond / 10^-6
306 862fcd79 Leszek Koltunski
    eglCore.swapBuffers(eglSurface);
307
    }
308
309
  }