Project

General

Profile

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

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

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
   
105
  private GLSurfaceView mView;
106
  private DistortedTexture mGFFATexture, mLogoTexture, mCrawlTexture, mCrawlBackgroundTexture, mStarTexture;
107
  private DistortedEffects mGFFAEffects, mLogoEffects, mCrawlEffects, mCrawlBackgroundEffects;
108
  private DistortedEffects[] mStarEffects;
109
  private DistortedNode mBackground;
110
  private DistortedScreen mScreen;
111
  private MeshFlat mQuad;
112

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

    
117
///////////////////////////////////////////////////////////////////////////////////////////////////
118

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

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

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

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

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

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

    
143
///////////////////////////////////////////////////////////////////////////////////////////////////
144

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

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

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

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

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

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

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

    
187
    setupBitmaps();
188

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

    
201
  private void setupScreen(int w, int h)
202
    {
203
    mCrawlBackgroundTexture = new DistortedTexture(w,(int)(Math.sqrt(3.0)*h));
204
       
205
    int randomA, randomX, randomY, randomTime;
206
    float randomS, randomAlpha1, randomAlpha2;
207
       
208
    Static3D center = new Static3D(0,0,0);
209
    Static3D axis   = new Static3D(0,0,1);
210
    Static1D alphaNoise = new Static1D(0.4f);
211

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

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

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

    
319
    gffaID = mGFFAEffects.getID();
320
    logoID = mLogoEffects.getID();
321
    crawlID= mCrawlEffects.getID();
322
    }
323
 
324
///////////////////////////////////////////////////////////////////////////////////////////////////
325

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

    
333
    float left=x,w = (numspaces>0 ? (length-paint.measureText(str))/numspaces : 0);
334
    String tmp;
335
    int begin,end=0;
336

    
337
    while( end<len )
338
      {
339
      begin=end;
340
      end = str.indexOf(' ', begin)+1;
341
      if( end<=0 ) end = len;
342

    
343
      tmp = str.substring(begin,end);
344
      c.drawText( tmp, left, y, paint);
345
      left+= (paint.measureText(tmp)+w);
346
      }  
347
    }
348

    
349
///////////////////////////////////////////////////////////////////////////////////////////////////
350
   
351
  private int retNumSpaces(String str)
352
    {
353
    int begin=0, ret=0;
354

    
355
    while( true )
356
      {
357
      begin = str.indexOf(' ', begin) +1;
358

    
359
      if( begin>0 ) ret++;
360
      else break;
361
      }
362

    
363
    return ret;
364
    }
365
    
366
///////////////////////////////////////////////////////////////////////////////////////////////////
367
// the library sending messages to us. This is running on a library 'MessageSender' thread.
368

    
369
  public void effectMessage(final EffectMessage em, final long effectID, final EffectNames effectName, final long objectID)
370
    {
371
    if( em==EffectMessage.EFFECT_FINISHED )
372
      {
373
      if( objectID == gffaID )
374
        {
375
        mScreen.detach(mGFFAEffects);
376
        mGFFATexture.markForDeletion();
377

    
378
        int screenW=mScreen.getWidth();
379
        int screenH=mScreen.getHeight();
380
        
381
        int logoW = mLogoTexture.getWidth();
382
        int logoH = mLogoTexture.getHeight();
383
      
384
        int initSize= (int)(3.0f*screenW/logoW);
385
        int finaSize= (int)(0.1f*screenW/logoW);
386
      
387
        Dynamic3D di = new Dynamic3D(10000,0.5f);
388
        di.add(new Static3D(initSize,initSize,1));
389
        di.add(new Static3D(finaSize,finaSize,1));
390

    
391
        mLogoEffects.move( new Static3D(screenW/2,screenH/2,0) );
392
        mLogoEffects.scale(di);
393
        mLogoEffects.move( new Static3D(-logoW/2,-logoH/2,0) );
394
      
395
        mScreen.attach(mLogoTexture, mLogoEffects,mQuad);
396
        mLogoEffects.registerForMessages(this);
397
        }
398
      else if( objectID==logoID )
399
        {
400
        mScreen.detach(mLogoEffects);
401
        mLogoTexture.markForDeletion();
402
        
403
        int crawlW = mCrawlTexture.getWidth();
404
        int crawlH = mCrawlTexture.getHeight();
405
        int screenW= mScreen.getWidth();
406
        int screenH= mScreen.getHeight();
407
        int backH  = mCrawlBackgroundTexture.getHeight();
408
        float scale= (float)screenW/crawlW;
409
      
410
        Dynamic3D di = new Dynamic3D(60000,0.5f);
411
        di.add(new Static3D(screenW/2,+backH       , 0));
412
        di.add(new Static3D(screenW/2,-scale*crawlH, 0));
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/2), region, true);
420
        
421
        mCrawlEffects.move(di);
422
        mCrawlEffects.scale( new Static3D(scale,scale,scale) );
423
        mCrawlEffects.move( new Static3D(-crawlW/2,0,0) );
424
        
425
        mBackground = mScreen.attach(mCrawlBackgroundTexture, mCrawlBackgroundEffects,mQuad);
426
        mBackground.attach(mCrawlTexture, mCrawlEffects,mQuad);
427
        mBackground.glDisable(GLES30.GL_DEPTH_TEST);
428
        mBackground.glDepthMask(false);
429
        mCrawlEffects.registerForMessages(this);
430
        }
431
      else if( objectID==crawlID )
432
        {
433
        mScreen.detach(mBackground);
434
        mBackground.detach(mCrawlEffects);
435
        mCrawlTexture.markForDeletion();
436
        mCrawlBackgroundEffects.abortAllEffects();
437
        mCrawlBackgroundTexture.markForDeletion();
438
        }
439
      }
440
    }
441
  }
(2-2/3)