diff --git a/main.c b/main.c index d729e28..4553930 100644 --- a/main.c +++ b/main.c @@ -19,11 +19,15 @@ int main(void) { Window * w = openWindow("Window", 800, 600); + windowSetFps(w, 300); + while (!windowKeyPressed(w, WINDOW_KEY_ESC)) { windowHandleEvents(w); handleInput(w); + printf("fps: %lf\n", 1 / windowGetDeltaTime(w)); + glClearColor(0.1, 0.2, 0.3, 1); glClear(GL_COLOR_BUFFER_BIT); glViewport(0, 0, 800, 600); diff --git a/src/openwindow.c b/src/openwindow.c index 87d38c9..abd4bf9 100644 --- a/src/openwindow.c +++ b/src/openwindow.c @@ -3,7 +3,9 @@ #include "openwindow.h" #include +#include #include +#include int initOpenGL() { if (getOpenGLProcs() == 0) return -1; @@ -175,12 +177,20 @@ int init(Window * window, const char * name, size_t width, size_t height) { XSync(window->x.display, False); glXMakeCurrent(window->x.display, window->x.window, window->glx.context); + //TODO: Check for errors + PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC) + glXGetProcAddress((const GLubyte *)"glXSwapIntervalEXT"); + + if (glXSwapIntervalEXT) glXSwapIntervalEXT(window->x.display, window->x.window, 0); + return 0; } Window * openWindow(const char * name, size_t width, size_t height) { Window * w = calloc(1, sizeof(Window)); w->fps = WINDOW_DEFAULT_FPS; + w->dt.t1 = calloc(1, sizeof(struct timespec)); + w->dt.t2 = calloc(1, sizeof(struct timespec)); if (init(w, name, width, height) < 0) { fprintf(stderr, "Failed to initialize window: X11 error!\n"); @@ -199,9 +209,19 @@ void windowSetFps(Window * window, uint32_t fps) { window->fps = fps; } +double windowGetDeltaTime(Window *window) { + return window->dt.dt; +} + void windowDraw(Window * window) { glXSwapBuffers(window->x.display, window->x.window); - usleep(1 / window->fps); + + usleep(((float)1 / (window->fps + 1)) * 1e6); + clock_gettime(CLOCK_MONOTONIC, window->dt.t2); + + window->dt.dt = (double) (window->dt.t2->tv_sec - window->dt.t1->tv_sec) + (window->dt.t2->tv_nsec - window->dt.t1->tv_nsec) / 1e9; + + clock_gettime(CLOCK_MONOTONIC, window->dt.t1); } void resetIOState(Window * window) { @@ -209,6 +229,7 @@ void resetIOState(Window * window) { } void windowHandleEvents(Window * window) { + XEvent xev = {0}; resetIOState(window); @@ -227,6 +248,10 @@ void closeWindow(Window * window) { XFreeColormap(window->x.display, window->x.cmap); XDestroyWindow(window->x.display, window->x.window); XCloseDisplay(window->x.display); + + free(window->dt.t1); + free(window->dt.t2); + free(window); } @@ -414,6 +439,10 @@ int init(Window * window, const char * title, size_t width, size_t height) { SetTimer(window->wgl.window, 1, (1 / window->fps) * 1000, NULL); + //TODO: Check for errors + PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = (void *)wglGetProcAddress("wglSwapIntervalEXT"); + if (wglSwapIntervalEXT) wglSwapIntervalEXT(0); + return 0; } @@ -434,8 +463,25 @@ Window * openWindow(const char * name, size_t width, size_t height) { return w; } +void windowSetFps(Window * window, uint32_t fps) { + window->fps = fps; +} + +double windowGetDeltaTime(Window * window) { + return window->dt.dt; +} + void windowDraw(Window * window) { SwapBuffers(window->wgl.display); + + Sleep((uint32_t)(((double)1 / (window->fps + 1)) * 1e3)); + + QueryPerformanceFrequency(&window->dt.freq); + QueryPerformanceCounter(&window->dt.t2); + + window->dt.dt = (double) (window->dt.t2.QuadPart - window->dt.t1.QuadPart) / window->dt.freq.QuadPart; + + QueryPerformanceCounter(&window->dt.t1); } void resetIOState(Window * window) { diff --git a/src/openwindow.h b/src/openwindow.h index 94b2817..92d002f 100644 --- a/src/openwindow.h +++ b/src/openwindow.h @@ -9,6 +9,7 @@ #include #include #include +#include int gladLoadGL(void); @@ -40,12 +41,19 @@ typedef struct { char last[WINDOW_KEY_COUNT]; } WindowIOState; +typedef struct { + struct timespec * t1; + struct timespec * t2; + double dt; +} WindowDeltaTime; + typedef struct Window Window; typedef struct Window { WindowIOState io; GLX glx; X11 x; + WindowDeltaTime dt; uint32_t fps; } Window; @@ -114,11 +122,19 @@ typedef struct { BYTE last[WINDOW_KEY_COUNT]; } WindowIOState; +typedef struct { + LARGE_INTEGER t1; + LARGE_INTEGER t2; + LARGE_INTEGER freq; + double dt; +} WindowDeltaTime; + typedef struct Window Window; typedef struct Window { WindowIOState io; WGL wgl; + WindowDeltaTime dt; uint32_t fps; } Window; @@ -175,6 +191,7 @@ bool windowKeyAlt(Window * window); Window * openWindow(const char * name, size_t width, size_t height); void windowSetFps(Window * window, uint32_t fps); +double windowGetDeltaTime(Window * window); void windowDraw(Window * window); void windowHandleEvents(Window * window); void closeWindow(Window * window);