www.pudn.com > 32709.zip > application.cpp
/***************************************************
* Developer: Clinton Jon Selke *
* Version: Totally FreeWare (Do what you will) *
* Section: Application Implementation *
***************************************************/
#include "application.h"
#include "winexception.h"
#include "vector3.h"
const char *Application::WINDOW_CLASS_NAME = "ParticalSim";
const char *Application::WINDOW_CAPTION = "Partical Sim v0.0.1 (ESCAPE -> Quits)";
const int Application::WINDOW_WIDTH = 400;
const int Application::WINDOW_HEIGHT = 400;
Application::Application():
_is_running(false),
_error_code(0),
_hwnd(0), _hdc(0), _hrc(0),
_particle_system(
Vector3(0.f, 0.f, 0.f), // position of particle system
Vector3(0.f, 0.f, 0.f), // velocity of particle system
2.0f, // min dying age of particle
5.0f, // max dying age of particle
0.15f, // starting particle size
0.10f, // finishing particle size
1.f, // starting particle transparency
0.3f, // finishing particle transparency
0.4f, // min particle speed
0.9f, // max particle speed
0.005f, // particle creation delay
Vector3(0.f, 0.f, 1.f), // starting particle colour
Vector3(1.f, 0.f, 0.f), // finishing particle colour
Vector3(0.f, -100.f, 0.f),// gravity
1000 // max number of particles
) {}
Application::~Application() {}
int Application::run() {
// Initialise window and opengl api
initWindow();
initOpenGL();
// Show the window
ShowWindow(_hwnd, SW_SHOW);
UpdateWindow(_hwnd);
// Set _is_running flag to true
_is_running = true;
// Config opengl
glClearDepth(1.f);
glClearColor(0.f, 0.f, 0.f, 0.f);
glAccum(GL_MULT, 0.5);
glShadeModel(GL_SMOOTH);
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
glEnable(GL_TEXTURE_2D);
_particle_system.loadTexture();
// Perform message loop
MSG msg;
while (_is_running) {
if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
_particle_system.draw();
glPopMatrix();
Sleep(10);
_particle_system.calculate(0.012f);
SwapBuffers(_hdc);
}
// Release window and opengl api
killOpenGL();
killWindow();
// Return error code
return _error_code;
}
void Application::initWindow() {
// Grab the handle to this application
HINSTANCE hinst = GetModuleHandle(0);
// Register window class
WNDCLASSEX wc;
wc.cbSize = sizeof(wc);
wc.style = CS_VREDRAW | CS_HREDRAW;
wc.lpfnWndProc = windowProcedure;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hinst;
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = 0;
wc.lpszClassName = WINDOW_CLASS_NAME;
wc.hIconSm = LoadIcon(0, IDI_APPLICATION);
if (!RegisterClassEx(&wc)) {
throw WinException("Unable to register window class");
}
// Grab screen dimensions
RECT scrn_rect;
GetClientRect(GetDesktopWindow(), &scrn_rect);
// Create window
_hwnd = CreateWindowEx(
0, // dwExStyle
WINDOW_CLASS_NAME, // lpszClassName
WINDOW_CAPTION, // lpszWindowName
WS_SYSMENU |
WS_MINIMIZEBOX, // dwStyle
(scrn_rect.right + 1 - WINDOW_WIDTH) >> 1, // x
(scrn_rect.bottom + 1 - WINDOW_HEIGHT) >> 1, // y
WINDOW_WIDTH, // nWidth
WINDOW_HEIGHT, // nHeight
0, // hWndParent
0, // hMenu
hinst, // hInstance
0 // lpParam
);
if (!_hwnd) {
UnregisterClass(WINDOW_CLASS_NAME, hinst);
throw WinException("Unable to create window");
}
// Store address of application object in window
SetWindowLong(_hwnd, GWL_USERDATA, (LONG)this);
}
void Application::initOpenGL() {
PIXELFORMATDESCRIPTOR pfd;
// Grab a reference to the window's DC
_hdc = GetDC(_hwnd);
// Set the pixel format for the DC
ZeroMemory(&pfd, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;
SetPixelFormat(_hdc, ChoosePixelFormat(_hdc, &pfd), &pfd);
// Create and enable render context
_hrc = wglCreateContext(_hdc);
wglMakeCurrent(_hdc, _hrc);
}
void Application::killWindow() {
if (_hwnd) { DestroyWindow(_hwnd); }
UnregisterClass(WINDOW_CLASS_NAME, GetModuleHandle(0));
}
void Application::killOpenGL() {
// Delete and disable render context
wglDeleteContext(_hrc);
wglMakeCurrent(0, 0);
// Release the DC reference back to the window
ReleaseDC(_hwnd, _hdc);
// Clear handles
_hdc = 0;
_hrc = 0;
}
LRESULT CALLBACK Application::windowProcedure(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
Application *app = (Application *)GetWindowLong(hwnd, GWL_USERDATA);
switch (msg) {
case WM_CREATE:
return 0;
case WM_CLOSE:
app->_error_code = 0;
DestroyWindow(hwnd);
return 0;
case WM_KEYDOWN:
switch (wparam) {
case VK_ESCAPE:
app->_error_code = 0;
DestroyWindow(hwnd);
}
return 0;
case WM_DESTROY:
app->_hwnd = 0;
app->_is_running = false;
return 0;
default:
return DefWindowProc(hwnd, msg, wparam, lparam);
}
}