Project

General

Profile

Download (12.4 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / magic / RubikRenderer.java @ c3ffcf58

1 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski                                                               //
3
//                                                                                               //
4 fdec60a3 Leszek Koltunski
// This file is part of Magic Cube.                                                              //
5 0c52af30 Leszek Koltunski
//                                                                                               //
6 fdec60a3 Leszek Koltunski
// Magic Cube is free software: you can redistribute it and/or modify                            //
7 0c52af30 Leszek Koltunski
// 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 fdec60a3 Leszek Koltunski
// Magic Cube is distributed in the hope that it will be useful,                                 //
12 0c52af30 Leszek Koltunski
// 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 fdec60a3 Leszek Koltunski
// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
19
20
package org.distorted.magic;
21
22 0333d81e Leszek Koltunski
import android.content.SharedPreferences;
23 0c52af30 Leszek Koltunski
import android.opengl.GLSurfaceView;
24
25 64975793 Leszek Koltunski
import org.distorted.effect.BaseEffect;
26 0c52af30 Leszek Koltunski
import org.distorted.library.effect.VertexEffectSink;
27 e1111500 Leszek Koltunski
import org.distorted.library.main.DistortedLibrary;
28 0c52af30 Leszek Koltunski
import org.distorted.library.main.DistortedScreen;
29
import org.distorted.library.message.EffectListener;
30 4f9f99a2 Leszek Koltunski
import org.distorted.object.RubikObject;
31 27a70eae Leszek Koltunski
import org.distorted.object.RubikObjectList;
32 c3ffcf58 Leszek Koltunski
import org.distorted.scores.RubikScores;
33 211b48f2 Leszek Koltunski
import org.distorted.uistate.RubikState;
34 0333d81e Leszek Koltunski
import org.distorted.uistate.RubikStateSolving;
35 0c52af30 Leszek Koltunski
36
import javax.microedition.khronos.egl.EGLConfig;
37
import javax.microedition.khronos.opengles.GL10;
38
39
///////////////////////////////////////////////////////////////////////////////////////////////////
40
41 9208e27b Leszek Koltunski
public class RubikRenderer implements GLSurfaceView.Renderer, EffectListener
42 0c52af30 Leszek Koltunski
{
43 ba740a0c Leszek Koltunski
    public static final int NODE_FBO_SIZE = 600;
44 0c52af30 Leszek Koltunski
45
    private RubikSurfaceView mView;
46
    private DistortedScreen mScreen;
47 27a70eae Leszek Koltunski
    private RubikObjectList mNextObject;
48 4888e97c Leszek Koltunski
    private int mNextSize;
49 27a70eae Leszek Koltunski
    private int mScrambleObjectNum;
50 64975793 Leszek Koltunski
    private long mRotationFinishedID;
51
    private long[] mEffectID;
52 05fa94d9 Leszek Koltunski
    private boolean mFinishRotation, mRemoveRotation, mSetQuatCurrent, mSetQuatAccumulated;
53 27a70eae Leszek Koltunski
    private boolean mChangeObject, mSolveObject, mScrambleObject;
54 45686da2 Leszek Koltunski
    private boolean mCanRotate, mCanDrag, mCanUI;
55 47ba5ddc Leszek Koltunski
    private boolean mIsSolved;
56 27a70eae Leszek Koltunski
    private RubikObject mOldObject, mNewObject;
57 d1484aba Leszek Koltunski
    private int mScreenWidth, mScreenHeight;
58 5bfc1b49 Leszek Koltunski
    private SharedPreferences mPreferences;
59 9208e27b Leszek Koltunski
60 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
61
62
    RubikRenderer(RubikSurfaceView v)
63
      {
64
      mView = v;
65
      mScreen = new DistortedScreen();
66
67 27a70eae Leszek Koltunski
      mOldObject = null;
68
      mNewObject = null;
69 434f2f5a Leszek Koltunski
70 d1484aba Leszek Koltunski
      mScreenWidth = mScreenHeight = 0;
71 27a70eae Leszek Koltunski
      mScrambleObjectNum = 0;
72 d1484aba Leszek Koltunski
73 05fa94d9 Leszek Koltunski
      mFinishRotation     = false;
74
      mRemoveRotation     = false;
75
      mSetQuatCurrent     = false;
76
      mSetQuatAccumulated = false;
77 27a70eae Leszek Koltunski
      mChangeObject       = false;
78
      mSolveObject        = false;
79
      mScrambleObject     = false;
80 0c52af30 Leszek Koltunski
81 2ecf0c21 Leszek Koltunski
      mCanRotate   = true;
82
      mCanDrag     = true;
83 45686da2 Leszek Koltunski
      mCanUI       = true;
84 9208e27b Leszek Koltunski
85 64975793 Leszek Koltunski
      mEffectID = new long[BaseEffect.Type.LENGTH];
86 0c52af30 Leszek Koltunski
      }
87
88 47ba5ddc Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
89
90 4888e97c Leszek Koltunski
   private void createObjectNow(RubikObjectList object, int size)
91 47ba5ddc Leszek Koltunski
     {
92 27a70eae Leszek Koltunski
     boolean firstTime = (mNewObject==null);
93 5bfc1b49 Leszek Koltunski
94 27a70eae Leszek Koltunski
     if( mOldObject!=null ) mOldObject.releaseResources();
95
     mOldObject = mNewObject;
96 47ba5ddc Leszek Koltunski
97 4888e97c Leszek Koltunski
     mNewObject = object.create(size, mView.getQuatCurrent(), mView.getQuatAccumulated());
98 27a70eae Leszek Koltunski
     mNewObject.createTexture();
99
     mView.setMovement(object.getObjectMovementClass());
100
101
     if( firstTime ) mNewObject.restorePreferences(mPreferences);
102 47ba5ddc Leszek Koltunski
103
     if( mScreenWidth!=0 )
104
       {
105 27a70eae Leszek Koltunski
       mNewObject.recomputeScaleFactor(mScreenWidth, mScreenHeight);
106 47ba5ddc Leszek Koltunski
       }
107
108
     mIsSolved = true;
109
     }
110
111
///////////////////////////////////////////////////////////////////////////////////////////////////
112
// do all 'adjustable' effects (SizeChange, Solve, Scramble)
113
114
   private void doEffectNow(BaseEffect.Type type)
115
     {
116
     int index = type.ordinal();
117
118 beb325a0 Leszek Koltunski
     try
119
       {
120
       mEffectID[index] = type.startEffect(this);
121
       }
122
     catch( Exception ex )
123 47ba5ddc Leszek Koltunski
       {
124 beb325a0 Leszek Koltunski
       android.util.Log.e("renderer", "exception starting effect: "+ex.getMessage());
125
126 47ba5ddc Leszek Koltunski
       mCanUI     = true;
127
       mCanRotate = true;
128
       mCanDrag   = true;
129
       }
130
     }
131
132 0333d81e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
133
134
   void savePreferences(SharedPreferences.Editor editor)
135
     {
136 3c4a326c Leszek Koltunski
     if( mNewObject!=null )
137
       {
138
       mNewObject.savePreferences(editor);
139
       }
140 0333d81e Leszek Koltunski
     }
141
142
///////////////////////////////////////////////////////////////////////////////////////////////////
143
144
   void restorePreferences(SharedPreferences preferences)
145
     {
146 5bfc1b49 Leszek Koltunski
     mPreferences = preferences;
147 0333d81e Leszek Koltunski
     }
148
149 47ba5ddc Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
150
// no this will not race with onDrawFrame
151
152
   void finishRotation()
153
     {
154
     mFinishRotation = true;
155
     }
156
157
///////////////////////////////////////////////////////////////////////////////////////////////////
158
159 4888e97c Leszek Koltunski
   boolean createObject(RubikObjectList object, int size)
160 47ba5ddc Leszek Koltunski
     {
161 4888e97c Leszek Koltunski
     if( mCanDrag && mCanRotate && (object!=mNextObject || mNextSize!=size) && size>0 )
162 47ba5ddc Leszek Koltunski
       {
163 27a70eae Leszek Koltunski
       mChangeObject = true;
164
       mNextObject = object;
165 4888e97c Leszek Koltunski
       mNextSize   = size;
166 47ba5ddc Leszek Koltunski
       return true;
167
       }
168
169
     return false;
170
     }
171
172
///////////////////////////////////////////////////////////////////////////////////////////////////
173
174 27a70eae Leszek Koltunski
   void scrambleObject(int num)
175 47ba5ddc Leszek Koltunski
     {
176
     if( mCanUI )
177
       {
178 27a70eae Leszek Koltunski
       mScrambleObject = true;
179
       mScrambleObjectNum = num;
180 47ba5ddc Leszek Koltunski
       }
181
     }
182
183
///////////////////////////////////////////////////////////////////////////////////////////////////
184
185 27a70eae Leszek Koltunski
   void solveObject()
186 47ba5ddc Leszek Koltunski
     {
187
     if( mCanUI )
188
       {
189 27a70eae Leszek Koltunski
       mSolveObject = true;
190 47ba5ddc Leszek Koltunski
       }
191
     }
192
193
///////////////////////////////////////////////////////////////////////////////////////////////////
194
195
   boolean canRotate()
196
     {
197
     return mCanRotate;
198
     }
199
200
///////////////////////////////////////////////////////////////////////////////////////////////////
201
202
   boolean canDrag()
203
     {
204
     return mCanDrag;
205
     }
206
207
///////////////////////////////////////////////////////////////////////////////////////////////////
208
209
   void setQuatCurrentOnNextRender()
210
     {
211
     mSetQuatCurrent = true;
212
     }
213
214
///////////////////////////////////////////////////////////////////////////////////////////////////
215
216
   void setQuatAccumulatedOnNextRender()
217
     {
218
     mSetQuatAccumulated = true;
219
     }
220
221 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
222
// various things are done here delayed, 'after the next render' as not to be done mid-render and
223
// cause artifacts.
224
225 a7a7cc9c Leszek Koltunski
   @Override
226
   public void onDrawFrame(GL10 glUnused)
227
     {
228
     mScreen.render( System.currentTimeMillis() );
229
230
     if( mSetQuatCurrent )
231
       {
232
       mSetQuatCurrent = false;
233
       mView.setQuatCurrent();
234
       }
235
236
     if( mSetQuatAccumulated )
237
       {
238
       mSetQuatAccumulated = false;
239
       mView.setQuatAccumulated();
240
       }
241
242
     if( mFinishRotation )
243
       {
244
       mFinishRotation = false;
245
       mCanRotate      = false;
246
       mCanUI          = false;
247 27a70eae Leszek Koltunski
       mRotationFinishedID = mNewObject.finishRotationNow(this);
248 9cd7695f Leszek Koltunski
249
       if( mRotationFinishedID==0 ) // failed to add effect - should never happen
250
         {
251
         mCanRotate = true;
252
         mCanUI     = true;
253
         }
254 a7a7cc9c Leszek Koltunski
       }
255
256
     if( mRemoveRotation )
257
       {
258
       mRemoveRotation=false;
259 27a70eae Leszek Koltunski
       mNewObject.removeRotationNow();
260 a7a7cc9c Leszek Koltunski
261 27a70eae Leszek Koltunski
       boolean solved = mNewObject.isSolved();
262 a7a7cc9c Leszek Koltunski
263
       if( solved && !mIsSolved )
264
         {
265 0333d81e Leszek Koltunski
         if( RubikState.getCurrentState()==RubikState.SOLV )
266
           {
267
           RubikStateSolving solving = (RubikStateSolving)RubikState.SOLV.getStateClass();
268 714292f1 Leszek Koltunski
           solving.stopCounting();
269 0333d81e Leszek Koltunski
           }
270
271
         mCanDrag   = true;
272
         mCanRotate = false;
273
         mCanUI     = false;
274 a7a7cc9c Leszek Koltunski
         doEffectNow( BaseEffect.Type.WIN );
275
         }
276
       else
277
         {
278
         mCanRotate = true;
279
         mCanUI     = true;
280
         }
281
282
       mIsSolved = solved;
283
       }
284
285 27a70eae Leszek Koltunski
     if( mChangeObject )
286 a7a7cc9c Leszek Koltunski
       {
287 27a70eae Leszek Koltunski
       mChangeObject = false;
288
       mCanDrag      = false;
289
       mCanRotate    = false;
290
       mCanUI        = false;
291 4888e97c Leszek Koltunski
       createObjectNow(mNextObject, mNextSize);
292 a7a7cc9c Leszek Koltunski
       doEffectNow( BaseEffect.Type.SIZECHANGE );
293
       }
294
295 27a70eae Leszek Koltunski
     if( mSolveObject )
296 a7a7cc9c Leszek Koltunski
       {
297 27a70eae Leszek Koltunski
       mSolveObject    = false;
298 a7a7cc9c Leszek Koltunski
       mCanDrag        = false;
299
       mCanRotate      = false;
300
       mCanUI          = false;
301
       doEffectNow( BaseEffect.Type.SOLVE );
302
       }
303
304 27a70eae Leszek Koltunski
     if( mScrambleObject )
305 a7a7cc9c Leszek Koltunski
       {
306 27a70eae Leszek Koltunski
       mScrambleObject = false;
307
       mCanDrag        = false;
308
       mCanRotate      = false;
309
       mCanUI          = false;
310 fec72009 Leszek Koltunski
       mIsSolved       = false;
311 c3ffcf58 Leszek Koltunski
       RubikScores.getInstance().incrementNumPlays();
312 a7a7cc9c Leszek Koltunski
       doEffectNow( BaseEffect.Type.SCRAMBLE );
313
       }
314
     }
315 0c52af30 Leszek Koltunski
316
///////////////////////////////////////////////////////////////////////////////////////////////////
317 aa8b36aa Leszek Koltunski
318
   @Override
319
   public void onSurfaceChanged(GL10 glUnused, int width, int height)
320
      {
321 27a70eae Leszek Koltunski
      if( mNewObject!=null ) mNewObject.createTexture();
322 aa8b36aa Leszek Koltunski
323
      mScreen.resize(width, height);
324 123d6172 Leszek Koltunski
      mView.setScreenSize(width,height);
325 aa8b36aa Leszek Koltunski
326 27a70eae Leszek Koltunski
      if( mNewObject!=null )
327 beb325a0 Leszek Koltunski
        {
328 27a70eae Leszek Koltunski
        mNewObject.recomputeScaleFactor(width,height);
329 beb325a0 Leszek Koltunski
        }
330 aa8b36aa Leszek Koltunski
331
      mScreenHeight = height;
332
      mScreenWidth  = width;
333
      }
334
335
///////////////////////////////////////////////////////////////////////////////////////////////////
336
337
   @Override
338
   public void onSurfaceCreated(GL10 glUnused, EGLConfig config)
339
      {
340
      VertexEffectSink.enable();
341 64975793 Leszek Koltunski
      BaseEffect.Type.enableEffects();
342 aa8b36aa Leszek Koltunski
343
      try
344
        {
345
        DistortedLibrary.onCreate(mView.getContext());
346
        }
347
      catch(Exception ex)
348
        {
349
        android.util.Log.e("Rubik", ex.getMessage() );
350
        }
351
      }
352
353 ad9e8bb3 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
354
// PUBLIC API
355 aa8b36aa Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
356 0c52af30 Leszek Koltunski
357 f647630d Leszek Koltunski
   public void effectFinished(final long effectID)
358 0c52af30 Leszek Koltunski
     {
359 45686da2 Leszek Koltunski
     if( effectID == mRotationFinishedID )
360 434f2f5a Leszek Koltunski
       {
361
       mRemoveRotation = true;
362
       }
363 45686da2 Leszek Koltunski
     else
364 3b12e641 Leszek Koltunski
       {
365 45686da2 Leszek Koltunski
       for(int i=0; i<BaseEffect.Type.LENGTH; i++)
366
         {
367
         if( effectID == mEffectID[i] )
368
           {
369
           mCanRotate   = true;
370
           mCanDrag     = true;
371
           mCanUI       = true;
372 ad9e8bb3 Leszek Koltunski
373
           if( i==BaseEffect.Type.SCRAMBLE.ordinal() )
374
             {
375
             final RubikActivity act = (RubikActivity)mView.getContext();
376
377
             act.runOnUiThread(new Runnable()
378
               {
379
               @Override
380
               public void run()
381
                 {
382
                 RubikState.switchState( act, RubikState.SOLV);
383
                 }
384
               });
385
             }
386 45686da2 Leszek Koltunski
           break;
387
           }
388
         }
389 3b12e641 Leszek Koltunski
       }
390 34747dd1 Leszek Koltunski
     }
391 f291130e Leszek Koltunski
392 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
393
394 27a70eae Leszek Koltunski
   public RubikObject getObject()
395 8197c92d Leszek Koltunski
     {
396 27a70eae Leszek Koltunski
     return mNewObject;
397 8197c92d Leszek Koltunski
     }
398
399
///////////////////////////////////////////////////////////////////////////////////////////////////
400
401 27a70eae Leszek Koltunski
   public RubikObject getOldObject()
402 8197c92d Leszek Koltunski
     {
403 27a70eae Leszek Koltunski
     return mOldObject;
404 8197c92d Leszek Koltunski
     }
405
406 434f2f5a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
407
408 64975793 Leszek Koltunski
   public DistortedScreen getScreen()
409 434f2f5a Leszek Koltunski
     {
410 64975793 Leszek Koltunski
     return mScreen;
411 434f2f5a Leszek Koltunski
     }
412
413 8197c92d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
414
415 64975793 Leszek Koltunski
   public int getNumScrambles()
416 8197c92d Leszek Koltunski
     {
417 27a70eae Leszek Koltunski
     return mScrambleObjectNum;
418 8197c92d Leszek Koltunski
     }
419 0c52af30 Leszek Koltunski
}