Project

General

Profile

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

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

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
import android.opengl.GLES20;
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 10b7e588 Leszek Koltunski
import org.distorted.library.GridFlat;
35 f6d884d5 Leszek Koltunski
import org.distorted.library.DistortedTexture;
36
import org.distorted.library.DistortedEffectQueues;
37 95593730 Leszek Koltunski
import org.distorted.library.EffectTypes;
38 7bf107f7 Leszek Koltunski
import org.distorted.library.type.Dynamic3D;
39 7589635e Leszek Koltunski
import org.distorted.library.type.Static3D;
40
import org.distorted.library.type.Static4D;
41 862fcd79 Leszek Koltunski
import org.distorted.examples.R;
42
43
import java.io.IOException;
44
import java.io.InputStream;
45
46
///////////////////////////////////////////////////////////////////////////////////////////////////
47 bc0a685b Leszek Koltunski
48 f6d884d5 Leszek Koltunski
class RenderThread extends Thread
49 862fcd79 Leszek Koltunski
  {
50
  private static final String TAG = "RenderThread";
51
52
  // Object must be created on render thread to get correct Looper, but is used from
53
  // UI thread, so we need to declare it volatile to ensure the UI thread sees a fully
54
  // constructed object.
55
  private volatile RenderHandler mHandler;
56
57
  // Used to wait for the thread to start.
58 ee76cb8f Leszek Koltunski
  private final Object mStartLock = new Object();
59 862fcd79 Leszek Koltunski
  private boolean mReady = false;
60
  private volatile SurfaceHolder mSurfaceHolder;  // may be updated by UI thread
61
  private EglCore eglCore;
62
  private EGLSurface eglSurface;
63
64 f6d884d5 Leszek Koltunski
  private DistortedTexture mTexture;
65
  private DistortedEffectQueues mQueues;
66 10b7e588 Leszek Koltunski
  private GridFlat mGrid;
67 862fcd79 Leszek Koltunski
  private int bmpHeight, bmpWidth;
68 f6d884d5 Leszek Koltunski
  private SurfaceView mView;
69 862fcd79 Leszek Koltunski
70
///////////////////////////////////////////////////////////////////////////////////////////////////
71 bc0a685b Leszek Koltunski
72 f6d884d5 Leszek Koltunski
  RenderThread(SurfaceHolder holder, SurfaceView view)
73 862fcd79 Leszek Koltunski
    {
74
    mSurfaceHolder = holder;
75
    mView = view;
76
77 f6d884d5 Leszek Koltunski
    Static3D pLeft = new Static3D( 90, 258, 0);
78
    Static3D pRight= new Static3D(176, 255, 0);
79 862fcd79 Leszek Koltunski
80 f6d884d5 Leszek Koltunski
    Static4D rLeft = new Static4D(-10,-10,25,25);
81
    Static4D rRight= new Static4D( 10, -5,25,25);
82 862fcd79 Leszek Koltunski
83 f6d884d5 Leszek Koltunski
    Dynamic3D dLeft = new Dynamic3D(1000,0.0f);
84
    Dynamic3D dRight= new Dynamic3D(1000,0.0f);
85 7bf107f7 Leszek Koltunski
86
    dLeft.add( new Static3D(  0,  0,0) );
87
    dLeft.add( new Static3D(-20,-20,0) );
88
89
    dRight.add( new Static3D(  0,  0,0) );
90
    dRight.add( new Static3D( 20,-10,0) );
91 f6d884d5 Leszek Koltunski
92
    mQueues = new DistortedEffectQueues();
93
    mQueues.distort( dLeft, pLeft , rLeft );
94
    mQueues.distort(dRight, pRight, rRight);
95
    }
96
97
///////////////////////////////////////////////////////////////////////////////////////////////////
98
99
  private static void checkGlError(String op)
100
    {
101
    int error = GLES20.glGetError();
102
103
    if (error != GLES20.GL_NO_ERROR)
104
      {
105
      String msg = op + ": glError 0x" + Integer.toHexString(error);
106
      Log.e(TAG, msg);
107
      throw new RuntimeException(msg);
108
      }
109 862fcd79 Leszek Koltunski
    }
110
111
///////////////////////////////////////////////////////////////////////////////////////////////////
112 bc0a685b Leszek Koltunski
113 862fcd79 Leszek Koltunski
  @Override
114
  public void run()
115
    {
116
    Looper.prepare();
117
    mHandler = new RenderHandler(this);
118
    eglCore = new EglCore(null, EglCore.FLAG_RECORDABLE | EglCore.FLAG_TRY_GLES3);
119
120
    synchronized (mStartLock)
121
      {
122
      mReady = true;
123
      mStartLock.notify();    // signal waitUntilReady()
124
      }
125
126
    Looper.loop();
127
    Log.d(TAG, "looper quit");
128
129
    checkGlError("releaseGl start");
130
131
    if (eglSurface != null)
132
      {
133
      eglCore.releaseSurface(eglSurface);
134
      eglSurface = EGL14.EGL_NO_SURFACE;
135
      }
136
137
    checkGlError("releaseGl done");
138
139
    eglCore.makeNothingCurrent();
140
    eglCore.release();
141
142
    synchronized (mStartLock)
143
      {
144
      mReady = false;
145
      }
146
    }
147
148
///////////////////////////////////////////////////////////////////////////////////////////////////
149 bc0a685b Leszek Koltunski
150 f6d884d5 Leszek Koltunski
  void waitUntilReady()
151 862fcd79 Leszek Koltunski
    {
152
    synchronized (mStartLock)
153
      {
154
      while (!mReady)
155
        {
156
        try
157
          {
158
          mStartLock.wait();
159
          }
160 bc0a685b Leszek Koltunski
        catch (InterruptedException ie) {  }
161 862fcd79 Leszek Koltunski
        }
162
      }
163
    }
164
165
///////////////////////////////////////////////////////////////////////////////////////////////////
166 bc0a685b Leszek Koltunski
167 862fcd79 Leszek Koltunski
  void shutdown()
168
    {
169
    Log.d(TAG, "shutdown");
170
    Looper.myLooper().quit();
171
    }
172
173
///////////////////////////////////////////////////////////////////////////////////////////////////
174 bc0a685b Leszek Koltunski
175 f6d884d5 Leszek Koltunski
  RenderHandler getHandler()
176 bc0a685b Leszek Koltunski
    {
177
    return mHandler;
178
    }
179 862fcd79 Leszek Koltunski
180
///////////////////////////////////////////////////////////////////////////////////////////////////
181 bc0a685b Leszek Koltunski
182 862fcd79 Leszek Koltunski
  void surfaceCreated()
183
    {
184
    Surface surface = mSurfaceHolder.getSurface();
185
186
    eglSurface = eglCore.createWindowSurface(surface);
187
    eglCore.makeCurrent(eglSurface);
188
189 e7a4ef16 Leszek Koltunski
    GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
190
191 862fcd79 Leszek Koltunski
    InputStream is = mView.getContext().getResources().openRawResource(R.raw.monalisa);
192
    Bitmap bmp;
193
194
    try
195
      {
196
      bmp = BitmapFactory.decodeStream(is);
197
      }
198
    finally
199
      {
200
      try
201
        {
202
        is.close();
203
        }
204
      catch(IOException io) {}
205
      }
206
207 e8b6aa95 Leszek Koltunski
    bmpHeight = bmp.getHeight();
208
    bmpWidth  = bmp.getWidth();
209
210 f6d884d5 Leszek Koltunski
    mTexture = new DistortedTexture(bmpWidth,bmpHeight,0);
211
    mTexture.setTexture(bmp);
212 862fcd79 Leszek Koltunski
213 10b7e588 Leszek Koltunski
    mGrid= new GridFlat(9,9*bmpHeight/bmpWidth);  // more-or-less square Grid with 9 columns.
214 862fcd79 Leszek Koltunski
215
    try
216
      {
217
      Distorted.onSurfaceCreated(mView.getContext());
218
      }
219
    catch(Exception ex)
220
      {
221 ee76cb8f Leszek Koltunski
      Log.e("PlainMonaLisa", ex.getMessage() );
222 862fcd79 Leszek Koltunski
      }
223
    }
224
225
///////////////////////////////////////////////////////////////////////////////////////////////////
226
227
  void surfaceChanged(int width, int height)
228
    {
229
    Log.d(TAG, "surfaceChanged " + width + "x" + height);
230
231 f6d884d5 Leszek Koltunski
    mQueues.abortEffects(EffectTypes.MATRIX);
232 862fcd79 Leszek Koltunski
233 5055b5d4 Leszek Koltunski
    if( (float)bmpHeight/bmpWidth > (float)height/width )
234 862fcd79 Leszek Koltunski
      {
235
      int w = (height*bmpWidth)/bmpHeight;
236 7589635e Leszek Koltunski
      float factor = (float)height/bmpHeight;
237
238 f6d884d5 Leszek Koltunski
      mQueues.move( new Static3D((width-w)/2,0,0) );
239
      mQueues.scale( factor );
240 862fcd79 Leszek Koltunski
      }
241
    else
242
      {
243
      int h = (width*bmpHeight)/bmpWidth;
244 7589635e Leszek Koltunski
      float factor = (float)width/bmpWidth;
245
246 f6d884d5 Leszek Koltunski
      mQueues.move( new Static3D(0,(height-h)/2,0) );
247
      mQueues.scale( factor );
248 862fcd79 Leszek Koltunski
      }
249
250
    Distorted.onSurfaceChanged(width, height);
251
    }
252
253
///////////////////////////////////////////////////////////////////////////////////////////////////
254
255 f6d884d5 Leszek Koltunski
  void doFrame(long frameTimeNs)
256 862fcd79 Leszek Koltunski
    {
257 e52f9d96 Leszek Koltunski
    if( PlainMonaLisaSurfaceView.isPaused() )
258
      {
259
      android.util.Log.e("Thread", "Got here after onPaused- ignoring frame draw call!!");
260
      return;
261
      }
262
263 862fcd79 Leszek Koltunski
    eglCore.makeCurrent(eglSurface);
264
265
    GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
266 f6d884d5 Leszek Koltunski
    mQueues.draw(System.currentTimeMillis(), mTexture,mGrid);
267 862fcd79 Leszek Koltunski
268
    eglCore.swapBuffers(eglSurface);
269
    }
270
271
  }