Libraries needed: OpenGL32.lib glu32.lib dxguid.lib dinput.lib dinput8.lib
Input.h
#ifndef H_INPUT#define H_INPUT#include <dinput.h>#include "glheaders.h"#include "point.h"class Input{public: explicit Input() : mouse_x(), mouse_y() { Init(); } ~Input(); void Update(); Point2d<long> mousePos() const { return Point2d<long>(mouse_x, mouse_y); } bool leftUp() const { return !mouse_data.rgbButtons[0] && last_mouse.rgbButtons[0]; } bool rightUp() const { return !mouse_data.rgbButtons[1] && last_mouse.rgbButtons[1]; } bool leftDown() const { return mouse_data.rgbButtons[0] && !last_mouse.rgbButtons[0]; } bool rightDown() const { return mouse_data.rgbButtons[1] && !last_mouse.rgbButtons[1]; } bool rightClick() const { return mouse_data.rgbButtons[1]; } bool leftClick() const { return mouse_data.rgbButtons[0]; } float xDrag() const { if(rightClick()) return xMove(); else return 0.0f; } float yDrag() const { if(rightClick()) return yMove(); else return 0.0f; } float xMove() const { return static_cast<float>(mouse_data.lX); } float yMove() const { return static_cast<float>(mouse_data.lY); } float xMouse() const { return static_cast<float>(mouse_x); } float yMouse() const { return static_cast<float>(mouse_y); } char key(const char c) const { return keys[c]; } char keyDown(const char c) const { return (keys[c] && !last_keys[c]); } char keyUp(const char c) const { return (!keys[c] && last_keys[c]); }private: bool Init(); void KillInput(); char last_keys[256]; char keys[256]; DIMOUSESTATE last_mouse; DIMOUSESTATE mouse_data; long mouse_x; long mouse_y; LPDIRECTINPUT8 lpdi; LPDIRECTINPUTDEVICE8 keyboard_device; LPDIRECTINPUTDEVICE8 mouse_device;};#endif
Input.cpp
#include "input.h"Input::~Input(){ KillInput();}bool Input::Init(){ HWND hWnd = GetForegroundWindow(); for(int i = 0; i < sizeof(keys); i++) { keys = 0; last_keys = 0; } lpdi = 0; keyboard_device = 0; mouse_device = 0; HRESULT hr = DirectInput8Create(GetModuleHandle(0), DIRECTINPUT_VERSION, IID_IDirectInput8, reinterpret_cast<LPVOID*>(&lpdi), 0); if(FAILED(hr)) { MessageBox(0, "DirectInput8Create() failed miserably.", "IT CAN'T BE, BUT IT IS!", MB_OK); return false; } hr = lpdi->CreateDevice(GUID_SysKeyboard, &keyboard_device, 0); if(FAILED(hr)) { MessageBox(0, "createdevice", ".", MB_OK); KillInput(); return false; } hr = keyboard_device->SetDataFormat(&c_dfDIKeyboard); if(FAILED(hr)) { MessageBox(0, "setdataformat", ".", MB_OK); KillInput(); return false; } hr = keyboard_device->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE); if(FAILED(hr)) { MessageBox(0, "set co-op level failed", ".", MB_OK); KillInput(); return false; } if(keyboard_device) { hr = keyboard_device->Acquire(); if(FAILED(hr)) { MessageBox(0, "initial keyboard acquire", "!", MB_OK); KillInput(); return false; } } hr = lpdi->CreateDevice(GUID_SysMouse, &mouse_device, 0); if(FAILED(hr)) { KillInput(); return false; } hr = mouse_device->SetDataFormat(&c_dfDIMouse); if(FAILED(hr)) { KillInput(); return false; } hr = mouse_device->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_EXCLUSIVE); if(FAILED(hr)) { KillInput(); return false; } /*DIPROPDWORD dipdw; dipdw.diph.dwSize = sizeof(DIPROPDWORD); dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); dipdw.diph.dwObj = 0; dipdw.diph.dwHow = DIPH_DEVICE; dipdw.dwData = DIPROPAXISMODE_ABS; hr = mouse_device->SetProperty(DIPROP_AXISMODE, &dipdw.diph); if(FAILED(hr)) { KillInput(); return false; }*/ if(mouse_device) { if(FAILED(mouse_device->Acquire())) { MessageBox(0, "initial mouse acquire", "!", MB_OK); KillInput(); return false; } } return true;}void Input::KillInput(){ if(keyboard_device) keyboard_device->Unacquire(); if(keyboard_device) keyboard_device->Release(); if(mouse_device) mouse_device->Unacquire(); if(mouse_device) mouse_device->Release(); if(lpdi) lpdi->Release();}void Input::Update(){ HRESULT hr = 0; for(int i = 0; i < sizeof(keys); i++) { last_keys = keys; } hr = keyboard_device->GetDeviceState(sizeof(keys), static_cast<LPVOID>(&keys)); if(FAILED(hr)) { if(FAILED(keyboard_device->Acquire())) { MessageBox(0, "Keyboard died.", "F1 F1!", MB_OK); PostQuitMessage(0); return; } keyboard_device->GetDeviceState(256, static_cast<LPVOID>(&keys)); } last_mouse = mouse_data; hr = mouse_device->GetDeviceState(sizeof(mouse_data), static_cast<LPVOID>(&mouse_data)); if(FAILED(hr)) { if(FAILED(mouse_device->Acquire())) { MessageBox(0, "Mouse died.", "F1 F1!", MB_OK); PostQuitMessage(0); return; } mouse_device->GetDeviceState(sizeof(mouse_data), static_cast<LPVOID>(&mouse_data)); } mouse_x += mouse_data.lX; mouse_y += mouse_data.lY; if(mouse_x > 800) mouse_x = 800; if(mouse_x < 0) mouse_x = 0; if(mouse_y > 600) mouse_y = 600; if(mouse_y < 0) mouse_y = 0;}
Window.h
#ifndef H_WINDOW#define H_WINDOW#define WIN32_LEAN_AND_MEAN#include <windows.h>#include <string>#include "glheaders.h"class OGLWindow{public: OGLWindow(); OGLWindow(int, int, int, bool, WNDPROC); ~OGLWindow(); HWND GetHWND() const { return hWnd; } HDC GetHDC() const { return hDC; } int GetWidth() const { return current_width; } int GetHeight() const { return current_height; } int GetBits() const { return current_bits; } bool GetFullscreen() const { return current_fullscreen; } void SetWidth(int w) { width = w; } void SetHeight(int h) { height = h; } void SetBits(int b) { bits = b; } void SetFullscreen(bool f) { fullscreen = f; } bool BuildWindow();private: HDC hDC; HGLRC hRC; HWND hWnd; WNDPROC WndPrc; int width; int height; int bits; bool fullscreen; int current_width; int current_height; int current_bits; bool current_fullscreen; bool SetupOpenGL(); bool SetFS(bool&); void KillWindow(); void InitGL();};#endif
Window.cpp
#include <memory>#include "window.h"OGLWindow::OGLWindow() : width(), height(), bits(), fullscreen(), WndPrc(){}OGLWindow::OGLWindow(int w, int h, int b, bool f, WNDPROC wp) : width(w), height(h), bits(b), fullscreen(f), WndPrc(wp){ hDC = 0; hRC = 0; if(!BuildWindow()) { MessageBox(0, "build window", "s", MB_OK); }}OGLWindow::~OGLWindow(){ KillWindow();}void OGLWindow::InitGL(){ glViewport(0, 0, width, height); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClearDepth(1.0); glDepthFunc(GL_LESS); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE); glEnable(GL_DEPTH_TEST); glShadeModel(GL_SMOOTH); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0f, (float)width, (float)height, 0.0f, -4.0f, 4.0f); glMatrixMode(GL_MODELVIEW);}bool OGLWindow::SetFS(bool& fs){ DEVMODE dmScreenSettings; std::uninitialized_fill_n(&dmScreenSettings, 1, DEVMODE()); dmScreenSettings.dmSize=sizeof(dmScreenSettings); dmScreenSettings.dmPelsWidth = width; dmScreenSettings.dmPelsHeight = height; dmScreenSettings.dmBitsPerPel = bits; dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL) { if (MessageBox(NULL,"No fullscreen for this mode!","YOUR FAULT",MB_YESNO|MB_ICONEXCLAMATION)==IDYES) { fs=false; } else { return false; } } return true;}bool OGLWindow::SetupOpenGL(){ unsigned int PixelFormat; static PIXELFORMATDESCRIPTOR pfd= // pfd Tells Windows How We Want Things To Be { 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 current_bits, // 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 }; if (!(hDC=GetDC(hWnd))) { KillWindow(); MessageBox(NULL,"Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION); return false; } if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd))) { KillWindow(); MessageBox(NULL,"Can't Find A Suitable PixelFormat.","PIXELS ARE EVERYTHING",MB_OK|MB_ICONEXCLAMATION); return false; } if(!SetPixelFormat(hDC,PixelFormat,&pfd)) { KillWindow(); MessageBox(NULL,"Can't Set The PixelFormat.","OH LORDY",MB_OK|MB_ICONEXCLAMATION); return false; } if (!(hRC=wglCreateContext(hDC))) { KillWindow(); MessageBox(NULL,"Can't Create A GL Rendering Context.","UNGODLY ERROR",MB_OK|MB_ICONEXCLAMATION); return false; } if(!wglMakeCurrent(hDC,hRC)) { KillWindow(); MessageBox(NULL,"Can't Activate The GL Rendering Context.","HORRIBLE ERROR",MB_OK|MB_ICONEXCLAMATION); return false; } InitGL(); return true;}bool OGLWindow::BuildWindow(){ DWORD dwExStyle = 0; DWORD dwStyle = 0; WNDCLASSEX wndclassx; RECT WndRect; WndRect.left = static_cast<long>(0); WndRect.right = static_cast<long>(width); WndRect.top = static_cast<long>(0); WndRect.bottom = static_cast<long>(height); HINSTANCE hInstance = GetModuleHandle(0); wndclassx.cbSize = sizeof(wndclassx); wndclassx.style = CS_HREDRAW | CS_VREDRAW; wndclassx.lpfnWndProc = WndPrc; wndclassx.cbClsExtra = 0; wndclassx.cbWndExtra = 0; wndclassx.hInstance = hInstance; wndclassx.hCursor = LoadCursor(0, IDC_ARROW); wndclassx.hIcon = LoadIcon(0, IDI_WINLOGO); wndclassx.hIconSm = LoadIcon(0, IDI_WINLOGO); wndclassx.hbrBackground = 0; wndclassx.lpszClassName = "^_^"; wndclassx.lpszMenuName = 0; if(!RegisterClassEx(&wndclassx)) { MessageBox(0, "RegisterClassEx() failed :-(", "HORRIBLE ERROR!", MB_OK); return false; } if(fullscreen) { if(!(SetFS(fullscreen))) { return false; } } if(fullscreen) { // still fullscreen? dwExStyle = WS_EX_APPWINDOW; dwStyle = WS_POPUP; ShowCursor(true); } else { dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; dwStyle = WS_CAPTION | WS_SYSMENU; } AdjustWindowRectEx(&WndRect, dwStyle, 0, dwExStyle); hWnd = CreateWindowEx(dwExStyle, "^_^", "^_^", dwStyle | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, CW_USEDEFAULT, CW_USEDEFAULT, WndRect.right - WndRect.left, WndRect.bottom - WndRect.top, 0, 0, hInstance, 0); if(!(SetupOpenGL())) { return false; } current_width = width; current_height = height; current_bits = bits; current_fullscreen = fullscreen; return true;}void OGLWindow::KillWindow(){ HINSTANCE hInstance = GetModuleHandle(0); if(current_fullscreen) { ChangeDisplaySettings(0,0); ShowCursor(true); } if (hRC) { if (!wglMakeCurrent(0, 0)) { MessageBox(NULL,"Release Of DC And RC Failed.", "AWFUL", MB_OK | MB_ICONINFORMATION); } if (!wglDeleteContext(hRC)) { MessageBox(NULL,"Release Rendering Context Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); } hRC=0; } if (hDC && !ReleaseDC(hWnd, hDC)) { MessageBox(NULL,"Release Device Context Failed.", "OH NO", MB_OK | MB_ICONINFORMATION); hDC=0; } if (hWnd && !DestroyWindow(hWnd)) { MessageBox(NULL,"Could Not Release hWnd.", "SOMETHING'S WRONG", MB_OK | MB_ICONINFORMATION); hWnd=0; } if (!UnregisterClass("^_^", hInstance)) { MessageBox(NULL,"Could Not Unregister Class.", "YOU BROKE MY PROGRAM", MB_OK | MB_ICONINFORMATION); hInstance=0; }}
Main.cpp
#include <memory>#include "window.h"LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);int active;int done;int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR szCmdLine, int iCmdShow){ active = 0; done = 0; MSG msg; std::auto_ptr<OGLWindow> wnd(new OGLWindow(800, 600, 32, 0, WndProc)); ShowWindow(wnd->GetHWND(), iCmdShow); UpdateWindow(wnd->GetHWND()); while(!done) { SwapBuffers(wnd->GetHDC()); if(PeekMessage(&msg,0,0,0,PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return msg.wParam;}LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam){ switch(iMsg) { case WM_ACTIVATE: if(LOWORD(wParam) == WA_INACTIVE) active = 0; else active = 1; return 0; case WM_CLOSE: done = 1; PostQuitMessage(0); return 0; } return DefWindowProc(hWnd, iMsg, wParam, lParam);}
Point.h (the only math-base stuff I'll have)
#ifndef H_POINT#define H_POINT#include <limits>template<typename T> class Point2d {public: template<typename U> Point2d(U nx, U ny) : x_val(nx), y_val(ny) { } template<typename U> Point2d(U nx) : x_val(nx), y_val() { } template<typename U> void operator=(const Point2d<U>& rhs) { x_val = rhs.x(); y_val = rhs.y(); } Point2d() : x_val(), y_val() { } ~Point2d() {} template<typename U> void operator+=(const Point2d<U>& rhs) { x_val += rhs.x(); y_val += rhs.y(); } template<typename U> void operator-=(const Point2d<U>& rhs) { x_val += rhs.x(); y_val += rhs.y(); } template<typename U> void operator*=(const U& rhs) { x_val *= rhs; y_val *= rhs; } template<typename U> void operator/=(const U& rhs) { x_val /= rhs; y_val /= rhs; } friend const bool operator==(const Point2d& lhs, const Point2d& rhs); friend const bool operator!=(const Point2d& lhs, const Point2d& rhs); friend const Point2d operator*(const Point2d& lhs, const T& rhs); friend const Point2d operator/(const Point2d& lhs, const T& rhs); friend const Point2d operator*(const T& lhs, const Point2d& rhs); friend const Point2d operator/(const T& lhs, const Point2d& rhs); friend const Point2d operator+(const Point2d& lhs, const Point2d& rhs); friend const Point2d operator-(const Point2d& lhs, const Point2d& rhs); T x() { return x_val; } T y() { return y_val; } void reset() { x_val -= x_val; y_val -= y_val; } void set(T& nx, T& ny) { x_val = nx; y_val = ny; } void set_x(T& nx) { x_val = nx; } void set_y(T& ny) { y_val = ny; }private: T x_val; T y_val;};template<typename T> const bool operator==(const Point2d<T>& lhs, const Point2d<T>& rhs){ return ((rhs.x() - lhs.x()) <= std::numeric_limits<T>::epsilon()) && ((rhs.y() - lhs.y()) <= std::numeric_limits<T>::epsilon());}template<typename T> const bool operator!=(const Point2d<T>& lhs, const Point2d<T>& rhs){ return (!(lhs == rhs));}template<typename T> const Point2d<T> operator*(const Point2d<T>& lhs, const T& rhs){ return Point2d<T>(lhs.x() * rhs, lhs.y() * T);}template<typename T> const Point2d<T> operator/(const Point2d<T>& lhs, const T& rhs){ return Point2d<T>(lhs.x() / rhs, lhs.y() / rhs);}template<typename T> const Point2d<T> operator*(const T& lhs, const Point2d<T>& rhs){ return rhs*lhs; }template<typename T> const Point2d<T> operator/(const T& lhs, const Point2d<T>& rhs){ return rhs/lhs; }template<typename T> const Point2d<T> operator+(const Point2d<T>& lhs, const Point2d<T>& rhs){ return Point2d<T>(lhs.x() + rhs.x(), lhs.y() + rhs.y());}template<typename T> const Point2d<T> operator-(const Point2d<T>& lhs, const Point2d<T>& rhs){ return Point2d<T>(lhs.x() - rhs.x(), lhs.y() - rhs.y());}#endif
glheaders.h
#ifndef H_GLHEADERS#define H_GLHEADERS#include <windows.h>#include <gl.h>#include <glu.h>#endif