Project

General

Profile

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

magiccube / src / main / java / org / distorted / magic / RubikRenderer.java @ 408d4676

1 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski                                                               //
3
//                                                                                               //
4 ffd744be Leszek Koltunski
// This file is part of Distorted.                                                               //
5 0c52af30 Leszek Koltunski
//                                                                                               //
6 ffd744be Leszek Koltunski
// Distorted 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 ffd744be Leszek Koltunski
// Distorted 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 ffd744be Leszek Koltunski
// along with Distorted.  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
33
import javax.microedition.khronos.egl.EGLConfig;
34
import javax.microedition.khronos.opengles.GL10;
35
36
///////////////////////////////////////////////////////////////////////////////////////////////////
37
38 9208e27b Leszek Koltunski
public class RubikRenderer implements GLSurfaceView.Renderer, EffectListener
39 0c52af30 Leszek Koltunski
{
40
    private static final float CUBE_SCREEN_RATIO = 0.5f;
41
    private static final float CAMERA_DISTANCE   = 0.6f;  // 0.6 of the length of max(scrHeight,scrWidth)
42 9208e27b Leszek Koltunski
    public  static final int TEXTURE_SIZE = 600;
43 0c52af30 Leszek Koltunski
44
    private RubikSurfaceView mView;
45
    private DistortedScreen mScreen;
46
    private float mCubeSizeInScreenSpace;
47 3b12e641 Leszek Koltunski
    private int mNextCubeSize, mScrambleCubeNum;
48 64975793 Leszek Koltunski
    private long mRotationFinishedID;
49
    private long[] mEffectID;
50 408d4676 Leszek Koltunski
    private boolean mFinishRotation, mRemoveRotation, mFinishDragCurrent, mFinishDragAccumulated;
51
    private boolean mSizeChangeCube, mSolveCube, mScrambleCube;
52 45686da2 Leszek Koltunski
    private boolean mCanRotate, mCanDrag, mCanUI;
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
63
      mScreen = new DistortedScreen();
64
65 434f2f5a Leszek Koltunski
      mOldCube = null;
66
      mNewCube = null;
67
68 d1484aba Leszek Koltunski
      mScreenWidth = mScreenHeight = 0;
69 3b12e641 Leszek Koltunski
      mScrambleCubeNum = 0;
70 d1484aba Leszek Koltunski
71 0c52af30 Leszek Koltunski
      mFinishRotation        = false;
72
      mRemoveRotation        = false;
73
      mFinishDragCurrent     = false;
74
      mFinishDragAccumulated = false;
75 408d4676 Leszek Koltunski
      mSizeChangeCube        = false;
76 584f7954 Leszek Koltunski
      mSolveCube             = false;
77 3b12e641 Leszek Koltunski
      mScrambleCube          = 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
85 39fb9047 Leszek Koltunski
      mMesh= new MeshFlat(20,20);
86 34747dd1 Leszek Koltunski
      mNextCubeSize =RubikActivity.getSize();
87 0c52af30 Leszek Koltunski
      }
88
89
///////////////////////////////////////////////////////////////////////////////////////////////////
90
// various things are done here delayed, 'after the next render' as not to be done mid-render and
91
// cause artifacts.
92
93 aa8b36aa Leszek Koltunski
    @Override
94 0c52af30 Leszek Koltunski
    public void onDrawFrame(GL10 glUnused) 
