Project

General

Profile

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

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

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

    
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 onDrawFrame(GL10 glUnused) 
140
    {
141
    GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
142
    mRoot.draw(System.currentTimeMillis());
143
    }
144

    
145
///////////////////////////////////////////////////////////////////////////////////////////////////
146
    
147
  public void onSurfaceChanged(GL10 glUnused, int width, int height) 
148
    { 
149
    Distorted.onSurfaceChanged(width, height); 
150
    setupScreen(width,height);
151
    }
152

    
153
///////////////////////////////////////////////////////////////////////////////////////////////////
154
    
155
  public void onSurfaceCreated(GL10 glUnused, EGLConfig config) 
156
    {
157
    GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
158

    
159
    setupBitmaps();
160
         
161
    try
162
      {
163
      Distorted.onSurfaceCreated(mView.getContext());
164
      }
165
    catch(Exception ex)
166
      {
167
      android.util.Log.e("Star Wars", ex.getMessage() );
168
      }
169
    }
170
    
171
///////////////////////////////////////////////////////////////////////////////////////////////////
172

    
173
  private void setupScreen(int w, int h)
174
    {
175
    mScreenTexture = new DistortedTexture(w,h,0);
176
    mRoot = new DistortedObjectTree(mScreenTexture,mScreenQueue,mQuad);
177
      
178
    mCrawlBackgroundTexture = new DistortedTexture(w,(int)(Math.sqrt(3.0)*h),0);
179
       
180
    int randomA, randomX, randomY, randomTime;
181
    float randomS, randomAlpha1, randomAlpha2;
182
       
183
    Static3D center = new Static3D(0,0,0);
184
    Static3D axis   = new Static3D(0,0,1);
185

    
186
    Static1D alphaNoise = new Static1D(0.4f);
187

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

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

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

    
295
    gffaID = mGFFAQueue.getID();
296
    logoID = mLogoQueue.getID();
297
    crawlID= mCrawlQueue.getID();
298
    }
299
 
300
///////////////////////////////////////////////////////////////////////////////////////////////////
301

    
302
  private void displayJustified(String str, int x, int y, int length, Canvas c, Paint paint)
303
    { 
304
    int len       = str.length();
305
    int numspaces = retNumSpaces(str);
306
    
307
    if( len>0 && str.charAt(len-1) == ' ' ) numspaces--;
308

    
309
    float left=x,w = (numspaces>0 ? (length-paint.measureText(str))/numspaces : 0);
310
    String tmp;
311
    int begin,end=0;
312

    
313
    while( end<len )
314
      {
315
      begin=end;
316
      end = str.indexOf(' ', begin)+1;
317
      if( end<=0 ) end = len;
318

    
319
      tmp = str.substring(begin,end);
320
      c.drawText( tmp, left, y, paint);
321
      left+= (paint.measureText(tmp)+w);
322
      }  
323
    }
324

    
325
///////////////////////////////////////////////////////////////////////////////////////////////////
326
   
327
  private int retNumSpaces(String str)
328
    {
329
    int begin=0, ret=0;
330

    
331
    while( true )
332
      {
333
      begin = str.indexOf(' ', begin) +1;
334

    
335
      if( begin>0 ) ret++;
336
      else break;
337
      }
338

    
339
    return ret;
340
    }
341
    
342
///////////////////////////////////////////////////////////////////////////////////////////////////
343
// the library sending messages to us. This is running on a library 'MessageSender' thread.
344

    
345
  public void effectMessage(final EffectMessage em, final long effectID, final EffectNames effectName, final long objectID, final String message)
346
    {
347
    if( em==EffectMessage.EFFECT_FINISHED )
348
      {
349
      if( objectID == gffaID )
350
        {
351
        mRoot.detach(mGFFAQueue);
352
        mGFFAQueue.removeEventListener(this);
353
       
354
        int screenW=mScreenTexture.getWidth();
355
        int screenH=mScreenTexture.getHeight();
356
        
357
        int logoW = mLogoTexture.getWidth();
358
        int logoH = mLogoTexture.getHeight();
359
      
360
        int initSize= (int)(3.0f*screenW/logoW);
361
        int finaSize= (int)(0.1f*screenW/logoW);
362
      
363
        Dynamic3D di = new Dynamic3D(10000,0.5f);
364
        di.add(new Static3D(initSize,initSize,1));
365
        di.add(new Static3D(finaSize,finaSize,1));
366

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