rev |
line source |
discordia@2
|
1 #include <GLTools.h>
|
discordia@2
|
2 #include <GLShaderManager.h>
|
discordia@2
|
3 #include <GLFrustum.h>
|
discordia@2
|
4 #include <GLBatch.h>
|
discordia@2
|
5 #include <GLFrame.h>
|
discordia@2
|
6 #include <GLMatrixStack.h>
|
discordia@2
|
7 #include <GLGeometryTransform.h>
|
discordia@2
|
8 #include <StopWatch.h>
|
discordia@2
|
9
|
discordia@2
|
10 #include <math.h>
|
discordia@2
|
11 #include <ctype.h>
|
discordia@2
|
12 #include <stdlib.h>
|
discordia@2
|
13 #include <string.h>
|
discordia@2
|
14
|
discordia@2
|
15 #include <dirent.h>
|
discordia@2
|
16
|
discordia@2
|
17 #include <GL/glut.h>
|
discordia@2
|
18 #include <GL/glx.h>
|
discordia@2
|
19
|
discordia@2
|
20 GLShaderManager shaderManager;
|
discordia@2
|
21 GLMatrixStack modelViewMatrix;
|
discordia@2
|
22 GLMatrixStack projectionMatrix;
|
discordia@2
|
23 GLFrustum viewFrustum;
|
discordia@2
|
24 GLGeometryTransform transformPipeline;
|
discordia@2
|
25
|
discordia@2
|
26 GLFrame cameraFrame;
|
discordia@2
|
27
|
discordia@2
|
28 GLenum polymode = GL_FILL;
|
discordia@2
|
29
|
discordia@2
|
30 int width = 800;
|
discordia@2
|
31 int height = 600;
|
discordia@2
|
32 int fullscreen = 0;
|
discordia@2
|
33
|
discordia@2
|
34 #define NUM_SPHERES 50
|
discordia@2
|
35 GLFrame spheres[NUM_SPHERES];
|
discordia@2
|
36
|
discordia@2
|
37 GLTriangleBatch jupiterBatch;
|
discordia@2
|
38 GLTriangleBatch sphereBatch;
|
discordia@2
|
39 GLTriangleBatch earthBatch;
|
discordia@2
|
40 GLTriangleBatch moonBatch;
|
discordia@2
|
41 GLTriangleBatch sunBatch;
|
discordia@2
|
42 GLBatch floorBatch;
|
discordia@2
|
43
|
discordia@2
|
44 #define TEX_EARTH 1
|
discordia@2
|
45 #define TEX_MOON 2
|
discordia@2
|
46 #define TEX_JUPITER 3
|
discordia@2
|
47 #define TEX_SUN 4
|
discordia@2
|
48 #define NUM_TEXTURES 5
|
discordia@2
|
49 GLuint uiTextures[NUM_TEXTURES];
|
discordia@2
|
50
|
discordia@2
|
51 ////////////////////////////////////////////////////////////////////////////////
|
discordia@2
|
52 #define SCREENSHOT_FILENAME_BASE "screenshot-"
|
discordia@2
|
53 #define SCREENSHOT_FILENAME_BASELEN 11
|
discordia@2
|
54 #define SCREENSHOT_FILENAME_EXT ".tga"
|
discordia@2
|
55 #define SCREENSHOT_FILENAME_EXTLEN 4
|
discordia@2
|
56
|
discordia@2
|
57 int scandir_filter(const struct dirent * d)
|
discordia@2
|
58 {
|
discordia@2
|
59 if (memcmp(d->d_name, SCREENSHOT_FILENAME_BASE,
|
discordia@2
|
60 SCREENSHOT_FILENAME_BASELEN) != 0) return 0;
|
discordia@2
|
61 if (memcmp(d->d_name+SCREENSHOT_FILENAME_BASELEN+3,
|
discordia@2
|
62 SCREENSHOT_FILENAME_EXT, SCREENSHOT_FILENAME_EXTLEN) != 0)
|
discordia@2
|
63 return 0;
|
discordia@2
|
64 if (isdigit(d->d_name[SCREENSHOT_FILENAME_BASELEN])
|
discordia@2
|
65 && isdigit(d->d_name[SCREENSHOT_FILENAME_BASELEN+1])
|
discordia@2
|
66 && isdigit(d->d_name[SCREENSHOT_FILENAME_BASELEN+2]))
|
discordia@2
|
67 return 1;
|
discordia@2
|
68 return 0;
|
discordia@2
|
69 }
|
discordia@2
|
70
|
discordia@2
|
71
|
discordia@2
|
72 int get_next_file_name(char * filename)
|
discordia@2
|
73 {
|
discordia@2
|
74 static int i = 0;
|
discordia@2
|
75
|
discordia@2
|
76 if (i == 0)
|
discordia@2
|
77 {
|
discordia@2
|
78 char pattern[SCREENSHOT_FILENAME_BASELEN+3+SCREENSHOT_FILENAME_EXTLEN];
|
discordia@2
|
79 struct dirent ** file_list;
|
discordia@2
|
80 int num_files = scandir(".", &file_list, scandir_filter, alphasort);
|
discordia@2
|
81 if (num_files != 0)
|
discordia@2
|
82 sprintf(pattern, "%s%%03d%s", SCREENSHOT_FILENAME_BASE,
|
discordia@2
|
83 SCREENSHOT_FILENAME_EXT);
|
discordia@2
|
84 sscanf(file_list[num_files-1]->d_name, pattern, &i);
|
discordia@2
|
85 }
|
discordia@2
|
86 i++;
|
discordia@2
|
87
|
discordia@2
|
88 sprintf(filename, "%s%03d%s", SCREENSHOT_FILENAME_BASE, i,
|
discordia@2
|
89 SCREENSHOT_FILENAME_EXT);
|
discordia@2
|
90 return i;
|
discordia@2
|
91 }
|
discordia@2
|
92
|
discordia@2
|
93 ////////////////////////////////////////////////////////////////////////////////
|
discordia@2
|
94 bool LoadTGATexture(const char * szFileName, GLenum minFilter,
|
discordia@2
|
95 GLenum magFilter, GLenum wrapMode)
|
discordia@2
|
96 {
|
discordia@2
|
97 GLbyte * pBits;
|
discordia@2
|
98 int nWidth, nHeight, nComponents;
|
discordia@2
|
99 GLenum eFormat;
|
discordia@2
|
100
|
discordia@2
|
101 pBits = gltReadTGABits(szFileName, &nWidth, &nHeight, &nComponents, &eFormat);
|
discordia@2
|
102 if (pBits == NULL)
|
discordia@2
|
103 {
|
discordia@2
|
104 fprintf(stderr, "Failed to load %s\n", szFileName);
|
discordia@2
|
105 exit(EXIT_FAILURE);
|
discordia@2
|
106 }
|
discordia@2
|
107
|
discordia@2
|
108 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode);
|
discordia@2
|
109 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode);
|
discordia@2
|
110
|
discordia@2
|
111 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
|
discordia@2
|
112 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
|
discordia@2
|
113
|
discordia@2
|
114 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
discordia@2
|
115 glTexImage2D(GL_TEXTURE_2D, 0, nComponents, nWidth, nHeight, 0,
|
discordia@2
|
116 eFormat, GL_UNSIGNED_BYTE, pBits);
|
discordia@2
|
117
|
discordia@2
|
118 free(pBits);
|
discordia@2
|
119
|
discordia@2
|
120 if (minFilter == GL_LINEAR_MIPMAP_LINEAR ||
|
discordia@2
|
121 minFilter == GL_LINEAR_MIPMAP_NEAREST ||
|
discordia@2
|
122 minFilter == GL_NEAREST_MIPMAP_LINEAR ||
|
discordia@2
|
123 minFilter == GL_NEAREST_MIPMAP_NEAREST)
|
discordia@2
|
124 {
|
discordia@2
|
125 glGenerateMipmap(GL_TEXTURE_2D);
|
discordia@2
|
126 }
|
discordia@2
|
127
|
discordia@2
|
128 return true;
|
discordia@2
|
129 }
|
discordia@2
|
130
|
discordia@2
|
131 ////////////////////////////////////////////////////////////////////////////////
|
discordia@2
|
132 void DrawSolarSystem(GLfloat yRot)
|
discordia@2
|
133 {
|
discordia@2
|
134 static GLfloat vWhite[] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
discordia@2
|
135 static GLfloat vLightPos[] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
discordia@2
|
136 static M3DVector3f vSunPos = { 0.0f, 0.0f, 0.0f };
|
discordia@2
|
137 static M3DVector3f vEarthPos = { 5.0f, 0.0f, 0.0f };
|
discordia@2
|
138 static M3DVector3f vJupiterPos = { 10.0f, 0.0f, 0.0f };
|
discordia@2
|
139
|
discordia@2
|
140 float RotScale = 100.0;
|
discordia@2
|
141 float SunRotSpeed = 1.0/(25*24) * RotScale;
|
discordia@2
|
142
|
discordia@2
|
143 float JupiterRotSpeed = 1.0/9 * RotScale;
|
discordia@2
|
144 float JupiterAxialTilt = 3.13;
|
discordia@2
|
145
|
discordia@2
|
146 float EarthRotSpeed = 1.0/24 * RotScale;
|
discordia@2
|
147 float EarthAxialTilt = 23.5;
|
discordia@2
|
148
|
discordia@2
|
149 float MoonRotSpeed = 1.0/29.5 * RotScale;
|
discordia@2
|
150 float MoonAxialTilt = 6.7;
|
discordia@2
|
151 float MoonOrbitSpeed = 1.0/29.5 * RotScale;
|
discordia@2
|
152 float MoonOrbitTilt = 5.145;
|
discordia@2
|
153
|
discordia@2
|
154 static CStopWatch rotTimer;
|
discordia@2
|
155
|
discordia@2
|
156 // Get the light position in eye space
|
discordia@2
|
157 M3DVector4f vLightTransformed;
|
discordia@2
|
158 M3DMatrix44f mCamera;
|
discordia@2
|
159 modelViewMatrix.GetMatrix(mCamera);
|
discordia@2
|
160 m3dTransformVector4(vLightTransformed, vLightPos, mCamera);
|
discordia@2
|
161
|
discordia@2
|
162
|
discordia@2
|
163 ////////////////////////////////
|
discordia@2
|
164 // Begin Sun
|
discordia@2
|
165
|
discordia@2
|
166 float SunRot = rotTimer.GetElapsedSeconds() * SunRotSpeed;
|
discordia@2
|
167
|
discordia@2
|
168 modelViewMatrix.PushMatrix();
|
discordia@2
|
169
|
discordia@2
|
170 modelViewMatrix.Translatev(vSunPos);
|
discordia@2
|
171 // North is up!
|
discordia@2
|
172 modelViewMatrix.Rotate(-90.0f, 1.0f, 0.0f, 0.0f);
|
discordia@2
|
173 // Rotate on axis
|
discordia@2
|
174 modelViewMatrix.Rotate(SunRot, 0.0f, 0.0f, 1.0f);
|
discordia@2
|
175
|
discordia@2
|
176 glBindTexture(GL_TEXTURE_2D, uiTextures[TEX_SUN]);
|
discordia@2
|
177 if (polymode == GL_FILL)
|
discordia@2
|
178 {
|
discordia@2
|
179 shaderManager.UseStockShader(GLT_SHADER_TEXTURE_REPLACE,
|
discordia@2
|
180 transformPipeline.GetModelViewProjectionMatrix(),
|
discordia@2
|
181 0);
|
discordia@2
|
182 }
|
discordia@2
|
183 else
|
discordia@2
|
184 {
|
discordia@2
|
185 shaderManager.UseStockShader(GLT_SHADER_FLAT,
|
discordia@2
|
186 transformPipeline.GetModelViewProjectionMatrix(),
|
discordia@2
|
187 vWhite);
|
discordia@2
|
188 }
|
discordia@2
|
189 sunBatch.Draw();
|
discordia@2
|
190 modelViewMatrix.PopMatrix();
|
discordia@2
|
191 // End Sun
|
discordia@2
|
192 /////////////////////////////////
|
discordia@2
|
193
|
discordia@2
|
194
|
discordia@2
|
195 ////////////////////////////////
|
discordia@2
|
196 // Jupiter
|
discordia@2
|
197 float JupiterRot = rotTimer.GetElapsedSeconds() * JupiterRotSpeed;
|
discordia@2
|
198
|
discordia@2
|
199 modelViewMatrix.PushMatrix();
|
discordia@2
|
200 modelViewMatrix.Translatev(vJupiterPos);
|
discordia@2
|
201 // North is up!
|
discordia@2
|
202 modelViewMatrix.Rotate(-90.0f - JupiterAxialTilt, 1.0f, 0.0f, 0.0f);
|
discordia@2
|
203 // Rotate on axis
|
discordia@2
|
204 modelViewMatrix.Rotate(JupiterRot, 0.0f, 0.0f, 1.0f);
|
discordia@2
|
205
|
discordia@2
|
206 glBindTexture(GL_TEXTURE_2D, uiTextures[TEX_JUPITER]);
|
discordia@2
|
207 if (polymode == GL_FILL)
|
discordia@2
|
208 {
|
discordia@2
|
209 // shaderManager.UseStockShader(GLT_SHADER_TEXTURE_REPLACE,
|
discordia@2
|
210 // transformPipeline.GetModelViewProjectionMatrix(),
|
discordia@2
|
211 // 0);
|
discordia@2
|
212 shaderManager.UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF,
|
discordia@2
|
213 modelViewMatrix.GetMatrix(),
|
discordia@2
|
214 transformPipeline.GetProjectionMatrix(),
|
discordia@2
|
215 vLightTransformed,
|
discordia@2
|
216 vWhite,
|
discordia@2
|
217 0);
|
discordia@2
|
218 }
|
discordia@2
|
219 else
|
discordia@2
|
220 {
|
discordia@2
|
221 shaderManager.UseStockShader(GLT_SHADER_FLAT,
|
discordia@2
|
222 transformPipeline.GetModelViewProjectionMatrix(),
|
discordia@2
|
223 vWhite);
|
discordia@2
|
224
|
discordia@2
|
225 }
|
discordia@2
|
226 jupiterBatch.Draw();
|
discordia@2
|
227 modelViewMatrix.PopMatrix();
|
discordia@2
|
228 // End Jupiter
|
discordia@2
|
229 ////////////////////////////////
|
discordia@2
|
230
|
discordia@2
|
231
|
discordia@2
|
232
|
discordia@2
|
233
|
discordia@2
|
234 /////////////////////////////////
|
discordia@2
|
235 // Begin Earth/Moon
|
discordia@2
|
236
|
discordia@2
|
237 // Begin Earth
|
discordia@2
|
238 float EarthRot = rotTimer.GetElapsedSeconds() * EarthRotSpeed;
|
discordia@2
|
239
|
discordia@2
|
240 modelViewMatrix.PushMatrix();
|
discordia@2
|
241 modelViewMatrix.Translatev(vEarthPos);
|
discordia@2
|
242 modelViewMatrix.PushMatrix(); // Save unrotated matrix for when we do the Moon
|
discordia@2
|
243
|
discordia@2
|
244 // NOrth is up!
|
discordia@2
|
245 modelViewMatrix.Rotate(-90.0f - EarthAxialTilt, 1.0f, 0.0f, 0.0f);
|
discordia@2
|
246 // Rotate on the axis
|
discordia@2
|
247 modelViewMatrix.Rotate(EarthRot, 0.0f, 0.0f, 1.0f);
|
discordia@2
|
248
|
discordia@2
|
249 if (polymode == GL_FILL)
|
discordia@2
|
250 {
|
discordia@2
|
251 glBindTexture(GL_TEXTURE_2D, uiTextures[TEX_EARTH]);
|
discordia@2
|
252 shaderManager.UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF,
|
discordia@2
|
253 modelViewMatrix.GetMatrix(),
|
discordia@2
|
254 transformPipeline.GetProjectionMatrix(),
|
discordia@2
|
255 vLightTransformed,
|
discordia@2
|
256 vWhite,
|
discordia@2
|
257 0);
|
discordia@2
|
258 }
|
discordia@2
|
259 else
|
discordia@2
|
260 {
|
discordia@2
|
261 shaderManager.UseStockShader(GLT_SHADER_FLAT,
|
discordia@2
|
262 transformPipeline.GetModelViewProjectionMatrix(),
|
discordia@2
|
263 vWhite);
|
discordia@2
|
264
|
discordia@2
|
265 }
|
discordia@2
|
266 earthBatch.Draw();
|
discordia@2
|
267 modelViewMatrix.PopMatrix();
|
discordia@2
|
268
|
discordia@2
|
269 // Begin Moon
|
discordia@2
|
270
|
discordia@2
|
271
|
discordia@2
|
272 // orbit the Earth
|
discordia@2
|
273 modelViewMatrix.Rotate(MoonOrbitTilt, 0.0f, 0.0f, 1.0f);
|
discordia@2
|
274 // NOrth is up!
|
discordia@2
|
275 modelViewMatrix.Rotate(-90.0f - MoonAxialTilt, 0.0f, 1.0f, 0.0f);
|
discordia@2
|
276
|
discordia@2
|
277 float MoonRot = rotTimer.GetElapsedSeconds() * MoonOrbitSpeed * 10;
|
discordia@2
|
278 modelViewMatrix.Rotate(MoonRot, 0.0f, 1.0f, 0.0f);
|
discordia@2
|
279
|
discordia@2
|
280 modelViewMatrix.Translate(0.5f, 0.0f, 0.0f);
|
discordia@2
|
281
|
discordia@2
|
282
|
discordia@2
|
283 glBindTexture(GL_TEXTURE_2D, uiTextures[TEX_MOON]);
|
discordia@2
|
284 if (polymode == GL_FILL)
|
discordia@2
|
285 {
|
discordia@2
|
286 shaderManager.UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF,
|
discordia@2
|
287 modelViewMatrix.GetMatrix(),
|
discordia@2
|
288 transformPipeline.GetProjectionMatrix(),
|
discordia@2
|
289 vLightTransformed,
|
discordia@2
|
290 vWhite,
|
discordia@2
|
291 0);
|
discordia@2
|
292 }
|
discordia@2
|
293 else
|
discordia@2
|
294 {
|
discordia@2
|
295 shaderManager.UseStockShader(GLT_SHADER_FLAT,
|
discordia@2
|
296 transformPipeline.GetModelViewProjectionMatrix(),
|
discordia@2
|
297 vWhite);
|
discordia@2
|
298 }
|
discordia@2
|
299 moonBatch.Draw();
|
discordia@2
|
300 modelViewMatrix.PopMatrix();
|
discordia@2
|
301
|
discordia@2
|
302
|
discordia@2
|
303 modelViewMatrix.PopMatrix();
|
discordia@2
|
304 // End Earth/Moon
|
discordia@2
|
305 ////////////////////////////////
|
discordia@2
|
306
|
discordia@2
|
307 }
|
discordia@2
|
308
|
discordia@2
|
309 ////////////////////////////////////////////////////////////////////////////////
|
discordia@2
|
310 void RenderScene(void)
|
discordia@2
|
311 {
|
discordia@2
|
312 static CStopWatch rotTimer;
|
discordia@2
|
313 float yRot = - rotTimer.GetElapsedSeconds() * 60.0f;
|
discordia@2
|
314
|
discordia@2
|
315 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
discordia@2
|
316
|
discordia@2
|
317 // Begin Render
|
discordia@2
|
318 modelViewMatrix.PushMatrix();
|
discordia@2
|
319
|
discordia@2
|
320 // Begin Camera position
|
discordia@2
|
321 static M3DMatrix44f mCamera;
|
discordia@2
|
322 cameraFrame.GetCameraMatrix(mCamera);
|
discordia@2
|
323 modelViewMatrix.MultMatrix(mCamera);
|
discordia@2
|
324 // End Camera position
|
discordia@2
|
325
|
discordia@2
|
326 DrawSolarSystem(yRot);
|
discordia@2
|
327
|
discordia@2
|
328 // End Render
|
discordia@2
|
329 modelViewMatrix.PopMatrix();
|
discordia@2
|
330
|
discordia@2
|
331 glutSwapBuffers();
|
discordia@2
|
332 glutPostRedisplay();
|
discordia@2
|
333 }
|
discordia@2
|
334
|
discordia@2
|
335 ////////////////////////////////////////////////////////////////////////////////
|
discordia@2
|
336 void SetupRC()
|
discordia@2
|
337 {
|
discordia@2
|
338 shaderManager.InitializeStockShaders();
|
discordia@2
|
339 glEnable(GL_DEPTH_TEST);
|
discordia@2
|
340 glEnable(GL_CULL_FACE);
|
discordia@2
|
341 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
discordia@2
|
342
|
discordia@2
|
343 gltMakeSphere(jupiterBatch, 0.5f, 128, 128 );
|
discordia@2
|
344 gltMakeSphere(earthBatch, 0.2f, 26, 26);
|
discordia@2
|
345 gltMakeSphere(moonBatch, 0.1f, 26, 26);
|
discordia@2
|
346 gltMakeSphere(sunBatch, 1.0f, 26, 26);
|
discordia@2
|
347
|
discordia@2
|
348 glGenTextures(NUM_TEXTURES, uiTextures);
|
discordia@2
|
349
|
discordia@2
|
350 glBindTexture(GL_TEXTURE_2D, uiTextures[TEX_EARTH]);
|
discordia@2
|
351 LoadTGATexture("../textures/earth.tga", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_CLAMP_TO_EDGE);
|
discordia@2
|
352
|
discordia@2
|
353 glBindTexture(GL_TEXTURE_2D, uiTextures[TEX_MOON]);
|
discordia@2
|
354 LoadTGATexture("../textures/moon.tga", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_CLAMP_TO_EDGE);
|
discordia@2
|
355
|
discordia@2
|
356 glBindTexture(GL_TEXTURE_2D, uiTextures[TEX_JUPITER]);
|
discordia@2
|
357 LoadTGATexture("../textures/jupiter.tga", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_CLAMP_TO_EDGE);
|
discordia@2
|
358
|
discordia@2
|
359 glBindTexture(GL_TEXTURE_2D, uiTextures[TEX_SUN]);
|
discordia@2
|
360 LoadTGATexture("../textures/sun.tga", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_CLAMP_TO_EDGE);
|
discordia@2
|
361
|
discordia@2
|
362 static M3DMatrix44f mCamera;
|
discordia@2
|
363 cameraFrame.GetCameraMatrix(mCamera);
|
discordia@2
|
364 cameraFrame.MoveForward(-10.0);
|
discordia@2
|
365 // cameraFrame.RotateWorld(15.0, 0.0f, 1.0f, 0.0f);
|
discordia@2
|
366 }
|
discordia@2
|
367
|
discordia@2
|
368 ////////////////////////////////////////////////////////////////////////////////
|
discordia@2
|
369 void ShutDownRC(void)
|
discordia@2
|
370 {
|
discordia@2
|
371 glDeleteTextures(NUM_TEXTURES, uiTextures);
|
discordia@2
|
372 }
|
discordia@2
|
373
|
discordia@2
|
374 ////////////////////////////////////////////////////////////////////////////////
|
discordia@2
|
375 void ChangeSize(int nWidth, int nHeight)
|
discordia@2
|
376 {
|
discordia@2
|
377 if (nHeight == 0)
|
discordia@2
|
378 {
|
discordia@2
|
379 nHeight = 1;
|
discordia@2
|
380 }
|
discordia@2
|
381 glViewport(0,0,nWidth, nHeight);
|
discordia@2
|
382 viewFrustum.SetPerspective(35.0f, float(nWidth)/float(nHeight), 1.0f, 100.0f);
|
discordia@2
|
383 projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());
|
discordia@2
|
384 transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix);
|
discordia@2
|
385 }
|
discordia@2
|
386
|
discordia@2
|
387 ////////////////////////////////////////////////////////////////////////////////
|
discordia@2
|
388 void SpecialKeys(int key, int x, int y)
|
discordia@2
|
389 {
|
discordia@2
|
390 }
|
discordia@2
|
391
|
discordia@2
|
392 ////////////////////////////////////////////////////////////////////////////////
|
discordia@2
|
393 void KeyboardFunc(unsigned char key, int x, int y)
|
discordia@2
|
394 {
|
discordia@2
|
395 static int changed;
|
discordia@2
|
396 static float linear = 0.1f;
|
discordia@2
|
397
|
discordia@2
|
398 changed = 0;
|
discordia@2
|
399
|
discordia@2
|
400 if ('w' == key)
|
discordia@2
|
401 {
|
discordia@2
|
402 cameraFrame.MoveForward(linear);
|
discordia@2
|
403 changed = 1;
|
discordia@2
|
404 }
|
discordia@2
|
405 else if ('W' == key)
|
discordia@2
|
406 {
|
discordia@2
|
407 cameraFrame.MoveForward(10*linear);
|
discordia@2
|
408 changed = 1;
|
discordia@2
|
409 }
|
discordia@2
|
410 else if ('s' == key)
|
discordia@2
|
411 {
|
discordia@2
|
412 cameraFrame.MoveForward(-linear);
|
discordia@2
|
413 changed = 1;
|
discordia@2
|
414 }
|
discordia@2
|
415 else if ('S' == key)
|
discordia@2
|
416 {
|
discordia@2
|
417 cameraFrame.MoveForward(-10*linear);
|
discordia@2
|
418 changed = 1;
|
discordia@2
|
419 }
|
discordia@2
|
420 else if ('a' == key)
|
discordia@2
|
421 {
|
discordia@2
|
422 cameraFrame.MoveRight(linear);
|
discordia@2
|
423 changed = 1;
|
discordia@2
|
424 }
|
discordia@2
|
425 else if ('A' == key)
|
discordia@2
|
426 {
|
discordia@2
|
427 cameraFrame.MoveRight(10*linear);
|
discordia@2
|
428 changed = 1;
|
discordia@2
|
429 }
|
discordia@2
|
430 else if ('d' == key)
|
discordia@2
|
431 {
|
discordia@2
|
432 cameraFrame.MoveRight(-linear);
|
discordia@2
|
433 changed = 1;
|
discordia@2
|
434 }
|
discordia@2
|
435 else if ('D' == key)
|
discordia@2
|
436 {
|
discordia@2
|
437 cameraFrame.MoveRight(-10*linear);
|
discordia@2
|
438 changed = 1;
|
discordia@2
|
439 }
|
discordia@2
|
440
|
discordia@2
|
441 else if ('q' == key)
|
discordia@2
|
442 {
|
discordia@2
|
443 exit(0);
|
discordia@2
|
444 }
|
discordia@2
|
445 else if ('f' == key)
|
discordia@2
|
446 {
|
discordia@2
|
447 if (fullscreen)
|
discordia@2
|
448 {
|
discordia@2
|
449 glutReshapeWindow(width, height);
|
discordia@2
|
450 fullscreen = 0;
|
discordia@2
|
451 }
|
discordia@2
|
452 else
|
discordia@2
|
453 {
|
discordia@2
|
454 width = glutGet(GLUT_WINDOW_WIDTH);
|
discordia@2
|
455 height = glutGet(GLUT_WINDOW_HEIGHT);
|
discordia@2
|
456 glutFullScreen();
|
discordia@2
|
457 fullscreen = 1;
|
discordia@2
|
458 }
|
discordia@2
|
459 }
|
discordia@2
|
460 else if ('o' == key)
|
discordia@2
|
461 {
|
discordia@2
|
462 // 'o' for 'outline' - toggle wireframe rendering
|
discordia@2
|
463 polymode = (polymode == GL_FILL) ? GL_LINE : GL_FILL;
|
discordia@2
|
464 glPolygonMode(GL_FRONT_AND_BACK, polymode);
|
discordia@2
|
465 }
|
discordia@2
|
466 else if ('p' == key)
|
discordia@2
|
467 {
|
discordia@2
|
468 // 'p' for 'print screen' - save a screenshot
|
discordia@2
|
469 char filename[20];
|
discordia@2
|
470 get_next_file_name(filename);
|
discordia@2
|
471
|
discordia@2
|
472 gltGrabScreenTGA(filename);
|
discordia@2
|
473 }
|
discordia@2
|
474
|
discordia@2
|
475 if (changed)
|
discordia@2
|
476 {
|
discordia@2
|
477 glutPostRedisplay();
|
discordia@2
|
478 }
|
discordia@2
|
479 }
|
discordia@2
|
480
|
discordia@2
|
481 ////////////////////////////////////////////////////////////////////////////////
|
discordia@2
|
482 void MouseMotionFunc (int x, int y)
|
discordia@2
|
483 {
|
discordia@2
|
484 static float angular = (float) m3dDegToRad(0.5f);
|
discordia@2
|
485 static int xx = -1;
|
discordia@2
|
486 static int yy = -1;
|
discordia@2
|
487
|
discordia@2
|
488 if (-1 == xx)
|
discordia@2
|
489 {
|
discordia@2
|
490 xx = x;
|
discordia@2
|
491 yy = y;
|
discordia@2
|
492 }
|
discordia@2
|
493
|
discordia@2
|
494 if ((0 == x) || (x < xx))
|
discordia@2
|
495 {
|
discordia@2
|
496 cameraFrame.RotateWorld(angular, 0.0f, 1.0f, 0.0f);
|
discordia@2
|
497 glutPostRedisplay();
|
discordia@2
|
498 }
|
discordia@2
|
499 else if ((x == glutGet(GLUT_WINDOW_WIDTH) -1) || (x > xx))
|
discordia@2
|
500 {
|
discordia@2
|
501 cameraFrame.RotateWorld(-angular, 0.0f, 1.0f, 0.0f);
|
discordia@2
|
502 glutPostRedisplay();
|
discordia@2
|
503 }
|
discordia@2
|
504 // Hmm. Need to transform normal vector, don't I?
|
discordia@2
|
505 // if ((0 == y) || (y < yy))
|
discordia@2
|
506 // {
|
discordia@2
|
507 // cameraFrame.RotateWorld(angular, 1.0f, 0.0f, 0.0f);
|
discordia@2
|
508 // }
|
discordia@2
|
509 // else if ((y == glutGet(GLUT_WINDOW_HEIGHT) -1) || (y > yy))
|
discordia@2
|
510 // {
|
discordia@2
|
511 // cameraFrame.RotateWorld(-angular, 1.0f, 0.0f, 0.0f);
|
discordia@2
|
512 // }
|
discordia@2
|
513
|
discordia@2
|
514 xx = x;
|
discordia@2
|
515 yy = y;
|
discordia@2
|
516 }
|
discordia@2
|
517
|
discordia@2
|
518 ////////////////////////////////////////////////////////////////////////////////
|
discordia@2
|
519 int main (int argc, char * argv[])
|
discordia@2
|
520 {
|
discordia@2
|
521 gltSetWorkingDirectory(argv[0]);
|
discordia@2
|
522 glutInit(&argc, argv);
|
discordia@2
|
523 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
|
discordia@2
|
524 glutInitWindowSize(800, 600);
|
discordia@2
|
525 glutCreateWindow("OpenGL SphereWorld");
|
discordia@2
|
526
|
discordia@2
|
527 glutReshapeFunc(ChangeSize);
|
discordia@2
|
528 glutDisplayFunc(RenderScene);
|
discordia@2
|
529 glutSpecialFunc(SpecialKeys);
|
discordia@2
|
530 glutKeyboardFunc(KeyboardFunc);
|
discordia@2
|
531 glutMotionFunc(MouseMotionFunc);
|
discordia@2
|
532 glutPassiveMotionFunc(MouseMotionFunc);
|
discordia@2
|
533 glutSetCursor(GLUT_CURSOR_NONE);
|
discordia@2
|
534
|
discordia@2
|
535 GLenum err = glewInit();
|
discordia@2
|
536 if (GLEW_OK != err)
|
discordia@2
|
537 {
|
discordia@2
|
538 fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
|
discordia@2
|
539 return 1;
|
discordia@2
|
540 }
|
discordia@2
|
541
|
discordia@2
|
542 // This enabled vertical sync on Linux
|
discordia@2
|
543 // For full generality I should use Glew and check what OS I'm on.
|
discordia@2
|
544 // Note that the ATI Catalyst driver exports the WGL_EXT_swap_control
|
discordia@2
|
545 // extension name instead of SGI_swap_control as it should.
|
discordia@2
|
546 // but nonetheless the actual function provided is glXSwapIntervalSGI
|
discordia@2
|
547
|
discordia@2
|
548 PFNGLXSWAPINTERVALSGIPROC SwapInterval;
|
discordia@2
|
549 SwapInterval = (PFNGLXSWAPINTERVALSGIPROC)glXGetProcAddress((const GLubyte*)"glXSwapIntervalSGI");
|
discordia@2
|
550
|
discordia@2
|
551 if (SwapInterval)
|
discordia@2
|
552 SwapInterval(1);
|
discordia@2
|
553
|
discordia@2
|
554 SetupRC();
|
discordia@2
|
555 glutMainLoop();
|
discordia@2
|
556 ShutDownRC();
|
discordia@2
|
557
|
discordia@2
|
558 return 0;
|
discordia@2
|
559 }
|
discordia@2
|
560
|
discordia@2
|
561
|
discordia@2
|
562
|
discordia@2
|
563
|
discordia@2
|
564
|