Project

General

Profile

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

examples / src / main / java / org / distorted / examples / starwars / StarWarsRenderer.java @ 10b7e588

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.GridFlat;
32
import org.distorted.library.EffectNames;
33
import org.distorted.library.type.Dynamic1D;
34
import org.distorted.library.type.Dynamic3D;
35
import org.distorted.library.DistortedObjectTree;
36
import org.distorted.library.type.Static1D;
37
import org.distorted.library.type.Static3D;
38
import org.distorted.library.type.Static4D;
39
import org.distorted.library.message.EffectListener;
40
import org.distorted.library.message.EffectMessage;
41
import org.distorted.library.Distorted;
42
import org.distorted.library.DistortedObject;
43

    
44
import android.graphics.Bitmap;
45
import android.graphics.BitmapFactory;
46
import android.graphics.Canvas;
47
import android.graphics.Paint;
48
import android.graphics.Typeface;
49
import android.opengl.GLES20;
50
import android.opengl.GLSurfaceView;
51

    
52
///////////////////////////////////////////////////////////////////////////////////////////////////
53

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

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

    
112

    
113
///////////////////////////////////////////////////////////////////////////////////////////////////
114

    
115
  StarWarsRenderer(GLSurfaceView v)
116
    {
117
    mView = v;
118

    
119
    mQuad = new GridFlat(1,1);
120
    Distorted.setProjection(60.0f, 0.0f, 0.0f);
121
    }
122

    
123
///////////////////////////////////////////////////////////////////////////////////////////////////
124
   
125
  public void onDrawFrame(GL10 glUnused) 
126
    {
127
    GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
128
    mRoot.draw(System.currentTimeMillis());
129
    }
130

    
131
///////////////////////////////////////////////////////////////////////////////////////////////////
132
    
133
  public void onSurfaceChanged(GL10 glUnused, int width, int height) 
134
    { 
135
    Distorted.onSurfaceChanged(width, height); 
136
    setupScreen(width,height);
137
    }
138

    
139
///////////////////////////////////////////////////////////////////////////////////////////////////
140
    
141
  public void onSurfaceCreated(GL10 glUnused, EGLConfig config) 
142
    {
143
    GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
144

    
145
    setupBitmaps();
146
         
147
    try
148
      {
149
      Distorted.onSurfaceCreated(mView.getContext());
150
      }
151
    catch(Exception ex)
152
      {
153
      android.util.Log.e("Star Wars", ex.getMessage() );
154
      }
155
    }
156
    
157
///////////////////////////////////////////////////////////////////////////////////////////////////
158

    
159
  private void setupScreen(int w, int h)
160
    {
161
    mScreen = new DistortedObject(w,h,1);
162
    mRoot = new DistortedObjectTree(mScreen,mQuad);
163
      
164
    mCrawlBackground = new DistortedObject(w,(int)(Math.sqrt(3.0)*h),1);
165
       
166
    int randomA, randomX, randomY, randomTime;
167
    float randomS, randomAlpha1, randomAlpha2;
168
       
169
    Static3D center = new Static3D(0,0,0);
170
    Static3D axis   = new Static3D(0,0,1);
171

    
172
    Static1D alphaNoise = new Static1D(0.4f);
173

    
174
    for(int i=0; i<NUM_STARS; i++)
175
      {
176
      randomX = mRnd.nextInt(w);
177
      randomY = mRnd.nextInt(h);
178
      randomS = 0.2f+ mRnd.nextFloat();
179
      randomA = (int)(180*mRnd.nextFloat());
180
      randomAlpha1 = 0.2f + 0.8f*mRnd.nextFloat();
181
      randomAlpha2 = 0.8f + 0.2f*mRnd.nextFloat();
182
      randomTime = 500+mRnd.nextInt(2000);
183
      
184
      mStars[i].move( new Static3D(randomX,randomY,0) );
185
      mStars[i].scale( new Static3D(randomS,randomS,randomS) );
186
      mStars[i].rotate( new Static1D(randomA), axis, center );
187
      
188
      Dynamic1D di = new Dynamic1D(randomTime,0.0f);
189
      di.setNoise(alphaNoise);
190
      di.add(new Static1D(randomAlpha1));
191
      di.add(new Static1D(randomAlpha2));
192
      
193
      mStars[i].alpha(di);
194
      
195
      mRoot.attach(mStars[i], mQuad);
196
      }
197
      
198
    float scale = (0.5f*w/mGFFA.getWidth());
199
    
200
    Dynamic1D di = new Dynamic1D(6000,0.5f);
201
    di.add(new Static1D(1.0f));
202
    di.add(new Static1D(1.0f));
203
    di.add(new Static1D(0.0f));
204
    
205
    mGFFA.move( new Static3D(w/5,h/3,0) );
206
    mGFFA.scale( new Static3D(scale,scale,scale) );
207
    mGFFA.alpha(di);
208
      
209
    mRoot.attach(mGFFA, mQuad);
210
    mGFFA.addEventListener(this); 
211
    }
