Project

General

Profile

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

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

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.examples.rubik;
21

    
22
import android.opengl.GLSurfaceView;
23

    
24
import org.distorted.library.effect.VertexEffectSink;
25
import org.distorted.library.main.Distorted;
26
import org.distorted.library.main.DistortedScreen;
27
import org.distorted.library.message.EffectListener;
28
import org.distorted.library.message.EffectMessage;
29
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
class RubikRenderer implements GLSurfaceView.Renderer, EffectListener
38
{
39
    private static final int NUM_CUBES = 4;
40
    private static final float CUBE_SCREEN_RATIO = 0.5f;
41
    private static final float CAMERA_DISTANCE   = 0.5f;  // 0.5 of the length of max(scrHeight,scrWidth)
42

    
43
    private RubikSurfaceView mView;
44
    private DistortedScreen mScreen;
45
    private Static3D mMove, mScale;
46
    private Static4D mQuatCurrent, mQuatAccumulated;
47
    private Static4D mTempCurrent, mTempAccumulated;
48
    private float mCubeSizeInScreenSpace;
49
    private boolean mFinishRotation, mRemoveRotation, mFinishDragCurrent, mFinishDragAccumulated;
50
    private RubikCube mCube;
51

    
52
///////////////////////////////////////////////////////////////////////////////////////////////////
53

    
54
    RubikRenderer(RubikSurfaceView v)
55
      {
56
      mView = v;
57

    
58
      mScreen = new DistortedScreen();
59

    
60
      mTempCurrent     = new Static4D(0,0,0,1);
61
      mTempAccumulated = initializeQuat();
62
      mQuatCurrent     = new Static4D(0,0,0,1);
63
      mQuatAccumulated = initializeQuat();
64

    
65
      mMove  = new Static3D(0,0,0);
66
      mScale = new Static3D(1,1,1);
67

    
68
      mFinishRotation        = false;
69
      mRemoveRotation        = false;
70
      mFinishDragCurrent     = false;
71
      mFinishDragAccumulated = false;
72

    
73
      mCube = new RubikCube(NUM_CUBES, mMove, mScale, mQuatCurrent, mQuatAccumulated);
74
      }
75

    
76
///////////////////////////////////////////////////////////////////////////////////////////////////
77
// various things are done here delayed, 'after the next render' as not to be done mid-render and
78
// cause artifacts.
79

    
80
    public void onDrawFrame(GL10 glUnused) 
81
      {
82
      mScreen.render( System.currentTimeMillis() );
83

    
84
      if( mFinishDragCurrent )
85
        {
86
        mFinishDragCurrent = false;
87
        mQuatCurrent.set(mTempCurrent);
88
        }
89

    
90
      if( mFinishDragAccumulated )
91
        {
92
        mFinishDragAccumulated = false;
93
        mQuatAccumulated.set(mTempAccumulated);
94
        }
95

    
96
      if( mFinishRotation )
97
        {
98
        mFinishRotation=false;
99
        mCube.finishRotationCalledOnNextRender(this);
100
        }
101

    
102
      if( mRemoveRotation )
103
        {
104
        mRemoveRotation=false;
105
        mCube.removeRotationCalledOnNextRender(this);
106
        }
107
      }
108

    
109
///////////////////////////////////////////////////////////////////////////////////////////////////
110
// EffectListener. The library sends a message to us when it's time to call 'removeRotation'
111

    
112
   public void effectMessage(final EffectMessage em, final long effectID, final long objectID)
113
     {
114
     switch(em)
115
        {
116
        case EFFECT_FINISHED: mRemoveRotation = true; break;
117
        }
118
     }
119

    
120
///////////////////////////////////////////////////////////////////////////////////////////////////
121
    
122
    public void onSurfaceChanged(GL10 glUnused, int width, int height) 
123
      {
124
      float cameraDistance = CAMERA_DISTANCE*(width>height ? width:height);
125
      float fovInDegrees   = computeFOV(cameraDistance,height);
126

    
127
      mScreen.setProjection( fovInDegrees, 0.1f);
128
      mView.setScreenSize(width,height);
129
      mView.setCameraDist(cameraDistance);
130

    
131
      mCubeSizeInScreenSpace = CUBE_SCREEN_RATIO*(width>height ? height:width);
132
      float texSize = mCube.getTextureSize();
133
      float scaleFactor = mCubeSizeInScreenSpace/(texSize*mCube.getSize());
134

    
135
      mMove.set( (width-scaleFactor*texSize)/2 , (height-scaleFactor*texSize)/2 , -scaleFactor*texSize/2 );
136
      mScale.set(scaleFactor,scaleFactor,scaleFactor);
137

    
138
      mScreen.resize(width, height);
139
      }
140

    
141
///////////////////////////////////////////////////////////////////////////////////////////////////
142
    
143
    public void onSurfaceCreated(GL10 glUnused, EGLConfig config) 
144
      {
145
      mCube.createTexture();
146
      mScreen.detachAll();
147
      mCube.attachToScreen(mScreen);
148

    
149
      VertexEffectSink.enable();
150

    
151
      try
152
        {
153
        Distorted.onCreate(mView.getContext());
154
        }
155
      catch(Exception ex)
156
        {
157
        android.util.Log.e("Rubik", ex.getMessage() );
158
        }
159
      }
160

    
161
///////////////////////////////////////////////////////////////////////////////////////////////////
162

    
163
    private float computeFOV(float cameraDistance, int screenHeight)
164
      {
165
      double halfFOVInRadians = Math.atan( screenHeight/(2*cameraDistance) );
166
      return (float)(2*halfFOVInRadians*(180/Math.PI));
167
      }
168

    
169
///////////////////////////////////////////////////////////////////////////////////////////////////
170
// no this will not race with onDrawFrame
171

    
172
    void finishRotation()
173
      {
174
      mFinishRotation = true;
175
      }
176

    
177
///////////////////////////////////////////////////////////////////////////////////////////////////
178

    
179
    float returnCubeSizeInScreenSpace()
180
      {
181
      return mCubeSizeInScreenSpace;
182
      }
183

    
184
///////////////////////////////////////////////////////////////////////////////////////////////////
185

    
186
    RubikCube getCube()
187
      {
188
      return mCube;
189
      }
190

    
191
///////////////////////////////////////////////////////////////////////////////////////////////////
192
// Initial rotation of the cube. Something semi-random that looks good.
193

    
194
    Static4D initializeQuat()
195
      {
196
      return new Static4D(-0.25189602f,0.3546389f,0.009657208f,0.90038127f);
197
      }
198

    
199
///////////////////////////////////////////////////////////////////////////////////////////////////
200

    
201
    void setQuatCurrent(Static4D current)
202
      {
203
      mTempCurrent.set(current);
204
      mFinishDragCurrent = true;
205
      }
206

    
207
///////////////////////////////////////////////////////////////////////////////////////////////////
208

    
209
    void setQuatAccumulated(Static4D accumulated)
210
      {
211
      mTempAccumulated.set(accumulated);
212
      mFinishDragAccumulated = true;
213
      }
214
}
(3-3/4)