Project

General

Profile

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

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

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

    
114
///////////////////////////////////////////////////////////////////////////////////////////////////
115

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

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

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

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

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

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

    
136
///////////////////////////////////////////////////////////////////////////////////////////////////
137
   
138
  public void onDrawFrame(GL10 glUnused) 
139
    {
140
    GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
141
    mRoot.draw(System.currentTimeMillis());
142
    }
143

    
144
///////////////////////////////////////////////////////////////////////////////////////////////////
145
    
146
  public void onSurfaceChanged(GL10 glUnused, int width, int height) 
147
    {
148
    mScreenQueue.abortAllEffects();
149
    mGFFAQueue.abortAllEffects();
150
    mLogoQueue.abortAllEffects();
151
    mCrawlQueue.abortAllEffects();
152
    mCrawlBackgroundQueue.abortAllEffects();
153

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

    
156
    setupScreen(width,height);
157

    
158
    Distorted.onSurfaceChanged(width, height);
159
    }
160

    
161
///////////////////////////////////////////////////////////////////////////////////////////////////
162
    
163
  public void onSurfaceCreated(GL10 glUnused, EGLConfig config) 
164
    {
165
    GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
166

    
167
    setupBitmaps();
168

    
169
    try
170
      {
171
      Distorted.onSurfaceCreated(mView.getContext());
172
      }
173
    catch(Exception ex)
174
      {
175
      android.util.Log.e("Star Wars", ex.getMessage() );
176
      }
177
    }
178
    
179
///////////////////////////////////////////////////////////////////////////////////////////////////
180

    
181
  private void setupScreen(int w, int h)
182
    {
183
    mScreenTexture = new DistortedTexture(w,h);
184
    mRoot = new DistortedObjectTree(mScreenTexture,mScreenQueue,mQuad);
185
      
186
    mCrawlBackgroundTexture = new DistortedTexture(w,(int)(Math.sqrt(3.0)*h));
187
       
188
    int randomA, randomX, randomY, randomTime;
189
    float randomS, randomAlpha1, randomAlpha2;
190
       
191
    Static3D center = new Static3D(0,0,0);
192
    Static3D axis   = new Static3D(0,0,1);
193
    Static1D alphaNoise = new Static1D(0.4f);
194

    
195
    for(int i=0; i<NUM_STARS; i++)
196
      {
197
      randomX = mRnd.nextInt(w);
198
      randomY = mRnd.nextInt(h);
199
      randomS = 0.2f+ 0.8f*mRnd.nextFloat();
200
      randomA = (int)(180*mRnd.nextFloat());
201
      randomAlpha1 = 0.2f + 0.8f*mRnd.nextFloat();
202
      randomAlpha2 = 0.8f + 0.2f*mRnd.nextFloat();
203
      randomTime = 500+mRnd.nextInt(2000);
204
      
205
      mStarQueue[i].move( new Static3D(randomX,randomY,0) );
206
      mStarQueue[i].scale(randomS);
207
      mStarQueue[i].rotate( new Static1D(randomA), axis, center );
208
      
209
      Dynamic1D di = new Dynamic1D(randomTime,0.0f);
210
      di.setNoise(alphaNoise);
211
      di.add(new Static1D(randomAlpha1));
212
      di.add(new Static1D(randomAlpha2));
213
      
214
      mStarQueue[i].alpha(di);
215
      
216
      mRoot.attach(mStarTexture, mStarQueue[i], mQuad);
217
      }
218
      
219
    float scale = (0.5f*w/mGFFATexture.getWidth());
220
    
221
    Dynamic1D di = new Dynamic1D(6000,0.5f);
222
    di.add(new Static1D(1.0f));
223
    di.add(new Static1D(1.0f));
224
    di.add(new Static1D(0.0f));
225
    
226
    mGFFAQueue.move( new Static3D(w/5,h/3,0) );
227
    mGFFAQueue.scale( new Static3D(scale,scale,scale) );
228
    mGFFAQueue.alpha(di);
229
      
230
    mRoot.attach(mGFFATexture, mGFFAQueue, mQuad);
231
    mGFFAQueue.addEventListener(this);
232
    }
233
    
234
///////////////////////////////////////////////////////////////////////////////////////////////////
235

    
236
  private void setupBitmaps()
