Project

General

Profile

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

examples / src / main / java / org / distorted / examples / starwars / StarWarsRenderer.java @ 5a683295

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.starwars;
21

    
22
import java.io.IOException;
23
import java.io.InputStream;
24
import java.util.Random;
25

    
26
import javax.microedition.khronos.egl.EGLConfig;
27
import javax.microedition.khronos.opengles.GL10;
28

    
29
import org.distorted.examples.R;
30

    
31
import org.distorted.library.effect.FragmentEffectAlpha;
32
import org.distorted.library.effect.MatrixEffectMove;
33
import org.distorted.library.effect.MatrixEffectRotate;
34
import org.distorted.library.effect.MatrixEffectScale;
35
import org.distorted.library.main.DistortedNode;
36
import org.distorted.library.main.DistortedScreen;
37
import org.distorted.library.mesh.MeshQuad;
38
import org.distorted.library.type.Dynamic1D;
39
import org.distorted.library.type.Dynamic3D;
40
import org.distorted.library.type.Static1D;
41
import org.distorted.library.type.Static3D;
42
import org.distorted.library.message.EffectListener;
43
import org.distorted.library.main.DistortedLibrary;
44
import org.distorted.library.main.DistortedTexture;
45
import org.distorted.library.main.DistortedEffects;
46

    
47
import android.graphics.Bitmap;
48
import android.graphics.BitmapFactory;
49
import android.graphics.Canvas;
50
import android.graphics.Paint;
51
import android.graphics.Typeface;
52
import android.opengl.GLES31;
53
import android.opengl.GLSurfaceView;
54

    
55
///////////////////////////////////////////////////////////////////////////////////////////////////
56

    
57
class StarWarsRenderer implements GLSurfaceView.Renderer, EffectListener
58
  {
59
  private final String[] mGFFAString = 
60
         
61
            { "A long time ago, in a galaxy far,",
62
              "far away...." };                    // yes, there really was a four-dot ellipsis
63

    
64
  private final String[] mCRAWLString = 
65
      
66
            { "It is a period of civil war.",      // in the original 1977 version, there was no 
67
              "Rebel spaceships, striking",        // 'Episode IV New Hope' subtitle line before
68
              "from a hidden base, have",          // the crawl. Lets keep to the classic.
69
              "won their first victory",
70
              "against the evil Galactic",
71
              "Empire.",
72
              "",
73
              "During the battle, rebel",
74
              "spies managed to steal",
75
              "secret plans to the Empire's",
76
              "ultimate weapon, the",
77
              "DEATH STAR, an armored",
78
              "space station with enough",
79
              "power to destroy an entire",
80
              "planet.",
81
              "",
82
              "Pursued by the Empire's",
83
              "sinister agents, Princess",
84
              "Leia races home aboard her",
85
              "starship, custodian of the",
86
              "stolen plans that can save",
87
              "her people and restore",
88
              "freedom to the galaxy...." };      // four-dot.
89
   
90
  private final int NUM_STARS = 40;
91
   
92
  private final int CRAWL_COLOR = 0xffffe81f;
93
  private final int GFFA_COLOR  = 0xff0000ff;
94
  private final int FONT_HEIGHT      = 40;
95
  private final int VERTICAL_SPACING = 10;
96
  private final String CRAWL_TYPEFACE = "News Gothic";
97
   
98
  private final int CRAWL_WIDTH = 500;
99
  private final int CRAWL_HEIGHT= (FONT_HEIGHT+VERTICAL_SPACING)*(mCRAWLString.length+1);
100
   
101
  private final int GFFA_WIDTH = 600;
102
  private final int GFFA_HEIGHT= (FONT_HEIGHT+VERTICAL_SPACING)*(mGFFAString.length+1);
103
   
104
  private final float CRAWL_ANGLE = -30.0f;
105
  private final float FOV_ANGLE   =  60.0f;
106

    
107
  private GLSurfaceView mView;
108
  private DistortedTexture mGFFATexture, mLogoTexture, mCrawlTexture, mCrawlBackgroundTexture, mStarTexture;
109
  private DistortedEffects mGFFAEffects, mLogoEffects, mCrawlEffects, mCrawlBackgroundEffects;
110
  private DistortedEffects[] mStarEffects;
111
  private DistortedNode mBackground;
112
  private DistortedScreen mScreen;
113
  private MeshQuad mQuad;
114

    
115
  private long alphaEffectID, scaleEffectID, moveEffectID;
116
  private Random mRnd = new Random(0);
117
  private int mWidth, mHeight;
118
  private float mLogoRatio;
119
  private int mCrawlBackgroundW, mCrawlBackgroundH;
120

    
121
///////////////////////////////////////////////////////////////////////////////////////////////////
122

    
123
  StarWarsRenderer(GLSurfaceView v)
124
    {
125
    mView = v;
126

    
127
    mQuad = new MeshQuad();
128

    
129
    mGFFAEffects            = new DistortedEffects();
130
    mLogoEffects            = new DistortedEffects();
131
    mCrawlEffects           = new DistortedEffects();
132
    mCrawlBackgroundEffects = new DistortedEffects();
133

    
134
    if( NUM_STARS>0 )
135
      {
136
      mStarEffects = new DistortedEffects[NUM_STARS];
137
      mStarEffects[0] = new DistortedEffects();
138

    
139
      for (int i = 1; i < NUM_STARS; i++)
140
        mStarEffects[i] = new DistortedEffects(mStarEffects[0], DistortedLibrary.CLONE_VERTEX);
141
      }
142

    
143
    mScreen = new DistortedScreen();
144
    mScreen.setProjection(FOV_ANGLE, 0.02f);
145
    }
146

    
147
///////////////////////////////////////////////////////////////////////////////////////////////////
148

    
149
  public void onPause()
150
    {
151
    mWidth = 0;
152
    mHeight= 0;
153
    }
154

    
155
///////////////////////////////////////////////////////////////////////////////////////////////////
156
   
157
  public void onDrawFrame(GL10 glUnused) 
158
    {
159
    mScreen.render(System.currentTimeMillis());
160
    }
161

    
162
///////////////////////////////////////////////////////////////////////////////////////////////////
163
    
164
  public void onSurfaceChanged(GL10 glUnused, int width, int height) 
165
    {
166
    if( mWidth!=width || mHeight!=height )  // after onPause() we get 2 calls here
167
      {
168
      mWidth = width;
169
      mHeight= height;
170

    
171
      mGFFAEffects.abortAllEffects();
172
      mLogoEffects.abortAllEffects();
173
      mCrawlEffects.abortAllEffects();
174
      mCrawlBackgroundEffects.abortAllEffects();
175

    
176
      for(int i=0; i<NUM_STARS; i++) mStarEffects[i].abortAllEffects();
177

    
178
      mScreen.detachAll();
179
      setupScreen(width,height);
180
      mScreen.resize(width, height);
181
      }
182
    }
183

    
184
///////////////////////////////////////////////////////////////////////////////////////////////////
185
    
186
  public void onSurfaceCreated(GL10 glUnused, EGLConfig config) 
187
    {
188
    setupBitmaps();
189

    
190
    FragmentEffectAlpha.enable();
191

    
192
    try
193
      {
194
      DistortedLibrary.onCreate(mView.getContext());
195
      }
196
    catch(Exception ex)
197
      {
198
      android.util.Log.e("Star Wars", ex.getMessage() );
199
      }
200
    }
201
    
202
///////////////////////////////////////////////////////////////////////////////////////////////////
203

    
204
  private void setupScreen(int scrW, int scrH)
205
    {
206
    double angleA = (90.0f - FOV_ANGLE/2              ) * Math.PI/180;
207
    double angleB = (90.0f - FOV_ANGLE/2 + CRAWL_ANGLE) * Math.PI/180;
208

    
209
    if( mCrawlBackgroundTexture!=null ) mCrawlBackgroundTexture.markForDeletion();
210
    mCrawlBackgroundTexture = new DistortedTexture();
211

    
212
    mCrawlBackgroundW = scrW;
213
    mCrawlBackgroundH = (int)(scrH*Math.sin(angleA)/Math.sin(angleB));
214

    
215
    int randomA, randomX, randomY, randomTime;
216
    float randomS, randomAlpha1, randomAlpha2;
217
       
218
    Static3D center = new Static3D(0,0,0);
219
    Static3D axis   = new Static3D(0,0,1);
220
    Static1D alphaNoise = new Static1D(0.4f);
221

    
222
    for(int i=0; i<NUM_STARS; i++)
223
      {
224
      randomX = mRnd.nextInt(scrW) - scrW/2;
225
      randomY = mRnd.nextInt(scrH) - scrH/2;
226
      randomS = (0.2f+ 0.8f*mRnd.nextFloat())*20;
227
      randomA = (int)(180*mRnd.nextFloat());
228
      randomAlpha1 = 0.2f + 0.8f*mRnd.nextFloat();
229
      randomAlpha2 = 0.8f + 0.2f*mRnd.nextFloat();
230
      randomTime = 500+mRnd.nextInt(2000);
231

    
232
      mStarEffects[i].apply( new MatrixEffectRotate(new Static1D(randomA), axis, center) );
233
      mStarEffects[i].apply( new MatrixEffectScale(randomS) );
234
      mStarEffects[i].apply( new MatrixEffectMove(new Static3D(randomX,randomY,0)) );
235

    
236
      Dynamic1D di = new Dynamic1D(randomTime,0.0f);
237
      di.setNoise(alphaNoise);
238
      di.add(new Static1D(randomAlpha1));
239
      di.add(new Static1D(randomAlpha2));
240
      
241
      mStarEffects[i].apply( new FragmentEffectAlpha(di) );
242
      
243
      mScreen.attach(mStarTexture, mStarEffects[i], mQuad);
244
      }
245

    
246
    Dynamic1D di = new Dynamic1D(6000,0.5f);
247
    di.add(new Static1D(1.0f));
248
    di.add(new Static1D(1.0f));
249
    di.add(new Static1D(0.0f));
250

    
251
    FragmentEffectAlpha alpha = new FragmentEffectAlpha(di);
252
    alpha.notifyWhenFinished(this);
253
    alphaEffectID = alpha.getID();
254

    
255
    Static3D scale = new Static3D(0.5f*scrW, 0.5f*scrW * GFFA_HEIGHT / GFFA_WIDTH, 1);
256

    
257
    mGFFAEffects.apply( new MatrixEffectScale(scale) );
258
    mGFFAEffects.apply( new MatrixEffectMove(new Static3D(-scrW/3 + GFFA_WIDTH/2 ,scrH/6,0)) );
259
    mGFFAEffects.apply( alpha );
260
      
261
    mScreen.attach(mGFFATexture, mGFFAEffects, mQuad);
262
    }
263
    
264
///////////////////////////////////////////////////////////////////////////////////////////////////
265

    
266
  private void setupBitmaps()
267
    {
268
    InputStream is1 = mView.getContext().getResources().openRawResource(R.raw.starwars);
269
    InputStream is2 = mView.getContext().getResources().openRawResource(R.raw.star);
270
    
271
    Bitmap bitmapStar, bitmapGFFA, bitmapLogo, bitmapText;
272
      
273
    try 
274
      {
275
      bitmapLogo = BitmapFactory.decodeStream(is1);
276
      bitmapStar = BitmapFactory.decodeStream(is2);
277
      } 
278
    finally 
279
      {
280
      try 
281
        {
282
        is1.close();
283
        is2.close();
284
        } 
285
      catch(IOException e) { }
286
      } 
287
      
288
    Paint paint = new Paint();
289
    paint.setAntiAlias(true);
290
    paint.setTextAlign(Paint.Align.LEFT);
291
    paint.setTextSize(FONT_HEIGHT);
292
    paint.setColor(GFFA_COLOR);
293
      
294
    Typeface tf = Typeface.create(CRAWL_TYPEFACE, Typeface.BOLD);
295
    paint.setTypeface(tf);     
296
 
297
    ///// create GFFA ///////////////////
298
    if( mGFFATexture==null ) mGFFATexture  = new DistortedTexture();
299
    bitmapGFFA = Bitmap.createBitmap(GFFA_WIDTH,GFFA_HEIGHT,Bitmap.Config.ARGB_8888);
300
    bitmapGFFA.eraseColor(0x00000000);
301
    Canvas gffaCanvas = new Canvas(bitmapGFFA);
302
      
303
    for(int i=0; i<mGFFAString.length; i++)
304
      {
305
      gffaCanvas.drawText(mGFFAString[i], 0, (i+1)*(FONT_HEIGHT+VERTICAL_SPACING), paint);  
306
      }
307
  
308
    mGFFATexture.setTexture(bitmapGFFA);
309
      
310
    ///// create Logo ///////////////////
311
    if( mLogoTexture==null ) mLogoTexture = new DistortedTexture();
312
    mLogoTexture.setTexture(bitmapLogo);
313
    mLogoRatio = (float)bitmapLogo.getWidth()/bitmapLogo.getHeight();
314

    
315
    ///// create CRAWL //////////////////
316
    if( mCrawlTexture==null ) mCrawlTexture = new DistortedTexture();
317
    bitmapText = Bitmap.createBitmap(CRAWL_WIDTH,CRAWL_HEIGHT,Bitmap.Config.ARGB_8888);
318
    bitmapText.eraseColor(0x00000000);
319
    Canvas textCanvas = new Canvas(bitmapText);
320
    paint.setColor(CRAWL_COLOR);
321
  
322
    for(int i=0; i<mCRAWLString.length; i++)
323
      {
324
      displayJustified(mCRAWLString[i], 0, (i+1)*(FONT_HEIGHT+VERTICAL_SPACING), CRAWL_WIDTH, textCanvas, paint);  
325
      }
326
      
327
    mCrawlTexture.setTexture(bitmapText);
328
      
329
    ///// create Stars ///////////////////
330
    if( mStarTexture==null ) mStarTexture = new DistortedTexture();
331
    mStarTexture.setTexture(bitmapStar);
332
    }
333
 
334
///////////////////////////////////////////////////////////////////////////////////////////////////
335

    
336
  private void displayJustified(String str, int x, int y, int length, Canvas c, Paint paint)
337
    { 
338
    int len       = str.length();
339
    int numspaces = retNumSpaces(str);
340
    
341
    if( len>0 && str.charAt(len-1) == ' ' ) numspaces--;
342

    
343
    float left=x,w = (numspaces>0 ? (length-paint.measureText(str))/numspaces : 0);
344
    String tmp;
345
    int begin,end=0;
346

    
347
    while( end<len )
348
      {
349
      begin=end;
350
      end = str.indexOf(' ', begin)+1;
351
      if( end<=0 ) end = len;
352

    
353
      tmp = str.substring(begin,end);
354
      c.drawText( tmp, left, y, paint);
355
      left+= (paint.measureText(tmp)+w);
356
      }  
357
    }
358

    
359
///////////////////////////////////////////////////////////////////////////////////////////////////
360
   
361
  private int retNumSpaces(String str)
362
    {
363
    int begin=0, ret=0;
364

    
365
    while( true )
366
      {
367
      begin = str.indexOf(' ', begin) +1;
368

    
369
      if( begin>0 ) ret++;
370
      else break;
371
      }
372

    
373
    return ret;
374
    }
375
    
376
///////////////////////////////////////////////////////////////////////////////////////////////////
377

    
378
  public void effectFinished(final long effectID)
379
    {
380
    if( effectID == alphaEffectID )
381
      {
382
      mScreen.detach(mGFFAEffects);
383
      mGFFATexture.markForDeletion();
384

    
385
      int screenW = mScreen.getWidth();
386
      int initSize= (int)(3.00f*screenW);
387
      int finaSize= (int)(0.01f*screenW);
388
      
389
      Dynamic3D di = new Dynamic3D(10000,0.5f);
390
      di.add(new Static3D(initSize,initSize/mLogoRatio,1));
391
      di.add(new Static3D(finaSize,finaSize/mLogoRatio,1));
392
      MatrixEffectScale scale = new MatrixEffectScale(di);
393
      scale.notifyWhenFinished(this);
394
      scaleEffectID = scale.getID();
395
      mLogoEffects.apply( scale );
396
      mScreen.attach(mLogoTexture, mLogoEffects, mQuad);
397
      }
398
    else if( effectID == scaleEffectID )
399
      {
400
      mScreen.detach(mLogoEffects);
401
      mLogoTexture.markForDeletion();
402

    
403
      float scale = mCrawlBackgroundW/CRAWL_WIDTH;
404

    
405
      mCrawlBackgroundEffects.apply( new MatrixEffectScale( new Static3D(mCrawlBackgroundW, mCrawlBackgroundH, 1) ) );
406
      mCrawlBackgroundEffects.apply( new MatrixEffectRotate(new Static1D(CRAWL_ANGLE), new Static3D(1,0,0), new Static3D(0,-mCrawlBackgroundH/2,0)) );
407
      mCrawlBackgroundEffects.apply( new MatrixEffectMove(new Static3D( 0, (mCrawlBackgroundH-mHeight)/2, 0)) );
408

    
409
      final float transpDist = 5;
410
      Static3D center = new Static3D( 0, transpDist-0.5f, 0 );
411
      Static3D region = new Static3D( transpDist, transpDist, transpDist );
412
      mCrawlBackgroundEffects.apply( new FragmentEffectAlpha(new Static1D(1-transpDist*0.6f), center, region, true) );
413

    
414
      Dynamic3D di = new Dynamic3D(70000,0.5f);
415
      di.add(new Static3D(0, -(scale*CRAWL_HEIGHT+mCrawlBackgroundH)/2, 0));
416
      di.add(new Static3D(0, +(scale*CRAWL_HEIGHT+mCrawlBackgroundH)/2, 0));
417
      MatrixEffectMove move = new MatrixEffectMove(di);
418
      move.notifyWhenFinished(this);
419
      moveEffectID = move.getID();
420

    
421
      mCrawlEffects.apply( new MatrixEffectScale(new Static3D(scale*CRAWL_WIDTH,scale*CRAWL_HEIGHT,1)) );
422
      mCrawlEffects.apply( move );
423

    
424
      mBackground = mScreen.attach(mCrawlBackgroundTexture, mCrawlBackgroundEffects, mQuad);
425
      mBackground.resizeFBO(mCrawlBackgroundW,mCrawlBackgroundH);
426
      mBackground.attach(mCrawlTexture, mCrawlEffects, mQuad);
427
      mBackground.glDisable(GLES31.GL_DEPTH_TEST);
428
      mBackground.glDepthMask(false);
429
      }
430
    else if( effectID == moveEffectID )
431
      {
432
      mScreen.detach(mBackground);
433
      mBackground.detach(mCrawlEffects);
434
      mCrawlTexture.markForDeletion();
435
      mCrawlBackgroundEffects.abortAllEffects();
436
      mCrawlBackgroundTexture.markForDeletion();
437
      }
438
    }
439
  }
(2-2/3)