Project

General

Profile

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

examples / src / main / java / org / distorted / examples / starwars / StarWarsRenderer.java @ 9d12dd4a

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.DistortedFramebuffer;
32
import org.distorted.library.GridFlat;
33
import org.distorted.library.EffectNames;
34
import org.distorted.library.type.Dynamic1D;
35
import org.distorted.library.type.Dynamic3D;
36
import org.distorted.library.DistortedTree;
37
import org.distorted.library.type.Static1D;
38
import org.distorted.library.type.Static3D;
39
import org.distorted.library.type.Static4D;
40
import org.distorted.library.message.EffectListener;
41
import org.distorted.library.message.EffectMessage;
42
import org.distorted.library.Distorted;
43
import org.distorted.library.DistortedTexture;
44
import org.distorted.library.DistortedEffects;
45

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

    
54
///////////////////////////////////////////////////////////////////////////////////////////////////
55

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

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

    
113
  private long gffaID, logoID, crawlID;
114
  private Random mRnd = new Random(0);
115
  private int mWidth, mHeight;
116

    
117
///////////////////////////////////////////////////////////////////////////////////////////////////
118

    
119
  StarWarsRenderer(GLSurfaceView v)
120
    {
121
    mView = v;
122

    
123
    mQuad = new GridFlat(1,1);
124

    
125
    mScreenEffects          = new DistortedEffects();
126
    mGFFAEffects            = new DistortedEffects();
127
    mLogoEffects            = new DistortedEffects();
128
    mCrawlEffects           = new DistortedEffects();
129
    mCrawlBackgroundEffects = new DistortedEffects();
130

    
131
    mStarEffects = new DistortedEffects[NUM_STARS];
132
    mStarEffects[0] = new DistortedEffects();
133

    
134
    for(int i=1; i<NUM_STARS; i++) mStarEffects[i] = new DistortedEffects(mStarEffects[0],Distorted.CLONE_VERTEX);
135

    
136
    mScreen = new DistortedFramebuffer(0);
137
    mScreen.setProjection(60.0f, 0.0f, 0.0f);
138
    }
139

    
140
///////////////////////////////////////////////////////////////////////////////////////////////////
141

    
142
  public void onPause()
143
    {
144
    mWidth = 0;
145
    mHeight= 0;
146
    }
147

    
148
///////////////////////////////////////////////////////////////////////////////////////////////////
149
   
150
  public void onDrawFrame(GL10 glUnused) 
151
    {
152
    GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
153
    mScreen.renderTo(mRoot,System.currentTimeMillis());
154
    }
155

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

    
165
      mScreenEffects.abortAllEffects();
166
      mGFFAEffects.abortAllEffects();
167
      mLogoEffects.abortAllEffects();
168
      mCrawlEffects.abortAllEffects();
169
      mCrawlBackgroundEffects.abortAllEffects();
170

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

    
173
      setupScreen(width,height);
174

    
175
      mScreen.resize(width, height);
176
      }
177
    }
178

    
179
///////////////////////////////////////////////////////////////////////////////////////////////////
180
    
181
  public void onSurfaceCreated(GL10 glUnused, EGLConfig config) 
182
    {
183
    GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
184

    
185
    setupBitmaps();
186

    
187
    try
188
      {
189
      Distorted.onSurfaceCreated(mView.getContext());
190
      }
191
    catch(Exception ex)
192
      {
193
      android.util.Log.e("Star Wars", ex.getMessage() );
194
      }
195
    }
196
    
197
///////////////////////////////////////////////////////////////////////////////////////////////////
198

    
199
  private void setupScreen(int w, int h)
