Project

General

Profile

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

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

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

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

    
53
///////////////////////////////////////////////////////////////////////////////////////////////////
54

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

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

    
115
///////////////////////////////////////////////////////////////////////////////////////////////////
116

    
117
  StarWarsRenderer(GLSurfaceView v)
118
    {
119
    mView = v;
120

    
121
    mQuad = new GridFlat(1,1);
122

    
123
    mScreenQueue          = new DistortedEffectQueues();
124
    mGFFAQueue            = new DistortedEffectQueues();
125
    mLogoQueue            = new DistortedEffectQueues();
126
    mCrawlQueue           = new DistortedEffectQueues();
127
    mCrawlBackgroundQueue = new DistortedEffectQueues();
128

    
129
    mStarQueue = new DistortedEffectQueues[NUM_STARS];
130
    mStarQueue[0] = new DistortedEffectQueues();
131

    
132
    for(int i=1; i<NUM_STARS; i++) mStarQueue[i] = new DistortedEffectQueues(mStarQueue[0],Distorted.CLONE_VERTEX);
133

    
134
    Distorted.setProjection(60.0f, 0.0f, 0.0f);
135
    }
136

    
137
///////////////////////////////////////////////////////////////////////////////////////////////////
138

    
139
  public void onPause()
140
    {
141
    mWidth = 0;
142
    mHeight= 0;
143
    }
144

    
145
///////////////////////////////////////////////////////////////////////////////////////////////////
146
   
147
  public void onDrawFrame(GL10 glUnused) 
148
    {
149
    GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
150
    mRoot.draw(System.currentTimeMillis());
151
    }
152

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

    
162
      mScreenQueue.abortAllEffects();
163
      mGFFAQueue.abortAllEffects();
164
      mLogoQueue.abortAllEffects();
165
      mCrawlQueue.abortAllEffects();
166
      mCrawlBackgroundQueue.abortAllEffects();
167

    
168
      for(int i=0; i<NUM_STARS; i++) mStarQueue[i].abortAllEffects();
169

    
170
      setupScreen(width,height);
171

    
172
      Distorted.onSurfaceChanged(width, height);
173
      }
174
    }
175

    
176
///////////////////////////////////////////////////////////////////////////////////////////////////
177
    
178
  public void onSurfaceCreated(GL10 glUnused, EGLConfig config) 
179
    {
180
    GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
181

    
182
    setupBitmaps();
183

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

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

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

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

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

    
317
    gffaID = mGFFAQueue.getID();
318
    logoID = mLogoQueue.getID();
319
    crawlID= mCrawlQueue.getID();
320
    }
321
 
322
///////////////////////////////////////////////////////////////////////////////////////////////////
323

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

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

    
335
    while( end<len )
336
      {
337
      begin=end;
338
      end = str.indexOf(' ', begin)+1;
339
      if( end<=0 ) end = len;
340

    
341
      tmp = str.substring(begin,end);
342
      c.drawText( tmp, left, y, paint);
343
      left+= (paint.measureText(tmp)+w);
344
      }  
345
    }
346

    
347
///////////////////////////////////////////////////////////////////////////////////////////////////
348
   
349
  private int retNumSpaces(String str)
350
    {
351
    int begin=0, ret=0;
352

    
353
    while( true )
354
      {
355
      begin = str.indexOf(' ', begin) +1;
356

    
357
      if( begin>0 ) ret++;
358
      else break;
359
      }
360

    
361
    return ret;
362
    }
363
    
364
///////////////////////////////////////////////////////////////////////////////////////////////////
365
// the library sending messages to us. This is running on a library 'MessageSender' thread.
366

    
367
  public void effectMessage(final EffectMessage em, final long effectID, final EffectNames effectName, final long objectID, final String message)
368
    {
369
    if( em==EffectMessage.EFFECT_FINISHED )
370
      {
371
      if( objectID == gffaID )
372
        {
373
        mRoot.detach(mGFFAQueue);
374
        mGFFAQueue.abortAllEffects();
375
        mGFFATexture.markForDeletion();
376

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

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