Project

General

Profile

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

magiccube / src / main / java / org / distorted / magic / RubikRenderer.java @ 9cd7695f

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