200
    {
201
    mScreenTexture = new DistortedTexture(w,h);
202
    mRoot = new DistortedTree(mScreenTexture, mScreenEffects,mQuad);
203
      
204
    mCrawlBackgroundTexture = new DistortedTexture(w,(int)(Math.sqrt(3.0)*h));
205
       
206
    int randomA, randomX, randomY, randomTime;
207
    float randomS, randomAlpha1, randomAlpha2;
208
       
209
    Static3D center = new Static3D(0,0,0);
210
    Static3D axis   = new Static3D(0,0,1);
211
    Static1D alphaNoise = new Static1D(0.4f);
212

    
213
    for(int i=0; i<NUM_STARS; i++)
214
      {
215
      randomX = mRnd.nextInt(w);
216
      randomY = mRnd.nextInt(h);
217
      randomS = 0.2f+ 0.8f*mRnd.nextFloat();
218
      randomA = (int)(180*mRnd.nextFloat());
219
      randomAlpha1 = 0.2f + 0.8f*mRnd.nextFloat();
220
      randomAlpha2 = 0.8f + 0.2f*mRnd.nextFloat();
221
      randomTime = 500+mRnd.nextInt(2000);
222
      
223
      mStarEffects[i].move( new Static3D(randomX,randomY,0) );
224
      mStarEffects[i].scale(randomS);
225
      mStarEffects[i].rotate( new Static1D(randomA), axis, center );
226
      
227
      Dynamic1D di = new Dynamic1D(randomTime,0.0f);
228
      di.setNoise(alphaNoise);
229
      di.add(new Static1D(randomAlpha1));
230
      di.add(new Static1D(randomAlpha2));
231
      
232
      mStarEffects[i].alpha(di);
233
      
234
      mRoot.attach(mStarTexture, mStarEffects[i], mQuad);
235
      }
236
      
237
    float scale = (0.5f*w/mGFFATexture.getWidth());
238
    
239
    Dynamic1D di = new Dynamic1D(6000,0.5f);
240
    di.add(new Static1D(1.0f));
241
    di.add(new Static1D(1.0f));
242
    di.add(new Static1D(0.0f));
243
    
244
    mGFFAEffects.move( new Static3D(w/5,h/3,0) );
245
    mGFFAEffects.scale( new Static3D(scale,scale,scale) );
246
    mGFFAEffects.alpha(di);
247
      
248
    mRoot.attach(mGFFATexture, mGFFAEffects, mQuad);
249
    mGFFAEffects.registerForMessages(this);
250
    }
251
    
252
///////////////////////////////////////////////////////////////////////////////////////////////////
253

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

    
302
    ///// create CRAWL //////////////////
303
    mCrawlTexture = new DistortedTexture(CRAWL_WIDTH,CRAWL_HEIGHT);
304
    bitmapText = Bitmap.createBitmap(CRAWL_WIDTH,CRAWL_HEIGHT,Bitmap.Config.ARGB_8888);
305
    bitmapText.eraseColor(0x00000000);
306
    Canvas textCanvas = new Canvas(bitmapText);
307
    paint.setColor(CRAWL_COLOR);
308
  
309
    for(int i=0; i<mCRAWLString.length; i++)
310
      {
311
      displayJustified(mCRAWLString[i], 0, (i+1)*(FONT_HEIGHT+VERTICAL_SPACING), CRAWL_WIDTH, textCanvas, paint);  
312
      }
313
      
314
    mCrawlTexture.setTexture(bitmapText);
315
      
316
    ///// create Stars ///////////////////
317
    mStarTexture = new DistortedTexture(bitmapStar.getWidth(),bitmapStar.getHeight());
318
    mStarTexture.setTexture(bitmapStar);
319

    
320
    gffaID = mGFFAEffects.getID();
321
    logoID = mLogoEffects.getID();
322
    crawlID= mCrawlEffects.getID();
323
    }
324
 
325
///////////////////////////////////////////////////////////////////////////////////////////////////
326

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

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

    
338
    while( end<len )
339
      {
340
      begin=end;
341
      end = str.indexOf(' ', begin)+1;
342
      if( end<=0 ) end = len;
343

    
344
      tmp = str.substring(begin,end);
345
      c.drawText( tmp, left, y, paint);
346
      left+= (paint.measureText(tmp)+w);
347
      }  
348
    }
349

    
350
///////////////////////////////////////////////////////////////////////////////////////////////////
351
   
352
  private int retNumSpaces(String str)
