aboutsummaryrefslogtreecommitdiff
path: root/src/os/sdl/sdl_window.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/os/sdl/sdl_window.c')
-rw-r--r--src/os/sdl/sdl_window.c171
1 files changed, 171 insertions, 0 deletions
diff --git a/src/os/sdl/sdl_window.c b/src/os/sdl/sdl_window.c
new file mode 100644
index 0000000..000ed50
--- /dev/null
+++ b/src/os/sdl/sdl_window.c
@@ -0,0 +1,171 @@
+#include <os/os.h>
+#include <SDL3/SDL_events.h>
+#include <SDL3/SDL.h>
+#include <GL/gl.h>
+
+
+struct OSWindow {
+ SDL_Window *sdl_window;
+ SDL_GLContext gl_context;
+ u32 gl_texture_id;
+ OSOffscreenBuffer offscreen_buffer;
+};
+
+
+static void
+os_offscreen_buffer_reinit(OSOffscreenBuffer *buffer, i32 w, i32 h)
+{
+ void *realloced_pixels = realloc(buffer->pixels, w*h*sizeof(buffer->pixels[0]));
+ if (!realloced_pixels) {
+ printf("could not resize offscreen buffer\n");
+ return;
+ }
+ buffer->green_shift = 8;
+ buffer->blue_shift = 16;
+ buffer->red_shift = 0;
+ buffer->alpha_shift = 24;
+ buffer->width = w;
+ buffer->height = h;
+ buffer->pixels = realloced_pixels;
+}
+
+static void
+os_offscreen_buffer_deinit(OSOffscreenBuffer *buffer)
+{
+ buffer->width = 0;
+ buffer->height = 0;
+ free(buffer->pixels);
+}
+
+
+OSWindow *
+os_window_create(const char *name, i32 width, i32 height)
+{
+ OSWindow *window = malloc(sizeof(*window));
+ memset(window, 0, sizeof(*window));
+
+ SDL_Window *sdl_window = SDL_CreateWindow(name, width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
+ if (!sdl_window) {
+ printf("SDL_CreateWindow failed\n");
+ return 0;
+ }
+
+
+ SDL_GLContext gl_context = SDL_GL_CreateContext(sdl_window);
+
+ glEnable(GL_TEXTURE_2D);
+ glActiveTexture(GL_TEXTURE0);
+
+ glGenTextures(1, &window->gl_texture_id);
+ glBindTexture(GL_TEXTURE_2D, window->gl_texture_id);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+
+ window->sdl_window = sdl_window;
+ window->gl_context = gl_context;
+ os_offscreen_buffer_reinit(&window->offscreen_buffer, width, height);
+
+ return window;
+}
+
+void
+os_window_destroy(OSWindow *window)
+{
+ os_offscreen_buffer_deinit(&window->offscreen_buffer);
+ SDL_GL_DestroyContext(window->gl_context);
+ SDL_DestroyWindow(window->sdl_window);
+ free(window);
+}
+
+b32
+os_window_get_event(OSWindow *window, OSEvent *event)
+{
+ SDL_Window *sdl_window = window->sdl_window;
+ SDL_Event sdl_event;
+ if (SDL_PollEvent(&sdl_event)) {
+ if (sdl_event.type == SDL_EVENT_WINDOW_DESTROYED) {
+ event->type = OS_EVENT_WINDOW_DESTROYED;
+ return true;
+ }
+ else if (sdl_event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED) {
+ SDL_DestroyWindow(sdl_window);
+ event->type = OS_EVENT_WINDOW_DESTROYED;
+ return true;
+ }
+ else if (sdl_event.type == SDL_EVENT_WINDOW_RESIZED) {
+ event->type = OS_EVENT_WINDOW_RESIZE;
+ event->ev.resize.width = sdl_event.window.data1;
+ event->ev.resize.height = sdl_event.window.data2;
+ os_offscreen_buffer_reinit(&window->offscreen_buffer, sdl_event.window.data1, sdl_event.window.data2);
+ return true;
+ }
+ else if (sdl_event.type == SDL_EVENT_KEY_DOWN) {
+ if ((sdl_event.key.key >= SDLK_SPACE && sdl_event.key.key <= SDLK_TILDE) ||
+ sdl_event.key.key == '\t' ||
+ sdl_event.key.key == '\r' ||
+ sdl_event.key.key == '\b' ||
+ sdl_event.key.key == SDLK_DELETE)
+ {
+ event->type = OS_EVENT_KEY_PRESS;
+ event->ev.key_press.is_unicode = true;
+ event->ev.key_press.code = sdl_event.key.key;
+ return true;
+ }
+ else if (sdl_event.key.key == SDLK_LEFT) {
+ event->type = OS_EVENT_KEY_PRESS;
+ event->ev.key_press.is_unicode = false;
+ event->ev.key_press.code = OS_KEYCODE_LEFT;
+ return true;
+ }
+ else if (sdl_event.key.key == SDLK_RIGHT) {
+ event->type = OS_EVENT_KEY_PRESS;
+ event->ev.key_press.is_unicode = false;
+ event->ev.key_press.code = OS_KEYCODE_RIGHT;
+ return true;
+ }
+ else if (sdl_event.key.key == SDLK_UP) {
+ event->type = OS_EVENT_KEY_PRESS;
+ event->ev.key_press.is_unicode = false;
+ event->ev.key_press.code = OS_KEYCODE_UP;
+ return true;
+ }
+ else if (sdl_event.key.key == SDLK_DOWN) {
+ event->type = OS_EVENT_KEY_PRESS;
+ event->ev.key_press.is_unicode = false;
+ event->ev.key_press.code = OS_KEYCODE_DOWN;
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+OSOffscreenBuffer*
+os_window_get_offscreen_buffer(OSWindow *window)
+{
+ return &window->offscreen_buffer;
+}
+
+void os_window_swap_buffers(OSWindow *window, OSOffscreenBuffer *offscreen_buffer)
+{
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, window->gl_texture_id);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, offscreen_buffer->width, offscreen_buffer->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, offscreen_buffer->pixels);
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
+ glTexCoord2f(1.0f, 0.0f); glVertex2f( 1.0f, -1.0f);
+ glTexCoord2f(1.0f, 1.0f); glVertex2f( 1.0f, 1.0f);
+ glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, 1.0f);
+ glEnd();
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ SDL_GL_SwapWindow(window->sdl_window);
+}
+