Project

General

Profile

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

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

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.effect.EffectName;
32
import org.distorted.library.effect.FragmentEffectAlpha;
33
import org.distorted.library.effect.MatrixEffectMove;
34
import org.distorted.library.effect.MatrixEffectRotate;
35
import org.distorted.library.effect.MatrixEffectScale;
36
import org.distorted.library.main.DistortedNode;
37
import org.distorted.library.main.DistortedScreen;
38
import org.distorted.library.main.MeshFlat;
39
import org.distorted.library.type.Dynamic1D;
40
import org.distorted.library.type.Dynamic3D;
41
import org.distorted.library.type.Static1D;
42
import org.distorted.library.type.Static3D;
43
import org.distorted.library.type.Static4D;
44
import org.distorted.library.message.EffectListener;
45
import org.distorted.library.message.EffectMessage;
46
import org.distorted.library.main.Distorted;
47
import org.distorted.library.main.DistortedTexture;
48
import org.distorted.library.main.DistortedEffects;
49

    
50
import android.graphics.Bitmap;
51
import android.graphics.BitmapFactory;
52
import android.graphics.Canvas;
53
import android.graphics.Paint;
54
import android.graphics.Typeface;
55
import android.opengl.GLES30;
56
import android.opengl.GLSurfaceView;
57

    
58
///////////////////////////////////////////////////////////////////////////////////////////////////
59

    
60
class StarWarsRenderer implements GLSurfaceView.Renderer, EffectListener
61
  {
62
  private final String[] mGFFAString = 
63
         
64
            { "A long time ago, in a galaxy far,",
65
              "far away...." };                    // yes, there really was a four-dot ellipsis
66

    
67
  private final String[] mCRAWLString = 
68
      
69
            { "It is a period of civil war.",      // in the original 1977 version, there was no 
70
              "Rebel spaceships, striking",        // 'Episode IV New Hope' subtitle line before
71
              "from a hidden base, have",          // the crawl. Lets keep to the classic.
72
              "won their first victory",
73
              "against the evil Galactic",
74
              "Empire.",
75
              "",
76
              "During the battle, rebel",
77
              "spies managed to steal",
78
              "secret plans to the Empire's",
79
              "ultimate weapon, the",
80
              "DEATH STAR, an armored",
81
              "space station with enough",
82
              "power to destroy an entire",
83
              "planet.",
84
              "",
85
              "Pursued by the Empire's",
86
              "sinister agents, Princess",
87
              "Leia races home aboard her",
88
              "starship, custodian of the",
89
              "stolen plans that can save",
90
              "her people and restore",
91
              "freedom to the galaxy...." };      // four-dot.
92
   
93
  private final int NUM_STARS = 40;
94
   
95
  private final int CRAWL_COLOR = 0xffffe81f;
96
  private final int GFFA_COLOR  = 0xff0000ff;
97
  private final int FONT_HEIGHT      = 40;
98
  private final int VERTICAL_SPACING = 10;
99
  private final String CRAWL_TYPEFACE = "News Gothic";
100
   
101
  private final int CRAWL_WIDTH = 500;
102
  private final int CRAWL_HEIGHT= (FONT_HEIGHT+VERTICAL_SPACING)*(mCRAWLString.length+1);
103
   
104
  private final int GFFA_WIDTH = 600;
105
  private final int GFFA_HEIGHT= (FONT_HEIGHT+VERTICAL_SPACING)*(mGFFAString.length+1);
106
   
107
  private final float CRAWL_ANGLE = -30.0f;
108
  private final float FOV_ANGLE   =  60.0f;
109

    
110
  private GLSurfaceView mView;
111
  private DistortedTexture mGFFATexture, mLogoTexture, mCrawlTexture, mCrawlBackgroundTexture, mStarTexture;
112
  private DistortedEffects mGFFAEffects, mLogoEffects, mCrawlEffects, mCrawlBackgroundEffects;
113
  private DistortedEffects[] mStarEffects;
114
  private DistortedNode mBackground;
115
  private DistortedScreen mScreen;
116
  private MeshFlat mQuad;
117

    
118
  private long gffaID, logoID, crawlID;
119
  private Random mRnd = new Random(0);
120
  private int mWidth, mHeight;
121

    
122
///////////////////////////////////////////////////////////////////////////////////////////////////
123

    
124
  StarWarsRenderer(GLSurfaceView v)
125
    {
126
    mView = v;
127

    
128
    mQuad = new MeshFlat(1,1);
129

    
130
    mGFFAEffects            = new DistortedEffects();
131
    mLogoEffects            = new DistortedEffects();
132
    mCrawlEffects           = new DistortedEffects();
133
    mCrawlBackgroundEffects = new DistortedEffects();
134

    
135
    if( NUM_STARS>0 )
136
      {
137
      mStarEffects = new DistortedEffects[NUM_STARS];
138
      mStarEffects[0] = new DistortedEffects();
139

    
140
      for (int i = 1; i < NUM_STARS; i++)
141
        mStarEffects[i] = new DistortedEffects(mStarEffects[0], Distorted.CLONE_VERTEX);
142
      }
143

    
144
    mScreen = new DistortedScreen();
145
    mScreen.setProjection(FOV_ANGLE, 0.02f);
146
    }
147

    
148
///////////////////////////////////////////////////////////////////////////////////////////////////
149

    
150
  public void onPause()
151
    {
152
    mWidth = 0;
153
    mHeight= 0;
154
    }
155

    
156
///////////////////////////////////////////////////////////////////////////////////////////////////
157
   
158
  public void onDrawFrame(GL10 glUnused) 
159
    {
160
    mScreen.render(System.currentTimeMillis());
161
    }
162

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

    
172
      mGFFAEffects.abortAllEffects();
173
      mLogoEffects.abortAllEffects();
174
      mCrawlEffects.abortAllEffects();
175
      mCrawlBackgroundEffects.abortAllEffects();
176

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

    
179
      mScreen.detachAll();
180
      setupScreen(width,height);
181
      mScreen.resize(width, height);
182
      }
