Project

General

Profile

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

examples / src / main / java / org / distorted / examples / plainmonalisa / RenderThread.java @ 10b7e588

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