95
      {
96
      mScreen.render( System.currentTimeMillis() );
97
98
      if( mFinishDragCurrent )
99
        {
100
        mFinishDragCurrent = false;
101 45686da2 Leszek Koltunski
        mView.setQuatCurrent();
102 0c52af30 Leszek Koltunski
        }
103
104
      if( mFinishDragAccumulated )
105
        {
106
        mFinishDragAccumulated = false;
107 45686da2 Leszek Koltunski
        mView.setQuatAccumulated();
108 0c52af30 Leszek Koltunski
        }
109
110
      if( mFinishRotation )
111
        {
112
        mCanRotate = false;
113
        mFinishRotation=false;
114 434f2f5a Leszek Koltunski
        mRotationFinishedID = mNewCube.finishRotationNow(this);
115 0c52af30 Leszek Koltunski
        }
116
117
      if( mRemoveRotation )
118
        {
119
        mRemoveRotation=false;
120 f647630d Leszek Koltunski
        mNewCube.removeRotationNow();
121 0c52af30 Leszek Koltunski
        mCanRotate = true;
122
        }
123 34998c9d Leszek Koltunski
124 408d4676 Leszek Koltunski
      if( mSizeChangeCube )
125 34998c9d Leszek Koltunski
        {
126 408d4676 Leszek Koltunski
        mSizeChangeCube = false;
127
        mCanDrag        = false;
128
        mCanRotate      = false;
129 34998c9d Leszek Koltunski
        createCubeNow(mNextCubeSize);
130 64975793 Leszek Koltunski
        doEffectNow(0);
131 34998c9d Leszek Koltunski
        }
132 584f7954 Leszek Koltunski
133
      if( mSolveCube )
134
        {
135 2ecf0c21 Leszek Koltunski
        mSolveCube   = false;
136
        mCanDrag     = false;
137
        mCanRotate   = false;
138 45686da2 Leszek Koltunski
        mCanUI       = false;
139 64975793 Leszek Koltunski
        doEffectNow(1);
140 584f7954 Leszek Koltunski
        }
141 3b12e641 Leszek Koltunski
142
      if( mScrambleCube )
143
        {
144
        mScrambleCube = false;
145
        mCanDrag      = false;
146
        mCanRotate    = false;
147 45686da2 Leszek Koltunski
        mCanUI        = false;
148 64975793 Leszek Koltunski
        doEffectNow(2);
149 3b12e641 Leszek Koltunski
        }
150 0c52af30 Leszek Koltunski
      }
151
152
///////////////////////////////////////////////////////////////////////////////////////////////////
153 aa8b36aa Leszek Koltunski
154
   @Override
155
   public void onSurfaceChanged(GL10 glUnused, int width, int height)
156
      {
157
      if( mNewCube!=null ) mNewCube.createTexture();
158
159
      float cameraDistance = CAMERA_DISTANCE*(width>height ? width:height);
160
      float fovInDegrees   = computeFOV(cameraDistance,height);
161
162
      mScreen.setProjection( fovInDegrees, 0.1f);
163
      mView.setScreenSize(width,height);
164
      mView.setCameraDist(cameraDistance);
165
      mScreen.resize(width, height);
166
167
      recomputeScaleFactor(width,height);
168
169
      mScreenHeight = height;
170
      mScreenWidth  = width;
171
      }
172
173
///////////////////////////////////////////////////////////////////////////////////////////////////
174
175
   @Override
176
   public void onSurfaceCreated(GL10 glUnused, EGLConfig config)
177
      {
178
      VertexEffectSink.enable();
179 64975793 Leszek Koltunski
      BaseEffect.Type.enableEffects();
180 aa8b36aa Leszek Koltunski
181
      try
182
        {
183
        DistortedLibrary.onCreate(mView.getContext());
184
        }
185
      catch(Exception ex)
186
        {
187
        android.util.Log.e("Rubik", ex.getMessage() );
188
        }
189
      }
190
191
///////////////////////////////////////////////////////////////////////////////////////////////////
192 0c52af30 Leszek Koltunski
193 f647630d Leszek Koltunski
   public void effectFinished(final long effectID)
194 0c52af30 Leszek Koltunski
     {
195 45686da2 Leszek Koltunski
     if( effectID == mRotationFinishedID )
196 434f2f5a Leszek Koltunski
       {
197
       mRemoveRotation = true;
198
       }
199 45686da2 Leszek Koltunski
     else
200 3b12e641 Leszek Koltunski
       {
201 45686da2 Leszek Koltunski
       for(int i=0; i<BaseEffect.Type.LENGTH; i++)
202
         {
203
         if( effectID == mEffectID[i] )
204
           {
205
           mCanRotate   = true;
206
           mCanDrag     = true;
207
           mCanUI       = true;
208
           break;
209
           }
210
         }
211 3b12e641 Leszek Koltunski
       }
212 34747dd1 Leszek Koltunski
     }
