Project

General

Profile

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

examples / src / main / java / org / distorted / examples / starwars / StarWarsRenderer.java @ 95bc9f69

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
    Distorted.onSurfaceChanged(width, height); 
149
    setupScreen(width,height);
150
    }
151

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

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

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

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

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

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

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

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

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

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

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

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

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

    
333
      if( begin>0 ) ret++;
334
      else break;
335
      }
336

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

    
343
  public void effectMessage(final EffectMessage em, final long effectID, final EffectNames effectName, final long objectID, final String message)
344
    {
345
    if( em==EffectMessage.EFFECT_FINISHED )
346
      {
347
      if( objectID == gffaID )
348
        {
349
        mRoot.detach(mGFFAQueue);
350
        mGFFAQueue.delete();
351
        mGFFATexture.markForDeletion();
352

    
353
        int screenW=mScreenTexture.getWidth();
354
        int screenH=mScreenTexture.getHeight();
355
        
356
        int logoW = mLogoTexture.getWidth();
357
        int logoH = mLogoTexture.getHeight();
358
      
359
        int initSize= (int)(3.0f*screenW/logoW);
360
        int finaSize= (int)(0.1f*screenW/logoW);
361
      
362
        Dynamic3D di = new Dynamic3D(10000,0.5f);
363
        di.add(new Static3D(initSize,initSize,1));
364
        di.add(new Static3D(finaSize,finaSize,1));
365

    
366
        mLogoQueue.move( new Static3D(screenW/2,screenH/2,0) );
367
        mLogoQueue.scale(di);
368
        mLogoQueue.move( new Static3D(-logoW/2,-logoH/2,0) );
369
      
370
        mRoot.attach(mLogoTexture,mLogoQueue,mQuad);
371
        mLogoQueue.addEventListener(this);
372
        }
373
      else if( objectID==logoID )
374
        {
375
        mRoot.detach(mLogoQueue);
376
        mLogoQueue.delete();
377
        mLogoTexture.markForDeletion();
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.delete();
410
        mCrawlTexture.markForDeletion();
411
        mCrawlBackgroundQueue.delete();
412
        mCrawlBackgroundTexture.markForDeletion();
413
        }
414
      }
415
    }
416
  }
(2-2/3)