Project

General

Profile

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

magiccube / src / main / java / org / distorted / magic / RubikRenderer.java @ 5be1059b

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
import android.opengl.GLSurfaceView;
23
24 64975793 Leszek Koltunski
import org.distorted.effect.BaseEffect;
25 0c52af30 Leszek Koltunski
import org.distorted.library.effect.VertexEffectSink;
26 9208e27b Leszek Koltunski
import org.distorted.library.main.DistortedEffects;
27 e1111500 Leszek Koltunski
import org.distorted.library.main.DistortedLibrary;
28 0c52af30 Leszek Koltunski
import org.distorted.library.main.DistortedScreen;
29 9208e27b Leszek Koltunski
import org.distorted.library.main.DistortedTexture;
30 39fb9047 Leszek Koltunski
import org.distorted.library.mesh.MeshFlat;
31 0c52af30 Leszek Koltunski
import org.distorted.library.message.EffectListener;
32 beb325a0 Leszek Koltunski
import org.distorted.object.RubikCube;
33 0c52af30 Leszek Koltunski
34
import javax.microedition.khronos.egl.EGLConfig;
35
import javax.microedition.khronos.opengles.GL10;
36
37
///////////////////////////////////////////////////////////////////////////////////////////////////
38
39 9208e27b Leszek Koltunski
public class RubikRenderer implements GLSurfaceView.Renderer, EffectListener
40 0c52af30 Leszek Koltunski
{
41 123d6172 Leszek Koltunski
    public static final float CAMERA_DISTANCE   = 0.6f;  // 0.6 of the length of max(scrHeight,scrWidth)
42
    public static final int TEXTURE_SIZE = 600;
43 0c52af30 Leszek Koltunski
44
    private RubikSurfaceView mView;
45
    private DistortedScreen mScreen;
46 3b12e641 Leszek Koltunski
    private int mNextCubeSize, mScrambleCubeNum;
47 64975793 Leszek Koltunski
    private long mRotationFinishedID;
48
    private long[] mEffectID;
49 05fa94d9 Leszek Koltunski
    private boolean mFinishRotation, mRemoveRotation, mSetQuatCurrent, mSetQuatAccumulated;
50 408d4676 Leszek Koltunski
    private boolean mSizeChangeCube, mSolveCube, mScrambleCube;
51 45686da2 Leszek Koltunski
    private boolean mCanRotate, mCanDrag, mCanUI;
52 47ba5ddc Leszek Koltunski
    private boolean mIsSolved;
53 434f2f5a Leszek Koltunski
    private RubikCube mOldCube, mNewCube;
54 d1484aba Leszek Koltunski
    private int mScreenWidth, mScreenHeight;
55 39fb9047 Leszek Koltunski
    private MeshFlat mMesh;
56 9208e27b Leszek Koltunski
57 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
58
59
    RubikRenderer(RubikSurfaceView v)
60
      {
61
      mView = v;
62
      mScreen = new DistortedScreen();
63
64 434f2f5a Leszek Koltunski
      mOldCube = null;
65
      mNewCube = null;
66
67 d1484aba Leszek Koltunski
      mScreenWidth = mScreenHeight = 0;
68 3b12e641 Leszek Koltunski
      mScrambleCubeNum = 0;
69 d1484aba Leszek Koltunski
70 05fa94d9 Leszek Koltunski
      mFinishRotation     = false;
71
      mRemoveRotation     = false;
72
      mSetQuatCurrent     = false;
73
      mSetQuatAccumulated = false;
74
      mSizeChangeCube     = true;
75
      mSolveCube          = false;
76
      mScrambleCube       = false;
77 0c52af30 Leszek Koltunski
78 2ecf0c21 Leszek Koltunski
      mCanRotate   = true;
79
      mCanDrag     = true;
80 45686da2 Leszek Koltunski
      mCanUI       = true;
81 9208e27b Leszek Koltunski
82 64975793 Leszek Koltunski
      mEffectID = new long[BaseEffect.Type.LENGTH];
83
84 39fb9047 Leszek Koltunski
      mMesh= new MeshFlat(20,20);
85 5be1059b Leszek Koltunski
      mNextCubeSize = RubikSize.getSize(RubikSurfaceView.getRedButton()).getCubeSize();
86 0c52af30 Leszek Koltunski
      }
87
88 47ba5ddc Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
89
90
   private void createCubeNow(int newSize)
91
     {
92
     if( mOldCube!=null ) mOldCube.releaseResources();
93
     mOldCube = mNewCube;
94
95
     DistortedTexture texture = new DistortedTexture(TEXTURE_SIZE,TEXTURE_SIZE);
96
     DistortedEffects effects = new DistortedEffects();
97
98
     mNewCube = new RubikCube(newSize, mView.getQuatCurrent(), mView.getQuatAccumulated(), texture, mMesh, effects);
99
     mNewCube.createTexture();
100
101
     if( mScreenWidth!=0 )
102
       {
103 beb325a0 Leszek Koltunski
       mNewCube.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
///////////////////////////////////////////////////////////////////////////////////////////////////
131
// no this will not race with onDrawFrame
132
133
   void finishRotation()
134
     {
135
     mFinishRotation = true;
136
     }
137
138
///////////////////////////////////////////////////////////////////////////////////////////////////
139
140
   boolean createCube(int newSize)
141
     {
142
     if( mCanDrag && mCanRotate && (mNewCube==null || newSize != mNewCube.getSize()) )
143
       {
144
       mSizeChangeCube = true;
145
       mNextCubeSize = newSize;
146
       return true;
147
       }
148
149
     return false;
150
     }
151
152
///////////////////////////////////////////////////////////////////////////////////////////////////
153
154
   void scrambleCube(int num)
155
     {
156
     if( mCanUI )
157
       {
158
       mScrambleCube = true;
159
       mScrambleCubeNum = num;
160
       }
161
     }
162
163
///////////////////////////////////////////////////////////////////////////////////////////////////
164
165
   void solveCube()
166
     {
167
     if( mCanUI )
168
       {
169
       mSolveCube = true;
170
       }
171
     }
172
173
///////////////////////////////////////////////////////////////////////////////////////////////////
174
175
   boolean canRotate()
176
     {
177
     return mCanRotate;
178
     }
179
180
///////////////////////////////////////////////////////////////////////////////////////////////////
181
182
   boolean canDrag()
183
     {
184
     return mCanDrag;
185
     }
186
187
///////////////////////////////////////////////////////////////////////////////////////////////////
188
189
   void setQuatCurrentOnNextRender()
190
     {
191
     mSetQuatCurrent = true;
192
     }
193
194
///////////////////////////////////////////////////////////////////////////////////////////////////
195
196
   void setQuatAccumulatedOnNextRender()
197
     {
198
     mSetQuatAccumulated = true;
199
     }
200
201
///////////////////////////////////////////////////////////////////////////////////////////////////
202
// PUBLIC API
203 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
204
// various things are done here delayed, 'after the next render' as not to be done mid-render and
205
// cause artifacts.
206
207 a7a7cc9c Leszek Koltunski
   @Override
208
   public void onDrawFrame(GL10 glUnused)
209
     {
210
     mScreen.render( System.currentTimeMillis() );
211
212
     if( mSetQuatCurrent )
213
       {
214
       mSetQuatCurrent = false;
215
       mView.setQuatCurrent();
216
       }
217
218
     if( mSetQuatAccumulated )
219
       {
220
       mSetQuatAccumulated = false;
221
       mView.setQuatAccumulated();
222
       }
223
224
     if( mFinishRotation )
225
       {
226
       mFinishRotation = false;
227
       mCanRotate      = false;
228
       mCanUI          = false;
229
       mRotationFinishedID = mNewCube.finishRotationNow(this);
230
       }
231
232
     if( mRemoveRotation )
233
       {
234
       mRemoveRotation=false;
235
       mNewCube.removeRotationNow();
236
237
       boolean solved = mNewCube.isSolved();
238
239
       if( solved && !mIsSolved )
240
         {
241
         mCanDrag        = false;
242
         mCanRotate      = false;
243
         mCanUI          = false;
244
         doEffectNow( BaseEffect.Type.WIN );
245 beb325a0 Leszek Koltunski
         mView.leaveScrambleModeNonUI();
246 a7a7cc9c Leszek Koltunski
         }
247
       else
248
         {
249
         mCanRotate = true;
250
         mCanUI     = true;
251
         }
252
253
       mIsSolved = solved;
254
       }
255
256
     if( mSizeChangeCube )
257
       {
258
       mSizeChangeCube = false;
259
       mCanDrag        = false;
260
       mCanRotate      = false;
261
       mCanUI          = false;
262
       createCubeNow(mNextCubeSize);
263
       doEffectNow( BaseEffect.Type.SIZECHANGE );
264
       }
265
266
     if( mSolveCube )
267
       {
268
       mSolveCube      = false;
269
       mCanDrag        = false;
270
       mCanRotate      = false;
271
       mCanUI          = false;
272
       doEffectNow( BaseEffect.Type.SOLVE );
273
       }
274
275
     if( mScrambleCube )
276
       {
277
       mScrambleCube = false;
278
       mCanDrag      = false;
279
       mCanRotate    = false;
280
       mCanUI        = false;
281
       doEffectNow( BaseEffect.Type.SCRAMBLE );
282
       }
283
     }
284 0c52af30 Leszek Koltunski
285
///////////////////////////////////////////////////////////////////////////////////////////////////
286 aa8b36aa Leszek Koltunski
287
   @Override
288
   public void onSurfaceChanged(GL10 glUnused, int width, int height)
289
      {
290
      if( mNewCube!=null ) mNewCube.createTexture();
291
292 123d6172 Leszek Koltunski
      double halfFOVInRadians = Math.atan( 1.0f/(2*CAMERA_DISTANCE) );
293
      float fovInDegrees = (float)(2*halfFOVInRadians*(180/Math.PI));
294 beb325a0 Leszek Koltunski
295
      mScreen.setProjection( fovInDegrees, 0.1f);
296 aa8b36aa Leszek Koltunski
      mScreen.resize(width, height);
297 123d6172 Leszek Koltunski
      mView.setScreenSize(width,height);
298 aa8b36aa Leszek Koltunski
299 beb325a0 Leszek Koltunski
      if( mNewCube!=null )
300
        {
301 123d6172 Leszek Koltunski
        mNewCube.recomputeScaleFactor(width,height);
302 beb325a0 Leszek Koltunski
        }
303 aa8b36aa Leszek Koltunski
304
      mScreenHeight = height;
305
      mScreenWidth  = width;
306
      }
307
308
///////////////////////////////////////////////////////////////////////////////////////////////////
309
310
   @Override
311
   public void onSurfaceCreated(GL10 glUnused, EGLConfig config)
312
      {
313
      VertexEffectSink.enable();
314 64975793 Leszek Koltunski
      BaseEffect.Type.enableEffects();
315 aa8b36aa Leszek Koltunski
316
      try
317
        {
318
        DistortedLibrary.onCreate(mView.getContext());
319
        }
320
      catch(Exception ex)
321
        {
322
        android.util.Log.e("Rubik", ex.getMessage() );
323
        }
324
      }
325
326
///////////////////////////////////////////////////////////////////////////////////////////////////
327 0c52af30 Leszek Koltunski
328 f647630d Leszek Koltunski
   public void effectFinished(final long effectID)
329 0c52af30 Leszek Koltunski
     {
330 45686da2 Leszek Koltunski
     if( effectID == mRotationFinishedID )
331 434f2f5a Leszek Koltunski
       {
332
       mRemoveRotation = true;
333
       }
334 45686da2 Leszek Koltunski
     else
335 3b12e641 Leszek Koltunski
       {
336 45686da2 Leszek Koltunski
       for(int i=0; i<BaseEffect.Type.LENGTH; i++)
337
         {
338
         if( effectID == mEffectID[i] )
339
           {
340
           mCanRotate   = true;
341
           mCanDrag     = true;
342
           mCanUI       = true;
343
           break;
344
           }
345
         }
346 3b12e641 Leszek Koltunski
       }
347 34747dd1 Leszek Koltunski
     }
348 f291130e Leszek Koltunski
349 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
350
351 64975793 Leszek Koltunski
   public RubikCube getCube()
352 8197c92d Leszek Koltunski
     {
353 64975793 Leszek Koltunski
     return mNewCube;
354 8197c92d Leszek Koltunski
     }
355
356
///////////////////////////////////////////////////////////////////////////////////////////////////
357
358 64975793 Leszek Koltunski
   public RubikCube getOldCube()
359 8197c92d Leszek Koltunski
     {
360 64975793 Leszek Koltunski
     return mOldCube;
361 8197c92d Leszek Koltunski
     }
362
363 434f2f5a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
364
365 64975793 Leszek Koltunski
   public DistortedScreen getScreen()
366 434f2f5a Leszek Koltunski
     {
367 64975793 Leszek Koltunski
     return mScreen;
368 434f2f5a Leszek Koltunski
     }
369
370 8197c92d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
371
372 64975793 Leszek Koltunski
   public int getNumScrambles()
373 8197c92d Leszek Koltunski
     {
374 64975793 Leszek Koltunski
     return mScrambleCubeNum;
375 8197c92d Leszek Koltunski
     }
376 0c52af30 Leszek Koltunski
}