[2642] | 1 | // occquery.cpp : Defines the entry point for the console application.
|
---|
| 2 | //
|
---|
[2746] | 3 | #include <math.h>
|
---|
| 4 | #include <time.h>
|
---|
[2756] | 5 | #include "common.h"
|
---|
[2642] | 6 | #include "glInterface.h"
|
---|
| 7 | #include "RenderTraverser.h"
|
---|
[2756] | 8 | #include "SceneEntity.h"
|
---|
| 9 | #include "Vector3.h"
|
---|
| 10 | #include "Matrix4x4.h"
|
---|
| 11 | #include "BinaryLoader.h"
|
---|
| 12 | #include "Bvh.h"
|
---|
| 13 | #include "Camera.h"
|
---|
| 14 | #include "Geometry.h"
|
---|
[2760] | 15 | #include "BvhLoader.h"
|
---|
| 16 | #include "FrustumCullingTraverser.h"
|
---|
[2763] | 17 | #include "StopAndWaitTraverser.h"
|
---|
[2642] | 18 |
|
---|
| 19 |
|
---|
[2760] | 20 |
|
---|
[2756] | 21 | using namespace std;
|
---|
| 22 | using namespace CHCDemo;
|
---|
[2642] | 23 |
|
---|
| 24 |
|
---|
[2756] | 25 |
|
---|
| 26 | /// the renderable scene geometry
|
---|
| 27 | SceneEntityContainer sceneEntities;
|
---|
| 28 | // traverses and renders the hierarchy
|
---|
| 29 | RenderTraverser *traverser;
|
---|
| 30 | /// the hierarchy
|
---|
| 31 | Bvh *bvh;
|
---|
| 32 | /// the scene camera
|
---|
| 33 | Camera *camera;
|
---|
| 34 | /// the scene bounding box
|
---|
| 35 | AxisAlignedBox3 sceneBox;
|
---|
[2760] | 36 | /// the current render state
|
---|
| 37 | RenderState state;
|
---|
[2756] | 38 |
|
---|
| 39 | // eye near plane distance
|
---|
| 40 | float nearDist = 0.1f;
|
---|
[2760] | 41 | int winWidth = 1024;
|
---|
| 42 | int winHeight = 768;
|
---|
[2759] | 43 | float winAspectRatio = 1.0f;
|
---|
[2642] | 44 |
|
---|
| 45 | float visZoomFactor = 1.5f;
|
---|
| 46 |
|
---|
| 47 | bool showHelp = false;
|
---|
| 48 | bool showStatistics = true;
|
---|
| 49 | bool showBoundingVolumes = false;
|
---|
| 50 | bool visMode = false;
|
---|
| 51 | bool showCreateParams = false;
|
---|
| 52 |
|
---|
[2760] | 53 | int currentFrame = -1;
|
---|
[2642] | 54 |
|
---|
[2760] | 55 | // visualisation view matrix
|
---|
| 56 | Matrix4x4 visView;
|
---|
[2642] | 57 |
|
---|
| 58 | //mouse navigation state
|
---|
| 59 | int xEyeBegin, yEyeBegin, yMotionBegin, verticalMotionBegin, horizontalMotionBegin = 0;
|
---|
[2756] | 60 | //int renderMode = RenderTraverser::RENDER_COHERENT;
|
---|
[2642] | 61 |
|
---|
| 62 | const int renderTimeSize = 100;
|
---|
| 63 | long renderTimes[renderTimeSize];
|
---|
| 64 | int renderTimesIdx = 0;
|
---|
| 65 | int renderTimesValid = 0;
|
---|
| 66 |
|
---|
| 67 | bool useOptimization = true;
|
---|
| 68 |
|
---|
[2756] | 69 |
|
---|
[2642] | 70 | Vector3 amb[2];
|
---|
| 71 | Vector3 dif[2];
|
---|
| 72 | Vector3 spec[2];
|
---|
| 73 |
|
---|
[2759] | 74 | void InitExtensions();
|
---|
[2756] | 75 | void DisplayVisualization();
|
---|
[2759] | 76 | void InitGLstate();
|
---|
| 77 | void CleanUp();
|
---|
| 78 | void SetupEyeView();
|
---|
| 79 | void UpdateEyeMtx();
|
---|
| 80 | void SetupLighting();
|
---|
[2756] | 81 |
|
---|
[2759] | 82 | void begin2D();
|
---|
| 83 | void end2D();
|
---|
[2756] | 84 | void output(int x, int y, const char *string);
|
---|
[2759] | 85 | void keyboard(unsigned char c, int x, int y);
|
---|
| 86 | void drawHelpMessage();
|
---|
| 87 | void drawStatistics();
|
---|
[2642] | 88 | void display(void);
|
---|
[2756] | 89 | void special(int c, int x, int y);
|
---|
| 90 | void reshape(int w, int h);
|
---|
[2642] | 91 | void mouse(int button, int state, int x, int y);
|
---|
| 92 | void leftMotion(int x, int y);
|
---|
[2758] | 93 | void rightMotion(int x, int y);
|
---|
[2642] | 94 | void middleMotion(int x, int y);
|
---|
| 95 | void drawEyeView(void);
|
---|
| 96 | void setupVisView(void);
|
---|
| 97 | long calcRenderTime(void);
|
---|
| 98 | void resetTimer(void);
|
---|
[2756] | 99 | void calcDecimalPoint(std::string &str, int d);
|
---|
[2642] | 100 |
|
---|
| 101 |
|
---|
| 102 |
|
---|
| 103 |
|
---|
| 104 | int main(int argc, char* argv[])
|
---|
| 105 | {
|
---|
[2760] | 106 | camera = new Camera(winWidth, winHeight);
|
---|
[2758] | 107 |
|
---|
[2760] | 108 | glutInitWindowSize(winWidth, winHeight);
|
---|
[2756] | 109 | glutInit(&argc, argv);
|
---|
[2642] | 110 | glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
|
---|
[2756] | 111 |
|
---|
[2642] | 112 | glutCreateWindow("Coherent Hierarchical Culling");
|
---|
| 113 |
|
---|
| 114 | glutDisplayFunc(display);
|
---|
| 115 | glutKeyboardFunc(keyboard);
|
---|
| 116 | glutSpecialFunc(special);
|
---|
| 117 | glutReshapeFunc(reshape);
|
---|
| 118 | glutMouseFunc(mouse);
|
---|
| 119 | glutIdleFunc(display);
|
---|
| 120 |
|
---|
[2756] | 121 | InitExtensions();
|
---|
| 122 | InitGLstate();
|
---|
[2642] | 123 |
|
---|
[2756] | 124 | leftMotion(0, 0);
|
---|
| 125 | middleMotion(0, 0);
|
---|
| 126 |
|
---|
| 127 | BinaryLoader loader;
|
---|
| 128 |
|
---|
[2757] | 129 | //const string filename("house_test.dem");
|
---|
[2760] | 130 | //const string filename("city_demo.dem");
|
---|
[2763] | 131 | const string filename("city.dem");
|
---|
| 132 | //const string filename("roofs.dem");
|
---|
[2756] | 133 |
|
---|
| 134 | if (loader.Load(filename, sceneEntities))
|
---|
| 135 | cout << "scene " << filename << " loaded" << endl;
|
---|
| 136 | else
|
---|
| 137 | cerr << "loading scene " << filename << " failed" << endl;
|
---|
| 138 |
|
---|
[2760] | 139 | BvhLoader bvhLoader;
|
---|
[2763] | 140 | //bvh = bvhLoader.Load("roofs.bvh", sceneEntities);
|
---|
| 141 | bvh = bvhLoader.Load("city.bvh", sceneEntities);
|
---|
| 142 | //bvh = bvhLoader.Load("city_demo.bvh", sceneEntities);
|
---|
[2762] | 143 | //bvh = bvhLoader.Load("house_test.bvh", sceneEntities);
|
---|
| 144 |
|
---|
[2760] | 145 | sceneBox = bvh->GetBox();
|
---|
[2756] | 146 |
|
---|
[2763] | 147 | //traverser = new FrustumCullingTraverser();
|
---|
| 148 | traverser = new StopAndWaitTraverser();
|
---|
[2760] | 149 | traverser->SetHierarchy(bvh);
|
---|
| 150 | traverser->SetRenderState(&state);
|
---|
[2756] | 151 |
|
---|
[2758] | 152 | //SetupProjection(800, 600, 60, sceneBox);
|
---|
[2757] | 153 | //camera->LookAtBox(sceneBox);
|
---|
| 154 | camera->LookInBox(sceneBox);
|
---|
[2756] | 155 | //camera->SetPosition(Vector3(0, 0, -3));
|
---|
| 156 | //camera->SetDirection(Vector3(0, 0, 1));
|
---|
| 157 |
|
---|
[2642] | 158 | /// initialise rendertime array
|
---|
| 159 | for(int i=0; i<renderTimeSize; i++)
|
---|
| 160 | renderTimes[i] = 0;
|
---|
| 161 |
|
---|
| 162 | glutMainLoop();
|
---|
| 163 |
|
---|
| 164 | // clean up
|
---|
[2756] | 165 | CleanUp();
|
---|
| 166 |
|
---|
[2642] | 167 | return 0;
|
---|
| 168 | }
|
---|
| 169 |
|
---|
[2756] | 170 |
|
---|
| 171 | void InitGLstate(void)
|
---|
[2642] | 172 | {
|
---|
[2760] | 173 | glClearColor(0.5f, 0.5f, 0.8f, 0.0);
|
---|
[2642] | 174 |
|
---|
| 175 | glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
---|
| 176 | glPixelStorei(GL_PACK_ALIGNMENT,1);
|
---|
| 177 |
|
---|
| 178 | glDepthFunc(GL_LESS);
|
---|
[2762] | 179 | glEnable(GL_DEPTH_TEST);
|
---|
[2642] | 180 |
|
---|
[2759] | 181 | SetupLighting();
|
---|
[2642] | 182 |
|
---|
[2760] | 183 | glColor3f(1.0f, 1.0f, 1.0f);
|
---|
[2642] | 184 | glShadeModel(GL_SMOOTH);
|
---|
| 185 |
|
---|
| 186 | glMaterialf(GL_FRONT, GL_SHININESS, 64);
|
---|
| 187 | glEnable(GL_NORMALIZE);
|
---|
| 188 |
|
---|
| 189 | glFrontFace(GL_CCW);
|
---|
| 190 | glCullFace(GL_BACK);
|
---|
| 191 | glEnable(GL_CULL_FACE);
|
---|
[2756] | 192 | //glDisable(GL_CULL_FACE);
|
---|
[2642] | 193 |
|
---|
[2762] | 194 |
|
---|
[2756] | 195 | GLfloat ambientColor[] = {0.5, 0.5, 0.5, 1.0};
|
---|
| 196 | GLfloat diffuseColor[] = {1.0, 0.0, 0.0, 1.0};
|
---|
[2759] | 197 | GLfloat specularColor[] = {0.0, 0.0, 0.0, 1.0};
|
---|
[2642] | 198 |
|
---|
[2756] | 199 | glMaterialfv(GL_FRONT, GL_AMBIENT, ambientColor);
|
---|
| 200 | glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuseColor);
|
---|
| 201 | glMaterialfv(GL_FRONT, GL_SPECULAR, specularColor);
|
---|
| 202 | //setupVisView();
|
---|
[2642] | 203 | }
|
---|
| 204 |
|
---|
| 205 |
|
---|
| 206 | void drawHelpMessage(void)
|
---|
| 207 | {
|
---|
| 208 | const char *message[] =
|
---|
| 209 | {
|
---|
| 210 | "Help information",
|
---|
| 211 | "",
|
---|
| 212 | "'F1' - shows/dismisses this message",
|
---|
| 213 | "'F2' - decreases number of objects (valid after scene recreation)",
|
---|
| 214 | "'F3' - increases number of objects (valid after scene recreation)",
|
---|
| 215 | "'F4' - decreases box length in z direction (valid after scene recreation)",
|
---|
| 216 | "'F5' - increases box length in z direction (valid after scene recreation)",
|
---|
| 217 | "'F6' - decreases object size (valid after scene recreation)",
|
---|
| 218 | "'F7' - increases object size (valid after scene recreation)",
|
---|
| 219 | "'F8' - cycles through object types (teapot, ...) (valid after scene recreation)",
|
---|
| 220 | "",
|
---|
| 221 | "'MOUSE-LEFT' - turn left/right, move forward/backward",
|
---|
| 222 | "'MOUSE-RIGHT' - turn left/right, move forward/backward",
|
---|
| 223 | "'MOUSE-MIDDLE' - move up/down, left/right",
|
---|
| 224 | "'CURSOR UP' - move forward",
|
---|
| 225 | "'CURSOR BACK' - move backward",
|
---|
| 226 | "'CURSOR RIGHT' - turn right",
|
---|
| 227 | "'CURSOR LEFT' - turn left",
|
---|
| 228 | "",
|
---|
| 229 | "'SPACE' - cycles through occlusion culling algorithms",
|
---|
| 230 | "'-' - decreases visibility threshold",
|
---|
| 231 | "'+' - increases visibility threshold",
|
---|
| 232 | "'C' - recreates the scene hierarchy",
|
---|
| 233 | "'G' - enables/disables optimization to take geometry as occluder",
|
---|
| 234 | "'N' - triggers NV / ARB queries",
|
---|
| 235 | "",
|
---|
| 236 | "'R' - shows/hides recreation parameters",
|
---|
| 237 | "'S' - shows/hides statistics",
|
---|
| 238 | "'V' - shows/hides bounding volumes",
|
---|
| 239 | "",
|
---|
| 240 | "'1' - shows/hides visualization",
|
---|
| 241 | "'2' - zooms out visualization",
|
---|
| 242 | "'3' - zooms in visualization",
|
---|
| 243 | 0,
|
---|
| 244 | };
|
---|
| 245 |
|
---|
[2756] | 246 |
|
---|
[2642] | 247 | int x = 40, y = 42;
|
---|
[2756] | 248 |
|
---|
[2642] | 249 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
---|
| 250 | glEnable(GL_BLEND);
|
---|
[2756] | 251 | glColor4f(0.0f, 1.0f , 0.0f, 0.2f); // 20% green.
|
---|
[2642] | 252 |
|
---|
| 253 | // Drawn clockwise because the flipped Y axis flips CCW and CW.
|
---|
| 254 | glRecti(winWidth - 30, 30, 30, winHeight - 30);
|
---|
| 255 |
|
---|
| 256 | glDisable(GL_BLEND);
|
---|
| 257 |
|
---|
[2756] | 258 | glColor3f(1.0f, 1.0f, 1.0f);
|
---|
| 259 |
|
---|
| 260 | for(int i = 0; message[i] != 0; i++)
|
---|
| 261 | {
|
---|
| 262 | if(message[i][0] == '\0')
|
---|
| 263 | {
|
---|
[2642] | 264 | y += 7;
|
---|
[2756] | 265 | }
|
---|
| 266 | else
|
---|
| 267 | {
|
---|
| 268 | output(x, y, message[i]);
|
---|
[2642] | 269 | y += 14;
|
---|
| 270 | }
|
---|
| 271 | }
|
---|
| 272 |
|
---|
| 273 | }
|
---|
| 274 |
|
---|
| 275 |
|
---|
[2759] | 276 | void SetupLighting()
|
---|
[2642] | 277 | {
|
---|
[2759] | 278 | glEnable(GL_LIGHTING);
|
---|
| 279 | glEnable(GL_LIGHT0);
|
---|
| 280 | glEnable(GL_LIGHT1);
|
---|
| 281 | //glDisable(GL_LIGHT1);
|
---|
| 282 | //glDisable(GL_LIGHTING);
|
---|
[2642] | 283 |
|
---|
[2759] | 284 | //GLfloat ambient[] = {0.5, 0.5, 0.5, 1.0};
|
---|
| 285 | GLfloat ambient[] = {0.2, 0.2, 0.2, 1.0};
|
---|
| 286 | GLfloat diffuse[] = {1.0, 1.0, 1.0, 1.0};
|
---|
[2760] | 287 | //GLfloat specular[] = {1.0, 1.0, 1.0, 1.0};
|
---|
[2759] | 288 | GLfloat specular[] = {1.0, 1.0, 1.0, 1.0};
|
---|
| 289 |
|
---|
| 290 | //GLfloat lmodel_ambient[] = {0.5f, 0.5f, 0.5f, 1.0};
|
---|
| 291 | GLfloat lmodel_ambient[] = {0.2f, 0.2f, 0.2f, 1.0f};
|
---|
| 292 |
|
---|
| 293 | glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
|
---|
| 294 | glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
|
---|
| 295 | glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
|
---|
| 296 |
|
---|
[2760] | 297 | GLfloat position[] = {1.0, 1.0, 1.0, 0.0};
|
---|
[2759] | 298 | glLightfv(GL_LIGHT0, GL_POSITION, position);
|
---|
| 299 |
|
---|
| 300 |
|
---|
| 301 | ////////////
|
---|
| 302 | //-- second light
|
---|
| 303 |
|
---|
[2760] | 304 | GLfloat ambient1[] = {0.5, 0.5, 0.5, 1.0};
|
---|
| 305 | //GLfloat diffuse1[] = {1.0, 1.0, 1.0, 1.0};
|
---|
[2759] | 306 | GLfloat diffuse1[] = {0.5, 0.5, 0.5, 1.0};
|
---|
[2760] | 307 | GLfloat specular1[] = {0.5, 0.5, 0.5, 1.0};
|
---|
[2759] | 308 |
|
---|
| 309 | glLightfv(GL_LIGHT1, GL_AMBIENT, ambient1);
|
---|
| 310 | glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse1);
|
---|
| 311 | glLightfv(GL_LIGHT1, GL_SPECULAR, specular1);
|
---|
| 312 |
|
---|
| 313 | GLfloat position1[] = {0.0, 1.0, 0.0, 1.0};
|
---|
| 314 | glLightfv(GL_LIGHT1, GL_POSITION, position1);
|
---|
| 315 |
|
---|
| 316 | glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
|
---|
| 317 | glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
|
---|
| 318 | //glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE);
|
---|
| 319 | //glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL_EXT, GL_SEPARATE_SPECULAR_COLOR_EXT);
|
---|
| 320 | glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL_EXT, GL_SINGLE_COLOR_EXT);
|
---|
| 321 |
|
---|
[2642] | 322 | }
|
---|
| 323 |
|
---|
[2756] | 324 | void SetupEyeView(void)
|
---|
[2642] | 325 | {
|
---|
[2759] | 326 | glMatrixMode(GL_PROJECTION);
|
---|
| 327 | glLoadIdentity();
|
---|
| 328 |
|
---|
| 329 | gluPerspective(60.0f, 1.0f / winAspectRatio, nearDist, 2.0f * Magnitude(sceneBox.Diagonal()));
|
---|
| 330 |
|
---|
[2756] | 331 | glMatrixMode(GL_MODELVIEW);
|
---|
[2760] | 332 | camera->SetupCameraView();
|
---|
| 333 |
|
---|
| 334 | GLfloat position[] = {0.8f, 1.0f, 1.5f, 0.0f};
|
---|
[2759] | 335 | glLightfv(GL_LIGHT0, GL_POSITION, position);
|
---|
| 336 |
|
---|
[2760] | 337 | GLfloat position1[] = {sceneBox.Center().x, sceneBox.Max().y, sceneBox.Center().z, 1.0f};
|
---|
| 338 | //GLfloat position1[] = {-2.0f, 1.0f, 0.0f, 0.0f};
|
---|
[2759] | 339 | glLightfv(GL_LIGHT1, GL_POSITION, position1);
|
---|
[2642] | 340 | }
|
---|
| 341 |
|
---|
| 342 |
|
---|
| 343 | void display(void)
|
---|
| 344 | {
|
---|
| 345 | char * msg[] = {"Frustum culling only", "Hierarchical stop and wait",
|
---|
| 346 | "Coherent hierarchical culling"};
|
---|
| 347 |
|
---|
| 348 | char msg2[200];
|
---|
| 349 | char msg3[200];
|
---|
| 350 | char msg4[100];
|
---|
| 351 | char msg5[100];
|
---|
| 352 | char msg6[100];
|
---|
| 353 | char msg7[100];
|
---|
| 354 | char msg8[100];
|
---|
| 355 |
|
---|
[2759] | 356 |
|
---|
| 357 | /*sprintf_s(msg2, "Traversed: %4d, frustum culled: %4d, query culled: %4d (of %d nodes)",
|
---|
[2642] | 358 | traverser.GetNumTraversedNodes(), traverser.GetNumFrustumCulledNodes(),
|
---|
| 359 | traverser.GetNumQueryCulledNodes(),
|
---|
| 360 | traverser.GetHierarchy()->GetNumHierarchyNodes());
|
---|
[2759] | 361 | */
|
---|
[2642] | 362 | char *optstr[2] = {"", ", using optimization"};
|
---|
[2759] | 363 |
|
---|
[2748] | 364 | float fps = 1e3f;
|
---|
[2642] | 365 | long renderTime = calcRenderTime();
|
---|
[2759] | 366 | if (renderTime) fps = 1e3f / (float)renderTime;
|
---|
[2642] | 367 |
|
---|
[2759] | 368 | //sprintf_s(msg3, "Threshold: %4d, algorithm rendering time: %ld ms (%3.3f fps), queries: %s",
|
---|
| 369 | // traverser.GetVisibilityThreshold(), renderTime / 1000, fps, optstr[useOptimization]);
|
---|
| 370 | sprintf_s(msg3, "render time: %ld ms (%3.3f fps), queries: %s", renderTime, fps, optstr[useOptimization]);
|
---|
[2642] | 371 |
|
---|
| 372 | string str;
|
---|
| 373 | string str2;
|
---|
| 374 |
|
---|
[2759] | 375 | /*calcDecimalPoint(str, Geometry::CountTriangles(objectType) * traverser.GetNumRenderedGeometry());
|
---|
[2642] | 376 | calcDecimalPoint(str2, Geometry::CountTriangles(objectType) * numObjects);
|
---|
| 377 |
|
---|
[2748] | 378 | sprintf_s(msg4, "Rendered objects %d (of %d), rendered triangles: %s (of %s)",
|
---|
[2642] | 379 | traverser.GetNumRenderedGeometry(), numObjects, str.c_str(), str2.c_str());
|
---|
[2759] | 380 | */
|
---|
[2642] | 381 |
|
---|
[2760] | 382 | ++ currentFrame;
|
---|
[2642] | 383 |
|
---|
| 384 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
---|
| 385 |
|
---|
[2756] | 386 | // bring eye modelview matrix up-to-date
|
---|
| 387 | SetupEyeView();
|
---|
[2642] | 388 |
|
---|
[2760] | 389 | bvh->InitFrame(camera, currentFrame);
|
---|
| 390 |
|
---|
| 391 |
|
---|
[2759] | 392 | InitTiming(); |
---|
| 393 | |
---|
| 394 | long t1, t2; |
---|
| 395 | |
---|
| 396 | t1 = GetTime(); |
---|
| 397 |
|
---|
[2762] | 398 | traverser->SetCamera(camera);
|
---|
| 399 |
|
---|
| 400 | //traverser->RenderFrustum();
|
---|
| 401 |
|
---|
[2756] | 402 | glEnableClientState(GL_VERTEX_ARRAY);
|
---|
| 403 | glEnableClientState(GL_NORMAL_ARRAY);
|
---|
| 404 |
|
---|
[2760] | 405 | traverser->Render();
|
---|
| 406 | /*
|
---|
[2756] | 407 | bool usesTextures = false;
|
---|
| 408 |
|
---|
| 409 | SceneEntityContainer::const_iterator sit, sit_end = sceneEntities.end();
|
---|
| 410 |
|
---|
| 411 | for (sit = sceneEntities.begin(); sit != sit_end; ++ sit)
|
---|
| 412 | {
|
---|
| 413 | SceneEntity *entity = *sit;
|
---|
| 414 |
|
---|
| 415 | if (!usesTextures && entity->GetGeometry()->HasTexture())
|
---|
| 416 | {
|
---|
| 417 | glEnable(GL_TEXTURE_2D);
|
---|
| 418 | glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
---|
| 419 | usesTextures = true;
|
---|
| 420 | }
|
---|
| 421 | else if (usesTextures && !entity->GetGeometry()->HasTexture())
|
---|
| 422 | {
|
---|
| 423 | glDisable(GL_TEXTURE_2D);
|
---|
| 424 | glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
---|
| 425 | usesTextures = false;
|
---|
| 426 | }
|
---|
| 427 |
|
---|
| 428 | entity->Render();
|
---|
| 429 | }
|
---|
[2760] | 430 | */
|
---|
[2756] | 431 | glDisableClientState(GL_VERTEX_ARRAY);
|
---|
| 432 | glDisableClientState(GL_NORMAL_ARRAY);
|
---|
| 433 |
|
---|
| 434 | glDisable(GL_TEXTURE_2D);
|
---|
| 435 | glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
---|
[2759] | 436 | |
---|
| 437 | |
---|
| 438 | t2 = GetTime(); |
---|
| 439 | long loop_time = TimeDiff(t1, t2); |
---|
| 440 | //cout<<"t: " << loop_time<<endl;
|
---|
[2756] | 441 |
|
---|
| 442 | /*
|
---|
[2642] | 443 | traverser.SetViewpoint(eyePos);
|
---|
| 444 | traverser.SetProjViewMatrix(eyeProjView);
|
---|
| 445 | traverser.Render(renderMode);
|
---|
[2759] | 446 | */
|
---|
| 447 |
|
---|
[2642] | 448 | // cycle through rendertime array
|
---|
[2759] | 449 | renderTimes[renderTimesIdx] = loop_time;// traverser.GetRenderTime();
|
---|
[2642] | 450 | renderTimesIdx = (renderTimesIdx + 1) % renderTimeSize;
|
---|
| 451 |
|
---|
| 452 | if(renderTimesIdx > renderTimesValid)
|
---|
| 453 | renderTimesValid = renderTimesIdx;
|
---|
| 454 |
|
---|
[2759] | 455 | //if(visMode) displayVisualization();
|
---|
| 456 |
|
---|
[2756] | 457 |
|
---|
[2642] | 458 | begin2D();
|
---|
[2756] | 459 |
|
---|
[2642] | 460 | if(showHelp)
|
---|
[2756] | 461 | {
|
---|
[2642] | 462 | drawHelpMessage();
|
---|
[2756] | 463 | }
|
---|
[2642] | 464 | else
|
---|
| 465 | {
|
---|
| 466 | glColor3f(1.0,1.0,1.0);
|
---|
[2756] | 467 | //output(10, winHeight-10, msg[renderMode]);
|
---|
[2642] | 468 |
|
---|
| 469 | if(showStatistics)
|
---|
| 470 | {
|
---|
| 471 | if(showCreateParams)
|
---|
| 472 | {
|
---|
| 473 | output(10, winHeight-150, msg8);
|
---|
| 474 | output(10, winHeight-130, msg7);
|
---|
| 475 | output(10, winHeight-110, msg6);
|
---|
| 476 | output(10, winHeight-90, msg5);
|
---|
| 477 | }
|
---|
[2759] | 478 |
|
---|
[2642] | 479 | output(10, winHeight-70, msg3);
|
---|
[2759] | 480 | //output(10, winHeight-50, msg4);
|
---|
| 481 | //output(10, winHeight-30, msg2);
|
---|
[2642] | 482 | }
|
---|
| 483 | }
|
---|
| 484 | end2D();
|
---|
| 485 |
|
---|
| 486 | glutSwapBuffers();
|
---|
| 487 | }
|
---|
| 488 |
|
---|
| 489 |
|
---|
| 490 | #pragma warning( disable : 4100 )
|
---|
| 491 | void keyboard(const unsigned char c, const int x, const int y)
|
---|
| 492 | {
|
---|
[2756] | 493 | //int threshold;
|
---|
| 494 | //HierarchyNode *hierarchy;
|
---|
[2642] | 495 |
|
---|
| 496 | switch(c)
|
---|
| 497 | {
|
---|
| 498 | case 27:
|
---|
| 499 | exit(0);
|
---|
| 500 | break;
|
---|
| 501 | case 32: //space
|
---|
[2759] | 502 | // renderMode = (renderMode + 1) % RenderTraverser::NUM_RENDERMODES;
|
---|
[2642] | 503 | resetTimer();
|
---|
[2756] | 504 | //traverser.Render(renderMode); // render once so stats are updated
|
---|
[2642] | 505 | break;
|
---|
| 506 | case 'h':
|
---|
| 507 | case 'H':
|
---|
| 508 | showHelp = !showHelp;
|
---|
| 509 | break;
|
---|
| 510 | case 'v':
|
---|
| 511 | case 'V':
|
---|
| 512 | showBoundingVolumes = !showBoundingVolumes;
|
---|
[2756] | 513 | //HierarchyNode::SetRenderBoundingVolume(showBoundingVolumes);
|
---|
[2642] | 514 | break;
|
---|
| 515 | case 's':
|
---|
| 516 | case 'S':
|
---|
| 517 | showStatistics = !showStatistics;
|
---|
| 518 | break;
|
---|
| 519 | case '+':
|
---|
[2756] | 520 | //threshold = traverser.GetVisibilityThreshold() + 10;
|
---|
| 521 | //traverser.SetVisibilityThreshold(threshold);
|
---|
[2642] | 522 | break;
|
---|
| 523 | case '-':
|
---|
[2756] | 524 | //threshold = traverser.GetVisibilityThreshold() - 10;
|
---|
| 525 | //if(threshold < 0) threshold = 0;
|
---|
[2642] | 526 |
|
---|
[2756] | 527 | //traverser.SetVisibilityThreshold(threshold);
|
---|
[2642] | 528 | break;
|
---|
| 529 | case '1':
|
---|
| 530 | visMode = !visMode;
|
---|
| 531 | break;
|
---|
| 532 |
|
---|
| 533 | case '2':
|
---|
| 534 | visZoomFactor += 0.1;
|
---|
| 535 | setupVisView();
|
---|
| 536 | break;
|
---|
| 537 | case '3':
|
---|
| 538 | visZoomFactor -= 0.1;
|
---|
| 539 | if(visZoomFactor < 0.1) visZoomFactor = 0.1;
|
---|
| 540 |
|
---|
| 541 | setupVisView();
|
---|
| 542 | break;
|
---|
| 543 | case 'r':
|
---|
| 544 | case 'R':
|
---|
| 545 | showCreateParams = !showCreateParams;
|
---|
| 546 | break;
|
---|
| 547 | case 'g':
|
---|
| 548 | case 'G':
|
---|
| 549 | useOptimization = !useOptimization;
|
---|
[2756] | 550 | //traverser.SetUseOptimization(useOptimization);
|
---|
[2642] | 551 | break;
|
---|
[2756] | 552 | /*
|
---|
[2642] | 553 | case 'c':
|
---|
| 554 | case 'C':
|
---|
| 555 | hierarchy = traverser.GetHierarchy();
|
---|
| 556 | // delete old hierarchy
|
---|
[2756] | 557 | if (hierarchy) delete hierarchy;
|
---|
[2642] | 558 | deleteGeometry();
|
---|
| 559 |
|
---|
| 560 | maxTranslation[2] = -3.0 - zLength;
|
---|
| 561 | numObjects = numNextObjects;
|
---|
| 562 | objectType = nextObjectType;
|
---|
| 563 |
|
---|
| 564 | hierarchy = generateHierarchy(numObjects);
|
---|
| 565 | traverser.SetHierarchy(hierarchy);
|
---|
| 566 |
|
---|
| 567 | showCreateParams = false;
|
---|
| 568 |
|
---|
| 569 | traverser.Render(renderMode); // render once to update stats
|
---|
| 570 | resetTimer();
|
---|
| 571 | break;
|
---|
[2756] | 572 | */
|
---|
[2642] | 573 | default:
|
---|
| 574 | return;
|
---|
| 575 | }
|
---|
| 576 |
|
---|
| 577 | glutPostRedisplay();
|
---|
| 578 | }
|
---|
| 579 |
|
---|
| 580 |
|
---|
| 581 | void special(const int c, const int x, const int y)
|
---|
| 582 | {
|
---|
| 583 | // used to avoid vertical motion with the keys
|
---|
[2760] | 584 | //Vector3 hvec = Vector3(viewDir[0], 0, viewDir[2]);
|
---|
[2642] | 585 |
|
---|
| 586 | switch(c)
|
---|
| 587 | {
|
---|
| 588 | case GLUT_KEY_F1:
|
---|
| 589 | showHelp = !showHelp;
|
---|
| 590 | break;
|
---|
| 591 | case GLUT_KEY_F2:
|
---|
[2756] | 592 | //numNextObjects -= 100;
|
---|
| 593 | //if(numNextObjects < 100) numNextObjects = 100;
|
---|
[2642] | 594 | break;
|
---|
| 595 | case GLUT_KEY_F3:
|
---|
[2756] | 596 | // numNextObjects += 100;
|
---|
[2642] | 597 | break;
|
---|
| 598 | case GLUT_KEY_F4:
|
---|
[2759] | 599 | //zLength -= 1;
|
---|
| 600 | //if(zLength < 0) zLength = 0;
|
---|
[2642] | 601 | break;
|
---|
| 602 | case GLUT_KEY_F5:
|
---|
[2759] | 603 | //zLength += 1;
|
---|
[2642] | 604 | break;
|
---|
| 605 | case GLUT_KEY_F6:
|
---|
[2759] | 606 | //objectSize -= 0.1;
|
---|
| 607 | //if(objectSize < 0.1) objectSize = 0.1;
|
---|
[2642] | 608 | break;
|
---|
| 609 | case GLUT_KEY_F7:
|
---|
[2759] | 610 | //objectSize += 0.1;
|
---|
[2642] | 611 | break;
|
---|
| 612 | case GLUT_KEY_F8:
|
---|
[2756] | 613 | //nextObjectType = (nextObjectType + 1) % Geometry::NUM_OBJECTS;
|
---|
[2642] | 614 | break;
|
---|
| 615 | case GLUT_KEY_LEFT:
|
---|
[2756] | 616 | // rotateVectorY(viewDir, 0.2);
|
---|
[2642] | 617 | break;
|
---|
| 618 | case GLUT_KEY_RIGHT:
|
---|
[2756] | 619 | //rotateVectorY(viewDir, -0.2);
|
---|
[2642] | 620 | break;
|
---|
| 621 | case GLUT_KEY_UP:
|
---|
[2756] | 622 | // linCombVector3(eyePos, eyePos, hvec, 0.6);
|
---|
[2642] | 623 | break;
|
---|
| 624 | case GLUT_KEY_DOWN:
|
---|
[2756] | 625 | //linCombVector3(eyePos, eyePos, hvec, -0.6);
|
---|
[2642] | 626 | break;
|
---|
| 627 | default:
|
---|
| 628 | return;
|
---|
| 629 |
|
---|
| 630 | }
|
---|
| 631 |
|
---|
| 632 | glutPostRedisplay();
|
---|
| 633 | }
|
---|
| 634 | #pragma warning( default : 4100 )
|
---|
| 635 |
|
---|
| 636 |
|
---|
| 637 | void reshape(const int w, const int h)
|
---|
| 638 | {
|
---|
[2759] | 639 | winAspectRatio = 1.0f;
|
---|
[2642] | 640 |
|
---|
| 641 | glViewport(0, 0, w, h);
|
---|
| 642 |
|
---|
| 643 | winWidth = w;
|
---|
| 644 | winHeight = h;
|
---|
| 645 |
|
---|
[2759] | 646 | if (w) winAspectRatio = (float) h / (float) w;
|
---|
[2642] | 647 |
|
---|
[2758] | 648 | glMatrixMode(GL_PROJECTION);
|
---|
| 649 | glLoadIdentity();
|
---|
[2642] | 650 |
|
---|
[2759] | 651 | gluPerspective(60.0f, 1.0f / winAspectRatio, nearDist, 2.0f * Magnitude(sceneBox.Diagonal()));
|
---|
[2758] | 652 | glMatrixMode(GL_MODELVIEW);
|
---|
| 653 |
|
---|
[2642] | 654 | glutPostRedisplay();
|
---|
| 655 | }
|
---|
| 656 |
|
---|
| 657 |
|
---|
| 658 | void mouse(int button, int state, int x, int y)
|
---|
| 659 | {
|
---|
[2758] | 660 | if ((button == GLUT_LEFT_BUTTON) && (state == GLUT_DOWN))
|
---|
[2642] | 661 | {
|
---|
| 662 | xEyeBegin = x;
|
---|
| 663 | yMotionBegin = y;
|
---|
| 664 |
|
---|
| 665 | glutMotionFunc(leftMotion);
|
---|
| 666 | }
|
---|
[2758] | 667 | else if ((button == GLUT_RIGHT_BUTTON) && (state == GLUT_DOWN))
|
---|
[2642] | 668 | {
|
---|
[2758] | 669 | yEyeBegin = y;
|
---|
| 670 | yMotionBegin = y;
|
---|
| 671 |
|
---|
| 672 | glutMotionFunc(rightMotion);
|
---|
| 673 | }
|
---|
| 674 | else if ((button == GLUT_MIDDLE_BUTTON) && (state == GLUT_DOWN))
|
---|
| 675 | {
|
---|
[2642] | 676 | horizontalMotionBegin = x;
|
---|
| 677 | verticalMotionBegin = y;
|
---|
| 678 | glutMotionFunc(middleMotion);
|
---|
| 679 | }
|
---|
| 680 |
|
---|
| 681 | glutPostRedisplay();
|
---|
| 682 | }
|
---|
| 683 |
|
---|
[2758] | 684 |
|
---|
| 685 | /** rotation for left/right mouse drag
|
---|
[2642] | 686 | motion for up/down mouse drag
|
---|
| 687 | */
|
---|
| 688 | void leftMotion(int x, int y)
|
---|
| 689 | {
|
---|
[2758] | 690 | static float eyeXAngle = 0.0f;
|
---|
| 691 |
|
---|
| 692 | Vector3 viewDir = camera->GetDirection();
|
---|
| 693 | Vector3 pos = camera->GetPosition();
|
---|
| 694 |
|
---|
| 695 | // don't move in the vertical direction
|
---|
| 696 | Vector3 horView(viewDir[0], 0, viewDir[2]);
|
---|
[2642] | 697 |
|
---|
[2758] | 698 | eyeXAngle = -0.2f * M_PI * (xEyeBegin - x) / 180.0;
|
---|
[2756] | 699 |
|
---|
[2758] | 700 | // rotate view vector
|
---|
| 701 | Matrix4x4 rot = RotationYMatrix(eyeXAngle);
|
---|
| 702 | viewDir = rot * viewDir;
|
---|
| 703 |
|
---|
| 704 | pos += horView * (yMotionBegin - y) * 0.2f;
|
---|
| 705 |
|
---|
| 706 | camera->SetDirection(viewDir);
|
---|
| 707 | camera->SetPosition(pos);
|
---|
[2642] | 708 |
|
---|
| 709 | xEyeBegin = x;
|
---|
| 710 | yMotionBegin = y;
|
---|
[2758] | 711 |
|
---|
[2642] | 712 | glutPostRedisplay();
|
---|
| 713 | }
|
---|
| 714 |
|
---|
[2758] | 715 |
|
---|
| 716 | /** rotation for left/right mouse drag
|
---|
| 717 | motion for up/down mouse drag
|
---|
| 718 | */
|
---|
| 719 | void rightMotion(int x, int y)
|
---|
| 720 | {
|
---|
| 721 | static float eyeYAngle = 0.0f;
|
---|
| 722 |
|
---|
| 723 | Vector3 viewDir = camera->GetDirection();
|
---|
| 724 | Vector3 right = camera->GetRightVector();
|
---|
| 725 |
|
---|
| 726 | eyeYAngle = -0.2f * M_PI * (yEyeBegin - y) / 180.0;
|
---|
| 727 |
|
---|
| 728 | // rotate view vector
|
---|
| 729 | Matrix4x4 rot = RotationAxisMatrix(right, eyeYAngle);
|
---|
| 730 | viewDir = rot * viewDir;
|
---|
| 731 |
|
---|
| 732 | camera->SetDirection(viewDir);
|
---|
| 733 |
|
---|
| 734 | yEyeBegin = y;
|
---|
| 735 |
|
---|
| 736 | glutPostRedisplay();
|
---|
| 737 | }
|
---|
| 738 |
|
---|
| 739 |
|
---|
[2642] | 740 | // strafe
|
---|
| 741 | void middleMotion(int x, int y)
|
---|
| 742 | {
|
---|
[2758] | 743 | Vector3 viewDir = camera->GetDirection();
|
---|
| 744 | Vector3 pos = camera->GetPosition();
|
---|
| 745 |
|
---|
[2642] | 746 | // the 90 degree rotated view vector
|
---|
| 747 | // y zero so we don't move in the vertical
|
---|
[2758] | 748 | Vector3 rVec(viewDir[0], 0, viewDir[2]);
|
---|
[2642] | 749 |
|
---|
[2758] | 750 | Matrix4x4 rot = RotationYMatrix(M_PI * 0.5f);
|
---|
| 751 | rVec = rot * rVec;
|
---|
[2642] | 752 |
|
---|
[2758] | 753 | pos += rVec * (x - horizontalMotionBegin) * 0.1f;
|
---|
| 754 | pos[1] += (verticalMotionBegin - y) * 0.1f;
|
---|
[2642] | 755 |
|
---|
[2758] | 756 | camera->SetPosition(pos);
|
---|
| 757 |
|
---|
[2642] | 758 | horizontalMotionBegin = x;
|
---|
| 759 | verticalMotionBegin = y;
|
---|
[2758] | 760 |
|
---|
[2642] | 761 | glutPostRedisplay();
|
---|
| 762 | }
|
---|
| 763 |
|
---|
| 764 |
|
---|
[2756] | 765 | void InitExtensions(void)
|
---|
[2642] | 766 | {
|
---|
| 767 | GLenum err = glewInit();
|
---|
[2756] | 768 |
|
---|
[2642] | 769 | if (GLEW_OK != err)
|
---|
| 770 | {
|
---|
| 771 | // problem: glewInit failed, something is seriously wrong
|
---|
| 772 | fprintf(stderr,"Error: %s\n", glewGetErrorString(err));
|
---|
| 773 | exit(1);
|
---|
| 774 | }
|
---|
[2756] | 775 | if (!GLEW_ARB_occlusion_query)
|
---|
[2642] | 776 | {
|
---|
[2756] | 777 | printf("I require the GL_ARB_occlusion_query to work.\n");
|
---|
[2642] | 778 | exit(1);
|
---|
| 779 | }
|
---|
| 780 | }
|
---|
| 781 |
|
---|
| 782 |
|
---|
| 783 | void begin2D(void)
|
---|
| 784 | {
|
---|
| 785 | glDisable(GL_LIGHTING);
|
---|
| 786 | glDisable(GL_DEPTH_TEST);
|
---|
| 787 |
|
---|
| 788 | glPushMatrix();
|
---|
| 789 | glLoadIdentity();
|
---|
| 790 |
|
---|
| 791 | glMatrixMode(GL_PROJECTION);
|
---|
| 792 | glPushMatrix();
|
---|
| 793 | glLoadIdentity();
|
---|
| 794 | gluOrtho2D(0, winWidth, winHeight, 0);
|
---|
| 795 | }
|
---|
| 796 |
|
---|
| 797 |
|
---|
| 798 | void end2D(void)
|
---|
| 799 | {
|
---|
| 800 | glPopMatrix();
|
---|
| 801 | glMatrixMode(GL_MODELVIEW);
|
---|
| 802 | glPopMatrix();
|
---|
| 803 |
|
---|
| 804 | glEnable(GL_LIGHTING);
|
---|
| 805 | glEnable(GL_DEPTH_TEST);
|
---|
| 806 | }
|
---|
| 807 |
|
---|
| 808 |
|
---|
| 809 | void output(const int x, const int y, const char *string)
|
---|
| 810 | {
|
---|
| 811 | if(string != 0)
|
---|
| 812 | {
|
---|
| 813 | int len, i;
|
---|
| 814 | glRasterPos2f(x,y);
|
---|
| 815 | len = (int) strlen(string);
|
---|
| 816 |
|
---|
| 817 | for (i = 0; i < len; i++)
|
---|
| 818 | {
|
---|
[2759] | 819 | glutBitmapCharacter(GLUT_BITMAP_8_BY_13, string[i]);
|
---|
[2642] | 820 | }
|
---|
| 821 | }
|
---|
| 822 | }
|
---|
| 823 |
|
---|
| 824 | // displays the visualisation of the kd tree node culling
|
---|
| 825 | void displayVisualization()
|
---|
| 826 | {
|
---|
| 827 | begin2D();
|
---|
| 828 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
---|
| 829 | glEnable(GL_BLEND);
|
---|
| 830 | glColor4f(0.0,0.0,0.0,0.5);
|
---|
| 831 |
|
---|
| 832 | glRecti(winWidth, 0, winWidth / 2, winHeight / 2);
|
---|
| 833 | glDisable(GL_BLEND);
|
---|
| 834 | end2D();
|
---|
| 835 |
|
---|
| 836 | glViewport(winWidth / 2, winHeight / 2, winWidth, winHeight);
|
---|
| 837 | glPushMatrix();
|
---|
[2756] | 838 | glLoadMatrixf((float *)visView.x);
|
---|
[2642] | 839 |
|
---|
| 840 | glClear(GL_DEPTH_BUFFER_BIT);
|
---|
| 841 |
|
---|
| 842 | // --- visualization of the occlusion culling
|
---|
[2756] | 843 | /*HierarchyNode::SetRenderBoundingVolume(true);
|
---|
[2642] | 844 | traverser.RenderVisualization();
|
---|
| 845 | HierarchyNode::SetRenderBoundingVolume(showBoundingVolumes);
|
---|
[2756] | 846 | */
|
---|
[2642] | 847 | glPopMatrix();
|
---|
| 848 | glViewport(0, 0, winWidth, winHeight);
|
---|
| 849 | }
|
---|
| 850 |
|
---|
[2756] | 851 | /** Sets up view matrix in order to get a good position
|
---|
[2642] | 852 | for viewing the kd tree node culling
|
---|
| 853 | */
|
---|
| 854 | void setupVisView()
|
---|
| 855 | {
|
---|
[2756] | 856 | const Vector3 up(0.0, 1.0, 0.0);
|
---|
[2642] | 857 |
|
---|
[2756] | 858 | Vector3 visPos(24, 23, -6);
|
---|
[2642] | 859 |
|
---|
| 860 | visPos[0] *= visZoomFactor;
|
---|
| 861 | visPos[1] *= visZoomFactor;
|
---|
| 862 | visPos[2] *= visZoomFactor;
|
---|
| 863 |
|
---|
[2756] | 864 | Vector3 visDir = Vector3(-1.3, -1, -1);
|
---|
[2642] | 865 |
|
---|
[2756] | 866 | //normalize(visDir);
|
---|
| 867 | //look(visView, visPos, visDir, up);
|
---|
[2642] | 868 | }
|
---|
| 869 |
|
---|
| 870 | // we take a couple of measurements and compute the average
|
---|
| 871 | long calcRenderTime()
|
---|
| 872 | {
|
---|
| 873 | long result = 0;
|
---|
| 874 |
|
---|
| 875 | for(int i=0; i<renderTimesValid; i++)
|
---|
| 876 | result += renderTimes[i];
|
---|
| 877 |
|
---|
| 878 | if(renderTimesValid)
|
---|
| 879 | result /= renderTimesValid;
|
---|
| 880 |
|
---|
| 881 | return result;
|
---|
| 882 | }
|
---|
| 883 |
|
---|
| 884 |
|
---|
| 885 | // reset the timer array for a new traversal method
|
---|
| 886 | void resetTimer()
|
---|
| 887 | {
|
---|
| 888 | renderTimesValid = 0;
|
---|
| 889 | renderTimesIdx = 0;
|
---|
| 890 | }
|
---|
| 891 |
|
---|
| 892 |
|
---|
| 893 | // cleanup routine after the main loop
|
---|
[2756] | 894 | void CleanUp()
|
---|
[2642] | 895 | {
|
---|
[2756] | 896 | CLEAR_CONTAINER(sceneEntities);
|
---|
| 897 | DEL_PTR(traverser);
|
---|
[2642] | 898 |
|
---|
[2756] | 899 | DEL_PTR(bvh);
|
---|
[2642] | 900 | }
|
---|
| 901 |
|
---|
| 902 |
|
---|
| 903 | // this function inserts a dezimal point after each 1000
|
---|
| 904 | void calcDecimalPoint(string &str, int d)
|
---|
| 905 | {
|
---|
| 906 | vector<int> numbers;
|
---|
| 907 | char hstr[100];
|
---|
| 908 |
|
---|
| 909 | while (d != 0)
|
---|
| 910 | {
|
---|
| 911 | numbers.push_back(d % 1000);
|
---|
| 912 | d /= 1000;
|
---|
| 913 | }
|
---|
| 914 |
|
---|
| 915 | // first element without leading zeros
|
---|
| 916 | if (numbers.size() > 0)
|
---|
| 917 | {
|
---|
[2748] | 918 | sprintf_s(hstr, "%d", numbers.back());
|
---|
[2642] | 919 | str.append(hstr);
|
---|
| 920 | }
|
---|
| 921 |
|
---|
| 922 | for (size_t i = numbers.size() - 2; i >= 0; i--)
|
---|
| 923 | {
|
---|
[2748] | 924 | sprintf_s(hstr, ",%03d", numbers[i]);
|
---|
[2642] | 925 | str.append(hstr);
|
---|
| 926 | }
|
---|
[2756] | 927 | } |
---|