Skip to content

Instantly share code, notes, and snippets.

@mdsitton
Created September 8, 2016 14:07
Show Gist options
  • Save mdsitton/f2fb84a05b69ac76c6b49cdd575d1b49 to your computer and use it in GitHub Desktop.
Save mdsitton/f2fb84a05b69ac76c6b49cdd575d1b49 to your computer and use it in GitHub Desktop.
#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