| 1 | /*  | 
|---|
| 2 |    orxonox - the future of 3D-vertical-scrollers | 
|---|
| 3 |  | 
|---|
| 4 |    Copyright (C) 2004 orx | 
|---|
| 5 |  | 
|---|
| 6 |    This program 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, or (at your option) | 
|---|
| 9 |    any later version. | 
|---|
| 10 |  | 
|---|
| 11 |    ### File Specific: | 
|---|
| 12 |    main-programmer: Benjamin Grauer | 
|---|
| 13 |    co-programmer: ... | 
|---|
| 14 | */ | 
|---|
| 15 |  | 
|---|
| 16 | #include "framework.h" | 
|---|
| 17 |  | 
|---|
| 18 | #include "../vector.h" | 
|---|
| 19 |  | 
|---|
| 20 | int verbose; | 
|---|
| 21 | void DrawGLScene() | 
|---|
| 22 | { | 
|---|
| 23 |   currFrame = SDL_GetTicks(); | 
|---|
| 24 |   dt = currFrame - lastFrame;  | 
|---|
| 25 |   if (dt == 0) | 
|---|
| 26 |     dist += (zoomTo-dist)/500; | 
|---|
| 27 |   else  | 
|---|
| 28 |     dist += (zoomTo-dist)/500 *(float)dt; | 
|---|
| 29 |  | 
|---|
| 30 |   rotatorP += rotatorV *(float)dt; | 
|---|
| 31 |    | 
|---|
| 32 |  | 
|---|
| 33 |   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | 
|---|
| 34 |   glLoadIdentity(); // Reset the view | 
|---|
| 35 |    | 
|---|
| 36 |   glMatrixMode(GL_PROJECTION); | 
|---|
| 37 |   glLoadIdentity();      | 
|---|
| 38 |   gluPerspective(45.0f,500/375,0.1f,dist * 5.0f); | 
|---|
| 39 |     gluLookAt (0, dist , dist, 0,0,0, up.x,up.y,up.z); | 
|---|
| 40 |  | 
|---|
| 41 |   glMatrixMode(GL_MODELVIEW); | 
|---|
| 42 |   glPushMatrix(); | 
|---|
| 43 |   //  glRotatef (180, dir.x, dir.y, dir.z); | 
|---|
| 44 |   glMultMatrixf (*matQ); | 
|---|
| 45 |   if (obj) | 
|---|
| 46 |     obj->draw(); | 
|---|
| 47 |  | 
|---|
| 48 |   glPopMatrix(); | 
|---|
| 49 |  | 
|---|
| 50 |   SDL_GL_SwapBuffers(); // Swap the buffers | 
|---|
| 51 |   lastFrame = currFrame; | 
|---|
| 52 | } | 
|---|
| 53 |  | 
|---|
| 54 |  | 
|---|
| 55 | int main(int argc, char *argv[]) | 
|---|
| 56 | { | 
|---|
| 57 |   verbose = 3; | 
|---|
| 58 |  | 
|---|
| 59 |   Uint8* keys; // This variable will be used in the keyboard routine | 
|---|
| 60 |   int done=FALSE; // We aren't done yet, are we? | 
|---|
| 61 |  | 
|---|
| 62 |   // Create a new OpenGL window with the title "Cone3D Basecode" at | 
|---|
| 63 |   // 640x480x32, fullscreen and check for errors along the way | 
|---|
| 64 |   if(wHandler.CreateGLWindow("Whandler Basecode", 800, 600, 32, FALSE) == FALSE) | 
|---|
| 65 |   { | 
|---|
| 66 |     // If an error is found, display a message, kill the GL and SDL screens (if they were created) and exit | 
|---|
| 67 |     PRINTF(1)("Could not initalize OpenGL :(\n\n"); | 
|---|
| 68 |     wHandler.KillGLWindow(); | 
|---|
| 69 |     return 0; | 
|---|
| 70 |   } | 
|---|
| 71 |    | 
|---|
| 72 |   PRINTF(2)("screensize: %i, %i\n", wHandler.screen->w, wHandler.screen->h); | 
|---|
| 73 |   if (argc>=3) | 
|---|
| 74 |     obj = new OBJModel (argv[1], atof(argv[2])); | 
|---|
| 75 |   else if (argc>=2) | 
|---|
| 76 |     obj = new OBJModel(argv[1]); | 
|---|
| 77 |   else  | 
|---|
| 78 |     { | 
|---|
| 79 |       // This is an example, of how it is possible, to create a new Model, and adding some vertex-information. | 
|---|
| 80 |       // This also packs everything into a DisplayList, and can be handled exactly as any other model. | 
|---|
| 81 |       // This is an example of a cube with Texture-Coordinates, but without explicite Vertex-Normals. (they are soft-created). | 
|---|
| 82 |       /* | 
|---|
| 83 |       obj = (OBJModel*) new Model(); | 
|---|
| 84 |       obj->setName("CUBE"); | 
|---|
| 85 |       obj->addVertex (-0.5, -0.5, 0.5); | 
|---|
| 86 |       obj->addVertex (0.5, -0.5, 0.5); | 
|---|
| 87 |       obj->addVertex (-0.5, 0.5, 0.5); | 
|---|
| 88 |       obj->addVertex (0.5, 0.5, 0.5); | 
|---|
| 89 |       obj->addVertex (-0.5, 0.5, -0.5); | 
|---|
| 90 |       obj->addVertex (0.5, 0.5, -0.5); | 
|---|
| 91 |       obj->addVertex (-0.5, -0.5, -0.5); | 
|---|
| 92 |       obj->addVertex (0.5, -0.5, -0.5); | 
|---|
| 93 |        | 
|---|
| 94 |       obj->addVertexTexture (0.0, 0.0); | 
|---|
| 95 |       obj->addVertexTexture (1.0, 0.0); | 
|---|
| 96 |       obj->addVertexTexture (0.0, 1.0); | 
|---|
| 97 |       obj->addVertexTexture (1.0, 1.0); | 
|---|
| 98 |       obj->addVertexTexture (0.0, 2.0); | 
|---|
| 99 |       obj->addVertexTexture (1.0, 2.0); | 
|---|
| 100 |       obj->addVertexTexture (0.0, 3.0); | 
|---|
| 101 |       obj->addVertexTexture (1.0, 3.0); | 
|---|
| 102 |       obj->addVertexTexture (0.0, 4.0); | 
|---|
| 103 |       obj->addVertexTexture (1.0, 4.0); | 
|---|
| 104 |       obj->addVertexTexture (2.0, 0.0); | 
|---|
| 105 |       obj->addVertexTexture (2.0, 1.0); | 
|---|
| 106 |       obj->addVertexTexture (-1.0, 0.0); | 
|---|
| 107 |       obj->addVertexTexture (-1.0, 1.0); | 
|---|
| 108 |  | 
|---|
| 109 |       obj->addFace ("1 2 4 3"); | 
|---|
| 110 |       obj->addFace ("3 4 6 5"); | 
|---|
| 111 |       obj->addFace ("5 6 8 7"); | 
|---|
| 112 |       obj->addFace ("7 8 2 1"); | 
|---|
| 113 |       obj->addFace ("2 8 6 4"); | 
|---|
| 114 |       obj->addFace ("7 1 3 5"); | 
|---|
| 115 |       obj->finalize(); | 
|---|
| 116 |       */ | 
|---|
| 117 |       obj = (OBJModel*) new Model(CYLINDER); | 
|---|
| 118 |     } | 
|---|
| 119 |   M = Vector(wHandler.screen->w/2, wHandler.screen->h/2, 0);  | 
|---|
| 120 |   rotAxis = Vector (0.0,1.0,0.0); | 
|---|
| 121 |   rotAngle = 0; | 
|---|
| 122 |  | 
|---|
| 123 |   matQ[0][0] = matQ[1][1] = matQ[2][2] = matQ[3][3] = 1; | 
|---|
| 124 |   rotQ = Quaternion (rotAngle, rotAxis); | 
|---|
| 125 |   rotQlast = rotQ; | 
|---|
| 126 |   dir = Vector (0.0, 0.0, 1.0); | 
|---|
| 127 |   up = Vector (0.0, 1.0, 0.0); | 
|---|
| 128 |  | 
|---|
| 129 |   glEnable(GL_LIGHTING); | 
|---|
| 130 |   glEnable(GL_DEPTH_TEST); | 
|---|
| 131 |  | 
|---|
| 132 |   GLfloat whiteLight[] = {1.0, 1.0, 1.0,1.0}; | 
|---|
| 133 |   GLfloat light0Position[] = {10.0, 10.0, 10.0, 0.0}; | 
|---|
| 134 |   GLfloat light1Position[] = {-10.0, -7.0, -6.0, 0.0}; | 
|---|
| 135 |   GLfloat lmodelAmbient[] = {.1, .1, .1, 1.0}; | 
|---|
| 136 |  | 
|---|
| 137 |   glEnable(GL_LIGHT0); | 
|---|
| 138 |   glLightfv(GL_LIGHT0, GL_POSITION, light0Position); | 
|---|
| 139 |   glLightfv(GL_LIGHT0, GL_DIFFUSE, whiteLight); | 
|---|
| 140 |   glLightfv(GL_LIGHT0, GL_SPECULAR, whiteLight); | 
|---|
| 141 |    | 
|---|
| 142 |   glEnable(GL_LIGHT1); | 
|---|
| 143 |   glLightfv(GL_LIGHT1, GL_POSITION, light1Position); | 
|---|
| 144 |   glLightfv(GL_LIGHT1, GL_DIFFUSE, whiteLight); | 
|---|
| 145 |   glLightfv(GL_LIGHT1, GL_SPECULAR, whiteLight); | 
|---|
| 146 |    | 
|---|
| 147 |  | 
|---|
| 148 |   glEnable(GL_TEXTURE_2D); | 
|---|
| 149 |   rotatorP = .0; | 
|---|
| 150 |   rotatorV = .0; | 
|---|
| 151 |   dist = 5.0; | 
|---|
| 152 |   zoomTo = dist; | 
|---|
| 153 |   // Build the font from a TGA image font.tga in the data directory | 
|---|
| 154 |   // Hide the mouse cursor | 
|---|
| 155 |     SDL_ShowCursor(2); | 
|---|
| 156 |     mouse1Down = false; | 
|---|
| 157 |  | 
|---|
| 158 |   // This is the main loop for the entire program and it will run until done==TRUE | 
|---|
| 159 |   while(!done) | 
|---|
| 160 |   { | 
|---|
| 161 |     // Draw the scene | 
|---|
| 162 |     DrawGLScene(); | 
|---|
| 163 |     // And poll for events | 
|---|
| 164 |     SDL_Event event; | 
|---|
| 165 |     while ( SDL_PollEvent(&event) ) { | 
|---|
| 166 |       switch (event.type) { | 
|---|
| 167 |       case SDL_MOUSEMOTION: | 
|---|
| 168 |         PRINTF(3)("Mouse motion about %d,%d Pixels to (%d,%d).\n",  | 
|---|
| 169 |                   event.motion.xrel, event.motion.yrel, | 
|---|
| 170 |                   event.motion.x, event.motion.y); | 
|---|
| 171 |         // TRACKBALL | 
|---|
| 172 |         if (mouse1Down) | 
|---|
| 173 |           { | 
|---|
| 174 |             int mX = event.button.x; | 
|---|
| 175 |             int mY = event.button.y; | 
|---|
| 176 |             int wH = wHandler.screen->h; | 
|---|
| 177 |             int wW = wHandler.screen->w; | 
|---|
| 178 |             Vector tmpV (mX, mY, sqrt ( (float) abs(wH * wH/4 - (wW/2-mX) * (wW/2-mX) - (wH/2-mY) * (wH/2-mY)) )); | 
|---|
| 179 |             //      PRINTF(0)("tmpV: %f, %f, %f\n", tmpV.x, tmpV.y, tmpV.z); | 
|---|
| 180 |             p2 = tmpV-M; | 
|---|
| 181 |             p2.y = -p2.y; | 
|---|
| 182 |             rotAxis = p1.cross(p2); | 
|---|
| 183 |             //  PRINTF(0)("rotAxis: %f, %f, %f\n", rotAxis.x, rotAxis.y, rotAxis.z); | 
|---|
| 184 |  | 
|---|
| 185 |             // in case that there is no rotation-axis defined | 
|---|
| 186 |             if (rotAxis.x != 0 || rotAxis.y != 0 || rotAxis.z != 0) | 
|---|
| 187 |               { | 
|---|
| 188 |                 rotAxis.normalize(); | 
|---|
| 189 |                 //              PRINTF(0)("rotAxis: %f, %f, %f\n", rotAxis.x, rotAxis.y, rotAxis.z, rotAngle); | 
|---|
| 190 |                                  | 
|---|
| 191 |                 rotAngle = angleRad (p1, p2); | 
|---|
| 192 |                 rotQ = Quaternion (rotAngle, rotAxis); | 
|---|
| 193 |                 rotQ = rotQ * rotQlast; | 
|---|
| 194 |                 rotQ.matrix (matQ); | 
|---|
| 195 |                 //      dir = rotQ.apply(dir); | 
|---|
| 196 |                 //      dir.normalize(); | 
|---|
| 197 |                 //      PRINTF(0)("rotAxis: %f, %f, %f, %f\n", dir.x, dir.y, dir.z, rotAngle); | 
|---|
| 198 |               } | 
|---|
| 199 |             rotQlast = rotQ; | 
|---|
| 200 |             p1 = p2; | 
|---|
| 201 |  | 
|---|
| 202 |           } | 
|---|
| 203 |         break; | 
|---|
| 204 |       case SDL_MOUSEBUTTONDOWN: | 
|---|
| 205 |         if (event.button.button == 4) | 
|---|
| 206 |           { | 
|---|
| 207 |             PRINTF(0)("MouseWheel up\n"); | 
|---|
| 208 |             zoomTo *= .5; | 
|---|
| 209 |           } | 
|---|
| 210 |         else if (event.button.button == 5) | 
|---|
| 211 |           { | 
|---|
| 212 |             PRINTF(2)("MouseWheel down\n"); | 
|---|
| 213 |             zoomTo *= 2.0; | 
|---|
| 214 |           } | 
|---|
| 215 |         else if (event.button.button == 1) | 
|---|
| 216 |           { | 
|---|
| 217 |             mouse1Down = true; | 
|---|
| 218 |             int mX = event.button.x; | 
|---|
| 219 |             int mY = event.button.y; | 
|---|
| 220 |             int wH = wHandler.screen->h; | 
|---|
| 221 |             int wW = wHandler.screen->w; | 
|---|
| 222 |             Vector tmpV (mX, mY, sqrt ( (float) abs(wH * wH/4 - (wW/2-mX) * (wW/2-mX) - (wH/2-mY) * (wH/2-mY)) )); | 
|---|
| 223 |             p1 = tmpV-M; | 
|---|
| 224 |             p1.y = -p1.y; | 
|---|
| 225 |  | 
|---|
| 226 |           } | 
|---|
| 227 |         else | 
|---|
| 228 |           { | 
|---|
| 229 |             PRINTF(0)("MouseButton %d pressed at (%d,%d).\n", | 
|---|
| 230 |                    event.button.button, event.button.x, event.button.y); | 
|---|
| 231 |             rotatorV = ( (float)wHandler.screen->w/2 -event.button.x) / (float)wHandler.screen->w / 100.0; | 
|---|
| 232 |           } | 
|---|
| 233 |              | 
|---|
| 234 |         break; | 
|---|
| 235 |       case SDL_MOUSEBUTTONUP: | 
|---|
| 236 |         if (event.button.button == 4); | 
|---|
| 237 |         else if (event.button.button == 5); | 
|---|
| 238 |         else if (event.button.button == 1) | 
|---|
| 239 |           mouse1Down =false; | 
|---|
| 240 |         else  | 
|---|
| 241 |             { | 
|---|
| 242 |               PRINTF(2)("MouseButton %d released at (%d,%d).\n", | 
|---|
| 243 |                         event.button.button, event.button.x, event.button.y); | 
|---|
| 244 |             } | 
|---|
| 245 |         break; | 
|---|
| 246 |  | 
|---|
| 247 |  | 
|---|
| 248 |       case SDL_KEYDOWN: | 
|---|
| 249 |         switch (event.key.keysym.sym) | 
|---|
| 250 |           { | 
|---|
| 251 |           case SDLK_x: | 
|---|
| 252 |             delete obj; | 
|---|
| 253 |             obj = NULL; | 
|---|
| 254 |             break; | 
|---|
| 255 |           case SDLK_c: | 
|---|
| 256 |             if (!obj) | 
|---|
| 257 |               obj = new OBJModel(argv[1]); | 
|---|
| 258 |             break; | 
|---|
| 259 |           case SDLK_a: | 
|---|
| 260 |             zoomTo /=2; | 
|---|
| 261 |             break; | 
|---|
| 262 |           case SDLK_z: | 
|---|
| 263 |             zoomTo *=2; | 
|---|
| 264 |  | 
|---|
| 265 |           } | 
|---|
| 266 |         break; | 
|---|
| 267 |              | 
|---|
| 268 |         // If a quit event was recieved | 
|---|
| 269 |       case SDL_QUIT: | 
|---|
| 270 |         // then we're done and we'll end this program | 
|---|
| 271 |           done=TRUE; | 
|---|
| 272 |           break; | 
|---|
| 273 |       default: | 
|---|
| 274 |           break; | 
|---|
| 275 |       } | 
|---|
| 276 |  | 
|---|
| 277 |  | 
|---|
| 278 |     } | 
|---|
| 279 |  | 
|---|
| 280 |     // Get the state of the keyboard keys | 
|---|
| 281 |     keys = SDL_GetKeyState(NULL); | 
|---|
| 282 |  | 
|---|
| 283 |     // and check if ESCAPE has been pressed. If so then quit | 
|---|
| 284 |     if(keys[SDLK_ESCAPE]) done=TRUE; | 
|---|
| 285 |   } | 
|---|
| 286 |  | 
|---|
| 287 |   // Kill the GL & SDL screens | 
|---|
| 288 |   if (obj) | 
|---|
| 289 |     delete obj; | 
|---|
| 290 |   wHandler.KillGLWindow(); | 
|---|
| 291 |   // And quit | 
|---|
| 292 |   return 0; | 
|---|
| 293 | } | 
|---|