Project

General

Profile

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

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

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.plainmonalisa;
21

    
22
import android.graphics.Bitmap;
23
import android.graphics.BitmapFactory;
24
import android.opengl.EGL14;
25
import android.opengl.EGLSurface;
26
import android.opengl.GLES30;
27
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
import org.distorted.library.Distorted;
34
import org.distorted.library.DistortedEffects;
35
import org.distorted.library.DistortedScreen;
36
import org.distorted.library.EffectNames;
37
import org.distorted.library.MeshFlat;
38
import org.distorted.library.DistortedTexture;
39
import org.distorted.library.EffectTypes;
40
import org.distorted.library.type.Dynamic3D;
41
import org.distorted.library.type.Static3D;
42
import org.distorted.library.type.Static4D;
43
import org.distorted.examples.R;
44

    
45
import java.io.IOException;
46
import java.io.InputStream;
47

    
48
///////////////////////////////////////////////////////////////////////////////////////////////////
49

    
50
class RenderThread extends Thread
51
  {
52
  private static final String TAG = "RenderThread";
53

    
54
  // Object must be created on render thread to get correct Looper, but is used from
55
  // UI thread, so we need to declare it volatile to ensure the UI thread sees a fully
56
  // constructed object.
57
  private volatile RenderHandler mHandler;
58

    
59
  // Used to wait for the thread to start.
60
  private final Object mStartLock = new Object();
61
  private boolean mReady = false;
62
  private volatile SurfaceHolder mSurfaceHolder;  // may be updated by UI thread
63
  private EglCore eglCore;
64
  private EGLSurface eglSurface;
65

    
66
  private DistortedEffects mEffects;
67
  private DistortedTexture mTexture;
68
  private DistortedScreen mScreen;
69
  private int bmpHeight, bmpWidth;
70
  private SurfaceView mView;
71
  private static boolean resourcesCreated = false;
72

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

    
75
  RenderThread(SurfaceHolder holder, SurfaceView view)
76
    {
77
    mSurfaceHolder = holder;
78
    mView = view;
79

    
80
    Static3D pLeft = new Static3D( 90, 258, 0);
81
    Static3D pRight= new Static3D(176, 255, 0);
82

    
83
    Static4D rLeft = new Static4D(-10,-10,25,25);
84
    Static4D rRight= new Static4D( 10, -5,25,25);
85

    
86
    Dynamic3D dLeft = new Dynamic3D(1000,0.0f);
87
    Dynamic3D dRight= new Dynamic3D(1000,0.0f);
88

    
89
    dLeft.add( new Static3D(  0,  0,0) );
90
    dLeft.add( new Static3D(-20,-20,0) );
91

    
92
    dRight.add( new Static3D(  0,  0,0) );
93
    dRight.add( new Static3D( 20,-10,0) );
94

    
95
    mEffects = new DistortedEffects();
96
    mEffects.distort( dLeft, pLeft , rLeft );
97
    mEffects.distort(dRight, pRight, rRight);
98

    
99
    mScreen = new DistortedScreen();
100
    }
101

    
102
///////////////////////////////////////////////////////////////////////////////////////////////////
103

    
104
  static void setResourcesCreated()
105
    {
106
    resourcesCreated = false;
107
    }
108

    
109
///////////////////////////////////////////////////////////////////////////////////////////////////
110

    
111
  private static void checkGlError(String op)
112
    {
113
    int error = GLES30.glGetError();
114

    
115
    if (error != GLES30.GL_NO_ERROR)
116
      {
117
      String msg = op + ": glError 0x" + Integer.toHexString(error);
118
      Log.e(TAG, msg);
119
//      throw new RuntimeException(msg);
120
      }
121
    }
122

    
123
///////////////////////////////////////////////////////////////////////////////////////////////////
124

    
125
  @Override
126
  public void run()
127
    {
128
    Looper.prepare();
129
    mHandler = new RenderHandler(this);
130
    eglCore = new EglCore(null, EglCore.FLAG_RECORDABLE | EglCore.FLAG_TRY_GLES3);
131

    
132
    synchronized (mStartLock)
133
      {
134
      mReady = true;
135
      mStartLock.notify();    // signal waitUntilReady()
136
      }
137

    
138
    Looper.loop();
139
    Log.d(TAG, "looper quit");
140

    
141
    checkGlError("releaseGl start");
142

    
143
    if (eglSurface != null)
144
      {
145
      eglCore.releaseSurface(eglSurface);
146
      eglSurface = EGL14.EGL_NO_SURFACE;
147
      }
148

    
149
    checkGlError("releaseGl done");
150

    
151
    eglCore.makeNothingCurrent();
152
    eglCore.release();
153

    
154
    synchronized (mStartLock)
155
      {
156
      mReady = false;
157
      }
158
    }
159

    
160
///////////////////////////////////////////////////////////////////////////////////////////////////
161

    
162
  void waitUntilReady()
163
    {
164
    synchronized (mStartLock)
165
      {
166
      while (!mReady)
167
        {
168
        try
169
          {
170
          mStartLock.wait();
171
          }
172
        catch (InterruptedException ie) {  }
173
        }
174
      }
175
    }
176

    
177
///////////////////////////////////////////////////////////////////////////////////////////////////
178

    
179
  void shutdown()
180
    {
181
    Log.d(TAG, "shutdown");
182
    Looper.myLooper().quit();
183
    }
184

    
185
///////////////////////////////////////////////////////////////////////////////////////////////////
186

    
187
  RenderHandler getHandler()
188
    {
189
    return mHandler;
190
    }
191

    
192
///////////////////////////////////////////////////////////////////////////////////////////////////
193

    
194
  void surfaceCreated()
195
    {
196
    Log.d(TAG, "surfaceCreated");
197

    
198
    Surface surface = mSurfaceHolder.getSurface();
199

    
200
    eglSurface = eglCore.createWindowSurface(surface);
201
    eglCore.makeCurrent(eglSurface);
202

    
203
    createResources();
204
    }
205

    
206
///////////////////////////////////////////////////////////////////////////////////////////////////
207

    
208
  void surfaceChanged(int width, int height)
209
    {
210
    Log.d(TAG, "surfaceChanged " + width + "x" + height);
211

    
212
    mEffects.abortEffects(EffectTypes.MATRIX);
213

    
214
    if( (float)bmpHeight/bmpWidth > (float)height/width )
215
      {
216
      int w = (height*bmpWidth)/bmpHeight;
217
      float factor = (float)height/bmpHeight;
218

    
219
      mEffects.move( new Static3D((width-w)/2,0,0) );
220
      mEffects.scale( factor );
221
      }
222
    else
223
      {
224
      int h = (width*bmpHeight)/bmpWidth;
225
      float factor = (float)width/bmpWidth;
226

    
227
      mEffects.move( new Static3D(0,(height-h)/2,0) );
228
      mEffects.scale( factor );
229
      }
230

    
231
    mScreen.resize(width, height);
232
    }
233

    
234
///////////////////////////////////////////////////////////////////////////////////////////////////
235

    
236
  void createResources()
237
    {
238
    resourcesCreated = true;
239

    
240
    InputStream is = mView.getContext().getResources().openRawResource(R.raw.monalisa);
241
    Bitmap bmp;
242

    
243
    try
244
      {
245
      bmp = BitmapFactory.decodeStream(is);
246
      }
247
    finally
248
      {
249
      try
250
        {
251
        is.close();
252
        }
253
      catch(IOException io) {}
254
      }
255

    
256
    bmpHeight = bmp.getHeight();
257
    bmpWidth  = bmp.getWidth();
258

    
259
    if( mTexture==null ) mTexture = new DistortedTexture(bmpWidth,bmpHeight);
260
    mTexture.setTexture(bmp);
261

    
262
    mScreen.detachAll();
263
    mScreen.attach(mTexture,mEffects,new MeshFlat(9,9*bmpHeight/bmpWidth));
264

    
265
    DistortedEffects.enableEffect(EffectNames.DISTORT);
266

    
267
    try
268
      {
269
      Distorted.onCreate(mView.getContext());
270
      }
271
    catch(Exception ex)
272
      {
273
      Log.e("PlainMonaLisa", ex.getMessage() );
274
      }
275
    }
276

    
277
///////////////////////////////////////////////////////////////////////////////////////////////////
278

    
279
  void doFrame(long frameTimeNs)
280
    {
281
    // We can still get here after onPaused - ignore such calls.
282
    if( PlainMonaLisaSurfaceView.isPaused() )
283
      {
284
      android.util.Log.e("Thread", "Got here after onPaused- ignoring frame draw call!!");
285
      return;
286
      }
287

    
288
    // This will happen if we just briefly went into the background (press 'POWER')
289
    // Then surfaceCreated/changed is not called
290
    if( !resourcesCreated )
291
      {
292
      Log.e("Thread", "resources not created!!");
293
      createResources();
294
      }
295

    
296
    eglCore.makeCurrent(eglSurface);
297
    mScreen.render( frameTimeNs/1000000 );  // 1 nanosecond = 1 millisecond / 10^-6
298
    eglCore.swapBuffers(eglSurface);
299
    }
300

    
301
  }
(5-5/5)