237
    {
238
    InputStream is1 = mView.getContext().getResources().openRawResource(R.raw.starwars);
239
    InputStream is2 = mView.getContext().getResources().openRawResource(R.raw.star);
240
    
241
    Bitmap bitmapStar, bitmapGFFA, bitmapLogo, bitmapText;
242
      
243
    try 
244
      {
245
      bitmapLogo = BitmapFactory.decodeStream(is1);
246
      bitmapStar = BitmapFactory.decodeStream(is2);
247
      } 
248
    finally 
249
      {
250
      try 
251
        {
252
        is1.close();
253
        is2.close();
254
        } 
255
      catch(IOException e) { }
256
      } 
257
      
258
    Paint paint = new Paint();
259
    paint.setAntiAlias(true);
260
    paint.setTextAlign(Paint.Align.LEFT);
261
    paint.setTextSize(FONT_HEIGHT);
262
    paint.setColor(GFFA_COLOR);
263
      
264
    Typeface tf = Typeface.create(CRAWL_TYPEFACE, Typeface.BOLD);
265
    paint.setTypeface(tf);     
266
 
267
    ///// create GFFA ///////////////////
268
    mGFFATexture  = new DistortedTexture(GFFA_WIDTH,GFFA_HEIGHT);
269
    bitmapGFFA = Bitmap.createBitmap(GFFA_WIDTH,GFFA_HEIGHT,Bitmap.Config.ARGB_8888);
270
    bitmapGFFA.eraseColor(0x00000000);
271
    Canvas gffaCanvas = new Canvas(bitmapGFFA);
272
      
273
    for(int i=0; i<mGFFAString.length; i++)
274
      {
275
      gffaCanvas.drawText(mGFFAString[i], 0, (i+1)*(FONT_HEIGHT+VERTICAL_SPACING), paint);  
276
      }
277
  
278
    mGFFATexture.setTexture(bitmapGFFA);
279
      
280
    ///// create Logo ///////////////////
281
    mLogoTexture  = new DistortedTexture(bitmapLogo.getWidth(),bitmapLogo.getHeight());
282
    mLogoTexture.setTexture(bitmapLogo);
283

    
284
    ///// create CRAWL //////////////////
285
    mCrawlTexture = new DistortedTexture(CRAWL_WIDTH,CRAWL_HEIGHT);
286
    bitmapText = Bitmap.createBitmap(CRAWL_WIDTH,CRAWL_HEIGHT,Bitmap.Config.ARGB_8888);
287
    bitmapText.eraseColor(0x00000000);
288
    Canvas textCanvas = new Canvas(bitmapText);
289
    paint.setColor(CRAWL_COLOR);
290
  
291
    for(int i=0; i<mCRAWLString.length; i++)
292
      {
293
      displayJustified(mCRAWLString[i], 0, (i+1)*(FONT_HEIGHT+VERTICAL_SPACING), CRAWL_WIDTH, textCanvas, paint);  
294
      }
295
      
296
    mCrawlTexture.setTexture(bitmapText);
297
      
298
    ///// create Stars ///////////////////
299
    mStarTexture = new DistortedTexture(bitmapStar.getWidth(),bitmapStar.getHeight());
300
    mStarTexture.setTexture(bitmapStar);
301

    
302
    gffaID = mGFFAQueue.getID();
303
    logoID = mLogoQueue.getID();
304
    crawlID= mCrawlQueue.getID();
305
    }
306
 
307
///////////////////////////////////////////////////////////////////////////////////////////////////
308

    
309
  private void displayJustified(String str, int x, int y, int length, Canvas c, Paint paint)
310
    { 
311
    int len       = str.length();
312
    int numspaces = retNumSpaces(str);
313
    
314
    if( len>0 && str.charAt(len-1) == ' ' ) numspaces--;
315

    
316
    float left=x,w = (numspaces>0 ? (length-paint.measureText(str))/numspaces : 0);
317
    String tmp;
318
    int begin,end=0;
319

    
320
    while( end<len )
321
      {
322
      begin=end;
323
      end = str.indexOf(' ', begin)+1;
324
      if( end<=0 ) end = len;
325

    
326
      tmp = str.substring(begin,end);
327
      c.drawText( tmp, left, y, paint);
328
      left+= (paint.measureText(tmp)+w);
329
      }  
330
    }
