From 070051b8759806873267cff46ceb2be7d6a3262f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Constantin=20Ri=C3=9F?= Date: Mon, 1 Mar 2010 23:30:40 +0100 Subject: initial commit --- .gitignore | 12 ++ CMakeLists.txt | 16 ++ Cuboid.cpp | 128 ++++++++++++++ Cuboid.h | 30 ++++ Engine.cpp | 76 +++++++++ Engine.h | 44 +++++ Keys.h | 24 +++ Triangle.h | 59 +++++++ gl.h | 12 ++ main.cpp | 513 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 914 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 Cuboid.cpp create mode 100644 Cuboid.h create mode 100644 Engine.cpp create mode 100644 Engine.h create mode 100644 Keys.h create mode 100644 Triangle.h create mode 100644 gl.h create mode 100644 main.cpp 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 Cuboid::getTriangles() +{ + std::list 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 + +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 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::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 + +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 triangles; + + void run(unsigned long delta, const Keyset &keys); + +}; + +#endif /* ENGINE_H_ */ diff --git a/Keys.h b/Keys.h new file mode 100644 index 0000000..0bdfed4 --- /dev/null +++ b/Keys.h @@ -0,0 +1,24 @@ +/* + * Keys.h + * + * Created on: 10.02.2010 + * Author: constantin + */ + +#ifndef KEYS_H_ +#define KEYS_H_ + +#include + +enum Keys { + KEY_UP = 0, + KEY_DOWN, + KEY_LEFT, + KEY_RIGHT, + + KEY_LAST +}; + +typedef std::bitset 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 +#include + +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_*/ + diff --git a/gl.h b/gl.h new file mode 100644 index 0000000..fb5face --- /dev/null +++ b/gl.h @@ -0,0 +1,12 @@ +#ifndef _GL_H_ +#define _GL_H_ + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#endif + +#include +#include + +#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 + +#ifdef _WIN32 +#else +#include +#include +#include +#include +#include +#include +#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("HEADSHOT"); + chint.res_class = const_cast("HEADSHOT"); + XSetClassHint(disp, *wnd, &chint); + + char *str = const_cast("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(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 -- cgit v1.2.3