Project

General

Profile

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

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

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.MeshFlat;
37
import org.distorted.library.DistortedTexture;
38
import org.distorted.library.EffectTypes;
39
import org.distorted.library.type.Dynamic3D;
40
import org.distorted.library.type.Static3D;
41
import org.distorted.library.type.Static4D;
42
import org.distorted.examples.R;
43

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

    
47
///////////////////////////////////////////////////////////////////////////////////////////////////
48

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

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

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

    
65
  private DistortedEffects mEffects;
66
  private DistortedScreen mScreen;
67
  private int bmpHeight, bmpWidth;
68
  private SurfaceView mView;
69

    
70
///////////////////////////////////////////////////////////////////////////////////////////////////
71

    
72
  RenderThread(SurfaceHolder holder, SurfaceView view)
73
    {
74
    mSurfaceHolder = holder;
75
    mView = view;
76

    
77
    Static3D pLeft = new Static3D( 90, 258, 0);
78
    Static3D pRight= new Static3D(176, 255, 0);
79

    
80
    Static4D rLeft = new Static4D(-10,-10,25,25);
81
    Static4D rRight= new Static4D( 10, -5,25,25);
82

    
83
    Dynamic3D dLeft = new Dynamic3D(1000,0.0f);
84
    Dynamic3D dRight= new Dynamic3D(1000,0.0f);
85

    
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

    
92
    mEffects = new DistortedEffects();
93
    mEffects.distort( dLeft, pLeft , rLeft );
94
    mEffects.distort(dRight, pRight, rRight);
95

    
96
    mScreen = new DistortedScreen();
97
    }
98

    
99
///////////////////////////////////////////////////////////////////////////////////////////////////
100

    
101
  private static void checkGlError(String op)
102
    {
103
    int error = GLES30.glGetError();
104

    
105
    if (error != GLES30.GL_NO_ERROR)
106
      {
107
      String msg = op + ": glError 0x" + Integer.toHexString(error);
108
      Log.e(TAG, msg);
109
//      throw new RuntimeException(msg);
110
      }
111
    }
112

    
113
///////////////////////////////////////////////////////////////////////////////////////////////////
114

    
115
  @Override
116
  public void run()
117
    {
118
    Looper.prepare();
119
    mHandler = new RenderHandler(this);
120
    eglCore = new EglCore(null, EglCore.FLAG_RECORDABLE | EglCore.FLAG_TRY_GLES3);
121

    
122
    synchronized (mStartLock)
123
      {
124
      mReady = true;
125
      mStartLock.notify();    // signal waitUntilReady()
126
      }
127

    
128
    Looper.loop();
129
    Log.d(TAG, "looper quit");
130

    
131
    checkGlError("releaseGl start");
132

    
133
    if (eglSurface != null)
134
      {
135
      eglCore.releaseSurface(eglSurface);
136
      eglSurface = EGL14.EGL_NO_SURFACE;
137
      }
138

    
139
    checkGlError("releaseGl done");
140

    
141
    eglCore.makeNothingCurrent();
142
    eglCore.release();
143

    
144
    synchronized (mStartLock)
145
      {
146
      mReady = false;
147
      }
148
    }
149

    
150
///////////////////////////////////////////////////////////////////////////////////////////////////
151

    
152
  void waitUntilReady()
153
    {
154
    synchronized (mStartLock)
155
      {
156
      while (!mReady)
157
        {
158
        try
159
          {
160
          mStartLock.wait();
161
          }
162
        catch (InterruptedException ie) {  }
163
        }
164
      }
165
    }
166

    
167
///////////////////////////////////////////////////////////////////////////////////////////////////
168

    
169
  void shutdown()
170
    {
171
    Log.d(TAG, "shutdown");
172
    Looper.myLooper().quit();
173
    }
174

    
175
///////////////////////////////////////////////////////////////////////////////////////////////////
176

    
177
  RenderHandler getHandler()
178
    {
179
    return mHandler;
180
    }
181

    
182
///////////////////////////////////////////////////////////////////////////////////////////////////
183

    
184
  void surfaceCreated()
185
    {
186
    Surface surface = mSurfaceHolder.getSurface();
187

    
188
    eglSurface = eglCore.createWindowSurface(surface);
189
    eglCore.makeCurrent(eglSurface);
190

    
191
    GLES30.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
192

    
193
    InputStream is = mView.getContext().getResources().openRawResource(R.raw.monalisa);
194
    Bitmap bmp;
195

    
196
    try
197
      {
198
      bmp = BitmapFactory.decodeStream(is);
199
      }
200
    finally
201
      {
202
      try
203
        {
204
        is.close();
205
        }
206
      catch(IOException io) {}
207
      }
208

    
209
    bmpHeight = bmp.getHeight();
210
    bmpWidth  = bmp.getWidth();
211

    
212
    DistortedTexture texture = new DistortedTexture(bmpWidth,bmpHeight);
213
    texture.setTexture(bmp);
214
    MeshFlat mesh = new MeshFlat(9,9*bmpHeight/bmpWidth);  // more-or-less square Grid with 9 columns.
215

    
216
    mScreen.detachAll();
217
    mScreen.attach(texture,mEffects,mesh);
218

    
219
    try
220
      {
221
      Distorted.onCreate(mView.getContext());
222
      }
223
    catch(Exception ex)
224
      {
225
      Log.e("PlainMonaLisa", ex.getMessage() );
226
      }
227
    }
228

    
229
///////////////////////////////////////////////////////////////////////////////////////////////////
230

    
231
  void surfaceChanged(int width, int height)
232
    {
233
    Log.d(TAG, "surfaceChanged " + width + "x" + height);
234

    
235
    mEffects.abortEffects(EffectTypes.MATRIX);
236

    
237
    if( (float)bmpHeight/bmpWidth > (float)height/width )
238
      {
239
      int w = (height*bmpWidth)/bmpHeight;
240
      float factor = (float)height/bmpHeight;
241

    
242
      mEffects.move( new Static3D((width-w)/2,0,0) );
243
      mEffects.scale( factor );
244
      }
245
    else
246
      {
247
      int h = (width*bmpHeight)/bmpWidth;
248
      float factor = (float)width/bmpWidth;
249

    
250
      mEffects.move( new Static3D(0,(height-h)/2,0) );
251
      mEffects.scale( factor );
252
      }
253

    
254
    mScreen.resize(width, height);
255
    }
256

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

    
259
  void doFrame(long frameTimeNs)
260
    {
261
    if( PlainMonaLisaSurfaceView.isPaused() )
262
      {
263
      android.util.Log.e("Thread", "Got here after onPaused- ignoring frame draw call!!");
264
      return;
265
      }
266

    
267
    eglCore.makeCurrent(eglSurface);
268

    
269
    GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
270
    mScreen.render( System.currentTimeMillis() );
271

    
272
    eglCore.swapBuffers(eglSurface);
273
    }
274

    
275
  }
(5-5/5)