Project

General

Profile

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

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

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// Distorted is free software: you can redistribute it and/or modify                             //
7
// 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
// Distorted is distributed in the hope that it will be useful,                                  //
12
// 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
// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.magic;
21

    
22
import android.opengl.GLSurfaceView;
23

    
24
import org.distorted.effect.BaseEffect;
25
import org.distorted.library.effect.VertexEffectSink;
26
import org.distorted.library.main.DistortedEffects;
27
import org.distorted.library.main.DistortedLibrary;
28
import org.distorted.library.main.DistortedScreen;
29
import org.distorted.library.main.DistortedTexture;
30
import org.distorted.library.mesh.MeshFlat;
31
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
public class RubikRenderer implements GLSurfaceView.Renderer, EffectListener
39
{
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
    public  static final int TEXTURE_SIZE = 600;
43

    
44
    private RubikSurfaceView mView;
45
    private DistortedScreen mScreen;
46
    private float mCubeSizeInScreenSpace;
47
    private int mNextCubeSize, mScrambleCubeNum;
48
    private long mRotationFinishedID;
49
    private long[] mEffectID;
50
    private boolean mFinishRotation, mRemoveRotation, mFinishDragCurrent, mFinishDragAccumulated;
51
    private boolean mSizeChangeCube, mSolveCube, mScrambleCube;
52
    private boolean mCanRotate, mCanDrag, mCanUI;
53
    private RubikCube mOldCube, mNewCube;
54
    private int mScreenWidth, mScreenHeight;
55
    private MeshFlat mMesh;
56

    
57
///////////////////////////////////////////////////////////////////////////////////////////////////
58

    
59
    RubikRenderer(RubikSurfaceView v)
60
      {
61
      mView = v;
62

    
63
      mScreen = new DistortedScreen();
64

    
65
      mOldCube = null;
66
      mNewCube = null;
67

    
68
      mScreenWidth = mScreenHeight = 0;
69
      mScrambleCubeNum = 0;
70

    
71
      mFinishRotation        = false;
72
      mRemoveRotation        = false;
73
      mFinishDragCurrent     = false;
74
      mFinishDragAccumulated = false;
75
      mSizeChangeCube        = false;
76
      mSolveCube             = false;
77
      mScrambleCube          = false;
78

    
79
      mCanRotate   = true;
80
      mCanDrag     = true;
81
      mCanUI       = true;
82

    
83
      mEffectID = new long[BaseEffect.Type.LENGTH];
84

    
85
      mMesh= new MeshFlat(20,20);
86
      mNextCubeSize =RubikActivity.getSize();
87
      }
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
    @Override
94
    public void onDrawFrame(GL10 glUnused) 
95
      {
96
      mScreen.render( System.currentTimeMillis() );
97

    
98
      if( mFinishDragCurrent )
99
        {
100
        mFinishDragCurrent = false;
101
        mView.setQuatCurrent();
102
        }
103

    
104
      if( mFinishDragAccumulated )
105
        {
106
        mFinishDragAccumulated = false;
107
        mView.setQuatAccumulated();
108
        }
109

    
110
      if( mFinishRotation )
111
        {
112
        mCanRotate = false;
113
        mFinishRotation=false;
114
        mRotationFinishedID = mNewCube.finishRotationNow(this);
115
        }
116

    
117
      if( mRemoveRotation )
118
        {
119
        mRemoveRotation=false;
120
        mNewCube.removeRotationNow();
121
        mCanRotate = true;
122
        }
123

    
124
      if( mSizeChangeCube )
125
        {
126
        mSizeChangeCube = false;
127
        mCanDrag        = false;
128
        mCanRotate      = false;
129
        createCubeNow(mNextCubeSize);
130
        doEffectNow(0);
131
        }
132

    
133
      if( mSolveCube )
134
        {
135
        mSolveCube   = false;
136
        mCanDrag     = false;
137
        mCanRotate   = false;
138
        mCanUI       = false;
139
        doEffectNow(1);
140
        }
141

    
142
      if( mScrambleCube )
143
        {
144
        mScrambleCube = false;
145
        mCanDrag      = false;
146
        mCanRotate    = false;
147
        mCanUI        = false;
148
        doEffectNow(2);
149
        }
150
      }
151

    
152
///////////////////////////////////////////////////////////////////////////////////////////////////
153

    
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
      BaseEffect.Type.enableEffects();
180

    
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

    
193
   public void effectFinished(final long effectID)
194
     {
195
     if( effectID == mRotationFinishedID )
196
       {
197
       mRemoveRotation = true;
198
       }
199
     else
200
       {
201
       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
       }
212
     }
213

    
214
///////////////////////////////////////////////////////////////////////////////////////////////////
215

    
216
   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

    
222
///////////////////////////////////////////////////////////////////////////////////////////////////
223
// no this will not race with onDrawFrame
224

    
225
   void finishRotation()
226
     {
227
     mFinishRotation = true;
228
     }
229

    
230
///////////////////////////////////////////////////////////////////////////////////////////////////
231

    
232
   boolean createCube(int newSize)
233
     {
234
     if( mCanDrag && mCanRotate && (mNewCube==null || newSize != mNewCube.getSize()) )
235
       {
236
       mSizeChangeCube = true;
237
       mNextCubeSize = newSize;
238
       return true;
239
       }
240

    
241
     return false;
242
     }
243

    
244
///////////////////////////////////////////////////////////////////////////////////////////////////
245

    
246
   private void recomputeScaleFactor(int screenWidth, int screenHeight)
247
     {
248
     mCubeSizeInScreenSpace = CUBE_SCREEN_RATIO*(screenWidth>screenHeight ? screenHeight:screenWidth);
249

    
250
     if( mNewCube!=null )
251
       {
252
       mNewCube.recomputeScaleFactor(screenWidth, screenHeight, mCubeSizeInScreenSpace);
253
       }
254
     }
255

    
256
///////////////////////////////////////////////////////////////////////////////////////////////////
257

    
258
   void scrambleCube(int num)
259
     {
260
     if( mCanUI )
261
       {
262
       mScrambleCube = true;
263
       mScrambleCubeNum = num;
264
       }
265
     }
266

    
267
///////////////////////////////////////////////////////////////////////////////////////////////////
268

    
269
   void solveCube()
270
     {
271
     if( mCanUI )
272
       {
273
       mSolveCube = true;
274
       }
275
     }
276

    
277
///////////////////////////////////////////////////////////////////////////////////////////////////
278

    
279
   private void createCubeNow(int newSize)
280
     {
281
     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
     mNewCube = new RubikCube(newSize, mView.getQuatCurrent(), mView.getQuatAccumulated(), texture, mMesh, effects);
288
     mNewCube.createTexture();
289

    
290
     if( mScreenWidth!=0 )
291
       {
292
       recomputeScaleFactor(mScreenWidth,mScreenHeight);
293
       }
294
     }
295

    
296
///////////////////////////////////////////////////////////////////////////////////////////////////
297
// do all 'adjustable' effects (SizeChange, Solve, Scramble)
298

    
299
   private void doEffectNow(int index)
300
     {
301
     mEffectID[index] = BaseEffect.Type.getType(index).startEffect(this);
302

    
303
     if( mEffectID[index] == -1 )
304
       {
305
       mCanUI     = true;
306
       mCanRotate = true;
307
       mCanDrag   = true;
308
       }
309
     }
310

    
311
///////////////////////////////////////////////////////////////////////////////////////////////////
312

    
313
   float returnCubeSizeInScreenSpace()
314
     {
315
     return mCubeSizeInScreenSpace;
316
     }
317

    
318
///////////////////////////////////////////////////////////////////////////////////////////////////
319

    
320
   boolean canRotate()
321
     {
322
     return mCanRotate;
323
     }
324

    
325
///////////////////////////////////////////////////////////////////////////////////////////////////
326

    
327
   boolean canDrag()
328
     {
329
     return mCanDrag;
330
     }
331

    
332
///////////////////////////////////////////////////////////////////////////////////////////////////
333

    
334
   public RubikCube getCube()
335
     {
336
     return mNewCube;
337
     }
338

    
339
///////////////////////////////////////////////////////////////////////////////////////////////////
340

    
341
   public RubikCube getOldCube()
342
     {
343
     return mOldCube;
344
     }
345

    
346
///////////////////////////////////////////////////////////////////////////////////////////////////
347

    
348
   public DistortedScreen getScreen()
349
     {
350
     return mScreen;
351
     }
352

    
353
///////////////////////////////////////////////////////////////////////////////////////////////////
354

    
355
   public int getNumScrambles()
356
     {
357
     return mScrambleCubeNum;
358
     }
359

    
360
///////////////////////////////////////////////////////////////////////////////////////////////////
361

    
362
   void setQuatCurrentOnNextRender()
363
     {
364
     mFinishDragCurrent = true;
365
     }
366

    
367
///////////////////////////////////////////////////////////////////////////////////////////////////
368

    
369
   void setQuatAccumulatedOnNextRender()
370
     {
371
     mFinishDragAccumulated = true;
372
     }
373
}
(4-4/6)