Project

General

Profile

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

examples / src / main / java / org / distorted / examples / plainmonalisa / RenderThread.java @ 7bf107f7

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.GLES20;
27
import android.os.Looper;
28
import android.os.Trace;
29
import android.util.Log;
30
import android.view.Surface;
31
import android.view.SurfaceHolder;
32
import android.view.SurfaceView;
33

    
34
import org.distorted.library.Distorted;
35
import org.distorted.library.DistortedBitmap;
36
import org.distorted.library.EffectTypes;
37
import org.distorted.library.type.Dynamic3D;
38
import org.distorted.library.type.Static2D;
39
import org.distorted.library.type.Static3D;
40
import org.distorted.library.type.Static4D;
41
import org.distorted.examples.R;
42

    
43
import java.io.IOException;
44
import java.io.InputStream;
45

    
46
///////////////////////////////////////////////////////////////////////////////////////////////////
47

    
48
public class RenderThread extends Thread
49
  {
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
  private Object mStartLock = new Object();
59
  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
  private DistortedBitmap monaLisa;
65
  private int bmpHeight, bmpWidth;
66

    
67
  private Static2D pLeft, pRight;
68
  private Static4D rLeft, rRight;
69

    
70
  private Dynamic3D dLeft, dRight;
71

    
72
  SurfaceView mView;
73

    
74
///////////////////////////////////////////////////////////////////////////////////////////////////
75

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

    
81
    pLeft = new Static2D( 90, 258);
82
    pRight= new Static2D(176, 255);
83

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

    
87
    dLeft = new Dynamic3D();
88
    dRight= new Dynamic3D();
89

    
90
    dLeft.setDuration(1000);
91
    dRight.setDuration(1000);
92

    
93
    dLeft.setCount(0);
94
    dRight.setCount(0);
95

    
96
    dLeft.add( new Static3D(  0,  0,0) );
97
    dLeft.add( new Static3D(-20,-20,0) );
98

    
99
    dRight.add( new Static3D(  0,  0,0) );
100
    dRight.add( new Static3D( 20,-10,0) );
101
    }
102

    
103
///////////////////////////////////////////////////////////////////////////////////////////////////
104

    
105
  @Override
106
  public void run()
107
    {
108
    Looper.prepare();
109
    mHandler = new RenderHandler(this);
110
    eglCore = new EglCore(null, EglCore.FLAG_RECORDABLE | EglCore.FLAG_TRY_GLES3);
111

    
112
    synchronized (mStartLock)
113
      {
114
      mReady = true;
115
      mStartLock.notify();    // signal waitUntilReady()
116
      }
117

    
118
    Looper.loop();
119
    Log.d(TAG, "looper quit");
120

    
121
    checkGlError("releaseGl start");
122

    
123
    if (eglSurface != null)
124
      {
125
      eglCore.releaseSurface(eglSurface);
126
      eglSurface = EGL14.EGL_NO_SURFACE;
127
      }
128

    
129
    checkGlError("releaseGl done");
130

    
131
    eglCore.makeNothingCurrent();
132
    eglCore.release();
133

    
134
    synchronized (mStartLock)
135
      {
136
      mReady = false;
137
      }
138
    }
139

    
140
///////////////////////////////////////////////////////////////////////////////////////////////////
141

    
142
  public void waitUntilReady()
143
    {
144
    synchronized (mStartLock)
145
      {
146
      while (!mReady)
147
        {
148
        try
149
          {
150
          mStartLock.wait();
151
          }
152
        catch (InterruptedException ie) {  }
153
        }
154
      }
155
    }
156

    
157
///////////////////////////////////////////////////////////////////////////////////////////////////
158

    
159
  void shutdown()
160
    {
161
    Log.d(TAG, "shutdown");
162
    Looper.myLooper().quit();
163
    }
164

    
165
///////////////////////////////////////////////////////////////////////////////////////////////////
166

    
167
  public RenderHandler getHandler()
168
    {
169
    return mHandler;
170
    }
171

    
172
///////////////////////////////////////////////////////////////////////////////////////////////////
173

    
174
  void surfaceCreated()
175
    {
176
    Surface surface = mSurfaceHolder.getSurface();
177

    
178
    eglSurface = eglCore.createWindowSurface(surface);
179
    eglCore.makeCurrent(eglSurface);
180

    
181
    InputStream is = mView.getContext().getResources().openRawResource(R.raw.monalisa);
182
    Bitmap bmp;
183

    
184
    try
185
      {
186
      bmp = BitmapFactory.decodeStream(is);
187
      }
188
    finally
189
      {
190
      try
191
        {
192
        is.close();
193
        }
194
      catch(IOException io) {}
195
      }
196

    
197
    monaLisa = new DistortedBitmap(bmp, 10);
198
    monaLisa.distort( dLeft, pLeft , rLeft );
199
    monaLisa.distort(dRight, pRight, rRight);
200

    
201
    bmpHeight = bmp.getHeight();
202
    bmpWidth  = bmp.getWidth();
203

    
204
    try
205
      {
206
      Distorted.onSurfaceCreated(mView.getContext());
207
      }
208
    catch(Exception ex)
209
      {
210
      Log.e("MonaLisa", ex.getMessage() );
211
      }
212
    }
213

    
214
///////////////////////////////////////////////////////////////////////////////////////////////////
215

    
216
  void surfaceChanged(int width, int height)
217
    {
218
    Log.d(TAG, "surfaceChanged " + width + "x" + height);
219

    
220
    monaLisa.abortEffects(EffectTypes.MATRIX);
221

    
222
    if( bmpHeight/bmpWidth > height/width )
223
      {
224
      int w = (height*bmpWidth)/bmpHeight;
225
      float factor = (float)height/bmpHeight;
226

    
227
      monaLisa.move( new Static3D((width-w)/2,0,0) );
228
      monaLisa.scale( new Static3D(factor,factor,factor) );
229
      }
230
    else
231
      {
232
      int h = (width*bmpHeight)/bmpWidth;
233
      float factor = (float)width/bmpWidth;
234

    
235
      monaLisa.move( new Static3D(0,(height-h)/2,0) );
236
      monaLisa.scale( new Static3D(factor,factor,factor) );
237
      }
238

    
239
    Distorted.onSurfaceChanged(width, height);
240
    }
241

    
242
///////////////////////////////////////////////////////////////////////////////////////////////////
243

    
244
  public void doFrame(long frameTimeNs)
245
    {
246
    Trace.beginSection("doFrame draw");
247
    eglCore.makeCurrent(eglSurface);
248

    
249
    GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
250
    GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
251
    monaLisa.draw(System.currentTimeMillis());
252

    
253
    eglCore.swapBuffers(eglSurface);
254
    Trace.endSection();
255
    }
256

    
257
///////////////////////////////////////////////////////////////////////////////////////////////////
258

    
259
  public static void checkGlError(String op)
260
    {
261
    int error = GLES20.glGetError();
262

    
263
    if (error != GLES20.GL_NO_ERROR)
264
      {
265
      String msg = op + ": glError 0x" + Integer.toHexString(error);
266
      Log.e(TAG, msg);
267
      throw new RuntimeException(msg);
268
      }
269
    }
270
  }
(5-5/5)