212
    
213
///////////////////////////////////////////////////////////////////////////////////////////////////
214

    
215
  private void setupBitmaps()
216
    {
217
    InputStream is1 = mView.getContext().getResources().openRawResource(R.raw.starwars);
218
    InputStream is2 = mView.getContext().getResources().openRawResource(R.raw.star);
219
    
220
    Bitmap bitmapStar, bitmapGFFA, bitmapLogo, bitmapText;
221
      
222
    try 
223
      {
224
      bitmapLogo = BitmapFactory.decodeStream(is1);
225
      bitmapStar = BitmapFactory.decodeStream(is2);
226
      } 
227
    finally 
228
      {
229
      try 
230
        {
231
        is1.close();
232
        is2.close();
233
        } 
234
      catch(IOException e) { }
235
      } 
236
      
237
    Paint paint = new Paint();
238
    paint.setAntiAlias(true);
239
    paint.setTextAlign(Paint.Align.LEFT);
240
    paint.setTextSize(FONT_HEIGHT);
241
    paint.setColor(GFFA_COLOR);
242
      
243
    Typeface tf = Typeface.create(CRAWL_TYPEFACE, Typeface.BOLD);
244
    paint.setTypeface(tf);     
245
 
246
    ///// create GFFA ///////////////////
247
    mGFFA  = new DistortedObject(GFFA_WIDTH, GFFA_HEIGHT, 1);
248
    bitmapGFFA = Bitmap.createBitmap(GFFA_WIDTH,GFFA_HEIGHT,Bitmap.Config.ARGB_8888);
249
    bitmapGFFA.eraseColor(0x00000000);
250
    Canvas gffaCanvas = new Canvas(bitmapGFFA);
251
      
252
    for(int i=0; i<mGFFAString.length; i++)
253
      {
254
      gffaCanvas.drawText(mGFFAString[i], 0, (i+1)*(FONT_HEIGHT+VERTICAL_SPACING), paint);  
255
      }
256
  
257
    mGFFA.setTexture(bitmapGFFA);
258
      
259
    ///// create Logo ///////////////////
260
    mLogo  = new DistortedObject(bitmapLogo.getWidth(),bitmapLogo.getHeight(),1);
261
    mLogo.setTexture(bitmapLogo);
262

    
263
    ///// create CRAWL //////////////////
264
    mCrawl = new DistortedObject(CRAWL_WIDTH, CRAWL_HEIGHT, 1);
265
    bitmapText = Bitmap.createBitmap(CRAWL_WIDTH,CRAWL_HEIGHT,Bitmap.Config.ARGB_8888);
266
    bitmapText.eraseColor(0x00000000);
267
    Canvas textCanvas = new Canvas(bitmapText);
268
    paint.setColor(CRAWL_COLOR);
269
  
270
    for(int i=0; i<mCRAWLString.length; i++)
271
      {
272
      displayJustified(mCRAWLString[i], 0, (i+1)*(FONT_HEIGHT+VERTICAL_SPACING), CRAWL_WIDTH, textCanvas, paint);  
273
      }
274
      
275
    mCrawl.setTexture(bitmapText);
276
      
277
    ///// create Stars ///////////////////
278
      
279
    mStars = new DistortedObject[NUM_STARS];
280
      
281
    mStars[0] = new DistortedObject(bitmapStar.getWidth(),bitmapStar.getHeight(),1);
282
    mStars[0].setTexture(bitmapStar);
283

    
284
    for(int i=1; i<NUM_STARS; i++)
285
      {
286
      mStars[i] = new DistortedObject(mStars[0], Distorted.CLONE_BITMAP|Distorted.CLONE_VERTEX);
287
      }
288
      
289
    gffaID = mGFFA.getID();
290
    logoID = mLogo.getID();
291
    crawlID= mCrawl.getID();
292
    }
293
 
294
///////////////////////////////////////////////////////////////////////////////////////////////////
295

    
296
  private void displayJustified(String str, int x, int y, int length, Canvas c, Paint paint)
