Created
September 8, 2016 14:07
-
-
Save mdsitton/f2fb84a05b69ac76c6b49cdd575d1b49 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cassert> | |
#include <iostream> | |
#include <thread> | |
#define WIN32_LEAN_AND_MEAN | |
#include <Windows.h> | |
#include <gl/gl.h> | |
class FpsTimer | |
{ | |
private: | |
int m_frames; | |
double m_currentTime; | |
double m_previousTime; | |
double m_startTime; | |
double m_delta; | |
double m_fpsTime; | |
double m_fps; | |
LARGE_INTEGER m_frequency; | |
public: | |
FpsTimer() | |
{ | |
QueryPerformanceFrequency(&m_frequency); | |
m_frames = 1; | |
m_currentTime = get_time(); | |
m_previousTime = m_currentTime; | |
m_startTime = m_currentTime; | |
m_delta = 0.0; | |
m_fpsTime = 0.0; | |
m_fps = 0.0f; | |
} | |
double get_time() | |
{ | |
LARGE_INTEGER startingTime; | |
QueryPerformanceCounter(&startingTime); | |
return startingTime.QuadPart / static_cast<double>(m_frequency.QuadPart); | |
} | |
double tick() | |
{ | |
m_frames++; | |
m_previousTime = m_currentTime; | |
m_currentTime = get_time(); | |
m_delta = m_currentTime - m_previousTime; | |
m_fpsTime += m_delta; | |
return m_delta; | |
} | |
double get_current_time() { | |
return m_currentTime - m_startTime; | |
} | |
double get_fps() | |
{ | |
if (m_fpsTime == 0) { | |
m_fpsTime += 1; | |
} | |
m_fps = m_frames / m_fpsTime; | |
m_fpsTime = 0; | |
m_frames = 0; | |
return m_fps; | |
} | |
}; | |
static bool running = false; | |
long mytime = 0; | |
double myExactTime = 0.0; | |
int count = 0; | |
long lastMsgTime = 0; | |
double eLastMsgTime = 0; | |
FpsTimer eTimer; | |
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) | |
{ | |
long curTime = GetMessageTime(); | |
double eCurTime = eTimer.get_time(); | |
mytime += (curTime - lastMsgTime); | |
myExactTime += (eCurTime - eLastMsgTime); | |
++count; | |
lastMsgTime = curTime; | |
eLastMsgTime = eCurTime; | |
switch (message) | |
{ | |
case WM_DESTROY: | |
running = false; | |
PostQuitMessage(0); | |
break; | |
default: | |
return DefWindowProc(hWnd, message, wParam, lParam); | |
} | |
return 0; | |
} | |
static HDC deviceContext; | |
void render_thread() | |
{ | |
PIXELFORMATDESCRIPTOR pfd = | |
{ | |
sizeof(PIXELFORMATDESCRIPTOR), | |
1, | |
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, | |
PFD_TYPE_RGBA, //The kind of framebuffer. RGBA or palette. | |
32, //Colordepth of the framebuffer. | |
0, 0, 0, 0, 0, 0, | |
0, | |
0, | |
0, | |
0, 0, 0, 0, | |
24, //Number of bits for the depthbuffer | |
8, //Number of bits for the stencilbuffer | |
0, //Number of Aux buffers in the framebuffer. | |
PFD_MAIN_PLANE, | |
0, | |
0, 0, 0 | |
}; | |
int pixelFormat = ChoosePixelFormat(deviceContext, &pfd); | |
SetPixelFormat(deviceContext, pixelFormat, &pfd); | |
HGLRC context = wglCreateContext(deviceContext); | |
assert(context != nullptr); | |
std::cout << "context created" << std::endl; | |
wglMakeCurrent(deviceContext, context); | |
double fpsTime = 0.0; | |
std::cout.precision(5); | |
glViewport(0, 0, 1280, 720); | |
glClearColor(0.5, 0.5, 0.5, 1.0); | |
FpsTimer timer; | |
while (running) { | |
fpsTime += timer.tick(); | |
// Render loop here | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
SwapBuffers(deviceContext); | |
if (fpsTime >= 2.0) { | |
std::cout << "FPS: " << timer.get_fps() << std::endl; | |
fpsTime = 0; | |
} | |
} | |
wglMakeCurrent(nullptr, nullptr); | |
wglDeleteContext(context); | |
} | |
void create_window() | |
{ | |
// setup Win32 Window | |
WNDCLASS wndClass; | |
wndClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; | |
wndClass.lpfnWndProc = WndProc; | |
wndClass.cbClsExtra = 0; | |
wndClass.cbWndExtra = 0; | |
wndClass.hInstance = GetModuleHandle(nullptr); | |
wndClass.hIcon = LoadIcon(nullptr, IDI_INFORMATION); | |
wndClass.hCursor = LoadCursor(nullptr, IDC_ARROW); | |
wndClass.hbrBackground = nullptr; | |
wndClass.lpszMenuName = nullptr; | |
wndClass.lpszClassName = "speedywindow9000"; | |
ATOM clsReg = RegisterClass(&wndClass); | |
HWND hwnd = CreateWindowEx(WS_EX_APPWINDOW | WS_EX_WINDOWEDGE, | |
wndClass.lpszClassName, | |
"Speed Test", | |
WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, | |
CW_USEDEFAULT, CW_USEDEFAULT, | |
1280, 720, | |
nullptr, nullptr, | |
wndClass.hInstance, | |
nullptr); | |
assert(hwnd != nullptr); | |
// setup render thread | |
deviceContext = GetDC(hwnd); | |
assert(deviceContext != nullptr); | |
running = true; | |
std::thread renderThread(render_thread); | |
ShowWindow(hwnd, SW_SHOW); | |
SetForegroundWindow(hwnd); | |
SetFocus(hwnd); | |
MSG msg; | |
BOOL eventErr; | |
double fpsTime = 0.0; | |
std::cout.precision(5); | |
while (GetMessage(&msg, nullptr, 0, 0) != 0) | |
{ | |
fpsTime += eTimer.tick(); | |
if (eventErr == -1) { | |
throw std::runtime_error("event error"); | |
} else { | |
TranslateMessage(&msg); | |
DispatchMessage(&msg); | |
} | |
if (fpsTime >= 2.0) { | |
std::cout << "event LPS: " << eTimer.get_fps() << std::endl; | |
std::cout << "avg event time: " << (mytime/(count*1.0)) << std::endl; | |
std::cout << "eAvg event time: " << (myExactTime/count)*1000 << std::endl; | |
fpsTime = 0; | |
mytime = 0; | |
myExactTime = 0.0; | |
count = 0; | |
} | |
} | |
renderThread.join(); | |
} | |
int main() | |
{ | |
create_window(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment