Project

General

Profile

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

examples / src / main / java / org / distorted / examples / starwars / StarWarsRenderer.java @ 76f2d645

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.DistortedNode;
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.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.GLES30;
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 DistortedNode mRoot, mBackground;
110
  private DistortedScreen mScreen;
111
  private MeshFlat 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
    android.util.Log.d("STAR WARS", "constructor");
122

    
123
    mView = v;
124

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

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

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

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

    
142
    mScreen = new DistortedScreen();
143
    mScreen.setProjection(60.0f, 0.0f, 0.0f);
144
    }
145

    
146
///////////////////////////////////////////////////////////////////////////////////////////////////
147

    
148
  public void onPause()
149
    {
150
    android.util.Log.d("STAR WARS", "onPause");
151

    
152
    mWidth = 0;
153
    mHeight= 0;
154
    }
155

    
156
///////////////////////////////////////////////////////////////////////////////////////////////////
157
   
158
  public void onDrawFrame(GL10 glUnused) 
159
    {
160
    GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
161
    mScreen.render(System.currentTimeMillis());
162
    }
163

    
164
///////////////////////////////////////////////////////////////////////////////////////////////////
165
    
166
  public void onSurfaceChanged(GL10 glUnused, int width, int height) 
167
    {
168
    android.util.Log.d("STAR WARS", "surfaceChanged");
169

    
170

    
171
    if( mWidth!=width || mHeight!=height )  // after onPause() we get 2 calls here
172
      {
173
      mWidth = width;
174
      mHeight= height;
175

    
176
      mScreenEffects.abortAllEffects();
177
      mGFFAEffects.abortAllEffects();
178
      mLogoEffects.abortAllEffects();
179
      mCrawlEffects.abortAllEffects();
180
      mCrawlBackgroundEffects.abortAllEffects();
181

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

    
184
      setupScreen(width,height);
185

    
186
      mScreen.detachAll();
187
      mScreen.attach(mRoot);
188
      mScreen.resize(width, height);
189
      }
190
    }
191

    
192
///////////////////////////////////////////////////////////////////////////////////////////////////
193
    
194
  public void onSurfaceCreated(GL10 glUnused, EGLConfig config) 
195
    {
196
    android.util.Log.d("STAR WARS", "surfaceCreated");
197

    
198
    GLES30.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
199

    
200
    setupBitmaps();
201

    
202
    try
203
      {
204
      Distorted.onCreate(mView.getContext());
205
      }
206
    catch(Exception ex)
207
      {
208
      android.util.Log.e("Star Wars", ex.getMessage() );
209
      }
210
    }
211
    
212
///////////////////////////////////////////////////////////////////////////////////////////////////
213

    
214
  private void setupScreen(int w, int h)
215
    {
216
    mScreenTexture = new DistortedTexture(w,h);
217
    mRoot = new DistortedNode(mScreenTexture, mScreenEffects,mQuad);
218

    
219
    mCrawlBackgroundTexture = new DistortedTexture(w,(int)(Math.sqrt(3.0)*h));
220
       
221
    int randomA, randomX, randomY, randomTime;
222
    float randomS, randomAlpha1, randomAlpha2;
223
       
224
    Static3D center = new Static3D(0,0,0);
225
    Static3D axis   = new Static3D(0,0,1);
226
    Static1D alphaNoise = new Static1D(0.4f);
227

    
228
    for(int i=0; i<NUM_STARS; i++)
229
      {
230
      randomX = mRnd.nextInt(w);
231
      randomY = mRnd.nextInt(h);
232
      randomS = 0.2f+ 0.8f*mRnd.nextFloat();
233
      randomA = (int)(180*mRnd.nextFloat());
234
      randomAlpha1 = 0.2f + 0.8f*mRnd.nextFloat();
235
      randomAlpha2 = 0.8f + 0.2f*mRnd.nextFloat();
236
      randomTime = 500+mRnd.nextInt(2000);
237
      
238
      mStarEffects[i].move( new Static3D(randomX,randomY,0) );
239
      mStarEffects[i].scale(randomS);
240
      mStarEffects[i].rotate( new Static1D(randomA), axis, center );
241
      
242
      Dynamic1D di = new Dynamic1D(randomTime,0.0f);
243
      di.setNoise(alphaNoise);
244
      di.add(new Static1D(randomAlpha1));
245
      di.add(new Static1D(randomAlpha2));
246
      
247
      mStarEffects[i].alpha(di);
248
      
249
      mRoot.attach(mStarTexture, mStarEffects[i], mQuad);
250
      }
251
      
252
    float scale = (0.5f*w/mGFFATexture.getWidth());
253
    
254
    Dynamic1D di = new Dynamic1D(6000,0.5f);
255
    di.add(new Static1D(1.0f));
256
    di.add(new Static1D(1.0f));
257
    di.add(new Static1D(0.0f));
258
    
259
    mGFFAEffects.move( new Static3D(w/5,h/3,0) );
260
    mGFFAEffects.scale( new Static3D(scale,scale,scale) );
261
    mGFFAEffects.alpha(di);
262
      
263
    mRoot.attach(mGFFATexture, mGFFAEffects, mQuad);
264
    mGFFAEffects.registerForMessages(this);
265
    }
266
    
267
///////////////////////////////////////////////////////////////////////////////////////////////////
268

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

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

    
335
    gffaID = mGFFAEffects.getID();
