From 54b2376adad98d91d32378efc3f241f120ba970f Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sun, 10 Oct 2021 13:56:10 +0200 Subject: Draw every frame instead of x11 expose, enable vsync (if available) --- src/window.c | 63 +++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 20 deletions(-) (limited to 'src/window.c') diff --git a/src/window.c b/src/window.c index 9836907..bdbcd6f 100644 --- a/src/window.c +++ b/src/window.c @@ -24,7 +24,7 @@ int mgl_window_create_with_params(mgl_window *self, const char *title, int width XSetWindowAttributes window_attr; window_attr.colormap = color_map; - window_attr.event_mask = ExposureMask | KeyPressMask; + window_attr.event_mask = KeyPressMask; self->window = XCreateWindow(context->connection, parent_window, 0, 0, width, height, 0, ((XVisualInfo*)context->visual_info)->depth, InputOutput, ((XVisualInfo*)context->visual_info)->visual, CWColormap | CWEventMask, &window_attr); //XFreeColormap(context->connection, color_map); @@ -48,19 +48,27 @@ void mgl_window_deinit(mgl_window *self) { } } -static void mgl_window_draw(mgl_window *self) { +/* TODO: check for glx swap control extension string (GLX_EXT_swap_control, etc) */ +static void set_vertical_sync_enabled(Window window, int enabled) { + int result = 0; mgl_context *context = mgl_get_context(); - /* TODO: Get window size from window resize event instead */ - XWindowAttributes gwa; - XGetWindowAttributes(context->connection, self->window, &gwa); + if(context->gl.glXSwapIntervalEXT) { + context->gl.glXSwapIntervalEXT(context->connection, window, enabled ? 1 : 0); + } else if(context->gl.glXSwapIntervalMESA) { + result = context->gl.glXSwapIntervalMESA(enabled ? 1 : 0); + } else if(context->gl.glXSwapIntervalSGI) { + result = context->gl.glXSwapIntervalSGI(enabled ? 1 : 0); + } else { + static int warned = 0; + if (!warned) { + warned = 1; + fprintf(stderr, "Warning: setting vertical sync not supported\n"); + } + } - context->gl.glViewport(0, 0, gwa.width, gwa.height); - context->gl.glClear(GL_COLOR_BUFFER_BIT); - context->gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - if(self->callback.draw) - self->callback.draw(self, self->callback_userdata); - context->glx.glXSwapBuffers(context->connection, self->window); + if(result != 0) + fprintf(stderr, "Warning: setting vertical sync failed\n"); } void mgl_window_show(mgl_window *self) { @@ -70,19 +78,16 @@ void mgl_window_show(mgl_window *self) { XFlush(context->connection); /* TODO: Switch current when rendering to another window, and set current to NULL when destroying the currently selected context */ - context->glx.glXMakeCurrent(context->connection, self->window, context->glx_context); + context->gl.glXMakeCurrent(context->connection, self->window, context->glx_context); + set_vertical_sync_enabled(self->window, 1); mgl_window_draw(self); } static void on_receive_x11_event(mgl_window *window, XEvent *xev) { - switch(xev->type) { - case Expose: - mgl_window_draw(window); - break; - } + } -void mgl_window_event_poll(mgl_window *self, int timeout_ms) { +void mgl_window_event_poll(mgl_window *self) { Display *display = mgl_get_context()->connection; const int x11_fd = ConnectionNumber(display); @@ -91,9 +96,12 @@ void mgl_window_event_poll(mgl_window *self, int timeout_ms) { FD_SET(x11_fd, &in_fds); struct timeval tv; - tv.tv_sec = timeout_ms / 1000; - tv.tv_usec = (timeout_ms * 1000) - (tv.tv_sec * 1000 * 1000); + tv.tv_sec = 0; + tv.tv_usec = 0; + /*tv.tv_sec = timeout_ms / 1000; + tv.tv_usec = (timeout_ms * 1000) - (tv.tv_sec * 1000 * 1000);*/ + /* TODO: Is this needed when using XPending? */ const int num_ready_fds = select(1 + x11_fd, &in_fds, NULL, NULL, &tv); if(num_ready_fds > 0) { XEvent xev; @@ -103,3 +111,18 @@ void mgl_window_event_poll(mgl_window *self, int timeout_ms) { } } } + +void mgl_window_draw(mgl_window *self) { + mgl_context *context = mgl_get_context(); + + /* TODO: Get window size from window resize event instead */ + XWindowAttributes gwa; + XGetWindowAttributes(context->connection, self->window, &gwa); + + context->gl.glViewport(0, 0, gwa.width, gwa.height); + context->gl.glClear(GL_COLOR_BUFFER_BIT); + context->gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + if(self->callback.draw) + self->callback.draw(self, self->callback_userdata); + context->gl.glXSwapBuffers(context->connection, self->window); +} -- cgit v1.2.3