Added mouse support to turn
This commit is contained in:
parent
bc797d4c8b
commit
b3b74dc2af
3 changed files with 102 additions and 17 deletions
30
src/Game.cpp
30
src/Game.cpp
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
namespace Zoom {
|
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) {
|
input(0), lightPos(0) {
|
||||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
glClearColor(0.0, 0.0, 0.0, 1.0);
|
||||||
glClearDepth(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");
|
Shader::loadProgram("default.vert", "default.frag");
|
||||||
|
|
||||||
playerRot.rotate_y(-M_PI/6);
|
|
||||||
|
|
||||||
loadLevel("level.xml");
|
loadLevel("level.xml");
|
||||||
triangles.insert(triangles.end(), level->getRooms().front().walls.begin(), level->getRooms().front().walls.end());
|
triangles.insert(triangles.end(), level->getRooms().front().walls.begin(), level->getRooms().front().walls.end());
|
||||||
std::sort(triangles.begin(), triangles.end(), Renderer::TextureSorter());
|
std::sort(triangles.begin(), triangles.end(), Renderer::TextureSorter());
|
||||||
|
@ -76,24 +74,37 @@ bool Game::loadLevel(const std::string &name) {
|
||||||
return level;
|
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) {
|
void Game::run(int delta) {
|
||||||
lightPos += delta;
|
lightPos += delta;
|
||||||
lightPos %= 24000;
|
lightPos %= 24000;
|
||||||
|
|
||||||
playerRot.rotate_y(delta*M_PI/180/40);
|
vmml::vec3f playerMove(vmml::vec3f::ZERO);
|
||||||
|
|
||||||
if(input & FORWARD) {
|
if(input & FORWARD) {
|
||||||
playerPos -= playerRot*vmml::vec3f::UNIT_Z*0.01*delta;
|
playerMove -= playerRotY*vmml::vec3f::UNIT_Z;
|
||||||
}
|
}
|
||||||
if(input & BACKWARD) {
|
if(input & BACKWARD) {
|
||||||
playerPos += playerRot*vmml::vec3f::UNIT_Z*0.01*delta;
|
playerMove += playerRotY*vmml::vec3f::UNIT_Z;
|
||||||
}
|
}
|
||||||
if(input & LEFT) {
|
if(input & LEFT) {
|
||||||
playerPos -= playerRot*vmml::vec3f::UNIT_X*0.01*delta;
|
playerMove -= playerRotY*vmml::vec3f::UNIT_X;
|
||||||
}
|
}
|
||||||
if(input & RIGHT) {
|
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() {
|
void Game::render() {
|
||||||
|
@ -122,7 +133,8 @@ void Game::render() {
|
||||||
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
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.set_translation(playerPos);
|
||||||
transform.inverse(inverse);
|
transform.inverse(inverse);
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ class Game {
|
||||||
this->input = input;
|
this->input = input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void turn(float x, float y);
|
||||||
void run(int delta);
|
void run(int delta);
|
||||||
void render();
|
void render();
|
||||||
|
|
||||||
|
@ -56,7 +57,8 @@ class Game {
|
||||||
std::vector<BSPTree::TriangleRecord> triangles;
|
std::vector<BSPTree::TriangleRecord> triangles;
|
||||||
|
|
||||||
vmml::vec3f playerPos;
|
vmml::vec3f playerPos;
|
||||||
vmml::mat4f playerRot;
|
vmml::mat4f playerRotY;
|
||||||
|
float playerRotX;
|
||||||
|
|
||||||
unsigned input;
|
unsigned input;
|
||||||
|
|
||||||
|
|
85
src/zoom.cpp
85
src/zoom.cpp
|
@ -27,6 +27,7 @@
|
||||||
#else
|
#else
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <X11/X.h>
|
#include <X11/X.h>
|
||||||
|
#include <X11/extensions/XInput2.h>
|
||||||
#include <GL/glx.h>
|
#include <GL/glx.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -64,7 +65,7 @@ bool WGLInit(HINSTANCE hInstance, HWND *hWnd, HDC *hDC, HGLRC *hRC) {
|
||||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||||
wc.hbrBackground = 0;
|
wc.hbrBackground = 0;
|
||||||
wc.lpszMenuName = 0;
|
wc.lpszMenuName = 0;
|
||||||
wc.lpszClassName = "3D";
|
wc.lpszClassName = "Zoom";
|
||||||
|
|
||||||
if (!RegisterClass(&wc)) {
|
if (!RegisterClass(&wc)) {
|
||||||
MessageBox(0, "Failed To Register The Window Class.", "ERROR", MB_OK|MB_ICONEXCLAMATION);
|
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);
|
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);
|
0, 0, windowRect.right-windowRect.left, windowRect.bottom-windowRect.top, 0, 0, hInstance, 0);
|
||||||
if(!*hWnd) {
|
if(!*hWnd) {
|
||||||
MessageBox(0, "Window Creation Error.", "ERROR", MB_OK|MB_ICONEXCLAMATION);
|
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
|
#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,
|
static const int msAttributeList[] = {GLX_RENDER_TYPE, GLX_RGBA_BIT,
|
||||||
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
|
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
|
||||||
GLX_X_RENDERABLE, True,
|
GLX_X_RENDERABLE, True,
|
||||||
|
@ -248,6 +265,9 @@ bool GLXinit(Display *disp, Atom windele, Window *wnd, GLXContext *gc, bool *mul
|
||||||
GLX_DEPTH_SIZE, 1,
|
GLX_DEPTH_SIZE, 1,
|
||||||
None};
|
None};
|
||||||
|
|
||||||
|
if(!XIInit(disp, xi_opcode))
|
||||||
|
return false;
|
||||||
|
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
*multisample = true;
|
*multisample = true;
|
||||||
|
|
||||||
|
@ -276,11 +296,11 @@ bool GLXinit(Display *disp, Atom windele, Window *wnd, GLXContext *gc, bool *mul
|
||||||
vi->visual, CWBorderPixel|CWColormap|CWEventMask, &swa);
|
vi->visual, CWBorderPixel|CWColormap|CWEventMask, &swa);
|
||||||
|
|
||||||
XClassHint chint;
|
XClassHint chint;
|
||||||
chint.res_name = const_cast<char*>("3D");
|
chint.res_name = const_cast<char*>("Zoom");
|
||||||
chint.res_class = const_cast<char*>("3d");
|
chint.res_class = const_cast<char*>("zoom");
|
||||||
XSetClassHint(disp, *wnd, &chint);
|
XSetClassHint(disp, *wnd, &chint);
|
||||||
|
|
||||||
char *str = const_cast<char*>("3D");
|
char *str = const_cast<char*>("Zoom");
|
||||||
XTextProperty name;
|
XTextProperty name;
|
||||||
if(XStringListToTextProperty(&str, 1, &name) != 0)
|
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);
|
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);
|
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);
|
*gc = glXCreateContext(disp, vi, NULL, True);
|
||||||
|
|
||||||
|
@ -317,7 +361,9 @@ int main() {
|
||||||
GLXContext gc;
|
GLXContext gc;
|
||||||
|
|
||||||
bool multisample;
|
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;
|
return 1;
|
||||||
|
|
||||||
glewInit();
|
glewInit();
|
||||||
|
@ -371,6 +417,30 @@ int main() {
|
||||||
case XK_Left: case XK_a: input &= ~Zoom::Game::LEFT; break;
|
case XK_Left: case XK_a: input &= ~Zoom::Game::LEFT; break;
|
||||||
case XK_Right: case XK_d: input &= ~Zoom::Game::RIGHT; 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<XIRawEvent*>(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);
|
XDestroyWindow(disp, wnd);
|
||||||
glXDestroyContext(disp, gc);
|
glXDestroyContext(disp, gc);
|
||||||
XCloseDisplay(disp);
|
XCloseDisplay(disp);
|
||||||
|
|
Reference in a new issue