// ======================================================================== // // Copyright 2009-2013 Intel Corporation // // // // Licensed under the Apache License, Version 2.0 (the "License"); // // you may not use this file except in compliance with the License. // // You may obtain a copy of the License at // // // // http://www.apache.org/licenses/LICENSE-2.0 // // // // Unless required by applicable law or agreed to in writing, software // // distributed under the License is distributed on an "AS IS" BASIS, // // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // // See the License for the specific language governing permissions and // // limitations under the License. // // ======================================================================== // #include "glutdisplay.h" #include "sys/filename.h" #include "lexers/streamfilters.h" #include "lexers/parsestream.h" #include "transport/transport_host.h" /* include GLUT for display */ #if defined(__MACOSX__) # include # include # include #elif defined(__WIN32__) # include # include # include #else # include # include #endif namespace embree { static const double g_time0 = getSeconds(); /* camera */ Camera g_camera; /* output settings */ static size_t g_width = 512; static size_t g_height = 512; static bool g_display = true; /* fullscreen settings */ static bool g_fullscreen = false; static size_t g_window_width = 512; static size_t g_window_height = 512; /* ID of created window */ static int g_window = 0; /*************************************************************************************************/ /* Keyboard control */ /*************************************************************************************************/ static float g_speed = 1.0f; void keyboardFunc(unsigned char k, int, int) { key_pressed(k); switch (k) { case 'f' : if (g_fullscreen) { g_fullscreen = false; glutReshapeWindow(g_window_width,g_window_height); } else { g_fullscreen = true; g_window_width = g_width; g_window_height = g_height; glutFullScreen(); } break; case 'c' : { std::cout << "-vp " << g_camera.from.x << " " << g_camera.from.y << " " << g_camera.from.z << " " << std::endl << "-vi " << g_camera.to.x << " " << g_camera.to.y << " " << g_camera.to.z << " " << std::endl << "-vu " << g_camera.up.x << " " << g_camera.up.y << " " << g_camera.up.z << " " << std::endl << "-fov " << g_camera.fov << std::endl; break; } case 'a' : g_camera.rotate(-0.02f,0.0f); break; case 'd' : g_camera.rotate(+0.02f,0.0f); break; case 'w' : g_camera.move(0.0f,0.0f,+g_speed); break; case 's' : g_camera.move(0.0f,0.0f,-g_speed); break; case ' ' : g_display = !g_display; break; case '\033': case 'q': case 'Q': cleanup(); glutDestroyWindow(g_window); exit(0); break; } } void specialFunc(int k, int, int) { key_pressed(k); switch (k) { case GLUT_KEY_LEFT : g_camera.rotate(-0.02f,0.0f); break; case GLUT_KEY_RIGHT : g_camera.rotate(+0.02f,0.0f); break; case GLUT_KEY_UP : g_camera.move(0.0f,0.0f,+g_speed); break; case GLUT_KEY_DOWN : g_camera.move(0.0f,0.0f,-g_speed); break; case GLUT_KEY_PAGE_UP : g_speed *= 1.2f; break; case GLUT_KEY_PAGE_DOWN : g_speed /= 1.2f; break; } } /*************************************************************************************************/ /* Mouse control */ /*************************************************************************************************/ static int mouseMode = 0; static int clickX = 0, clickY = 0; static bool flip14 = false; void clickFunc(int button, int state, int x, int y) { if (state == GLUT_UP) { mouseMode = 0; if (button == GLUT_LEFT_BUTTON && glutGetModifiers() == GLUT_ACTIVE_CTRL) { AffineSpace3f pixel2world = g_camera.pixel2world(g_width,g_height); Vec3f p; bool hit = pick(x,y, pixel2world.l.vx, pixel2world.l.vy, pixel2world.l.vz, pixel2world.p, p); if (hit) { Vec3fa delta = p - g_camera.to; Vec3fa right = normalize(pixel2world.l.vx); Vec3fa up = normalize(pixel2world.l.vy); g_camera.to = p; g_camera.from += dot(delta,right)*right + dot(delta,up)*up; } } else if (button == GLUT_LEFT_BUTTON && glutGetModifiers() == (GLUT_ACTIVE_CTRL | GLUT_ACTIVE_SHIFT)) { AffineSpace3f pixel2world = g_camera.pixel2world(g_width,g_height); Vec3f p; bool hit = pick(x,y, pixel2world.l.vx, pixel2world.l.vy, pixel2world.l.vz, pixel2world.p, p); if (hit) g_camera.to = p; } } else { clickX = x; clickY = y; int modifiers = glutGetModifiers(); if (button == GLUT_LEFT_BUTTON && modifiers == GLUT_ACTIVE_SHIFT) mouseMode = 1; else if (button == GLUT_MIDDLE_BUTTON) mouseMode = 2; else if (button == GLUT_RIGHT_BUTTON ) mouseMode = 3; else if (button == GLUT_LEFT_BUTTON ) mouseMode = 4; if (flip14) { if (mouseMode == 4) mouseMode = 1; else if (mouseMode == 1) mouseMode = 4; } } } void motionFunc(int x, int y) { float dClickX = float(clickX - x), dClickY = float(clickY - y); clickX = x; clickY = y; switch (mouseMode) { case 1: g_camera.rotateOrbit(-0.005f*dClickX,0.005f*dClickY); break; case 2: break; case 3: g_camera.dolly(-dClickY); break; case 4: g_camera.rotate(-0.005f*dClickX,0.005f*dClickY); break; } } /*************************************************************************************************/ /* Window control */ /*************************************************************************************************/ void displayFunc(void) { AffineSpace3f pixel2world = g_camera.pixel2world(g_width,g_height); /* render image using ISPC */ double t0 = getSeconds(); render(g_time0-t0, pixel2world.l.vx, pixel2world.l.vy, pixel2world.l.vz, pixel2world.p); double dt0 = getSeconds()-t0; if (g_display) { /* draw pixels to screen */ int* pixels = map(); glRasterPos2i(-1, 1); glPixelZoom(1.0f, -1.0f); glDrawPixels(g_width,g_height,GL_RGBA,GL_UNSIGNED_BYTE,pixels); glutSwapBuffers(); unmap(); } double dt1 = getSeconds()-t0; /* print frame rate */ std::ostringstream stream; stream.setf(std::ios::fixed, std::ios::floatfield); stream.precision(2); stream << "render: "; stream << 1.0f/dt0 << " fps, "; stream << dt0*1000.0f << " ms, "; stream << "display: "; stream << 1.0f/dt1 << " fps, "; stream << dt1*1000.0f << " ms, "; stream << g_width << "x" << g_height << " pixels"; std::cout << stream.str() << std::endl; } void reshapeFunc(int width, int height) { resize(width,height); glViewport(0, 0, width, height); g_width = width; g_height = height; } void idleFunc() { glutPostRedisplay(); } /* initialize GLUT */ void initGlut (const std::string name, const size_t width, const size_t height, const bool fullscreen, const bool mouseMode) { g_width = width; g_height = height; resize(g_width,g_height); g_fullscreen = fullscreen; flip14 = mouseMode; int argc = 0; char** argv = NULL; glutInit(&argc, argv); glutInitWindowSize((GLsizei)g_width, (GLsizei)g_height); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); glutInitWindowPosition(0, 0); g_window = glutCreateWindow(name.c_str()); if (g_fullscreen) glutFullScreen(); glutDisplayFunc(displayFunc); glutIdleFunc(idleFunc); glutKeyboardFunc(keyboardFunc); glutSpecialFunc(specialFunc); glutMouseFunc(clickFunc); glutMotionFunc(motionFunc); glutReshapeFunc(reshapeFunc); glutMainLoop(); } }