213 f291130e Leszek Koltunski
214 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
215 34747dd1 Leszek Koltunski
216 aa8b36aa Leszek Koltunski
   private float computeFOV(float cameraDistance, int screenHeight)
217
     {
218
     double halfFOVInRadians = Math.atan( screenHeight/(2*cameraDistance) );
219
     return (float)(2*halfFOVInRadians*(180/Math.PI));
220
     }
221 34747dd1 Leszek Koltunski
222 aa8b36aa Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
223
// no this will not race with onDrawFrame
224 0c52af30 Leszek Koltunski
225 aa8b36aa Leszek Koltunski
   void finishRotation()
226
     {
227
     mFinishRotation = true;
228
     }
229 0c52af30 Leszek Koltunski
230
///////////////////////////////////////////////////////////////////////////////////////////////////
231
232 f291130e Leszek Koltunski
   boolean createCube(int newSize)
233 34998c9d Leszek Koltunski
     {
234 34747dd1 Leszek Koltunski
     if( mCanDrag && mCanRotate && (mNewCube==null || newSize != mNewCube.getSize()) )
235 f291130e Leszek Koltunski
       {
236 408d4676 Leszek Koltunski
       mSizeChangeCube = true;
237 f291130e Leszek Koltunski
       mNextCubeSize = newSize;
238
       return true;
239
       }
240
241
     return false;
242 34998c9d Leszek Koltunski
     }
243
244
///////////////////////////////////////////////////////////////////////////////////////////////////
245
246 ce0c7ca8 Leszek Koltunski
   private void recomputeScaleFactor(int screenWidth, int screenHeight)
247 8197c92d Leszek Koltunski
     {
248 ce0c7ca8 Leszek Koltunski
     mCubeSizeInScreenSpace = CUBE_SCREEN_RATIO*(screenWidth>screenHeight ? screenHeight:screenWidth);
249 434f2f5a Leszek Koltunski
250 ce0c7ca8 Leszek Koltunski
     if( mNewCube!=null )
251
       {
252
       mNewCube.recomputeScaleFactor(screenWidth, screenHeight, mCubeSizeInScreenSpace);
253
       }
254
     }
255 9208e27b Leszek Koltunski
256 ce0c7ca8 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
257 d1484aba Leszek Koltunski
258 ce0c7ca8 Leszek Koltunski
   void scrambleCube(int num)
259
     {
260 45686da2 Leszek Koltunski
     if( mCanUI )
261 e56c3711 Leszek Koltunski
       {
262 ce0c7ca8 Leszek Koltunski
       mScrambleCube = true;
263
       mScrambleCubeNum = num;
264 8197c92d Leszek Koltunski
       }
265
     }
266 0c52af30 Leszek Koltunski
267 d1484aba Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
268
269 ce0c7ca8 Leszek Koltunski
   void solveCube()
270 d1484aba Leszek Koltunski
     {
271 45686da2 Leszek Koltunski
     if( mCanUI )
272 34747dd1 Leszek Koltunski
       {
273 ce0c7ca8 Leszek Koltunski
       mSolveCube = true;
274 34747dd1 Leszek Koltunski
       }
275 d1484aba Leszek Koltunski
     }
276
277 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
278
279 ce0c7ca8 Leszek Koltunski
   private void createCubeNow(int newSize)
280 8197c92d Leszek Koltunski
     {
281 ce0c7ca8 Leszek Koltunski
     if( mOldCube!=null ) mOldCube.releaseResources();
282
     mOldCube = mNewCube;
283
284
     DistortedTexture texture = new DistortedTexture(TEXTURE_SIZE,TEXTURE_SIZE);
285
     DistortedEffects effects = new DistortedEffects();
286
287 45686da2 Leszek Koltunski
     mNewCube = new RubikCube(newSize, mView.getQuatCurrent(), mView.getQuatAccumulated(), texture, mMesh, effects);
288 ce0c7ca8 Leszek Koltunski
     mNewCube.createTexture();
289
290
     if( mScreenWidth!=0 )
291 2ecf0c21 Leszek Koltunski
       {
292 ce0c7ca8 Leszek Koltunski
       recomputeScaleFactor(mScreenWidth,mScreenHeight);
293 2ecf0c21 Leszek Koltunski
       }
294 3b12e641 Leszek Koltunski
     }
