Project

General

Profile

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

examples / src / main / java / org / distorted / examples / flatblur2 / OverlayStars.java @ 99a80c08

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2022 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is proprietary software licensed under an EULA which you should have received      //
7
// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
8
///////////////////////////////////////////////////////////////////////////////////////////////////
9

    
10
package org.distorted.examples.flatblur2;
11

    
12
import android.content.res.Resources;
13
import android.graphics.Bitmap;
14
import android.graphics.BitmapFactory;
15
import android.graphics.Canvas;
16
import android.graphics.Paint;
17

    
18
import org.distorted.examples.R;
19
import org.distorted.library.effect.EffectQuality;
20
import org.distorted.library.effect.FragmentEffectAlpha;
21
import org.distorted.library.effect.MatrixEffectMove;
22
import org.distorted.library.effect.MatrixEffectScale;
23
import org.distorted.library.effect.PostprocessEffectGlow;
24
import org.distorted.library.effect.VertexEffectMove;
25
import org.distorted.library.effect.VertexEffectScale;
26
import org.distorted.library.main.DistortedEffects;
27
import org.distorted.library.main.DistortedNode;
28
import org.distorted.library.main.DistortedScreen;
29
import org.distorted.library.main.DistortedTexture;
30
import org.distorted.library.main.InternalOutputSurface;
31
import org.distorted.library.mesh.MeshJoined;
32
import org.distorted.library.mesh.MeshQuad;
33
import org.distorted.library.message.EffectListener;
34
import org.distorted.library.type.Dynamic;
35
import org.distorted.library.type.Dynamic1D;
36
import org.distorted.library.type.Dynamic2D;
37
import org.distorted.library.type.Dynamic3D;
38
import org.distorted.library.type.Dynamic4D;
39
import org.distorted.library.type.Static1D;
40
import org.distorted.library.type.Static2D;
41
import org.distorted.library.type.Static3D;
42
import org.distorted.library.type.Static4D;
43

    
44
import java.util.Random;
45

    
46
///////////////////////////////////////////////////////////////////////////////////////////////////
47

    
48
public class OverlayStars extends OverlayGeneric implements EffectListener
49
{
50
   private static final int DUR_APP =  3500;
51
   private static final int DUR_MOV = 17500;
52
   private static final int DUR_GLO =  2600;
53

    
54
   private ListenerOverlay mListener;
55
   private DistortedNode mNodeFalling, mNodeCentral;
56
   private DistortedScreen mScreen;
57
   private DistortedTexture mTexture;
58
   private Bitmap mCountBitmap, mStarBitmap;
59
   private Canvas mCountCanvas;
60
   private Paint mPaint;
61
   private int mBmpW, mBmpH;
62
   private float mWidth, mHeight;
63
   private Random mRandom;
64
   private long mMoveID, mGlow1ID, mGlow2ID, mAlphaID;
65
   private int mTotalStars, mNewStars;
66
   private FragmentEffectAlpha mAlpha;
67
   private Dynamic1D mAlphaStrength;
68
   private boolean mIncrease;
69
   private float mTextHeight;
70

    
71
///////////////////////////////////////////////////////////////////////////////////////////////////
72

    
73
   private Dynamic3D createRandomMove(boolean increase)
74
      {
75
      Dynamic3D move = new Dynamic3D();
76
      move.setMode(Dynamic.MODE_PATH);
77
      move.setDuration(DUR_MOV);
78
      move.setCount(0.5f);
79

    
80
      float widthS = (mRandom.nextFloat()-0.5f)*mWidth*1.10f;
81
      float widthM = widthS + (mRandom.nextFloat()-0.5f)*mWidth*0.2f;
82
      float heighS = mRandom.nextFloat()*mHeight*0.2f;
83
      float heighM = (mRandom.nextFloat()-0.5f)*mHeight*0.2f;
84

    
85
      Static3D pointS = new Static3D(widthS,mHeight*0.55f+heighS,0);
86
      Static3D pointM = new Static3D(widthM,mHeight*0.25f+heighM,0);
87
      Static3D pointE = new Static3D(0,0,0);
88
      Static3D pointF = new Static3D(0,0,-10000);
89

    
90
      if( increase )
91
         {
92
         move.add(pointS);
93
         move.add(pointM);
94
         move.add(pointE);
95
         move.add(pointF);
96
         }
97
      else
98
         {
99
         move.add(pointF);
100
         move.add(pointE);
101
         move.add(pointM);
102
         move.add(pointS);
103
         }
104

    
105
      return move;
106
      }
107

    
108
///////////////////////////////////////////////////////////////////////////////////////////////////
109

    
110
   private void createAlphaEffect(boolean appear)
111
      {
112
      if( mAlpha==null )
113
         {
114
         mAlphaStrength = new Dynamic1D();
115
         mAlphaStrength.setMode(Dynamic.MODE_PATH);
116
         mAlphaStrength.setDuration(DUR_APP);
117
         mAlphaStrength.setCount(0.5f);
118
         equipAlpha(mAlphaStrength,appear);
119
         mAlpha = new FragmentEffectAlpha(mAlphaStrength);
120
         }
121
      else
122
         {
123
         mAlphaStrength.resetToBeginning();
124
         equipAlpha(mAlphaStrength,appear);
125
         }
126
      }
127

    
128
///////////////////////////////////////////////////////////////////////////////////////////////////
129

    
130
   private void equipAlpha(Dynamic1D alpha, boolean appear)
131
      {
132
      Static1D point0 = new Static1D(0.0f);
133
      Static1D point1 = new Static1D(1.0f);
134

    
135
      alpha.removeAll();
136

    
137
      if( appear )
138
        {
139
        alpha.add(point0);
140
        alpha.add(point1);
141
        }
142
      else
143
        {
144
        alpha.add(point1);
145
        alpha.add(point0);
146
        }
147
      }
148

    
149
///////////////////////////////////////////////////////////////////////////////////////////////////
150

    
151
   private float computeQuotientAndTextHeight(int total)
152
      {
153
      if( total>=10000 )
154
         {
155
         mTextHeight = 0.610f;
156
         return 0.16f;
157
         }
158
      if( total>= 1000 )
159
         {
160
         mTextHeight = 0.625f;
161
         return 0.20f;
162
         }
163
      if( total>=  100 )
164
         {
165
         mTextHeight = 0.640f;
166
         return 0.26f;
167
         }
168

    
169
      mTextHeight = 0.655f;
170
      return 0.28f;
171
      }
172

    
173
///////////////////////////////////////////////////////////////////////////////////////////////////
174

    
175
   private void createBitmap(Resources res, int total)
176
      {
177
      mStarBitmap = BitmapFactory.decodeResource(res, R.raw.yellow_star);
178
      mBmpW = mStarBitmap.getWidth();
179
      mBmpH = mStarBitmap.getHeight();
180
      mCountBitmap = Bitmap.createBitmap(mBmpW,mBmpH,Bitmap.Config.ARGB_8888);
181
      mCountCanvas = new Canvas(mCountBitmap);
182

    
183
      float quotient = computeQuotientAndTextHeight(total);
184

    
185
      mPaint = new Paint();
186
      mPaint.setColor(0xff000000);
187
      mPaint.setTextSize(mBmpH*quotient);
188
      mPaint.setAntiAlias(true);
189
      mPaint.setTextAlign(Paint.Align.CENTER);
190
      }
191

    
192
///////////////////////////////////////////////////////////////////////////////////////////////////
193

    
194
   private DistortedNode createNodeFalling(boolean increase)
195
      {
196
      DistortedTexture texture = new DistortedTexture();
197
      texture.setTexture(mStarBitmap);
198

    
199
      MeshQuad[] mesh = new MeshQuad[mNewStars];
200

    
201
      for(int i=0; i<mNewStars; i++)
202
         {
203
         mesh[i] = new MeshQuad();
204
         mesh[i].setEffectAssociation(0,1,i+1);
205
         }
206

    
207
      MeshJoined wholeMesh = new MeshJoined(mesh);
208

    
209
      DistortedEffects effects = new DistortedEffects();
210
      VertexEffectScale scaleE = new VertexEffectScale(mWidth*0.15f);
211
      scaleE.setMeshAssociation(1,-1);
212
      effects.apply(scaleE);
213

    
214
      for(int i=0; i<mNewStars; i++)
215
        {
216
        Dynamic3D moveP = createRandomMove(increase);
217
        VertexEffectMove moveE= new VertexEffectMove(moveP);
218
        moveE.setMeshAssociation(0,i+1);
219
        effects.apply(moveE);
220

    
221
        if( i==0 )
222
           {
223
           mMoveID = moveE.getID();
224
           moveE.notifyWhenFinished(this);
225
           }
226
        }
227

    
228
      return new DistortedNode(texture,effects,wholeMesh);
229
      }
230

    
231
///////////////////////////////////////////////////////////////////////////////////////////////////
232

    
233
   private DistortedNode createNodeCentral(int numStars)
234
      {
235
      mTexture = new DistortedTexture();
236
      renderStars(numStars);
237

    
238
      MeshQuad mesh = new MeshQuad();
239

    
240
      DistortedEffects effects = new DistortedEffects();
241
      float scaleM  = mWidth*0.40f;
242
      Static3D moveM= new Static3D(0,0,1);
243
      MatrixEffectMove move  = new MatrixEffectMove(moveM);
244
      MatrixEffectScale scale= new MatrixEffectScale(scaleM);
245
      effects.apply(move);
246
      effects.apply(scale);
247
      createAlphaEffect(true);
248
      effects.apply(mAlpha);
249

    
250
      return new DistortedNode(mTexture,effects,mesh);
251
      }
252

    
253
///////////////////////////////////////////////////////////////////////////////////////////////////
254

    
255
   private void renderStars(int numStars)
256
      {
257
      String txt = ""+numStars;
258
      mCountBitmap.eraseColor(0x00000000);
259
      mCountCanvas.drawBitmap(mStarBitmap,0,0,null);
260
      mCountCanvas.drawText(txt,mBmpW*0.5f,mBmpH*mTextHeight,mPaint);
261
      mTexture.setTexture(mCountBitmap);
262
      }
263

    
264
///////////////////////////////////////////////////////////////////////////////////////////////////
265

    
266
   public long startOverlay(DistortedScreen screen, ListenerOverlay listener, DataGeneric data)
267
      {
268
      mRandom = new Random();
269
      mScreen = screen;
270
      mListener= listener;
271
      DataStars stars = (DataStars)data;
272
      mTotalStars = stars.getTotal();
273
      mNewStars   = stars.getNew();
274
      Resources res = stars.getResources();
275
      mWidth = mScreen.getWidth();
276
      mHeight= mScreen.getHeight();
277
      mIncrease = mNewStars>0;
278
      if( !mIncrease ) mNewStars = -mNewStars;
279

    
280
      createBitmap(res, mTotalStars);
281
      mNodeFalling = createNodeFalling(mIncrease);
282
      mNodeFalling.enableDepthStencil(InternalOutputSurface.NO_DEPTH_NO_STENCIL);
283
      mScreen.attach(mNodeFalling);
284
      mNodeCentral = createNodeCentral(mTotalStars);
285
      mNodeCentral.glDepthMask(false);
286
      mScreen.attach(mNodeCentral);
287

    
288
      return 0;
289
      }
290

    
291
///////////////////////////////////////////////////////////////////////////////////////////////////
292

    
293
   private PostprocessEffectGlow constructGlow(boolean firstPhase)
294
      {
295
      Dynamic2D haloRadius = new Dynamic2D(DUR_GLO,0.5f);
296
      Static2D point20 = new Static2D( 0, 0);
297
      Static2D point21 = new Static2D(15,50);
298
      Dynamic4D color = new Dynamic4D(DUR_GLO, 0.5f);
299
      Static4D point40 = new Static4D(1,1,1,0.0f);
300
      Static4D point41 = new Static4D(1,1,1,0.8f);
301

    
302
      if( firstPhase )
303
         {
304
         haloRadius.add(point20);
305
         haloRadius.add(point21);
306
         color.add(point40);
307
         color.add(point41);
308
         }
309
      else
310
         {
311
         haloRadius.add(point21);
312
         haloRadius.add(point20);
313
         color.add(point41);
314
         color.add(point40);
315
         }
316

    
317
      PostprocessEffectGlow glow = new PostprocessEffectGlow(haloRadius,color);
318
      glow.setQuality(EffectQuality.MEDIUM);
319
      glow.notifyWhenFinished(this);
320

    
321
      return glow;
322
      }
323

    
324
///////////////////////////////////////////////////////////////////////////////////////////////////
325

    
326
   public void effectFinished(long id)
327
      {
328
      if( id==mMoveID )
329
         {
330
         PostprocessEffectGlow glow = constructGlow(true);
331
         mGlow1ID = glow.getID();
332
         DistortedEffects effects = mNodeCentral.getEffects();
333
         effects.apply(glow);
334
         }
335
      if( id==mGlow1ID )
336
         {
337
         renderStars(mTotalStars+(mIncrease ? mNewStars : -mNewStars));
338
         PostprocessEffectGlow glow = constructGlow(false);
339
         mGlow2ID = glow.getID();
340
         DistortedEffects effects = mNodeCentral.getEffects();
341
         effects.abortById(mGlow1ID);
342
         effects.apply(glow);
343
         }
344
      if( id==mGlow2ID )
345
         {
346
         DistortedEffects effects = mNodeCentral.getEffects();
347
         effects.abortById(mGlow2ID);
348
         createAlphaEffect(false);
349
         mAlphaID = mAlpha.getID();
350
         mAlpha.notifyWhenFinished(this);
351
         effects.apply(mAlpha);
352
         }
353
      if( id==mAlphaID )
354
         {
355
         mScreen.detach(mNodeCentral);
356
         mNodeCentral.markForDeletion();
357
         mNodeCentral=null;
358
         mScreen.detach(mNodeFalling);
359
         mNodeFalling.markForDeletion();
360
         mNodeFalling=null;
361
         mListener.overlayFinished(id);
362
         }
363
      }
364

    
365
///////////////////////////////////////////////////////////////////////////////////////////////////
366

    
367
  @SuppressWarnings("unused")
368
  public static void enableEffects()
369
     {
370
     FragmentEffectAlpha.enable();
371
     VertexEffectMove.enable();
372
     VertexEffectScale.enable();
373
     PostprocessEffectGlow.enable();
374
     }
375
}
(8-8/8)