#include #include #include #include #include "../mapviewer.h" #include "glx.h" using namespace std; #define SENSITIVITY 500 int isLDown; int isRDown; int isShiftDown; int isCtrlDown; int ox, oy; int mx, my; GL_Window window; Bool done; int selector = 0; int attrListSgl[] = { GLX_RGBA, GLX_RED_SIZE, 4, GLX_GREEN_SIZE, 4, GLX_BLUE_SIZE, 4, GLX_DEPTH_SIZE, 16, GLX_STENCIL_SIZE, 8, None }; int attrListDbl[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 4, GLX_GREEN_SIZE, 4, GLX_BLUE_SIZE, 4, GLX_STENCIL_SIZE, 8, None }; void Resize(int width, int height) { glViewport(0, 0, (GLsizei)(width), (GLsizei)(height)); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(Camera.GetFOV(), (GLfloat)(width)/(GLfloat)(height), 1.0f, Sky.GetFarClp()); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } bool CreateWindowGL(char *progname) { XVisualInfo *vi; Colormap cmap; int dpyWidth, dpyHeight; int i; int glxMajorVersion, glxMinorVersion; int vidModeMajorVersion, vidModeMinorVersion; XF86VidModeModeInfo **modes; int modeNum; int bestMode; Atom wmDelete; Window winDummy; unsigned int borderDummy; int x, y; bestMode = 0; window.init.dpy = XOpenDisplay(NULL); window.init.screen = DefaultScreen(window.init.dpy); XF86VidModeQueryVersion(window.init.dpy, &vidModeMajorVersion, &vidModeMinorVersion); XF86VidModeGetAllModeLines(window.init.dpy, window.init.screen, &modeNum, &modes); window.init.deskMode = *modes[0]; for (i = 0; i < modeNum; i++) { if ((modes[i]->hdisplay == window.init.width) && (modes[i]->vdisplay == window.init.height)) bestMode = i; } vi = glXChooseVisual(window.init.dpy, window.init.screen,attrListDbl); if (vi == NULL) { vi = glXChooseVisual(window.init.dpy, window.init.screen, attrListSgl); window.init.doubleBuffered = false; } else { window.init.doubleBuffered = true; } glXQueryVersion(window.init.dpy, &glxMajorVersion, &glxMinorVersion); window.init.ctx = glXCreateContext(window.init.dpy, vi, 0, GL_TRUE); cmap = XCreateColormap(window.init.dpy, RootWindow(window.init.dpy, vi->screen), vi->visual, AllocNone); window.init.attr.colormap = cmap; window.init.attr.border_pixel = 0; if (window.init.isFullScreen) { XF86VidModeSwitchToMode(window.init.dpy, window.init.screen, modes[bestMode]); XF86VidModeSetViewPort(window.init.dpy, window.init.screen, 0, 0); dpyWidth = modes[bestMode]->hdisplay; dpyHeight = modes[bestMode]->vdisplay; XFree(modes); window.init.attr.override_redirect = true; window.init.attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | StructureNotifyMask | PointerMotionMask; window.init.win = XCreateWindow(window.init.dpy, RootWindow(window.init.dpy, vi->screen), 0, 0, dpyWidth, dpyHeight, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &window.init.attr); XWarpPointer(window.init.dpy, None, window.init.win, 0, 0, 0, 0, 0, 0); XMapRaised(window.init.dpy, window.init.win); XGrabKeyboard(window.init.dpy, window.init.win, True, GrabModeAsync, GrabModeAsync, CurrentTime); XGrabPointer(window.init.dpy, window.init.win, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, window.init.win, None, CurrentTime); } else { window.init.attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | StructureNotifyMask | PointerMotionMask; window.init.win = XCreateWindow(window.init.dpy, RootWindow(window.init.dpy, vi->screen), 0, 0, window.init.width, window.init.height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &window.init.attr); wmDelete = XInternAtom(window.init.dpy, "WM_DELETE_WINDOW", True); XSetWMProtocols(window.init.dpy, window.init.win, &wmDelete, 1); XSetStandardProperties(window.init.dpy, window.init.win, window.init.title, window.init.title, None, NULL, 0, NULL); XMapRaised(window.init.dpy, window.init.win); } glXMakeCurrent(window.init.dpy, window.init.win, window.init.ctx); XGetGeometry(window.init.dpy, window.init.win, &winDummy, &x, &y, &window.init.width, &window.init.height, &borderDummy, &window.init.depth); return true; } void KillGlWindow() { if (window.init.ctx) { glXMakeCurrent(window.init.dpy, None, NULL); glXDestroyContext(window.init.dpy, window.init.ctx); } if (window.init.isFullScreen) { XF86VidModeSwitchToMode( window.init.dpy, window.init.screen, &window.init.deskMode); XF86VidModeSetViewPort(window.init.dpy, window.init.screen, 0, 0); } XCloseDisplay(window.init.dpy); } void CGLView::SwapBuffers() { glXSwapBuffers(window.init.dpy, window.init.win); } void Keyrelease(int key) { switch (key) { case XK_Shift_L: case XK_Shift_R: isShiftDown = 0; break; case XK_Control_L: case XK_Control_R: isCtrlDown = 0; break; default: break; } } void Keypress(int key) { // GLfloat phi = M_PI/32; int tmp; GLfloat dist; if (isShiftDown) dist = 8; else if (isCtrlDown) dist = 1; else dist = 4; switch (key) { case XK_Up: planey += dist; break; case XK_Down: planey -= dist; break; case XK_Left: planex += dist; break; case XK_Right: planex -= dist; break; case XK_bracketright: Camera.ChangeFOV(1.0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(Camera.GetFOV(), (GLfloat)(GLView.getWidth())/ (GLfloat)(GLView.getHeight()), 1.0f, Sky.GetFarClp()); glMatrixMode(GL_MODELVIEW); break; case XK_bracketleft: Camera.ChangeFOV(-1.0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(Camera.GetFOV(), (GLfloat)(GLView.getWidth())/ (GLfloat)(GLView.getHeight()), 1.0f, Sky.GetFarClp()); glMatrixMode(GL_MODELVIEW); break; case XK_n: if (isShiftDown) planescale -= 0.1; else planescale += 0.1; break; case XK_m: cout << "Enter length of Minute in Milliseconds: " << flush; cin >> tmp; Game.SetMinuteLength(tmp); break; case XK_o: GLView.MakeScreenshot(); break; case XK_p: printf("%f %f %f\n", planex, planey, planescale); break; case XK_Page_Up: Camera.MoveUpDown(dist); break; case XK_Page_Down: Camera.MoveUpDown(-dist); break; case XK_w: Camera.MoveForwardBackward(dist); break; case XK_s: Camera.MoveForwardBackward(-dist); break; case XK_a: Camera.StrafeLeftRight(dist); break; case XK_d: Camera.StrafeLeftRight(-dist); break; case XK_e: if (isShiftDown) Camera.IncreaseEyeDist(0.1); else Camera.DecreaseEyeDist(0.1); break; case XK_i: if (isShiftDown) World.SetInterior(World.GetInterior()-1); else World.SetInterior(World.GetInterior()+1); cout << "Interior: " << World.GetInterior() << endl; break; case XK_h: if (isShiftDown) Clock.TurnBackOneHour(); else Clock.AdvanceOneHour(); cout << "Time: " << Clock.GetHour() << ":" << Clock.GetMinute() << endl; break; case XK_g: if (isShiftDown) Clock.TurnBackOneMinute(); else Clock.AdvanceOneMinute(); cout << "Time: " << Clock.GetHour() << ":" << Clock.GetMinute() << endl; break; case XK_u: if (isShiftDown) Sky.PreviousWeather(); else Sky.NextWeather(); cout << "Weather: " << Sky.GetWeatherSelector() << endl; break; case XK_l: if (isShiftDown) World.SetLODmultiplier(World.GetLODmultiplier()-0.05); else World.SetLODmultiplier(World.GetLODmultiplier()+0.05); break; case XK_t: GLView.ToggleTextures(); break; case XK_v: GLView.ToggleVertexColors(); break; case XK_y: GLView.ToggleTint(); break; case XK_k: Game.ToggleTime(); break; case XK_f: GLView.ToggleFog(); break; case XK_c: GLView.ToggleStereo(); break; case XK_r: GLView.ToggleRadar(); break; case XK_j: GLView.ToggleCulling(); break; case XK_q: GLView.ToggleWire(); break; case XK_Shift_L: case XK_Shift_R: isShiftDown = 1; break; case XK_Control_L: case XK_Control_R: isCtrlDown = 1; break; case XK_F1: case XK_F2: case XK_F3: case XK_F4: case XK_F5: case XK_F6: case XK_F7: case XK_F8: case XK_F9: case XK_F10: case XK_F11: case XK_F12: if (isShiftDown) Camera.SavePosition(key-XK_F1); else Camera.LoadPosition(key-XK_F1); break; // window.init.isFullScreen = !window.init.isFullScreen; // CreateWindowGL(progname); case XK_Escape: done = true; break; default: break; } } int CGLView::getWidth() { return window.init.width; } int CGLView::getHeight() { return window.init.height; } void CGLView::StartOgl(int argc, char *argv[]) { XEvent event; Keys keys; KeySym key; int time, oldtime; window.keys = &keys; window.init.title = progname; window.init.width = 850; window.init.height = 480; window.init.depth = 32; window.init.isFullScreen = false; done = false; if (CreateWindowGL(progname) == false) exit(2); if (ViewMode == GAME) Game.Init(); else Viewer.Init(); oldtime = clock(); while (!done) { time = clock(); while (XPending(window.init.dpy) > 0) { XNextEvent( window.init.dpy, &event); switch (event.type) { case Expose: if (event.xexpose.count != 0) break; RenderScene(); break; case ConfigureNotify: if (((unsigned int) event.xconfigure.width != window.init.width) || ((unsigned int) event.xconfigure.height != window.init.height)) { window.init.width = event.xconfigure.width; window.init.height = event.xconfigure.height; Resize(window.init.width, window.init.height); } break; case ButtonPress: switch(event.xbutton.button) { case 1: mx = event.xbutton.x; my = event.xbutton.y; isLDown = 1; break; case 3: isRDown = 1; break; default: break; } break; case ButtonRelease: switch(event.xbutton.button) { case 1: isLDown = 0; break; case 3: isRDown = 0; break; case 5: break; case 6: break; default: break; } break; case MotionNotify: if (isLDown) { ox = mx; oy = my; mx = event.xbutton.x; my = event.xbutton.y; Camera.TurnLeftRight((float)(ox-mx) / (float)SENSITIVITY); Camera.TurnUpDown((float)(oy-my) / (float)SENSITIVITY); /* camtheta += (float)(ox-mx) / (float)SENSITIVITY; camphi += (float)(oy-my) / (float)SENSITIVITY; */ // CamCalcVector(); } break; case KeyPress: key = XLookupKeysym(&event.xkey, 0); Keypress(key); break; case KeyRelease: key = XLookupKeysym(&event.xkey, 0); Keyrelease(key); break; case ClientMessage: if (*XGetAtomName(window.init.dpy, event.xclient.message_type)==*"WM_PROTOCOLS") done = true; break; default: break; } } // if ((time - oldtime) > CLOCKS_PER_SEC/30) { UpdateScene((time - oldtime) * 1000/CLOCKS_PER_SEC); // oldtime = time; // } else RenderScene(); oldtime = time; } KillGlWindow(); }