295
296
///////////////////////////////////////////////////////////////////////////////////////////////////
297 408d4676 Leszek Koltunski
// do all 'adjustable' effects (SizeChange, Solve, Scramble)
298 3b12e641 Leszek Koltunski
299 64975793 Leszek Koltunski
   private void doEffectNow(int index)
300 3b12e641 Leszek Koltunski
     {
301 64975793 Leszek Koltunski
     mEffectID[index] = BaseEffect.Type.getType(index).startEffect(this);
302 3b12e641 Leszek Koltunski
303 64975793 Leszek Koltunski
     if( mEffectID[index] == -1 )
304
       {
305 408d4676 Leszek Koltunski
       mCanUI     = true;
306 3b12e641 Leszek Koltunski
       mCanRotate = true;
307
       mCanDrag   = true;
308
       }
309 f548942f Leszek Koltunski
     }
310
311
///////////////////////////////////////////////////////////////////////////////////////////////////
312 8197c92d Leszek Koltunski
313 64975793 Leszek Koltunski
   float returnCubeSizeInScreenSpace()
314 584f7954 Leszek Koltunski
     {
315 64975793 Leszek Koltunski
     return mCubeSizeInScreenSpace;
316 584f7954 Leszek Koltunski
     }
317
318
///////////////////////////////////////////////////////////////////////////////////////////////////
319
320 64975793 Leszek Koltunski
   boolean canRotate()
321 f548942f Leszek Koltunski
     {
322 64975793 Leszek Koltunski
     return mCanRotate;
323
     }
324 584f7954 Leszek Koltunski
325 64975793 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
326
327
   boolean canDrag()
328
     {
329
     return mCanDrag;
330 8197c92d Leszek Koltunski
     }
331 0c52af30 Leszek Koltunski
332
///////////////////////////////////////////////////////////////////////////////////////////////////
333
334 64975793 Leszek Koltunski
   public RubikCube getCube()
335 8197c92d Leszek Koltunski
     {
336 64975793 Leszek Koltunski
     return mNewCube;
337 8197c92d Leszek Koltunski
     }
338
339
///////////////////////////////////////////////////////////////////////////////////////////////////
340
341 64975793 Leszek Koltunski
   public RubikCube getOldCube()
342 8197c92d Leszek Koltunski
     {
343 64975793 Leszek Koltunski
     return mOldCube;
344 8197c92d Leszek Koltunski
     }
345
346 434f2f5a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
347
348 64975793 Leszek Koltunski
   public DistortedScreen getScreen()
349 434f2f5a Leszek Koltunski
     {
350 64975793 Leszek Koltunski
     return mScreen;
351 434f2f5a Leszek Koltunski
     }
352
353 8197c92d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
354
355 64975793 Leszek Koltunski
   public int getNumScrambles()
356 8197c92d Leszek Koltunski
     {
357 64975793 Leszek Koltunski
     return mScrambleCubeNum;
358 8197c92d Leszek Koltunski
     }
359 0c52af30 Leszek Koltunski
360
///////////////////////////////////////////////////////////////////////////////////////////////////
361
362 45686da2 Leszek Koltunski
   void setQuatCurrentOnNextRender()
363 8197c92d Leszek Koltunski
     {
364
     mFinishDragCurrent = true;
365
     }
366 0c52af30 Leszek Koltunski
367
///////////////////////////////////////////////////////////////////////////////////////////////////
368
369 45686da2 Leszek Koltunski
   void setQuatAccumulatedOnNextRender()
370 8197c92d Leszek Koltunski
     {
371
     mFinishDragAccumulated = true;
372
     }
373 0c52af30 Leszek Koltunski
}