From b3b74dc2afe4c67a6b74c2a681aa7bbad7077511 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 17 Dec 2009 19:12:13 +0100 Subject: Added mouse support to turn --- src/Game.cpp | 30 ++++++++++++++------- src/Game.h | 4 ++- src/zoom.cpp | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 102 insertions(+), 17 deletions(-) diff --git a/src/Game.cpp b/src/Game.cpp index 8f5af26..93b13c4 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -29,7 +29,7 @@ namespace Zoom { -Game::Game(bool multisample) : playerPos(vmml::vec3f::ZERO), playerRot(vmml::mat4f::IDENTITY), +Game::Game(bool multisample) : playerPos(vmml::vec3f::ZERO), playerRotY(vmml::mat4f::IDENTITY), playerRotX(0), input(0), lightPos(0) { glClearColor(0.0, 0.0, 0.0, 1.0); glClearDepth(1.0); @@ -63,8 +63,6 @@ Game::Game(bool multisample) : playerPos(vmml::vec3f::ZERO), playerRot(vmml::mat Shader::loadProgram("default.vert", "default.frag"); - playerRot.rotate_y(-M_PI/6); - loadLevel("level.xml"); triangles.insert(triangles.end(), level->getRooms().front().walls.begin(), level->getRooms().front().walls.end()); std::sort(triangles.begin(), triangles.end(), Renderer::TextureSorter()); @@ -76,24 +74,37 @@ bool Game::loadLevel(const std::string &name) { return level; } +void Game::turn(float x, float y) { + playerRotY.rotate_y(-x*M_PI/180/10); + + playerRotX -= y*M_PI/180/10; + if(playerRotX > M_PI_2) + playerRotX = M_PI_2; + else if(playerRotX < -M_PI_2) + playerRotX = -M_PI_2; +} + void Game::run(int delta) { lightPos += delta; lightPos %= 24000; - playerRot.rotate_y(delta*M_PI/180/40); + vmml::vec3f playerMove(vmml::vec3f::ZERO); if(input & FORWARD) { - playerPos -= playerRot*vmml::vec3f::UNIT_Z*0.01*delta; + playerMove -= playerRotY*vmml::vec3f::UNIT_Z; } if(input & BACKWARD) { - playerPos += playerRot*vmml::vec3f::UNIT_Z*0.01*delta; + playerMove += playerRotY*vmml::vec3f::UNIT_Z; } if(input & LEFT) { - playerPos -= playerRot*vmml::vec3f::UNIT_X*0.01*delta; + playerMove -= playerRotY*vmml::vec3f::UNIT_X; } if(input & RIGHT) { - playerPos += playerRot*vmml::vec3f::UNIT_X*0.01*delta; + playerMove += playerRotY*vmml::vec3f::UNIT_X; } + + playerMove.normalize(); + playerPos += playerMove*0.01*delta; } void Game::render() { @@ -122,7 +133,8 @@ void Game::render() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - vmml::mat4f transform(playerRot), inverse; + vmml::mat4f transform(playerRotY), inverse; + transform.rotate_x(playerRotX); transform.set_translation(playerPos); transform.inverse(inverse); diff --git a/src/Game.h b/src/Game.h index d935b7c..f6b775b 100644 --- a/src/Game.h +++ b/src/Game.h @@ -46,6 +46,7 @@ class Game { this->input = input; } + void turn(float x, float y); void run(int delta); void render(); @@ -56,7 +57,8 @@ class Game { std::vector triangles; vmml::vec3f playerPos; - vmml::mat4f playerRot; + vmml::mat4f playerRotY; + float playerRotX; unsigned input; diff --git a/src/zoom.cpp b/src/zoom.cpp index e5b0978..e0050c5 100644 --- a/src/zoom.cpp +++ b/src/zoom.cpp @@ -27,6 +27,7 @@ #else #include #include +#include #include #include #include @@ -64,7 +65,7 @@ bool WGLInit(HINSTANCE hInstance, HWND *hWnd, HDC *hDC, HGLRC *hRC) { wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = 0; wc.lpszMenuName = 0; - wc.lpszClassName = "3D"; + wc.lpszClassName = "Zoom"; if (!RegisterClass(&wc)) { MessageBox(0, "Failed To Register The Window Class.", "ERROR", MB_OK|MB_ICONEXCLAMATION); @@ -82,7 +83,7 @@ bool WGLInit(HINSTANCE hInstance, HWND *hWnd, HDC *hDC, HGLRC *hRC) { AdjustWindowRectEx(&windowRect, dwStyle, FALSE, dwExStyle); - *hWnd = CreateWindowEx(dwExStyle, "3D" /* Class Name */, "3D" /* Title*/, WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dwStyle, + *hWnd = CreateWindowEx(dwExStyle, "Zoom" /* Class Name */, "Zoom" /* Title*/, WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dwStyle, 0, 0, windowRect.right-windowRect.left, windowRect.bottom-windowRect.top, 0, 0, hInstance, 0); if(!*hWnd) { MessageBox(0, "Window Creation Error.", "ERROR", MB_OK|MB_ICONEXCLAMATION); @@ -231,7 +232,23 @@ LRESULT CALLBACK wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { #else -bool GLXinit(Display *disp, Atom windele, Window *wnd, GLXContext *gc, bool *multisample) { +bool XIInit(Display *disp, int *opcode) { + int event, error; + if (!XQueryExtension(disp, "XInputExtension", opcode, &event, &error)) { + std::cerr << "X Input extension not available." << std::endl; + return false; + } + + int major = 2, minor = 0; + if (XIQueryVersion(disp, &major, &minor) == BadRequest) { + std::cerr << "XI2 not available. Server supports " << major << "." << minor << std::endl; + return false; + } + + return true; +} + +bool GLXinit(Display *disp, Atom windele, Window *wnd, GLXContext *gc, bool *multisample, int *xi_opcode, int *pointer) { static const int msAttributeList[] = {GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, GLX_X_RENDERABLE, True, @@ -248,6 +265,9 @@ bool GLXinit(Display *disp, Atom windele, Window *wnd, GLXContext *gc, bool *mul GLX_DEPTH_SIZE, 1, None}; + if(!XIInit(disp, xi_opcode)) + return false; + bool ok = false; *multisample = true; @@ -276,11 +296,11 @@ bool GLXinit(Display *disp, Atom windele, Window *wnd, GLXContext *gc, bool *mul vi->visual, CWBorderPixel|CWColormap|CWEventMask, &swa); XClassHint chint; - chint.res_name = const_cast("3D"); - chint.res_class = const_cast("3d"); + chint.res_name = const_cast("Zoom"); + chint.res_class = const_cast("zoom"); XSetClassHint(disp, *wnd, &chint); - char *str = const_cast("3D"); + char *str = const_cast("Zoom"); XTextProperty name; if(XStringListToTextProperty(&str, 1, &name) != 0) { @@ -290,7 +310,31 @@ bool GLXinit(Display *disp, Atom windele, Window *wnd, GLXContext *gc, bool *mul XSetWMProtocols(disp, *wnd, &windele, 1); + XColor color; + color.pixel = WhitePixel(disp, vi->screen); + XQueryColor(disp, cmap, &color); + Pixmap pixmap = XCreatePixmap(disp, *wnd, 1, 1, 1); + Cursor cursor = XCreatePixmapCursor(disp, pixmap, pixmap, &color, &color, 0, 0); + XSync(disp, False); + + XFreePixmap(disp, pixmap); + XMapWindow(disp, *wnd); + XSync(disp, False); + + XIGetClientPointer(disp, *wnd, pointer); + + XIEventMask eventmask; + unsigned char mask[4] = {0}; + + eventmask.deviceid = 2; + eventmask.mask_len = sizeof(mask); + eventmask.mask = mask; + /*XISetMask(mask, XI_ButtonPress); + XISetMask(mask, XI_Motion); + XISetMask(mask, XI_KeyPress);*/ + XISetMask(mask, XI_RawMotion); + XIGrabDevice(disp, *pointer, *wnd, CurrentTime, cursor, GrabModeAsync, GrabModeAsync, True, &eventmask); *gc = glXCreateContext(disp, vi, NULL, True); @@ -317,7 +361,9 @@ int main() { GLXContext gc; bool multisample; - if(!GLXinit(disp, windele, &wnd, &gc, &multisample)) + int xi_opcode; + int pointer; + if(!GLXinit(disp, windele, &wnd, &gc, &multisample, &xi_opcode, &pointer)) return 1; glewInit(); @@ -371,6 +417,30 @@ int main() { case XK_Left: case XK_a: input &= ~Zoom::Game::LEFT; break; case XK_Right: case XK_d: input &= ~Zoom::Game::RIGHT; break; } + break; + + case GenericEvent: + if(event.xcookie.extension == xi_opcode && XGetEventData(disp, &event.xcookie)) { + XIRawEvent *rawEvent = reinterpret_cast(event.xcookie.data); + + float deltaX = 0, deltaY = 0; + double *rawValuator = rawEvent->raw_values; + + if(XIMaskIsSet(rawEvent->valuators.mask, 0)) { + deltaX = (float)*rawValuator; + ++rawValuator; + } + + if(XIMaskIsSet(rawEvent->valuators.mask, 1)) { + deltaY = (float)*rawValuator; + ++rawValuator; + } + + if(deltaX != 0 || deltaY != 0) + game.turn(deltaX, deltaY); + + XFreeEventData(disp, &event.xcookie); + } } } @@ -407,6 +477,7 @@ int main() { } } + XIUngrabDevice(disp, pointer, CurrentTime); XDestroyWindow(disp, wnd); glXDestroyContext(disp, gc); XCloseDisplay(disp); -- cgit v1.2.3