183
    }
184

    
185
///////////////////////////////////////////////////////////////////////////////////////////////////
186
    
187
  public void onSurfaceCreated(GL10 glUnused, EGLConfig config) 
188
    {
189
    setupBitmaps();
190

    
191
    DistortedEffects.enableEffect(EffectName.SMOOTH_ALPHA);
192
    DistortedEffects.enableEffect(EffectName.ALPHA);
193

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

    
206
  private void setupScreen(int w, int h)
207
    {
208
    double angleA = (90.0f - FOV_ANGLE/2)*Math.PI/180;
209
    double angleB = (90.0f - FOV_ANGLE/2 +CRAWL_ANGLE)*Math.PI/180;
210

    
211
    if( mCrawlBackgroundTexture!=null ) mCrawlBackgroundTexture.markForDeletion();
212
    mCrawlBackgroundTexture = new DistortedTexture(w,(int)(h*Math.sin(angleA)/Math.sin(angleB)));
213
       
214
    int randomA, randomX, randomY, randomTime;
215
    float randomS, randomAlpha1, randomAlpha2;
216
       
217
    Static3D center = new Static3D(0,0,0);
218
    Static3D axis   = new Static3D(0,0,1);
219
    Static1D alphaNoise = new Static1D(0.4f);
220

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

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

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

    
328
    gffaID = mGFFAEffects.getID();
329
    logoID = mLogoEffects.getID();
330
    crawlID= mCrawlEffects.getID();
331
    }
332
 
333
///////////////////////////////////////////////////////////////////////////////////////////////////
334

    
335
  private void displayJustified(String str, int x, int y, int length, Canvas c, Paint paint)
336
    { 
337
    int len       = str.length();
338
    int numspaces = retNumSpaces(str);
339
    
340
    if( len>0 && str.charAt(len-1) == ' ' ) numspaces--;
341

    
342
    float left=x,w = (numspaces>0 ? (length-paint.measureText(str))/numspaces : 0);
343
    String tmp;
344
    int begin,end=0;
345

    
346
    while( end<len )
347
      {
348
      begin=end;
349
      end = str.indexOf(' ', begin)+1;
350
      if( end<=0 ) end = len;
351

    
352
      tmp = str.substring(begin,end);
353
      c.drawText( tmp, left, y, paint);
354
      left+= (paint.measureText(tmp)+w);
355
      }  
356
    }
357

    
358
///////////////////////////////////////////////////////////////////////////////////////////////////
359
   
360
  private int retNumSpaces(String str)
361
    {
362
    int begin=0, ret=0;
363

    
364
    while( true )
365
      {
366
      begin = str.indexOf(' ', begin) +1;
367

    
368
      if( begin>0 ) ret++;
369
      else break;
370
      }
371

    
372
    return ret;
373
    }
374
    
375
///////////////////////////////////////////////////////////////////////////////////////////////////
376
// the library sending messages to us. This is running on a library 'MessageSender' thread.
377

    
378
  public void effectMessage(final EffectMessage em, final long effectID, final long objectID)
379
    {
380
    if( em==EffectMessage.EFFECT_FINISHED )
381
      {
382
      if( objectID == gffaID )
383
        {
384
        mScreen.detach(mGFFAEffects);
385
        mGFFATexture.markForDeletion();
386

    
387
        int screenW=mScreen.getWidth();
388
        int screenH=mScreen.getHeight();
389
        
390
        int logoW = mLogoTexture.getWidth();
391
        int logoH = mLogoTexture.getHeight();
392
      
393
        int initSize= (int)(3.0f*screenW/logoW);
394
        int finaSize= (int)(0.1f*screenW/logoW);
395
      
396
        Dynamic3D di = new Dynamic3D(10000,0.5f);
397
        di.add(new Static3D(initSize,initSize,1));
398
        di.add(new Static3D(finaSize,finaSize,1));
399

    
400
        mLogoEffects.apply( new MatrixEffectMove(new Static3D(screenW/2,screenH/2,0)) );
401
        mLogoEffects.apply( new MatrixEffectScale(di) );
402
        mLogoEffects.apply( new MatrixEffectMove(new Static3D(-logoW/2,-logoH/2,0)) );
403
      
404
        mScreen.attach(mLogoTexture, mLogoEffects,mQuad);
405
        mLogoEffects.registerForMessages(this);
406
        }
407
      else if( objectID==logoID )
408
        {
409
        mScreen.detach(mLogoEffects);
410
        mLogoTexture.markForDeletion();
411
        
412
        int crawlW = mCrawlTexture.getWidth();
413
        int crawlH = mCrawlTexture.getHeight();
414
        int screenW= mScreen.getWidth();
415
        int screenH= mScreen.getHeight();
416
        int backH  = mCrawlBackgroundTexture.getHeight();
417
        float scale= (float)screenW/crawlW;
418

    
419
        mCrawlBackgroundEffects.apply( new MatrixEffectMove(new Static3D(0,screenH-backH,0)) );
420
        mCrawlBackgroundEffects.apply( new MatrixEffectRotate(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.apply( new FragmentEffectAlpha(new Static1D(1-transpDist*0.6f), region, true) );
425

    
426
        Dynamic3D di = new Dynamic3D(70000,0.5f);
427
        di.add(new Static3D(screenW/2,+backH       , 0));
428
        di.add(new Static3D(screenW/2,-scale*crawlH, 0));
429

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