Project

General

Profile

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

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

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