Project

General

Profile

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

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

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
    mView = v;
122

    
123
    mQuad = new MeshFlat(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 DistortedScreen();
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
    GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
153
    mScreen.render(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.detachAll();
176
      mScreen.attach(mRoot);
177
      mScreen.resize(width, height);
178
      }
179
    }
180

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

    
187
    setupBitmaps();
188

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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