Project

General

Profile

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

examples / src / main / java / org / distorted / examples / plainmonalisa / RenderThread.java @ e4330c89

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