diff options
-rw-r--r-- | .gitignore | 12 | ||||
-rw-r--r-- | CMakeLists.txt | 16 | ||||
-rw-r--r-- | Cuboid.cpp | 128 | ||||
-rw-r--r-- | Cuboid.h | 30 | ||||
-rw-r--r-- | Engine.cpp | 76 | ||||
-rw-r--r-- | Engine.h | 44 | ||||
-rw-r--r-- | Keys.h | 24 | ||||
-rw-r--r-- | Triangle.h | 59 | ||||
-rw-r--r-- | gl.h | 12 | ||||
-rw-r--r-- | main.cpp | 513 |
10 files changed, 914 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ffb4888 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +/build + +/.project +/.cproject +/.setting + +*.exe +*.layout +*.win +*.dev +*.o +*.dll diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..cdf1ff9 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 2.6) +project(HEADSHOT) + +find_package(OpenGL REQUIRED) + +include_directories(${OPENGL_INCLUDE_DIR}) + +add_executable(headshot + Cuboid.h Cuboid.cpp + Engine.h Engine.cpp + gl.h + Keys.h + main.cpp + Triangle.h +) +target_link_libraries(headshot ${OPENGL_LIBRARIES} cwiid)
\ No newline at end of file diff --git a/Cuboid.cpp b/Cuboid.cpp new file mode 100644 index 0000000..5afae93 --- /dev/null +++ b/Cuboid.cpp @@ -0,0 +1,128 @@ +#include "Cuboid.h" +#include "gl.h" + +Cuboid::Cuboid(float width, float height, float depth) { + setSize(width, height, depth); + setPos(0, 0, 0); +} + +Cuboid::Cuboid(float width, float height, float depth, float x, float y, float z) +{ + setSize(width, height, depth); + setPos(x, y, z); +} + +float Cuboid::getHeight() +{ + return height; +} + +float Cuboid::getWidth() +{ + return width; +} + +float Cuboid::getDepth() +{ + return depth; +} + +float Cuboid::getPosX() +{ + return x; +} + +float Cuboid::getPosY() +{ + return y; +} + +float Cuboid::getPosZ() +{ + return z; +} + +void Cuboid::setSize(float w, float h, float d) +{ + width = w; + height = h; + depth = d; +} + +void Cuboid::setPos(float x, float y, float z) +{ + this->x = x; + this->y = y; + this->z = z; +} + +std::list<Triangle> Cuboid::getTriangles() +{ + std::list<Triangle> triangles; + // width, height, depth + // Front face + vmml::vec4f c(0.0, 0.0, 1.0, 0.5); + + triangles.push_back(Triangle(vmml::vec3f(x-width/2, y+height/2, z+depth/2), + vmml::vec3f(x-width/2, y-height/2, z+depth/2), + vmml::vec3f(x+width/2, y+height/2, z+depth/2), c)); + + triangles.push_back(Triangle(vmml::vec3f(x-width/2, y-height/2, z+depth/2), + vmml::vec3f(x+width/2, y-height/2, z+depth/2), + vmml::vec3f(x+width/2, y+height/2, z+depth/2), c)); + + // Back face + c = vmml::vec4f(1.0, 1.0, 0.0, 0.5); + + triangles.push_back(Triangle(vmml::vec3f(x-width/2, y+height/2, z-depth/2), + vmml::vec3f(x+width/2, y+height/2, z-depth/2), + vmml::vec3f(x-width/2, y-height/2, z-depth/2), c)); + + triangles.push_back(Triangle(vmml::vec3f(x-width/2, y-height/2, z-depth/2), + vmml::vec3f(x+width/2, y+height/2, z-depth/2), + vmml::vec3f(x+width/2, y-height/2, z-depth/2), c)); + + // Left face + c = vmml::vec4f(0.0, 1.0, 0.0, 0.5); + + triangles.push_back(Triangle(vmml::vec3f(x-width/2, y+height/2, z+depth/2), + vmml::vec3f(x-width/2, y+height/2, z-depth/2), + vmml::vec3f(x-width/2, y-height/2, z+depth/2), c)); + + triangles.push_back(Triangle(vmml::vec3f(x-width/2, y-height/2, z-depth/2), + vmml::vec3f(x-width/2, y-height/2, z+depth/2), + vmml::vec3f(x-width/2, y+height/2, z-depth/2), c)); + + // Right face + + triangles.push_back(Triangle(vmml::vec3f(x+width/2, y+height/2, z+depth/2), + vmml::vec3f(x+width/2, y-height/2, z+depth/2), + vmml::vec3f(x+width/2, y+height/2, z-depth/2), c)); + + triangles.push_back(Triangle(vmml::vec3f(x+width/2, y-height/2, z-depth/2), + vmml::vec3f(x+width/2, y+height/2, z-depth/2), + vmml::vec3f(x+width/2, y-height/2, z+depth/2), c)); + + // Top face + c = vmml::vec4f(1.0, 0.0, 0.0, 0.5); + + triangles.push_back(Triangle(vmml::vec3f(x-width/2, y+height/2, z+depth/2), + vmml::vec3f(x+width/2, y+height/2, z+depth/2), + vmml::vec3f(x-width/2, y+height/2, z-depth/2), c)); + + triangles.push_back(Triangle(vmml::vec3f(x+width/2, y+height/2, z+depth/2), + vmml::vec3f(x+width/2, y+height/2, z-depth/2), + vmml::vec3f(x-width/2, y+height/2, z-depth/2), c)); + + // Bottom face + + triangles.push_back(Triangle(vmml::vec3f(x-width/2, y-height/2, z+depth/2), + vmml::vec3f(x-width/2, y-height/2, z-depth/2), + vmml::vec3f(x+width/2, y-height/2, z+depth/2), c)); + + triangles.push_back(Triangle(vmml::vec3f(x+width/2, y-height/2, z+depth/2), + vmml::vec3f(x-width/2, y-height/2, z-depth/2), + vmml::vec3f(x+width/2, y-height/2, z-depth/2), c)); + + return triangles; +} diff --git a/Cuboid.h b/Cuboid.h new file mode 100644 index 0000000..d1c600d --- /dev/null +++ b/Cuboid.h @@ -0,0 +1,30 @@ +#ifndef _CUBOID_H_ +#define _CUBOID_H_ + +#include "Triangle.h" + +#include <list> + +class Cuboid +{ + public: + Cuboid() : width(0), height(0), depth(0), x(0), y(0), z(0) {} + Cuboid(float width, float height, float depth); + Cuboid(float width, float height, float depth, float x, float y, float z); + float getHeight(); + float getWidth(); + float getDepth(); + float getPosX(); + float getPosY(); + float getPosZ(); + void setSize(float w, float h, float d); + void setPos(float x, float y, float z); + std::list<Triangle> getTriangles(); + + private: + float width, height, depth; + float x, y, z; + +}; +#endif /*_CUBOID_H_*/ + diff --git a/Engine.cpp b/Engine.cpp new file mode 100644 index 0000000..20de3e6 --- /dev/null +++ b/Engine.cpp @@ -0,0 +1,76 @@ +/* + * Engine.cpp + * + * Created on: 26.02.2010 + * Author: constantin + */ + +#include "Engine.h" + +Engine::Renderer Engine::render; +const float Engine::PLAYER_SPEED = 3; + +Engine::Engine(): playerPos(vmml::vec3f::ZERO), playerRotY(vmml::mat4f::IDENTITY), playerRotX(0) +{ + //tree = new BSPTree(triangles); +} +Engine::~Engine() { + //delete tree; +} + +void Engine::renderScene(unsigned long delta, const Keyset &keys) { + //run(delta, keys); + static Cuboid cube(1, 1, 1, 0, 0, 0); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glLoadIdentity(); + + glTranslatef(0.0, 0.0, -10.0); // Then set up transformation + glRotatef(0, 1.0, 0.0, 0.0); + glRotatef(0, 0.0, 1.0, 0.0); + + //vmml::mat4f transform, inverseTransform; + //glGetFloatv(GL_MODELVIEW_MATRIX, transform.array); + + //transform.inverse(inverseTransform); + + //vmml::vec3f viewPoint = inverseTransform*vmml::vec3f::ZERO; + + glBegin(GL_TRIANGLES); + //tree->visit(render, viewPoint); + + triangles = cube.getTriangles(); + + for(std::list<Triangle>::iterator t = triangles.begin(); t != triangles.end(); ++t) { + render(*t); + } + glEnd(); + glFlush(); +} + +void Engine::run(unsigned long delta, const Keyset &keys) +{ + vmml::vec3f playerMove(vmml::vec3f::ZERO); + + if(keys.test(KEY_UP)) { + playerMove -= playerRotY*vmml::vec3f::UNIT_Z; + } + if(keys.test(KEY_DOWN)) { + playerMove += playerRotY*vmml::vec3f::UNIT_Z; + } + if(keys.test(KEY_LEFT)) { + playerMove -= playerRotY*vmml::vec3f::UNIT_X; + } + if(keys.test(KEY_RIGHT)) { + playerMove += playerRotY*vmml::vec3f::UNIT_X; + } + + if(playerMove == vmml::vec3f::ZERO) + return; + + playerMove.normalize(); + playerMove *= PLAYER_SPEED*delta/1; + playerPos += playerMove; + +} diff --git a/Engine.h b/Engine.h new file mode 100644 index 0000000..96eab27 --- /dev/null +++ b/Engine.h @@ -0,0 +1,44 @@ +/* + * Engine.h + * + * Created on: 24.02.2010 + * Author: constantin + */ + +#ifndef ENGINE_H_ +#define ENGINE_H_ + +#include "gl.h" +#include "Keys.h" +#include "Triangle.h" +#include "Cuboid.h" +#include <list> + +class Engine +{ + public: + Engine(); + virtual ~Engine(); + + void renderScene(unsigned long delta, const Keyset &keys); + + private: + static const float PLAYER_SPEED; + vmml::vec3f playerPos; + vmml::mat4f playerRotY; + float playerRotX; + + struct Renderer { + void operator() (const Triangle &t) const { + t.render(); + } + }; + static Renderer render; + + std::list<Triangle> triangles; + + void run(unsigned long delta, const Keyset &keys); + +}; + +#endif /* ENGINE_H_ */ @@ -0,0 +1,24 @@ +/* + * Keys.h + * + * Created on: 10.02.2010 + * Author: constantin + */ + +#ifndef KEYS_H_ +#define KEYS_H_ + +#include <bitset> + +enum Keys { + KEY_UP = 0, + KEY_DOWN, + KEY_LEFT, + KEY_RIGHT, + + KEY_LAST +}; + +typedef std::bitset<KEY_LAST> Keyset; + +#endif /* KEYS_H_ */ diff --git a/Triangle.h b/Triangle.h new file mode 100644 index 0000000..5e8a12c --- /dev/null +++ b/Triangle.h @@ -0,0 +1,59 @@ +#ifndef _TRIANGLE_H_ +#define _TRIANGLE_H_ + +#include "gl.h" +#include <vmmlib/vector.hpp> +#include <vmmlib/matrix.hpp> + +class Triangle +{ + public: + Triangle() : c(vmml::vec4f::ONE) { + v[0] = v[1] = v[2] = vmml::vec3f::ZERO; + } + + Triangle(const vmml::vec3f &v1, const vmml::vec3f &v2, const vmml::vec3f &v3, const vmml::vec4f &c0) : c(c0) + { + v[0] = v1; + v[1] = v2; + v[2] = v3; + } + + const vmml::vec3f& getVertex(int i) const {return v[i];} + const vmml::vec4f& getColor() const {return c;} + + vmml::vec3f getNormal() const { + return v[0].compute_normal(v[1], v[2]); + } + + void render() const { + glColor4fv(c.array); + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, c.array); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (c/2).array); + + glNormal3fv(getNormal().array); + + for(int i = 0; i < 3; ++i) + { + glVertex3fv(v[i].array); + } + } + + void transform(const vmml::mat4f &m) { + for(int i = 0; i < 3; ++i) + { + v[i] = m*v[i]; + } + } + + vmml::vec3f getCenter() const { + return (v[0]+v[1]+v[2])/3; + } + + private: + vmml::vec3f v[3]; + vmml::vec4f c; +}; + +#endif /*_TRIANGLE_H_*/ + @@ -0,0 +1,12 @@ +#ifndef _GL_H_ +#define _GL_H_ + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#endif + +#include <GL/gl.h> +#include <GL/glu.h> + +#endif /* _GL_H_ */ diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..2cbe672 --- /dev/null +++ b/main.cpp @@ -0,0 +1,513 @@ +/* + * main.cpp + * + * Created on: 24.02.2010 + * Author: constantin + */ + +#include "gl.h" +#include "Keys.h" +#include "Engine.h" +#include <cwiid.h> + +#ifdef _WIN32 +#else +#include <stdio.h> +#include <iostream> +#include <X11/X.h> +#include <GL/glx.h> +#include <sys/time.h> +#include <unistd.h> +#endif + +#define MIN_FRAME_DELTA 16 +//#define MIN_FRAME_DELTA 41 +#define DEFAULT_WIDTH 640 +#define DEFAULT_HEIGHT 480 + +Keyset keys; + +void initGL(bool multisample); +void resize(int width, int height); + +void initGL(bool multisample) { + glClearColor(0.0, 0.0, 0.0, 1.0); + glClearDepth(1.0); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + +#ifndef _WIN32 + if(multisample) + glEnable(GL_MULTISAMPLE_ARB); +#endif + + resize(DEFAULT_WIDTH, DEFAULT_HEIGHT); + + /*glEnable(GL_LIGHTING); + static const float light[] = {1, 1, 1, 0}; + static const float lightColor[] = {1, 1, 1, 1}; + glLightfv(GL_LIGHT0, GL_POSITION, light); + glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor); + glEnable(GL_LIGHT0);*/ + + //glEnable(GL_CULL_FACE); + //glFrontFace(GL_CCW); +} + +void resize(int width, int height) +{ + if(height==0) + { + height=1; + } + + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(50.0f, (GLfloat)width/(GLfloat)height, 0.1, 1000); + + glMatrixMode(GL_MODELVIEW); + + glViewport(0, 0, width, height); +} + + +#ifdef _WIN32 + +bool WGLInit(HINSTANCE hInstance, HWND *hWnd, HDC *hDC, HGLRC *hRC); +void WGLUninit(HWND hWnd, HDC hDC, HGLRC hRC); +LRESULT CALLBACK wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + +bool WGLInit(HINSTANCE hInstance, HWND *hWnd, HDC *hDC, HGLRC *hRC) { + WNDCLASS wc; + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; + wc.lpfnWndProc = (WNDPROC)wndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = 0; + wc.lpszMenuName = 0; + wc.lpszClassName = "HEADSHOT"; + + if (!RegisterClass(&wc)) + { + MessageBox(0, "Failed To Register The Window Class.", "ERROR", MB_OK|MB_ICONEXCLAMATION); + return false; // Exit And Return FALSE + } + + DWORD dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; + DWORD dwStyle = WS_OVERLAPPEDWINDOW; + + RECT windowRect; + windowRect.left = 0; + windowRect.right = DEFAULT_WIDTH; + windowRect.top = 0; + windowRect.bottom = DEFAULT_HEIGHT; + + AdjustWindowRectEx(&windowRect, dwStyle, FALSE, dwExStyle); + + *hWnd = CreateWindowEx(dwExStyle, "HEADSHOT" /* Class Name */, "HEADSHOT" /* 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); + return false; + } + + static PIXELFORMATDESCRIPTOR pfd = + { + sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor + 1, // Version Number + PFD_DRAW_TO_WINDOW | // Format Must Support Window + PFD_SUPPORT_OPENGL | // Format Must Support OpenGL + PFD_DOUBLEBUFFER, // Must Support Double Buffering + PFD_TYPE_RGBA, // Request An RGBA Format + 16, // Select Our Color Depth + 0, 0, 0, 0, 0, 0, // Color Bits Ignored + 0, // No Alpha Buffer + 0, // Shift Bit Ignored + 0, // No Accumulation Buffer + 0, 0, 0, 0, // Accumulation Bits Ignored + 16, // 16Bit Z-Buffer (Depth Buffer) + 0, // No Stencil Buffer + 0, // No Auxiliary Buffer + PFD_MAIN_PLANE, // Main Drawing Layer + 0, // Reserved + 0, 0, 0 // Layer Masks Ignored + }; + + *hDC=GetDC(*hWnd); + if (!*hDC) + { + WGLUninit(*hWnd, 0, 0); + MessageBox(0, "Can't Create A GL Device Context.", "ERROR", MB_OK|MB_ICONEXCLAMATION); + return false; + } + + GLuint pixelFormat = ChoosePixelFormat(*hDC, &pfd); + if(!pixelFormat) + { + WGLUninit(*hWnd, *hDC, 0); + MessageBox(0, "Can't Find A Suitable PixelFormat.", "ERROR", MB_OK|MB_ICONEXCLAMATION); + return false; + } + + if(!SetPixelFormat(*hDC, pixelFormat, &pfd)) + { + WGLUninit(*hWnd, *hDC, 0); + MessageBox(0, "Can't Set The PixelFormat.", "ERROR", MB_OK|MB_ICONEXCLAMATION); + return false; + } + + *hRC=wglCreateContext(*hDC); + if(!*hRC) + { + WGLUninit(*hWnd, *hDC, 0); + MessageBox(0, "Can't Create A GL Rendering Context.", "ERROR", MB_OK|MB_ICONEXCLAMATION); + return false; + } + + if(!wglMakeCurrent(*hDC, *hRC)) + { + WGLUninit(*hWnd, *hDC, *hRC); + MessageBox(0, "Can't Activate The GL Rendering Context.", "ERROR", MB_OK|MB_ICONEXCLAMATION); + return false; + } + + ShowWindow(*hWnd, SW_SHOW); + SetForegroundWindow(*hWnd); + SetFocus(*hWnd); + + return true; +} + +void WGLUninit(HWND hWnd, HDC hDC, HGLRC hRC) { + wglMakeCurrent(0, 0); + + if(hRC) + wglDeleteContext(hRC); + + if(hDC) + ReleaseDC(hWnd, hDC); + + if(hWnd) + DestroyWindow(hWnd); +} + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) +{ + HWND hWnd = 0; + HDC hDC = 0; + HGLRC hRC = 0; + + if(!WGLInit(hInstance, &hWnd, &hDC, &hRC)) + { + return 0; + } + + initGL(false); + + bool running = true; + MSG msg; + + while(running) + { + unsigned long delta = 0; + unsigned long ticks = GetTickCount(); + + while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + if(msg.message == WM_QUIT) + { + running = false; + break; + } + else // If Not, Deal With Window Messages + { + TranslateMessage(&msg); // Translate The Message + DispatchMessage(&msg); // Dispatch The Message + } + } + + void resize(int width, int height); + + delta = GetTickCount()-ticks; + + if(delta < MIN_FRAME_DELTA) { + Sleep(MIN_FRAME_DELTA - delta); + delta = GetTickCount()-ticks; + } + + ticks += delta; + + static Engine render; + render.renderScene(delta, keys); + SwapBuffers(hDC); + } + + WGLUninit(hWnd, hDC, hRC); + return msg.wParam; +} + +LRESULT CALLBACK wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { + switch(uMsg) { + case WM_CLOSE: + PostQuitMessage(0); + return 0; + + case WM_SIZE: + resize(LOWORD(lParam), HIWORD(lParam)); + return 0; + + case WM_KEYDOWN: + case WM_KEYUP: + bool pressed = (uMsg == WM_KEYDOWN); + + switch(wParam) { + case VK_Escape: + PostQuitMessage(0); + break; + case VK_Up: + case VK_W: + keys.set(KEY_UP, pressed); + break; + + case VK_Left: + case VK_A: + keys.set(KEY_LEFT, pressed); + break; + + case VK_Right: + case VK_D: + keys.set(KEY_RIGHT, pressed); + break; + + case VK_Down: + case VK_S: + keys.set(KEY_DOWN, pressed); + break; + } + + default: + return DefWindowProc(hWnd, uMsg, wParam, lParam); + } +} + +#else + +bool GLXinit(Display *disp, Atom windele, Window *wnd, GLXContext *gc, bool *multisample) { + static const int msAttributeList[] = {GLX_RENDER_TYPE, GLX_RGBA_BIT, + GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, + GLX_X_RENDERABLE, True, + GLX_DOUBLEBUFFER, True, + GLX_DEPTH_SIZE, 1, + GLX_SAMPLE_BUFFERS, 1, + GLX_SAMPLES, 4, + None}; + + static const int attributeList[] = {GLX_RENDER_TYPE, GLX_RGBA_BIT, + GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, + GLX_X_RENDERABLE, True, + GLX_DOUBLEBUFFER, True, + GLX_DEPTH_SIZE, 1, + None}; + + bool ok = false; + *multisample = true; + + int nElements; + GLXFBConfig *fbConfig = glXChooseFBConfig(disp, DefaultScreen(disp), msAttributeList, &nElements); + if(!fbConfig || !nElements) { + if(fbConfig) { + XFree(fbConfig); + } + + *multisample = false; + fbConfig = glXChooseFBConfig(disp, DefaultScreen(disp), attributeList, &nElements); + } + + if(fbConfig && nElements) { + XVisualInfo *vi = glXGetVisualFromFBConfig(disp, *fbConfig); + + if(vi) { + Colormap cmap = XCreateColormap(disp, RootWindow(disp, vi->screen), vi->visual, AllocNone); + XSetWindowAttributes swa; + swa.colormap = cmap; + swa.border_pixel = 0; + swa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask/* | PointerMotionMask | ButtonPressMask | ButtonReleaseMask*/; + + *wnd = XCreateWindow(disp, RootWindow(disp, vi->screen), 0, 0, DEFAULT_WIDTH, DEFAULT_HEIGHT, 0, vi->depth, InputOutput, + vi->visual, CWBorderPixel|CWColormap|CWEventMask, &swa); + + XClassHint chint; + chint.res_name = const_cast<char*>("HEADSHOT"); + chint.res_class = const_cast<char*>("HEADSHOT"); + XSetClassHint(disp, *wnd, &chint); + + char *str = const_cast<char*>("HEADSHOT"); + XTextProperty name; + if(XStringListToTextProperty(&str, 1, &name) != 0) + { + XSetWMName(disp, *wnd, &name); + XFree(name.value); + } + + XSetWMProtocols(disp, *wnd, &windele, 1); + + XMapWindow(disp, *wnd); + + *gc = glXCreateContext(disp, vi, NULL, True); + + glXMakeCurrent(disp, *wnd, *gc); + + ok = true; + + XFree(vi); + } + } + + if(fbConfig) + XFree(fbConfig); + + XSync(disp, 0); + + return ok; +} + +int main(/*int argc, char *argv[]*/) { + cwiid_mesg_callback_t cwiid_callback; + cwiid_wiimote_t *wiimote; /* wiimote handle */ + struct cwiid_state state; /* wiimote state */ + bdaddr_t bdaddr; /* bluetooth device address */ + unsigned char mesg = 0; + unsigned char led_state = 0; + unsigned char rpt_mode = 0; + unsigned char rumble = 0; + bdaddr= *BDADDR_ANY; + + /* Connect to the wiimote */ + printf("Put Wiimote in discoverable mode now (press 1+2)...\n"); + if (!(wiimote = cwiid_connect(&bdaddr, 0))) { + fprintf(stderr, "Unable to connect to wiimote\n"); + return -1; + } + if (cwiid_set_mesg_callback(wiimote, cwiid_callback)) { + fprintf(stderr, "Unable to set message callback\n"); + } + + Display *disp = XOpenDisplay(0); + Atom windele = XInternAtom(disp, "WM_DELETE_WINDOW", False); + Window wnd; + GLXContext gc; + + bool multisample; + if(!GLXinit(disp, windele, &wnd, &gc, &multisample)) + return 1; + initGL(multisample); + + GLint samples; + glGetIntegerv(GL_SAMPLES, &samples); + std::cerr << "Using " << samples << " samples" << std::endl; + + bool running = true; + + unsigned long delta = 0; + unsigned long frames = 0, tocks = 0; + + struct timeval tv; + gettimeofday(&tv, NULL); + unsigned long ticks = tv.tv_usec; + + while(running) { + while(XPending(disp)) { + XEvent event; + XNextEvent(disp, &event); + + switch(event.type) { + case ConfigureNotify: + resize(event.xconfigure.width, event.xconfigure.height); + break; + + case ClientMessage: + if(static_cast<Atom>(event.xclient.data.l[0]) == windele) + running = false; + break; + + case KeyPress: + case KeyRelease: + KeySym keysym = XKeycodeToKeysym(disp, event.xkey.keycode, 0); + bool pressed = (event.type == KeyPress); + + switch(keysym) { + case XK_Escape: + running = false; + break; + case XK_Up: + case XK_w: + keys.set(KEY_UP, pressed); + break; + + case XK_Left: + case XK_a: + keys.set(KEY_LEFT, pressed); + break; + + case XK_Right: + case XK_d: + keys.set(KEY_RIGHT, pressed); + break; + + case XK_Down: + case XK_s: + keys.set(KEY_DOWN, pressed); + break; + } + } + } + + if(!running) break; + + static Engine render; + render.renderScene(delta, keys); + + glXSwapBuffers(disp, wnd); + XSync(disp, 0); + + long slept = 0; + gettimeofday(&tv, NULL); + delta = ((tv.tv_usec + 1000000 - ticks)%1000000)/1000; + + if(delta < MIN_FRAME_DELTA) { + usleep((MIN_FRAME_DELTA-delta)*1000); + slept += (MIN_FRAME_DELTA-delta); + + gettimeofday(&tv, NULL); + delta = ((tv.tv_usec + 1000000 - ticks)%1000000)/1000; + } + + ticks = (ticks + delta*1000) % 1000000; + + frames++; + tocks += delta*1000; + if(tocks > 1000000) { + std::cerr << frames << " fps; slept a total of " << slept << " ms" << std::endl; + frames = 0; + tocks -= 1000000; + slept = 0; + } + } + + XDestroyWindow(disp, wnd); + glXDestroyContext(disp, gc); + XCloseDisplay(disp); + cwiid_disconnect(wiimote); + + return 0; +} + +#endif |