Project

General

Profile

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

examples / src / main / java / org / distorted / examples / starwars / StarWarsRenderer.java @ 2f7afccf

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
  private final float FOV_ANGLE   =  60.0f;
105

    
106
  private GLSurfaceView mView;
107
  private DistortedTexture mGFFATexture, mLogoTexture, mCrawlTexture, mCrawlBackgroundTexture, mStarTexture;
108
  private DistortedEffects mGFFAEffects, mLogoEffects, mCrawlEffects, mCrawlBackgroundEffects;
109
  private DistortedEffects[] mStarEffects;
110
  private DistortedNode mBackground;
111
  private DistortedScreen mScreen;
112
  private MeshFlat mQuad;
113

    
114
  private long gffaID, logoID, crawlID;
115
  private Random mRnd = new Random(0);
116
  private int mWidth, mHeight;
117

    
118
///////////////////////////////////////////////////////////////////////////////////////////////////
119

    
120
  StarWarsRenderer(GLSurfaceView v)
121
    {
122
    mView = v;
123

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

    
126
    mGFFAEffects            = new DistortedEffects();
127
    mLogoEffects            = new DistortedEffects();
128
    mCrawlEffects           = new DistortedEffects();
129
    mCrawlBackgroundEffects = new DistortedEffects();
130

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

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

    
140
    mScreen = new DistortedScreen();
141
    mScreen.setProjection(FOV_ANGLE, 0.02f);
142
    }
143

    
144
///////////////////////////////////////////////////////////////////////////////////////////////////
145

    
146
  public void onPause()
147
    {
148
    mWidth = 0;
149
    mHeight= 0;
150
    }
151

    
152
///////////////////////////////////////////////////////////////////////////////////////////////////
153
   
154
  public void onDrawFrame(GL10 glUnused) 
155
    {
156
    GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
157
    mScreen.render(System.currentTimeMillis());
158
    }
159

    
160
///////////////////////////////////////////////////////////////////////////////////////////////////
161
    
162
  public void onSurfaceChanged(GL10 glUnused, int width, int height) 
163
    {
164
    if( mWidth!=width || mHeight!=height )  // after onPause() we get 2 calls here
165
      {
166
      mWidth = width;
167
      mHeight= height;
168

    
169
      mGFFAEffects.abortAllEffects();
170
      mLogoEffects.abortAllEffects();
171
      mCrawlEffects.abortAllEffects();
172
      mCrawlBackgroundEffects.abortAllEffects();
173

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

    
176
      mScreen.detachAll();
177
      setupScreen(width,height);
178
      mScreen.resize(width, height);
179
      }
180
    }
181

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

    
188
    setupBitmaps();
189

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

    
202
  private void setupScreen(int w, int h)
203
    {
204
    double angleA = (90.0f - FOV_ANGLE/2)*Math.PI/180;
205
    double angleB = (90.0f - FOV_ANGLE/2 +CRAWL_ANGLE)*Math.PI/180;
206

    
207
    mCrawlBackgroundTexture = new DistortedTexture(w,(int)(h*Math.sin(angleA)/Math.sin(angleB)));
208
       
209
    int randomA, randomX, randomY, randomTime;
210
    float randomS, randomAlpha1, randomAlpha2;
211
       
212
    Static3D center = new Static3D(0,0,0);
213
    Static3D axis   = new Static3D(0,0,1);
214
    Static1D alphaNoise = new Static1D(0.4f);
215

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

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

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

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

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

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

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

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

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

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

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

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

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

    
382
        int screenW=mScreen.getWidth();
383
        int screenH=mScreen.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
        mScreen.attach(mLogoTexture, mLogoEffects,mQuad);
400
        mLogoEffects.registerForMessages(this);
401
        }
402
      else if( objectID==logoID )
403
        {
404
        mScreen.detach(mLogoEffects);
405
        mLogoTexture.markForDeletion();
406
        
407
        int crawlW = mCrawlTexture.getWidth();
408
        int crawlH = mCrawlTexture.getHeight();
409
        int screenW= mScreen.getWidth();
410
        int screenH= mScreen.getHeight();
411
        int backH  = mCrawlBackgroundTexture.getHeight();
412
        float scale= (float)screenW/crawlW;
413

    
414
        mCrawlBackgroundEffects.move( new Static3D(0,screenH-backH,0) );
415
        mCrawlBackgroundEffects.rotate( new Static1D(CRAWL_ANGLE), new Static3D(1,0,0), new Static3D(screenW/2,backH,0) );
416

    
417
        final int transpDist = 5;
418
        Static4D region = new Static4D(screenW/2,(1-transpDist)*backH,transpDist*backH,transpDist*backH);
419
        mCrawlBackgroundEffects.alpha(new Static1D(1-transpDist*0.6f), region, true);
420

    
421
        Dynamic3D di = new Dynamic3D(70000,0.5f);
422
        di.add(new Static3D(screenW/2,+backH       , 0));
423
        di.add(new Static3D(screenW/2,-scale*crawlH, 0));
424

    
425
        mCrawlEffects.move(di);
426
        mCrawlEffects.scale( new Static3D(scale,scale,scale) );
427
        mCrawlEffects.move( new Static3D(-crawlW/2,0,0) );
428
        
429
        mBackground = mScreen.attach(mCrawlBackgroundTexture, mCrawlBackgroundEffects,mQuad);
430
        mBackground.attach(mCrawlTexture, mCrawlEffects,mQuad);
431
        mBackground.glDisable(GLES30.GL_DEPTH_TEST);
432
        mBackground.glDepthMask(false);
433
        mCrawlEffects.registerForMessages(this);
434
        }
435
      else if( objectID==crawlID )
436
        {
437
        mScreen.detach(mBackground);
438
        mBackground.detach(mCrawlEffects);
439
        mCrawlTexture.markForDeletion();
440
        mCrawlBackgroundEffects.abortAllEffects();
441
        mCrawlBackgroundTexture.markForDeletion();
442
        }
443
      }
444
    }
445
  }
(2-2/3)