Project

General

Profile

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

examples / src / main / java / org / distorted / examples / starwars / StarWarsRenderer.java @ f3ca895f

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();
128
    mLogoEffects            = new DistortedEffects();
129
    mCrawlEffects           = new DistortedEffects();
130
    mCrawlBackgroundEffects = new DistortedEffects();
131

    
132
    if( NUM_STARS>0 )
133
      {
134
      mStarEffects = new DistortedEffects[NUM_STARS];
135
      mStarEffects[0] = new DistortedEffects();
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(w,(int)(h*Math.sin(angleA)/Math.sin(angleB)));
209
       
210
    int randomA, randomX, randomY, randomTime;
211
    float randomS, randomAlpha1, randomAlpha2;
212
       
213
    Static3D center = new Static3D(0,0,0);
214
    Static3D axis   = new Static3D(0,0,1);
215
    Static1D alphaNoise = new Static1D(0.4f);
216

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

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

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

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

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

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

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

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

    
337
    float left=x,w = (numspaces>0 ? (length-paint.measureText(str))/numspaces : 0);
338
    String tmp;
339
    int begin,end=0;
340

    
341
    while( end<len )
342
      {
343
      begin=end;
344
      end = str.indexOf(' ', begin)+1;
345
      if( end<=0 ) end = len;
346

    
347
      tmp = str.substring(begin,end);
348
      c.drawText( tmp, left, y, paint);
349
      left+= (paint.measureText(tmp)+w);
350
      }  
351
    }
352

    
353
///////////////////////////////////////////////////////////////////////////////////////////////////
354
   
355
  private int retNumSpaces(String str)
356
    {
357
    int begin=0, ret=0;
358

    
359
    while( true )
360
      {
361
      begin = str.indexOf(' ', begin) +1;
362

    
363
      if( begin>0 ) ret++;
364
      else break;
365
      }
366

    
367
    return ret;
368
    }
369
    
370
///////////////////////////////////////////////////////////////////////////////////////////////////
371

    
372
  public void effectFinished(final long effectID)
373
    {
374
    if( effectID == alphaEffectID )
375
      {
376
      mScreen.detach(mGFFAEffects);
377
      mGFFATexture.markForDeletion();
378

    
379
      int screenW=mScreen.getWidth();
380
      int screenH=mScreen.getHeight();
381
        
382
      int logoW = mLogoTexture.getWidth();
383
      int logoH = mLogoTexture.getHeight();
384
      
385
      int initSize= (int)(3.0f*screenW/logoW);
386
      int finaSize= (int)(0.1f*screenW/logoW);
387
      
388
      Dynamic3D di = new Dynamic3D(10000,0.5f);
389
      di.add(new Static3D(initSize,initSize,1));
390
      di.add(new Static3D(finaSize,finaSize,1));
391
      MatrixEffectScale scale = new MatrixEffectScale(di);
392
      scale.notifyWhenFinished(this);
393
      scaleEffectID = scale.getID();
394

    
395
      mLogoEffects.apply( new MatrixEffectMove(new Static3D(-logoW/2,-logoH/2,0)) );
396
      mLogoEffects.apply( scale );
397
      mLogoEffects.apply( new MatrixEffectMove(new Static3D(screenW/2,screenH/2,0)) );
398

    
399
      mScreen.attach(mLogoTexture, mLogoEffects,mQuad);
400
      }
401
    else if( effectID == scaleEffectID )
402
      {
403
      mScreen.detach(mLogoEffects);
404
      mLogoTexture.markForDeletion();
405
        
406
      int crawlW = mCrawlTexture.getWidth();
407
      int crawlH = mCrawlTexture.getHeight();
408
      int screenW= mScreen.getWidth();
409
      int backH  = mCrawlBackgroundTexture.getHeight();
410
      float scale= (float)screenW/crawlW;
411

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

    
414
      final int transpDist = 5;
415
      Static3D center = new Static3D( screenW/2 , transpDist*backH , 0 );
416
      Static3D region = new Static3D( transpDist*backH , transpDist*backH , transpDist*backH );
417
      mCrawlBackgroundEffects.apply( new FragmentEffectAlpha(new Static1D(1-transpDist*0.6f), center, region, true) );
418

    
419
      Dynamic3D di = new Dynamic3D(70000,0.5f);
420
      di.add(new Static3D(screenW/2,-scale*crawlH/2        , 0));
421
      di.add(new Static3D(screenW/2,+scale*crawlH/2 + backH, 0));
422
      MatrixEffectMove move = new MatrixEffectMove(di);
423
      move.notifyWhenFinished(this);
424
      moveEffectID = move.getID();
425

    
426
      mCrawlEffects.apply( new MatrixEffectMove(new Static3D(-crawlW/2,-crawlH/2,0)) );
427
      mCrawlEffects.apply( new MatrixEffectScale(new Static3D(scale,scale,scale)) );
428
      mCrawlEffects.apply( move );
429

    
430
      mBackground = mScreen.attach(mCrawlBackgroundTexture, mCrawlBackgroundEffects,mQuad);
431
      mBackground.attach(mCrawlTexture, mCrawlEffects,mQuad);
432
      mBackground.glDisable(GLES31.GL_DEPTH_TEST);
433
      mBackground.glDepthMask(false);
434
      }
435
    else if( effectID == moveEffectID )
436
      {
437
      mScreen.detach(mBackground);
438
      mBackground.detach(mCrawlEffects);
439
      mCrawlTexture.markForDeletion();
440
      mCrawlBackgroundEffects.abortAllEffects();
441
      mCrawlBackgroundTexture.markForDeletion();
442
      }
443
    }
444
  }
(2-2/3)