Project

General

Profile

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

examples / src / main / java / org / distorted / examples / starwars / StarWarsRenderer.java @ 061449ed

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, DistortedLibrary.ExceptionListener
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
    FragmentEffectAlpha.enable();
190
    DistortedLibrary.onCreate(mView.getContext(), this);
191
    }
192

    
193
///////////////////////////////////////////////////////////////////////////////////////////////////
194

    
195
  public void distortedException(Exception ex)
196
    {
197
    android.util.Log.e("StarWars", ex.getMessage() );
198
    }
199

    
200
///////////////////////////////////////////////////////////////////////////////////////////////////
201

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

    
207
    if( mCrawlBackgroundTexture!=null ) mCrawlBackgroundTexture.markForDeletion();
208
    mCrawlBackgroundTexture = new DistortedTexture();
209

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

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

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

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

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

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

    
249
    FragmentEffectAlpha alpha = new FragmentEffectAlpha(di);
250
    alpha.notifyWhenFinished(this);
251
    alphaEffectID = alpha.getID();
252

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

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

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

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

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

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

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

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

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

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

    
367
      if( begin>0 ) ret++;
368
      else break;
369
      }
370

    
371
    return ret;
372
    }
373
    
374
///////////////////////////////////////////////////////////////////////////////////////////////////
375

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

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

    
401
      float scale = mCrawlBackgroundW/CRAWL_WIDTH;
402

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

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

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

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

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