Project

General

Profile

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

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

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.DistortedScreen;
33
import org.distorted.library.MeshFlat;
34
import org.distorted.library.EffectNames;
35
import org.distorted.library.type.Dynamic1D;
36
import org.distorted.library.type.Dynamic3D;
37
import org.distorted.library.DistortedTree;
38
import org.distorted.library.type.Static1D;
39
import org.distorted.library.type.Static3D;
40
import org.distorted.library.type.Static4D;
41
import org.distorted.library.message.EffectListener;
42
import org.distorted.library.message.EffectMessage;
43
import org.distorted.library.Distorted;
44
import org.distorted.library.DistortedTexture;
45
import org.distorted.library.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.GLES30;
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
   
106
  private GLSurfaceView mView;
107
  private DistortedTexture mScreenTexture, mGFFATexture, mLogoTexture, mCrawlTexture, mCrawlBackgroundTexture, mStarTexture;
108
  private DistortedEffects mScreenEffects, mGFFAEffects, mLogoEffects, mCrawlEffects, mCrawlBackgroundEffects;
109
  private DistortedEffects[] mStarEffects;
110
  private DistortedTree mRoot, mBackground;
111
  private DistortedScreen mScreen;
112
  private MeshFlat mQuad;
113

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

    
118
///////////////////////////////////////////////////////////////////////////////////////////////////
119

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

    
124
    mQuad = new MeshFlat(1,1);
125

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

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

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

    
137
    mScreen = new DistortedScreen();
138
    mScreen.setProjection(60.0f, 0.0f, 0.0f);
139
    }
140

    
141
///////////////////////////////////////////////////////////////////////////////////////////////////
142

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

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

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

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

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

    
174
      setupScreen(width,height);
175

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

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

    
186
    setupBitmaps();
187

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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