annotate src/solar-system.cpp @ 3:4f8b47ac2715

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