rev |
line source |
nuclear@39
|
1 /*
|
nuclear@39
|
2 Stereoscopic tunnel for iOS.
|
nuclear@39
|
3 Copyright (C) 2011 John Tsiombikas <nuclear@member.fsf.org>
|
nuclear@39
|
4
|
nuclear@39
|
5 This program is free software: you can redistribute it and/or modify
|
nuclear@39
|
6 it under the terms of the GNU General Public License as published by
|
nuclear@39
|
7 the Free Software Foundation, either version 3 of the License, or
|
nuclear@39
|
8 (at your option) any later version.
|
nuclear@39
|
9
|
nuclear@39
|
10 This program is distributed in the hope that it will be useful,
|
nuclear@39
|
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
nuclear@39
|
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
nuclear@39
|
13 GNU General Public License for more details.
|
nuclear@39
|
14
|
nuclear@39
|
15 You should have received a copy of the GNU General Public License
|
nuclear@39
|
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
|
nuclear@39
|
17 */
|
nuclear@39
|
18
|
nuclear@20
|
19 #include <math.h>
|
nuclear@20
|
20 #include "opengl.h"
|
nuclear@20
|
21 #include "cam.h"
|
nuclear@20
|
22 #include "sanegl.h"
|
nuclear@20
|
23
|
nuclear@20
|
24 #define DEG_TO_RAD(x) (M_PI * (x) / 180.0)
|
nuclear@20
|
25
|
nuclear@20
|
26 typedef struct vec3 {
|
nuclear@20
|
27 float x, y, z;
|
nuclear@20
|
28 } vec3_t;
|
nuclear@20
|
29
|
nuclear@20
|
30 /* viewing parameters */
|
nuclear@20
|
31 #define DEF_THETA 0
|
nuclear@20
|
32 #define DEF_PHI 0
|
nuclear@20
|
33 #define DEF_DIST 0
|
nuclear@20
|
34 #define DEF_X 0
|
nuclear@20
|
35 #define DEF_Y 0
|
nuclear@20
|
36 #define DEF_Z 0
|
nuclear@20
|
37
|
nuclear@20
|
38 static float cam_theta = DEF_THETA, cam_phi = DEF_PHI;
|
nuclear@20
|
39 static float cam_dist = DEF_DIST;
|
nuclear@20
|
40 static vec3_t cam_pos = {DEF_X, DEF_Y, DEF_Z};
|
nuclear@20
|
41 static float cam_speed = 1.0;
|
nuclear@20
|
42
|
nuclear@20
|
43 /* projection parameters */
|
nuclear@20
|
44 #define DEF_VFOV 45.0
|
nuclear@20
|
45 #define DEF_ASPECT 1.3333333
|
nuclear@20
|
46 #define DEF_NEAR 1.0
|
nuclear@20
|
47 #define DEF_FAR 1000.0
|
nuclear@20
|
48
|
nuclear@20
|
49 static float vfov = DEF_VFOV;
|
nuclear@20
|
50 static float aspect = DEF_ASPECT;
|
nuclear@20
|
51 static float nearclip = DEF_NEAR, farclip = DEF_FAR;
|
nuclear@20
|
52
|
nuclear@20
|
53 /* stereo parameters */
|
nuclear@20
|
54 #define DEF_EYE_SEP 0.1
|
nuclear@20
|
55 #define DEF_FOCUS_DIST 1.0
|
nuclear@20
|
56
|
nuclear@20
|
57 static float eye_sep = DEF_EYE_SEP;
|
nuclear@20
|
58 static float focus_dist = DEF_FOCUS_DIST;
|
nuclear@20
|
59
|
nuclear@20
|
60
|
nuclear@20
|
61 static float rot_speed = 0.5;
|
nuclear@20
|
62 static float zoom_speed = 0.1;
|
nuclear@20
|
63
|
nuclear@20
|
64 void cam_reset(void)
|
nuclear@20
|
65 {
|
nuclear@20
|
66 cam_reset_view();
|
nuclear@20
|
67 cam_reset_proj();
|
nuclear@20
|
68 cam_reset_stereo();
|
nuclear@20
|
69 }
|
nuclear@20
|
70
|
nuclear@20
|
71 void cam_reset_view(void)
|
nuclear@20
|
72 {
|
nuclear@20
|
73 cam_theta = DEF_THETA;
|
nuclear@20
|
74 cam_phi = DEF_PHI;
|
nuclear@20
|
75 cam_dist = DEF_DIST;
|
nuclear@20
|
76 cam_pos.x = DEF_X;
|
nuclear@20
|
77 cam_pos.y = DEF_Y;
|
nuclear@20
|
78 cam_pos.z = DEF_Z;
|
nuclear@20
|
79 }
|
nuclear@20
|
80
|
nuclear@20
|
81 void cam_reset_proj(void)
|
nuclear@20
|
82 {
|
nuclear@20
|
83 vfov = DEF_VFOV;
|
nuclear@20
|
84 aspect = DEF_ASPECT;
|
nuclear@20
|
85 nearclip = DEF_NEAR;
|
nuclear@20
|
86 farclip = DEF_FAR;
|
nuclear@20
|
87 }
|
nuclear@20
|
88
|
nuclear@20
|
89 void cam_reset_stereo(void)
|
nuclear@20
|
90 {
|
nuclear@20
|
91 eye_sep = DEF_EYE_SEP;
|
nuclear@20
|
92 focus_dist = DEF_FOCUS_DIST;
|
nuclear@20
|
93 }
|
nuclear@20
|
94
|
nuclear@20
|
95 void cam_pan(int dx, int dy)
|
nuclear@20
|
96 {
|
nuclear@20
|
97 float dxf = dx * cam_speed;
|
nuclear@20
|
98 float dyf = dy * cam_speed;
|
nuclear@20
|
99 float angle = -DEG_TO_RAD(cam_theta);
|
nuclear@20
|
100
|
nuclear@20
|
101 cam_pos.x += cos(angle) * dxf + sin(angle) * dyf;
|
nuclear@20
|
102 cam_pos.z += -sin(angle) * dxf + cos(angle) * dyf;
|
nuclear@20
|
103 }
|
nuclear@20
|
104
|
nuclear@20
|
105 void cam_height(int dh)
|
nuclear@20
|
106 {
|
nuclear@20
|
107 cam_pos.y += dh * cam_speed;
|
nuclear@20
|
108 }
|
nuclear@20
|
109
|
nuclear@20
|
110 void cam_rotate(int dx, int dy)
|
nuclear@20
|
111 {
|
nuclear@20
|
112 cam_theta += dx * rot_speed;
|
nuclear@20
|
113 cam_phi += dy * rot_speed;
|
nuclear@20
|
114
|
nuclear@20
|
115 if(cam_phi < -90) cam_phi = -90;
|
nuclear@20
|
116 if(cam_phi > 90) cam_phi = 90;
|
nuclear@20
|
117 }
|
nuclear@20
|
118
|
nuclear@20
|
119 void cam_zoom(int dz)
|
nuclear@20
|
120 {
|
nuclear@20
|
121 cam_dist += dz * zoom_speed;
|
nuclear@20
|
122 if(cam_dist < 0.001) {
|
nuclear@20
|
123 cam_dist = 0.001;
|
nuclear@20
|
124 }
|
nuclear@20
|
125 }
|
nuclear@20
|
126
|
nuclear@20
|
127 void cam_clip(float n, float f)
|
nuclear@20
|
128 {
|
nuclear@20
|
129 nearclip = n;
|
nuclear@20
|
130 farclip = f;
|
nuclear@20
|
131 }
|
nuclear@20
|
132
|
nuclear@20
|
133 void cam_fov(float f)
|
nuclear@20
|
134 {
|
nuclear@20
|
135 vfov = f;
|
nuclear@20
|
136 }
|
nuclear@20
|
137
|
nuclear@20
|
138 void cam_aspect(float a)
|
nuclear@20
|
139 {
|
nuclear@20
|
140 aspect = a;
|
nuclear@20
|
141 }
|
nuclear@20
|
142
|
nuclear@20
|
143 void cam_separation(float s)
|
nuclear@20
|
144 {
|
nuclear@20
|
145 eye_sep = s;
|
nuclear@20
|
146 }
|
nuclear@20
|
147
|
nuclear@20
|
148 void cam_focus_dist(float d)
|
nuclear@20
|
149 {
|
nuclear@20
|
150 focus_dist = d;
|
nuclear@20
|
151
|
nuclear@20
|
152 cam_separation(d / 30.0);
|
nuclear@20
|
153 }
|
nuclear@20
|
154
|
nuclear@20
|
155 void cam_view_matrix(void)
|
nuclear@20
|
156 {
|
nuclear@20
|
157 cam_stereo_view_matrix(CAM_CENTER);
|
nuclear@20
|
158 }
|
nuclear@20
|
159
|
nuclear@20
|
160 void cam_stereo_view_matrix(int eye)
|
nuclear@20
|
161 {
|
nuclear@20
|
162 static const float offs_sign[] = {0.0f, 0.5f, -0.5f}; /* center, left, right */
|
nuclear@20
|
163 float offs = eye_sep * offs_sign[eye];
|
nuclear@20
|
164
|
nuclear@20
|
165 gl_translatef(offs, 0, 0);
|
nuclear@20
|
166
|
nuclear@20
|
167 gl_translatef(0, 0, -cam_dist);
|
nuclear@20
|
168 gl_rotatef(cam_phi, 1, 0, 0);
|
nuclear@20
|
169 gl_rotatef(cam_theta, 0, 1, 0);
|
nuclear@20
|
170 gl_translatef(-cam_pos.x, -cam_pos.y, -cam_pos.z);
|
nuclear@20
|
171 }
|
nuclear@20
|
172
|
nuclear@20
|
173 void cam_proj_matrix(void)
|
nuclear@20
|
174 {
|
nuclear@20
|
175 cam_stereo_proj_matrix(CAM_CENTER);
|
nuclear@20
|
176 }
|
nuclear@20
|
177
|
nuclear@20
|
178 void cam_stereo_proj_matrix(int eye)
|
nuclear@20
|
179 {
|
nuclear@20
|
180 float vfov_rad = M_PI * vfov / 180.0;
|
nuclear@20
|
181 float top = nearclip * tan(vfov_rad * 0.5);
|
nuclear@20
|
182 float right = top * aspect;
|
nuclear@20
|
183
|
nuclear@20
|
184 static const float offs_sign[] = {0.0f, 1.0, -1.0}; /* center, left, right */
|
nuclear@20
|
185 float frust_shift = offs_sign[eye] * (eye_sep * 0.5 * nearclip / focus_dist);
|
nuclear@20
|
186
|
nuclear@20
|
187 gl_frustum(-right + frust_shift, right + frust_shift, -top, top, nearclip, farclip);
|
nuclear@20
|
188 }
|