331

    
332
///////////////////////////////////////////////////////////////////////////////////////////////////
333
   
334
  private int retNumSpaces(String str)
335
    {
336
    int begin=0, ret=0;
337

    
338
    while( true )
339
      {
340
      begin = str.indexOf(' ', begin) +1;
341

    
342
      if( begin>0 ) ret++;
343
      else break;
344
      }
345

    
346
    return ret;
347
    }
348
    
349
///////////////////////////////////////////////////////////////////////////////////////////////////
350
// the library sending messages to us. This is running on a library 'MessageSender' thread.
351

    
352
  public void effectMessage(final EffectMessage em, final long effectID, final EffectNames effectName, final long objectID, final String message)
353
    {
354
    if( em==EffectMessage.EFFECT_FINISHED )
355
      {
356
      if( objectID == gffaID )
357
        {
358
        mRoot.detach(mGFFAQueue);
359
        mGFFAQueue.abortAllEffects();
360
        mGFFATexture.markForDeletion();
361

    
362
        int screenW=mScreenTexture.getWidth();
363
        int screenH=mScreenTexture.getHeight();
364
        
365
        int logoW = mLogoTexture.getWidth();
366
        int logoH = mLogoTexture.getHeight();
367
      
368
        int initSize= (int)(3.0f*screenW/logoW);
369
        int finaSize= (int)(0.1f*screenW/logoW);
370
      
371
        Dynamic3D di = new Dynamic3D(10000,0.5f);
372
        di.add(new Static3D(initSize,initSize,1));
373
        di.add(new Static3D(finaSize,finaSize,1));
374

    
375
        mLogoQueue.move( new Static3D(screenW/2,screenH/2,0) );
376
        mLogoQueue.scale(di);
377
        mLogoQueue.move( new Static3D(-logoW/2,-logoH/2,0) );
378
      
379
        mRoot.attach(mLogoTexture,mLogoQueue,mQuad);
380
        mLogoQueue.addEventListener(this);
381
        }
382
      else if( objectID==logoID )
383
        {
384
        mRoot.detach(mLogoQueue);
385
        mLogoQueue.abortAllEffects();
386
        mLogoTexture.markForDeletion();
387
        
388
        int crawlW = mCrawlTexture.getWidth();
389
        int crawlH = mCrawlTexture.getHeight();
390
        int screenW= mScreenTexture.getWidth();
391
        int screenH= mScreenTexture.getHeight();
392
        int backH  = mCrawlBackgroundTexture.getHeight();
393
        float scale= (float)screenW/crawlW;
394
      
395
        Dynamic3D di = new Dynamic3D(60000,0.5f);
396
        di.add(new Static3D(screenW/2,+backH       , 0));
397
        di.add(new Static3D(screenW/2,-scale*crawlH, 0));
398
        
399
        mCrawlBackgroundQueue.move( new Static3D(0,screenH-backH,0) );
400
        mCrawlBackgroundQueue.rotate( new Static1D(CRAWL_ANGLE), new Static3D(1,0,0), new Static3D(screenW/2,backH,0) );
401
        
402
        final int transpDist = 5;
403
        Static4D region = new Static4D(screenW/2,(1-transpDist)*backH,transpDist*backH,transpDist*backH);
404
        mCrawlBackgroundQueue.alpha(new Static1D(1-transpDist/2), region, true);
405
        
406
        mCrawlQueue.move(di);
407
        mCrawlQueue.scale( new Static3D(scale,scale,scale) );
408
        mCrawlQueue.move( new Static3D(-crawlW/2,0,0) );
409
        
410
        mBackground = mRoot.attach(mCrawlBackgroundTexture,mCrawlBackgroundQueue,mQuad);
411
        mBackground.attach(mCrawlTexture,mCrawlQueue,mQuad);
412
        mCrawlQueue.addEventListener(this);
413
        }
414
      else if( objectID==crawlID )
415
        {
416
        mRoot.detach(mBackground);
417
        mBackground.detach(mCrawlQueue);
418
        mCrawlQueue.abortAllEffects();
419
        mCrawlTexture.markForDeletion();
420
        mCrawlBackgroundQueue.abortAllEffects();
421
        mCrawlBackgroundTexture.markForDeletion();
422
        }
423
      }
424
    }
425
  }
(2-2/3)