336
    logoID = mLogoEffects.getID();
337
    crawlID= mCrawlEffects.getID();
338
    }
339
 
340
///////////////////////////////////////////////////////////////////////////////////////////////////
341

    
342
  private void displayJustified(String str, int x, int y, int length, Canvas c, Paint paint)
343
    { 
344
    int len       = str.length();
345
    int numspaces = retNumSpaces(str);
346
    
347
    if( len>0 && str.charAt(len-1) == ' ' ) numspaces--;
348

    
349
    float left=x,w = (numspaces>0 ? (length-paint.measureText(str))/numspaces : 0);
350
    String tmp;
351
    int begin,end=0;
352

    
353
    while( end<len )
354
      {
355
      begin=end;
356
      end = str.indexOf(' ', begin)+1;
357
      if( end<=0 ) end = len;
358

    
359
      tmp = str.substring(begin,end);
360
      c.drawText( tmp, left, y, paint);
361
      left+= (paint.measureText(tmp)+w);
362
      }  
363
    }
364

    
365
///////////////////////////////////////////////////////////////////////////////////////////////////
366
   
367
  private int retNumSpaces(String str)
368
    {
369
    int begin=0, ret=0;
370

    
371
    while( true )
372
      {
373
      begin = str.indexOf(' ', begin) +1;
374

    
375
      if( begin>0 ) ret++;
376
      else break;
377
      }
378

    
379
    return ret;
380
    }
381
    
382
///////////////////////////////////////////////////////////////////////////////////////////////////
383
// the library sending messages to us. This is running on a library 'MessageSender' thread.
384

    
385
  public void effectMessage(final EffectMessage em, final long effectID, final EffectNames effectName, final long objectID)
386
    {
387
    if( em==EffectMessage.EFFECT_FINISHED )
388
      {
389
      if( objectID == gffaID )
390
        {
391
        mRoot.detach(mGFFAEffects);
392
        mGFFAEffects.abortAllEffects();
393
        mGFFATexture.markForDeletion();
394

    
395
        int screenW=mScreenTexture.getWidth();
396
        int screenH=mScreenTexture.getHeight();
397
        
398
        int logoW = mLogoTexture.getWidth();
399
        int logoH = mLogoTexture.getHeight();
400
      
401
        int initSize= (int)(3.0f*screenW/logoW);
402
        int finaSize= (int)(0.1f*screenW/logoW);
403
      
404
        Dynamic3D di = new Dynamic3D(10000,0.5f);
405
        di.add(new Static3D(initSize,initSize,1));
406
        di.add(new Static3D(finaSize,finaSize,1));
407

    
408
        mLogoEffects.move( new Static3D(screenW/2,screenH/2,0) );
409
        mLogoEffects.scale(di);
410
        mLogoEffects.move( new Static3D(-logoW/2,-logoH/2,0) );
411
      
412
        mRoot.attach(mLogoTexture, mLogoEffects,mQuad);
413
        mLogoEffects.registerForMessages(this);
414
        }
415
      else if( objectID==logoID )
416
        {
417
        mRoot.detach(mLogoEffects);
418
        mLogoEffects.abortAllEffects();
419
        mLogoTexture.markForDeletion();
420
        
421
        int crawlW = mCrawlTexture.getWidth();
422
        int crawlH = mCrawlTexture.getHeight();
423
        int screenW= mScreenTexture.getWidth();
424
        int screenH= mScreenTexture.getHeight();
425
        int backH  = mCrawlBackgroundTexture.getHeight();
426
        float scale= (float)screenW/crawlW;
427
      
428
        Dynamic3D di = new Dynamic3D(60000,0.5f);
429
        di.add(new Static3D(screenW/2,+backH       , 0));
430
        di.add(new Static3D(screenW/2,-scale*crawlH, 0));
431
        
432
        mCrawlBackgroundEffects.move( new Static3D(0,screenH-backH,0) );
433
        mCrawlBackgroundEffects.rotate( new Static1D(CRAWL_ANGLE), new Static3D(1,0,0), new Static3D(screenW/2,backH,0) );
434
        
435
        final int transpDist = 5;
436
        Static4D region = new Static4D(screenW/2,(1-transpDist)*backH,transpDist*backH,transpDist*backH);
437
        mCrawlBackgroundEffects.alpha(new Static1D(1-transpDist/2), region, true);
438
        
439
        mCrawlEffects.move(di);
440
        mCrawlEffects.scale( new Static3D(scale,scale,scale) );
441
        mCrawlEffects.move( new Static3D(-crawlW/2,0,0) );
442
        
443
        mBackground = mRoot.attach(mCrawlBackgroundTexture, mCrawlBackgroundEffects,mQuad);
444
        mBackground.attach(mCrawlTexture, mCrawlEffects,mQuad);
445
        mCrawlEffects.registerForMessages(this);
446
        }
447
      else if( objectID==crawlID )
448
        {
449
        mRoot.detach(mBackground);
450
        mBackground.detach(mCrawlEffects);
451
        mCrawlEffects.abortAllEffects();
452
        mCrawlTexture.markForDeletion();
453
        mCrawlBackgroundEffects.abortAllEffects();
454
        mCrawlBackgroundTexture.markForDeletion();
455
        }
456
      }
457
    }
458
  }
(2-2/3)