Project

General

Profile

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

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

1
package org.distorted.examples.plainmonalisa;
2

    
3
import android.graphics.Bitmap;
4
import android.graphics.BitmapFactory;
5
import android.opengl.EGL14;
6
import android.opengl.EGLSurface;
7
import android.opengl.GLES20;
8
import android.os.Looper;
9
import android.os.Trace;
10
import android.util.Log;
11
import android.view.Surface;
12
import android.view.SurfaceHolder;
13
import android.view.SurfaceView;
14

    
15
import org.distorted.library.Distorted;
16
import org.distorted.library.DistortedBitmap;
17
import org.distorted.library.EffectTypes;
18
import org.distorted.library.Float2D;
19
import org.distorted.library.Float3D;
20
import org.distorted.library.Float4D;
21
import org.distorted.examples.R;
22

    
23
import java.io.IOException;
24
import java.io.InputStream;
25

    
26
///////////////////////////////////////////////////////////////////////////////////////////////////
27
/**
28
 * This class handles all OpenGL rendering.
29
 * <p>
30
 * Start the render thread after the Surface has been created.
31
 */
32
public class RenderThread extends Thread
33
  {
34
  private static final String TAG = "RenderThread";
35

    
36
  // Object must be created on render thread to get correct Looper, but is used from
37
  // UI thread, so we need to declare it volatile to ensure the UI thread sees a fully
38
  // constructed object.
39
  private volatile RenderHandler mHandler;
40

    
41
  // Used to wait for the thread to start.
42
  private Object mStartLock = new Object();
43
  private boolean mReady = false;
44
  private volatile SurfaceHolder mSurfaceHolder;  // may be updated by UI thread
45
  private EglCore eglCore;
46
  private EGLSurface eglSurface;
47

    
48
  private DistortedBitmap monaLisa;
49
  private int bmpHeight, bmpWidth;
50

    
51
  private Float2D pLeft, pRight;
52
  private Float4D rLeft, rRight;
53
  private Float3D vLeft, vRight;
54

    
55
  SurfaceView mView;
56

    
57
///////////////////////////////////////////////////////////////////////////////////////////////////
58
  /**
59
   * Pass in the SurfaceView's SurfaceHolder.  Note the Surface may not yet exist.
60
   */
61
  public RenderThread(SurfaceHolder holder, SurfaceView view)
62
    {
63
    mSurfaceHolder = holder;
64
    mView = view;
65

    
66
    pLeft = new Float2D( 90, 258);
67
    pRight= new Float2D(176, 255);
68

    
69
    rLeft = new Float4D(-10,-10,25,25);
70
    rRight= new Float4D( 10, -5,25,25);
71

    
72
    vLeft = new Float3D(-20,-20,0);
73
    vRight= new Float3D( 20,-10,0);
74
    }
75

    
76
///////////////////////////////////////////////////////////////////////////////////////////////////
77
  /**
78
   * Thread entry point.
79
   * <p>
80
   * The thread should not be started until the Surface associated with the SurfaceHolder
81
   * has been created.  That way we don't have to wait for a separate "surface created"
82
   * message to arrive.
83
   */
84
  @Override
85
  public void run()
86
    {
87
    Looper.prepare();
88
    mHandler = new RenderHandler(this);
89
    eglCore = new EglCore(null, EglCore.FLAG_RECORDABLE | EglCore.FLAG_TRY_GLES3);
90

    
91
    synchronized (mStartLock)
92
      {
93
      mReady = true;
94
      mStartLock.notify();    // signal waitUntilReady()
95
      }
96

    
97
    Looper.loop();
98
    Log.d(TAG, "looper quit");
99

    
100
    checkGlError("releaseGl start");
101

    
102
    if (eglSurface != null)
103
      {
104
      eglCore.releaseSurface(eglSurface);
105
      eglSurface = EGL14.EGL_NO_SURFACE;
106
      }
107

    
108
    checkGlError("releaseGl done");
109

    
110
    eglCore.makeNothingCurrent();
111
    eglCore.release();
112

    
113
    synchronized (mStartLock)
114
      {
115
      mReady = false;
116
      }
117
    }
118

    
119
///////////////////////////////////////////////////////////////////////////////////////////////////
120
  /**
121
   * Waits until the render thread is ready to receive messages.
122
   * <p>
123
   * Call from the UI thread.
124
   */
125
  public void waitUntilReady()
126
    {
127
    synchronized (mStartLock)
128
      {
129
      while (!mReady)
130
        {
131
        try
132
          {
133
          mStartLock.wait();
134
          }
135
        catch (InterruptedException ie) { /* not expected */ }
136
        }
137
      }
138
    }
139

    
140
///////////////////////////////////////////////////////////////////////////////////////////////////
141
  /**
142
   * Shuts everything down.
143
   */
144
  void shutdown()
145
    {
146
    Log.d(TAG, "shutdown");
147
    Looper.myLooper().quit();
148
    }
149

    
150
///////////////////////////////////////////////////////////////////////////////////////////////////
151
  /**
152
   * Returns the render thread's Handler.  This may be called from any thread.
153
   */
154
  public RenderHandler getHandler()
155
      {
156
      return mHandler;
157
      }
158

    
159
///////////////////////////////////////////////////////////////////////////////////////////////////
160
  /**
161
   * Prepares the surface.
162
   */
163
  void surfaceCreated()
164
    {
165
    Surface surface = mSurfaceHolder.getSurface();
166

    
167
    eglSurface = eglCore.createWindowSurface(surface);
168
    eglCore.makeCurrent(eglSurface);
169

    
170
    InputStream is = mView.getContext().getResources().openRawResource(R.raw.monalisa);
171
    Bitmap bmp;
172

    
173
    try
174
      {
175
      bmp = BitmapFactory.decodeStream(is);
176
      }
177
    finally
178
      {
179
      try
180
        {
181
        is.close();
182
        }
183
      catch(IOException io) {}
184
      }
185

    
186
    monaLisa = new DistortedBitmap(bmp, 10);
187
    monaLisa.distort( vLeft, rLeft , pLeft, 1000, 0);
188
    monaLisa.distort(vRight, rRight, pRight,1000, 0);
189

    
190
    bmpHeight = bmp.getHeight();
191
    bmpWidth  = bmp.getWidth();
192

    
193
    try
194
      {
195
      Distorted.onSurfaceCreated(mView.getContext());
196
      }
197
    catch(Exception ex)
198
      {
199
      Log.e("MonaLisa", ex.getMessage() );
200
      }
201
    }
202

    
203
///////////////////////////////////////////////////////////////////////////////////////////////////
204

    
205
  void surfaceChanged(int width, int height)
206
    {
207
    Log.d(TAG, "surfaceChanged " + width + "x" + height);
208

    
209
    monaLisa.abortEffects(EffectTypes.MATRIX);
210

    
211
    if( bmpHeight/bmpWidth > height/width )
212
      {
213
      int w = (height*bmpWidth)/bmpHeight;
214
      monaLisa.move((width-w)/2 ,0, 0);
215
      monaLisa.scale((float)height/bmpHeight);
216
      }
217
    else
218
      {
219
      int h = (width*bmpHeight)/bmpWidth;
220
      monaLisa.move(0 ,(height-h)/2, 0);
221
      monaLisa.scale((float)width/bmpWidth);
222
      }
223

    
224
    Distorted.onSurfaceChanged(width, height);
225
    }
226

    
227
///////////////////////////////////////////////////////////////////////////////////////////////////
228

    
229
  public void doFrame(long frameTimeNs)
230
    {
231
    Trace.beginSection("doFrame draw");
232
    eglCore.makeCurrent(eglSurface);
233

    
234
    GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
235
    GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
236
    monaLisa.draw(System.currentTimeMillis());
237

    
238
    eglCore.swapBuffers(eglSurface);
239
    Trace.endSection();
240
    }
241

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

    
244
  public static void checkGlError(String op)
245
    {
246
    int error = GLES20.glGetError();
247

    
248
    if (error != GLES20.GL_NO_ERROR)
249
      {
250
      String msg = op + ": glError 0x" + Integer.toHexString(error);
251
      Log.e(TAG, msg);
252
      throw new RuntimeException(msg);
253
      }
254
    }
255
  }
256
///////////////////////////////////////////////////////////////////////////////////////////////////
(5-5/5)