Project

General

Profile

Download (9.08 KB) Statistics
| Branch: | Revision:

examples / src / main / java / org / distorted / examples / rubik / RubikRenderer.java @ af8b42cc

1 5b4a2d76 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2 8647eae2 Leszek Koltunski
// Copyright 2019 Leszek Koltunski                                                               //
3 5b4a2d76 Leszek Koltunski
//                                                                                               //
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.examples.rubik;
21
22
import android.opengl.GLSurfaceView;
23
24 94cc96ff Leszek Koltunski
import org.distorted.library.effect.VertexEffectSink;
25 5b4a2d76 Leszek Koltunski
import org.distorted.library.main.Distorted;
26
import org.distorted.library.main.DistortedScreen;
27 b62eb334 Leszek Koltunski
import org.distorted.library.message.EffectListener;
28
import org.distorted.library.message.EffectMessage;
29 5b4a2d76 Leszek Koltunski
import org.distorted.library.type.Static3D;
30
import org.distorted.library.type.Static4D;
31
32
import javax.microedition.khronos.egl.EGLConfig;
33
import javax.microedition.khronos.opengles.GL10;
34
35
///////////////////////////////////////////////////////////////////////////////////////////////////
36
37 b62eb334 Leszek Koltunski
class RubikRenderer implements GLSurfaceView.Renderer, EffectListener
38 5b4a2d76 Leszek Koltunski
{
39 e4c0057e Leszek Koltunski
    private static final float CUBE_SCREEN_RATIO = 0.5f;
40 8a40abf4 Leszek Koltunski
    private static final float CAMERA_DISTANCE   = 0.6f;  // 0.6 of the length of max(scrHeight,scrWidth)
41 e4c0057e Leszek Koltunski
42 18709ae0 Leszek Koltunski
    private RubikSurfaceView mView;
43 5b4a2d76 Leszek Koltunski
    private DistortedScreen mScreen;
44 8647eae2 Leszek Koltunski
    private Static3D mMove, mScale;
45 94cc96ff Leszek Koltunski
    private Static4D mQuatCurrent, mQuatAccumulated;
46
    private Static4D mTempCurrent, mTempAccumulated;
47 483ae94e Leszek Koltunski
    private float mCubeSizeInScreenSpace;
48 b62eb334 Leszek Koltunski
    private boolean mFinishRotation, mRemoveRotation, mFinishDragCurrent, mFinishDragAccumulated;
49 d4374cd3 Leszek Koltunski
    private boolean mCanRotate;
50 8647eae2 Leszek Koltunski
    private RubikCube mCube;
51 5b4a2d76 Leszek Koltunski
52 af8b42cc Leszek Koltunski
    private int mScreenWidth, mScreenHeight;
53
54 5b4a2d76 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
55
56 18709ae0 Leszek Koltunski
    RubikRenderer(RubikSurfaceView v)
57 5b4a2d76 Leszek Koltunski
      {
58
      mView = v;
59
60
      mScreen = new DistortedScreen();
61
62 94cc96ff Leszek Koltunski
      mTempCurrent     = new Static4D(0,0,0,1);
63
      mTempAccumulated = initializeQuat();
64
      mQuatCurrent     = new Static4D(0,0,0,1);
65
      mQuatAccumulated = initializeQuat();
66 5b4a2d76 Leszek Koltunski
67 af8b42cc Leszek Koltunski
      mScreenWidth = mScreenHeight = 0;
68
69 5b4a2d76 Leszek Koltunski
      mMove  = new Static3D(0,0,0);
70
      mScale = new Static3D(1,1,1);
71 8647eae2 Leszek Koltunski
72
      mFinishRotation        = false;
73 b62eb334 Leszek Koltunski
      mRemoveRotation        = false;
74 8647eae2 Leszek Koltunski
      mFinishDragCurrent     = false;
75
      mFinishDragAccumulated = false;
76
77 d4374cd3 Leszek Koltunski
      mCanRotate = true;
78 5b4a2d76 Leszek Koltunski
      }
79
80
///////////////////////////////////////////////////////////////////////////////////////////////////
81 b62eb334 Leszek Koltunski
// various things are done here delayed, 'after the next render' as not to be done mid-render and
82
// cause artifacts.
83
84 5b4a2d76 Leszek Koltunski
    public void onDrawFrame(GL10 glUnused) 
85
      {
86
      mScreen.render( System.currentTimeMillis() );
87 94cc96ff Leszek Koltunski
88 8647eae2 Leszek Koltunski
      if( mFinishDragCurrent )
89
        {
90
        mFinishDragCurrent = false;
91
        mQuatCurrent.set(mTempCurrent);
92
        }
93
94
      if( mFinishDragAccumulated )
95
        {
96
        mFinishDragAccumulated = false;
97
        mQuatAccumulated.set(mTempAccumulated);
98
        }
99
100
      if( mFinishRotation )
101
        {
102 d4374cd3 Leszek Koltunski
        mCanRotate = false;
103 8647eae2 Leszek Koltunski
        mFinishRotation=false;
104 b62eb334 Leszek Koltunski
        mCube.finishRotationCalledOnNextRender(this);
105
        }
106
107
      if( mRemoveRotation )
108
        {
109
        mRemoveRotation=false;
110
        mCube.removeRotationCalledOnNextRender(this);
111 d4374cd3 Leszek Koltunski
        mCanRotate = true;
112 8647eae2 Leszek Koltunski
        }
113 5b4a2d76 Leszek Koltunski
      }
114
115 b62eb334 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
116
// EffectListener. The library sends a message to us when it's time to call 'removeRotation'
117
118
   public void effectMessage(final EffectMessage em, final long effectID, final long objectID)
119
     {
120
     switch(em)
121
        {
122
        case EFFECT_FINISHED: mRemoveRotation = true; break;
123
        }
124
     }
125
126 5b4a2d76 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
127
    
128
    public void onSurfaceChanged(GL10 glUnused, int width, int height) 
129
      {
130 483ae94e Leszek Koltunski
      float cameraDistance = CAMERA_DISTANCE*(width>height ? width:height);
131
      float fovInDegrees   = computeFOV(cameraDistance,height);
132 7f986357 Leszek Koltunski
133
      mScreen.setProjection( fovInDegrees, 0.1f);
134 18709ae0 Leszek Koltunski
      mView.setScreenSize(width,height);
135 483ae94e Leszek Koltunski
      mView.setCameraDist(cameraDistance);
136 af8b42cc Leszek Koltunski
      mScreen.resize(width, height);
137 5b4a2d76 Leszek Koltunski
138 af8b42cc Leszek Koltunski
      recomputeScaleFactor(width,height);
139 5b4a2d76 Leszek Koltunski
140 af8b42cc Leszek Koltunski
      mScreenHeight = height;
141
      mScreenWidth  = width;
142 5b4a2d76 Leszek Koltunski
      }
143
144
///////////////////////////////////////////////////////////////////////////////////////////////////
145
    
146
    public void onSurfaceCreated(GL10 glUnused, EGLConfig config) 
147
      {
148 8647eae2 Leszek Koltunski
      mCube.createTexture();
149 5b4a2d76 Leszek Koltunski
      mScreen.detachAll();
150 8647eae2 Leszek Koltunski
      mCube.attachToScreen(mScreen);
151 5b4a2d76 Leszek Koltunski
152 94cc96ff Leszek Koltunski
      VertexEffectSink.enable();
153 e4c0057e Leszek Koltunski
154 5b4a2d76 Leszek Koltunski
      try
155
        {
156
        Distorted.onCreate(mView.getContext());
157
        }
158
      catch(Exception ex)
159
        {
160
        android.util.Log.e("Rubik", ex.getMessage() );
161
        }
162
      }
163 e4c0057e Leszek Koltunski
164 483ae94e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
165
166 af8b42cc Leszek Koltunski
   private float computeFOV(float cameraDistance, int screenHeight)
167
     {
168
     double halfFOVInRadians = Math.atan( screenHeight/(2*cameraDistance) );
169
     return (float)(2*halfFOVInRadians*(180/Math.PI));
170
     }
171 483ae94e Leszek Koltunski
172 8647eae2 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
173
// no this will not race with onDrawFrame
174
175 af8b42cc Leszek Koltunski
   void finishRotation()
176
     {
177
     mFinishRotation = true;
178
     }
179 8647eae2 Leszek Koltunski
180 e4c0057e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
181
182 af8b42cc Leszek Koltunski
   void createCube(int newSize)
183
     {
184
     int oldSize = mCube==null ? 0 : mCube.getSize();
185
186
     if( oldSize!=newSize )
187
       {
188
       mCube = new RubikCube(newSize, mMove, mScale, mQuatCurrent, mQuatAccumulated);
189
       mCube.createTexture();
190
191
       if( mScreenWidth!=0 )
192
         {
193
         recomputeScaleFactor(mScreenWidth,mScreenHeight);
194
         }
195
196
       mScreen.detachAll();
197
       mCube.attachToScreen(mScreen);
198
       }
199
     }
200 e4c0057e Leszek Koltunski
201 d4374cd3 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
202
203 af8b42cc Leszek Koltunski
   void recomputeScaleFactor(int screenWidth, int screenHeight)
204
     {
205
     mCubeSizeInScreenSpace = CUBE_SCREEN_RATIO*(screenWidth>screenHeight ? screenHeight:screenWidth);
206
     float texSize = mCube.getTextureSize();
207
     float scaleFactor = mCubeSizeInScreenSpace/(texSize*mCube.getSize());
208
209
     mMove.set( (screenWidth-scaleFactor*texSize)/2 , (screenHeight-scaleFactor*texSize)/2 , -scaleFactor*texSize/2 );
210
     mScale.set(scaleFactor,scaleFactor,scaleFactor);
211
     }
212 d4374cd3 Leszek Koltunski
213 e4c0057e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
214
215 af8b42cc Leszek Koltunski
   void scrambleCube()
216
     {
217
218
     }
219
220
///////////////////////////////////////////////////////////////////////////////////////////////////
221
222
   float returnCubeSizeInScreenSpace()
223
     {
224
     return mCubeSizeInScreenSpace;
225
     }
226
227
///////////////////////////////////////////////////////////////////////////////////////////////////
228
229
   boolean canRotate()
230
     {
231
     return mCanRotate;
232
     }
233
234
///////////////////////////////////////////////////////////////////////////////////////////////////
235
236
   RubikCube getCube()
237
     {
238
     return mCube;
239
     }
240 e4c0057e Leszek Koltunski
241 94cc96ff Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
242
// Initial rotation of the cube. Something semi-random that looks good.
243
244 af8b42cc Leszek Koltunski
   Static4D initializeQuat()
245
     {
246
     return new Static4D(-0.25189602f,0.3546389f,0.009657208f,0.90038127f);
247
     }
248 94cc96ff Leszek Koltunski
249
///////////////////////////////////////////////////////////////////////////////////////////////////
250
251 af8b42cc Leszek Koltunski
   void setQuatCurrent(Static4D current)
252
     {
253
     mTempCurrent.set(current);
254
     mFinishDragCurrent = true;
255
     }
256 94cc96ff Leszek Koltunski
257
///////////////////////////////////////////////////////////////////////////////////////////////////
258
259 af8b42cc Leszek Koltunski
   void setQuatAccumulated(Static4D accumulated)
260
     {
261
     mTempAccumulated.set(accumulated);
262
     mFinishDragAccumulated = true;
263
     }
264 5b4a2d76 Leszek Koltunski
}