Project

General

Profile

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

examples / src / main / java / org / distorted / examples / starwars / StarWarsRenderer.java @ 687263cc

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.MeshRectangles;
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 MeshRectangles mQuad;
114

    
115
  private long alphaEffectID, scaleEffectID, moveEffectID;
116
  private Random mRnd = new Random(0);
117
  private int mWidth, mHeight;
118

    
119
///////////////////////////////////////////////////////////////////////////////////////////////////
120

    
121
  StarWarsRenderer(GLSurfaceView v)
122
    {
123
    mView = v;
124

    
125
    mQuad = new MeshRectangles(1,1);
126

    
127
    mGFFAEffects            = new DistortedEffects(1);
128
    mLogoEffects            = new DistortedEffects(1);
129
    mCrawlEffects           = new DistortedEffects(1);
130
    mCrawlBackgroundEffects = new DistortedEffects(1);
131

    
132
    if( NUM_STARS>0 )
133
      {
134
      mStarEffects = new DistortedEffects[NUM_STARS];
135
      mStarEffects[0] = new DistortedEffects(1);
136

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

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

    
145
///////////////////////////////////////////////////////////////////////////////////////////////////
146

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

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

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

    
169
      mGFFAEffects.abortAllEffects();
170
      mLogoEffects.abortAllEffects();
171
      mCrawlEffects.abortAllEffects();
172
      mCrawlBackgroundEffects.abortAllEffects();
173

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

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

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

    
188
    FragmentEffectAlpha.enable();
189

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

    
202
  private void setupScreen(int w, int h)
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
    mCrawlBackgroundEffects.setStretch(w,(int)(h*Math.sin(angleA)/Math.sin(angleB)),0);
211

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

    
219
    for(int i=0; i<NUM_STARS; i++)
220
      {
221
      randomX = mRnd.nextInt(w);
222
      randomY = mRnd.nextInt(h);
223
      randomS = 0.2f+ 0.8f*mRnd.nextFloat();
224
      randomA = (int)(180*mRnd.nextFloat());
225
      randomAlpha1 = 0.2f + 0.8f*mRnd.nextFloat();
226
      randomAlpha2 = 0.8f + 0.2f*mRnd.nextFloat();
227
      randomTime = 500+mRnd.nextInt(2000);
228

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

    
233
      Dynamic1D di = new Dynamic1D(randomTime,0.0f);
234
      di.setNoise(alphaNoise);
235
      di.add(new Static1D(randomAlpha1));
236
      di.add(new Static1D(randomAlpha2));
237
      
238
      mStarEffects[i].apply( new FragmentEffectAlpha(di) );
239
      
240
      mScreen.attach(mStarTexture, mStarEffects[i], mQuad);
241
      }
242
      
243
    float scale = (0.5f*w/mGFFAEffects.getStartchX());
244
    
245
    Dynamic1D di = new Dynamic1D(6000,0.5f);
246
    di.add(new Static1D(1.0f));
247
    di.add(new Static1D(1.0f));
248
    di.add(new Static1D(0.0f));
249

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

    
254
    mGFFAEffects.apply( new MatrixEffectScale(scale) );
255
    mGFFAEffects.apply( new MatrixEffectMove(new Static3D(w/5,2*h/3,0)) );
256
    mGFFAEffects.apply( alpha );
257
      
258
    mScreen.attach(mGFFATexture, mGFFAEffects, mQuad);
259
    }
260
    
261
///////////////////////////////////////////////////////////////////////////////////////////////////
262

    
263
  private void setupBitmaps()
264
    {
265
    InputStream is1 = mView.getContext().getResources().openRawResource(R.raw.starwars);
266
    InputStream is2 = mView.getContext().getResources().openRawResource(R.raw.star);
267
    
268
    Bitmap bitmapStar, bitmapGFFA, bitmapLogo, bitmapText;
269
      
270
    try 
271
      {
272
      bitmapLogo = BitmapFactory.decodeStream(is1);
273
      bitmapStar = BitmapFactory.decodeStream(is2);
274
      } 
275
    finally 
276
      {
277
      try 
278
        {
279
        is1.close();
280
        is2.close();
281
        } 
282
      catch(IOException e) { }
283
      } 
284
      
285
    Paint paint = new Paint();
286
    paint.setAntiAlias(true);
287
    paint.setTextAlign(Paint.Align.LEFT);
288
    paint.setTextSize(FONT_HEIGHT);
289
    paint.setColor(GFFA_COLOR);
290
      
291
    Typeface tf = Typeface.create(CRAWL_TYPEFACE, Typeface.BOLD);
292
    paint.setTypeface(tf);     
293
 
294
    ///// create GFFA ///////////////////
295
    mGFFAEffects.setStretch(GFFA_WIDTH,GFFA_HEIGHT,0);
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
    mLogoEffects.setStretch(bitmapLogo.getWidth(),bitmapLogo.getHeight(),0);
310
    if( mLogoTexture==null ) mLogoTexture  = new DistortedTexture();
311
    mLogoTexture.setTexture(bitmapLogo);
312

    
313
    ///// create CRAWL //////////////////
314
    mCrawlEffects.setStretch(CRAWL_WIDTH,CRAWL_HEIGHT,0);
315
    if( mCrawlTexture==null ) mCrawlTexture = new DistortedTexture();
316
    bitmapText = Bitmap.createBitmap(CRAWL_WIDTH,CRAWL_HEIGHT,Bitmap.Config.ARGB_8888);
317
    bitmapText.eraseColor(0x00000000);
318
    Canvas textCanvas = new Canvas(bitmapText);
319
    paint.setColor(CRAWL_COLOR);
320
  
321
    for(int i=0; i<mCRAWLString.length; i++)
322
      {
323
      displayJustified(mCRAWLString[i], 0, (i+1)*(FONT_HEIGHT+VERTICAL_SPACING), CRAWL_WIDTH, textCanvas, paint);  
324
      }
325
      
326
    mCrawlTexture.setTexture(bitmapText);
327
      
328
    ///// create Stars ///////////////////
329
    mStarEffects[0].setStretch(bitmapStar.getWidth(),bitmapStar.getHeight(),0);
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 screenH=mScreen.getHeight();
387
        
388
      int logoW = mLogoEffects.getStartchX();
389
      int logoH = mLogoEffects.getStartchY();
390
      
391
      int initSize= (int)(3.0f*screenW/logoW);
392
      int finaSize= (int)(0.1f*screenW/logoW);
393
      
394
      Dynamic3D di = new Dynamic3D(10000,0.5f);
395
      di.add(new Static3D(initSize,initSize,1));
396
      di.add(new Static3D(finaSize,finaSize,1));
397
      MatrixEffectScale scale = new MatrixEffectScale(di);
398
      scale.notifyWhenFinished(this);
399
      scaleEffectID = scale.getID();
400

    
401
      mLogoEffects.apply( new MatrixEffectMove(new Static3D(-logoW/2,-logoH/2,0)) );
402
      mLogoEffects.apply( scale );
403
      mLogoEffects.apply( new MatrixEffectMove(new Static3D(screenW/2,screenH/2,0)) );
404

    
405
      mScreen.attach(mLogoTexture, mLogoEffects,mQuad);
406
      }
407
    else if( effectID == scaleEffectID )
408
      {
409
      mScreen.detach(mLogoEffects);
410
      mLogoTexture.markForDeletion();
411
        
412
      int crawlW = mCrawlEffects.getStartchX();
413
      int crawlH = mCrawlEffects.getStartchY();
414
      int screenW= mScreen.getWidth();
415
      int backH  = mCrawlBackgroundEffects.getStartchY();
416
      float scale= (float)screenW/crawlW;
417

    
418
      mCrawlBackgroundEffects.apply( new MatrixEffectRotate(new Static1D(CRAWL_ANGLE), new Static3D(1,0,0), new Static3D(screenW/2,0,0)) );
419

    
420
      final int transpDist = 5;
421
      Static3D center = new Static3D( screenW/2 , transpDist*backH , 0 );
422
      Static3D region = new Static3D( transpDist*backH , transpDist*backH , transpDist*backH );
423
      mCrawlBackgroundEffects.apply( new FragmentEffectAlpha(new Static1D(1-transpDist*0.6f), center, region, true) );
424

    
425
      Dynamic3D di = new Dynamic3D(70000,0.5f);
426
      di.add(new Static3D(screenW/2,-scale*crawlH/2        , 0));
427
      di.add(new Static3D(screenW/2,+scale*crawlH/2 + backH, 0));
428
      MatrixEffectMove move = new MatrixEffectMove(di);
429
      move.notifyWhenFinished(this);
430
      moveEffectID = move.getID();
431

    
432
      mCrawlEffects.apply( new MatrixEffectMove(new Static3D(-crawlW/2,-crawlH/2,0)) );
433
      mCrawlEffects.apply( new MatrixEffectScale(new Static3D(scale,scale,scale)) );
434
      mCrawlEffects.apply( move );
435

    
436
      mBackground = mScreen.attach(mCrawlBackgroundTexture, mCrawlBackgroundEffects,mQuad);
437
      mBackground.attach(mCrawlTexture, mCrawlEffects,mQuad);
438
      mBackground.glDisable(GLES31.GL_DEPTH_TEST);
439
      mBackground.glDepthMask(false);
440
      }
441
    else if( effectID == moveEffectID )
442
      {
443
      mScreen.detach(mBackground);
444
      mBackground.detach(mCrawlEffects);
445
      mCrawlTexture.markForDeletion();
446
      mCrawlBackgroundEffects.abortAllEffects();
447
      mCrawlBackgroundTexture.markForDeletion();
448
      }
449
    }
450
  }
(2-2/3)