Project

General

Profile

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

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

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

    
48
import android.graphics.Bitmap;
49
import android.graphics.BitmapFactory;
50
import android.graphics.Canvas;
51
import android.graphics.Paint;
52
import android.graphics.Typeface;
53
import android.opengl.GLES31;
54
import android.opengl.GLSurfaceView;
55

    
56
///////////////////////////////////////////////////////////////////////////////////////////////////
57

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

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

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

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

    
120
///////////////////////////////////////////////////////////////////////////////////////////////////
121

    
122
  StarWarsRenderer(GLSurfaceView v)
123
    {
124
    mView = v;
125

    
126
    mQuad = new MeshFlat(1,1);
127

    
128
    mGFFAEffects            = new DistortedEffects();
129
    mLogoEffects            = new DistortedEffects();
130
    mCrawlEffects           = new DistortedEffects();
131
    mCrawlBackgroundEffects = new DistortedEffects();
132

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

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

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

    
146
///////////////////////////////////////////////////////////////////////////////////////////////////
147

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

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

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

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

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

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

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

    
189
    FragmentEffectAlpha.enable();
190

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

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

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

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

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

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

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

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

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

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

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

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

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

    
365
      if( begin>0 ) ret++;
366
      else break;
367
      }
368

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

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

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

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

    
415
        mCrawlBackgroundEffects.apply( new MatrixEffectRotate(new Static1D(CRAWL_ANGLE), new Static3D(1,0,0), new Static3D(screenW/2,0,0)) );
416

    
417
        final int transpDist = 5;
418
        Static3D center = new Static3D( screenW/2 , transpDist*backH , 0 );
419
        Static3D region = new Static3D( transpDist*backH , transpDist*backH , transpDist*backH );
420
        mCrawlBackgroundEffects.apply( new FragmentEffectAlpha(new Static1D(1-transpDist*0.6f), center, region, true) );
421

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

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