Project

General

Profile

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

examples / src / main / java / org / distorted / examples / starwars / StarWarsRenderer.java @ 885b9cca

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
    FragmentEffectAlpha.enable();
192

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
418
        mCrawlBackgroundEffects.apply( new MatrixEffectMove(new Static3D(0,screenH-backH,0)) );
419
        mCrawlBackgroundEffects.apply( new MatrixEffectRotate(new Static1D(CRAWL_ANGLE), new Static3D(1,0,0), new Static3D(screenW/2,backH,0)) );
420

    
421
        final int transpDist = 5;
422
        Static4D region = new Static4D(screenW/2,(1-transpDist)*backH,transpDist*backH,transpDist*backH);
423
        mCrawlBackgroundEffects.apply( new FragmentEffectAlpha(new Static1D(1-transpDist*0.6f), region, true) );
424

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

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