353
    {
354
    int begin=0, ret=0;
355

    
356
    while( true )
357
      {
358
      begin = str.indexOf(' ', begin) +1;
359

    
360
      if( begin>0 ) ret++;
361
      else break;
362
      }
363

    
364
    return ret;
365
    }
366
    
367
///////////////////////////////////////////////////////////////////////////////////////////////////
368
// the library sending messages to us. This is running on a library 'MessageSender' thread.
369

    
370
  public void effectMessage(final EffectMessage em, final long effectID, final EffectNames effectName, final long objectID)
371
    {
372
    if( em==EffectMessage.EFFECT_FINISHED )
373
      {
374
      if( objectID == gffaID )
375
        {
376
        mRoot.detach(mGFFAEffects);
377
        mGFFAEffects.abortAllEffects();
378
        mGFFATexture.markForDeletion();
379

    
380
        int screenW=mScreenTexture.getWidth();
381
        int screenH=mScreenTexture.getHeight();
382
        
383
        int logoW = mLogoTexture.getWidth();
384
        int logoH = mLogoTexture.getHeight();
385
      
386
        int initSize= (int)(3.0f*screenW/logoW);
387
        int finaSize= (int)(0.1f*screenW/logoW);
388
      
389
        Dynamic3D di = new Dynamic3D(10000,0.5f);
390
        di.add(new Static3D(initSize,initSize,1));
391
        di.add(new Static3D(finaSize,finaSize,1));
392

    
393
        mLogoEffects.move( new Static3D(screenW/2,screenH/2,0) );
394
        mLogoEffects.scale(di);
395
        mLogoEffects.move( new Static3D(-logoW/2,-logoH/2,0) );
396
      
397
        mRoot.attach(mLogoTexture, mLogoEffects,mQuad);
398
        mLogoEffects.registerForMessages(this);
399
        }
400
      else if( objectID==logoID )
401
        {
402
        mRoot.detach(mLogoEffects);
403
        mLogoEffects.abortAllEffects();
404
        mLogoTexture.markForDeletion();
405
        
406
        int crawlW = mCrawlTexture.getWidth();
407
        int crawlH = mCrawlTexture.getHeight();
408
        int screenW= mScreenTexture.getWidth();
409
        int screenH= mScreenTexture.getHeight();
410
        int backH  = mCrawlBackgroundTexture.getHeight();
411
        float scale= (float)screenW/crawlW;
412
      
413
        Dynamic3D di = new Dynamic3D(60000,0.5f);
414
        di.add(new Static3D(screenW/2,+backH       , 0));
415
        di.add(new Static3D(screenW/2,-scale*crawlH, 0));
416
        
417
        mCrawlBackgroundEffects.move( new Static3D(0,screenH-backH,0) );
418
        mCrawlBackgroundEffects.rotate( new Static1D(CRAWL_ANGLE), new Static3D(1,0,0), new Static3D(screenW/2,backH,0) );
419
        
420
        final int transpDist = 5;
421
        Static4D region = new Static4D(screenW/2,(1-transpDist)*backH,transpDist*backH,transpDist*backH);
422
        mCrawlBackgroundEffects.alpha(new Static1D(1-transpDist/2), region, true);
423
        
424
        mCrawlEffects.move(di);
425
        mCrawlEffects.scale( new Static3D(scale,scale,scale) );
426
        mCrawlEffects.move( new Static3D(-crawlW/2,0,0) );
427
        
428
        mBackground = mRoot.attach(mCrawlBackgroundTexture, mCrawlBackgroundEffects,mQuad);
429
        mBackground.attach(mCrawlTexture, mCrawlEffects,mQuad);
430
        mCrawlEffects.registerForMessages(this);
431
        }
432
      else if( objectID==crawlID )
433
        {
434
        mRoot.detach(mBackground);
435
        mBackground.detach(mCrawlEffects);
436
        mCrawlEffects.abortAllEffects();
437
        mCrawlTexture.markForDeletion();
438
        mCrawlBackgroundEffects.abortAllEffects();
439
        mCrawlBackgroundTexture.markForDeletion();
440
        }
441
      }
442
    }
443
  }
(2-2/3)