297
    { 
298
    int len       = str.length();
299
    int numspaces = retNumSpaces(str);
300
    
301
    if( len>0 && str.charAt(len-1) == ' ' ) numspaces--;
302

    
303
    float left=x,w = (numspaces>0 ? (length-paint.measureText(str))/numspaces : 0);
304
    String tmp;
305
    int begin,end=0;
306

    
307
    while( end<len )
308
      {
309
      begin=end;
310
      end = str.indexOf(' ', begin)+1;
311
      if( end<=0 ) end = len;
312

    
313
      tmp = str.substring(begin,end);
314
      c.drawText( tmp, left, y, paint);
315
      left+= (paint.measureText(tmp)+w);
316
      }  
317
    }
318

    
319
///////////////////////////////////////////////////////////////////////////////////////////////////
320
   
321
  private int retNumSpaces(String str)
322
    {
323
    int begin=0, ret=0;
324

    
325
    while( true )
326
      {
327
      begin = str.indexOf(' ', begin) +1;
328

    
329
      if( begin>0 ) ret++;
330
      else break;
331
      }
332

    
333
    return ret;
334
    }
335
    
336
///////////////////////////////////////////////////////////////////////////////////////////////////
337
// the library sending messages to us. This is running on a library 'MessageSender' thread.
338

    
339
  public void effectMessage(final EffectMessage em, final long effectID, final EffectNames effectName, final long objectID, final String message)
340
    {
341
    if( em==EffectMessage.EFFECT_FINISHED )
342
      {
343
      if( objectID == gffaID )
344
        {
345
        mRoot.detach(mGFFA);   
346
        mGFFA.removeEventListener(this);
347
       
348
        int screenW=mScreen.getWidth();
349
        int screenH=mScreen.getHeight();
350
        
351
        int logoW = mLogo.getWidth();
352
        int logoH = mLogo.getHeight();
353
      
354
        int initSize= (int)(3.0f*screenW/logoW);
355
        int finaSize= (int)(0.1f*screenW/logoW);
356
      
357
        Dynamic3D di = new Dynamic3D(10000,0.5f);
358
        di.add(new Static3D(initSize,initSize,1));
359
        di.add(new Static3D(finaSize,finaSize,1));
360

    
361
        mLogo.move( new Static3D(screenW/2,screenH/2,0) );
362
        mLogo.scale(di);
363
        mLogo.move( new Static3D(-logoW/2,-logoH/2,0) );
364
      
365
        mRoot.attach(mLogo,mQuad);
366
        mLogo.addEventListener(this);
367
        }
368
      else if( objectID==logoID )
369
        {
370
        mRoot.detach(mLogo);   
371
        mLogo.removeEventListener(this);
372
        
373
        int crawlW = mCrawl.getWidth();
374
        int crawlH = mCrawl.getHeight();
375
        int screenW= mScreen.getWidth();
376
        int screenH= mScreen.getHeight();
377
        int backH  = mCrawlBackground.getHeight();
378
        float scale= (float)screenW/crawlW;
379
      
380
        Dynamic3D di = new Dynamic3D(60000,0.5f);
381
        di.add(new Static3D(screenW/2,+backH       , 0));
382
        di.add(new Static3D(screenW/2,-scale*crawlH, 0));
383
        
384
        mCrawlBackground.move( new Static3D(0,screenH-backH,0) );
385
        mCrawlBackground.rotate( new Static1D(CRAWL_ANGLE), new Static3D(1,0,0), new Static3D(screenW/2,backH,0) );
386
        
387
        final int transpDist = 5;
388
        Static4D region = new Static4D(screenW/2,(1-transpDist)*backH,transpDist*backH,transpDist*backH);
389
        mCrawlBackground.alpha(new Static1D(1-transpDist/2), region, true);
390
        
391
        mCrawl.move(di);
392
        mCrawl.scale( new Static3D(scale,scale,scale) );
393
        mCrawl.move( new Static3D(-crawlW/2,0,0) );
394
        
395
        mBackground = mRoot.attach(mCrawlBackground,mQuad);
396
        mBackground.attach(mCrawl,mQuad);
397
        mCrawl.addEventListener(this);
398
        }
399
      else if( objectID==crawlID )
400
        {
401
        mRoot.detach(mBackground);
402
        mBackground.detach(mCrawl);
403
        mCrawl.removeEventListener(this);
404
        }
405
      }
406
    }
407
  }
(2-2/3)