Wed, 01 Nov 2023 20:09:49 +0100
move window related stuff to its own unit
src/Makefile | file | annotate | diff | comparison | revisions | |
src/ascension/core.h | file | annotate | diff | comparison | revisions | |
src/ascension/datatypes.h | file | annotate | diff | comparison | revisions | |
src/ascension/utils.h | file | annotate | diff | comparison | revisions | |
src/ascension/window.h | file | annotate | diff | comparison | revisions | |
src/core.c | file | annotate | diff | comparison | revisions | |
src/window.c | file | annotate | diff | comparison | revisions | |
test/Makefile | file | annotate | diff | comparison | revisions | |
test/sandbox.c | file | annotate | diff | comparison | revisions |
--- a/src/Makefile Mon Oct 30 18:54:16 2023 +0100 +++ b/src/Makefile Wed Nov 01 20:09:49 2023 +0100 @@ -27,21 +27,25 @@ BUILD_DIR=../build/lib -SRC = core.c +SRC = core.c window.c OBJ = $(SRC:%.c=$(BUILD_DIR)/%.o) all: $(BUILD_DIR)/libascension.a FORCE - echo "You have successfully ascended." + @echo "You have successfully ascended." $(BUILD_DIR)/libascension.a: $(OBJ) - echo "Creating library..." + @echo "Creating library..." $(AR) $(ARFLAGS) $@ $^ FORCE: -$(BUILD_DIR)/core.o: core.c ascension/core.h ascension/datatypes.h \ - ascension/utils.h - echo "Compiling $<" +$(BUILD_DIR)/core.o: core.c ascension/core.h ascension/datatypes.h + @echo "Compiling $<" $(CC) -o $@ $(CFLAGS) -c $< +$(BUILD_DIR)/window.o: window.c ascension/window.h ascension/core.h \ + ascension/datatypes.h + @echo "Compiling $<" + $(CC) -o $@ $(CFLAGS) -c $< +
--- a/src/ascension/core.h Mon Oct 30 18:54:16 2023 +0100 +++ b/src/ascension/core.h Wed Nov 01 20:09:49 2023 +0100 @@ -28,10 +28,6 @@ #ifndef ASCENSION_CORE_H #define ASCENSION_CORE_H -#include <SDL2/SDL.h> -#include <SDL2/SDL_ttf.h> -#include <GL/glew.h> - #include <cx/string.h> #include <cx/buffer.h> #include <cx/list.h> @@ -60,23 +56,6 @@ /** Global ascension context. */ extern AscContext asc_context; -typedef struct AscWindowSettings { - int depth_size; - int vsync; - asc_vec2i dimensions; - int fullscreen; - int gl_major_version; - int gl_minor_version; - char const* title; -} AscWindowSettings; - -typedef struct AscWindow { - SDL_Window* window; - SDL_GLContext glctx; - Uint32 id; - asc_vec2i dimensions; -} AscWindow; - void asc_context_initialize(void); void asc_context_destroy(void); @@ -107,47 +86,11 @@ char const* asc_get_error(void); void asc_clear_error(void); -/** - * Dispatches events and synchronizes all initialized windows. - * - * @return false, if one of the events is a QUIT event, true otherwise - */ -bool asc_loop_next(void); - -/** - * Initializes the settings structure with default values. - * - * @param settings an uninitialized settings object - */ -void asc_window_settings_init_defaults(AscWindowSettings* settings); - -/** - * Creates and initializes a new window and a corresponding OpenGL context. - * - * @param window the window structure - * @param settings the settings to be used for initialization - */ -void asc_window_initialize(AscWindow* window, AscWindowSettings const* settings); - -/** - * Destroys the window and its OpenGL context. - * - * Still alive windows will also be destroyed by asc_context_destroy() - * automatically. - * - * @param window the window - */ -void asc_window_destroy(AscWindow* window); - -/** - * Swaps buffers and adjusts the viewport to the current window size. - * - * This function is automatically invoked for all initialized windows - * by asc_loop_next(). You usually do not need to call this function manually. - * - * @param window the window - */ -void asc_window_sync(AscWindow const *window); +#ifdef NDEBUG +#define asc_dprintf(...) +#else +#define asc_dprintf(...) printf(__VA_ARGS__); putchar('\n') +#endif #ifdef __cplusplus } // extern "C"
--- a/src/ascension/datatypes.h Mon Oct 30 18:54:16 2023 +0100 +++ b/src/ascension/datatypes.h Wed Nov 01 20:09:49 2023 +0100 @@ -28,6 +28,7 @@ #ifndef ASCENSION_DATATYPES_H #define ASCENSION_DATATYPES_H +#include <stdbool.h> #include <SDL2/SDL_endian.h> #ifdef __cplusplus
--- a/src/ascension/utils.h Mon Oct 30 18:54:16 2023 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * Copyright 2023 Mike Becker. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ASCENSION_UTILS_H -#define ASCENSION_UTILS_H - -#include <stdbool.h> -#include <stdio.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef NDEBUG -#define asc_dprintf(...) -#else -#define asc_dprintf(...) printf(__VA_ARGS__); putchar('\n') -#endif - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // ASCENSION_UTILS_H \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ascension/window.h Wed Nov 01 20:09:49 2023 +0100 @@ -0,0 +1,104 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * Copyright 2023 Mike Becker. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ASCENSION_WINDOW_H +#define ASCENSION_WINDOW_H + +#include <SDL2/SDL.h> + +#include "core.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct AscWindowSettings { + int depth_size; + int vsync; + asc_vec2i dimensions; + int fullscreen; + int gl_major_version; + int gl_minor_version; + char const* title; +} AscWindowSettings; + +typedef struct AscWindow { + SDL_Window* window; + SDL_GLContext glctx; + Uint32 id; + asc_vec2i dimensions; +} AscWindow; + + +/** + * Dispatches events and synchronizes all initialized windows. + * + * @return false, if one of the events is a QUIT event, true otherwise + */ +bool asc_loop_next(void); + +/** + * Initializes the settings structure with default values. + * + * @param settings an uninitialized settings object + */ +void asc_window_settings_init_defaults(AscWindowSettings* settings); + +/** + * Creates and initializes a new window and a corresponding OpenGL context. + * + * @param window the window structure + * @param settings the settings to be used for initialization + */ +void asc_window_initialize(AscWindow* window, AscWindowSettings const* settings); + +/** + * Destroys the window and its OpenGL context. + * + * Still alive windows will also be destroyed by asc_context_destroy() + * automatically. + * + * @param window the window + */ +void asc_window_destroy(AscWindow* window); + +/** + * Swaps buffers and adjusts the viewport to the current window size. + * + * This function is automatically invoked for all initialized windows + * by asc_loop_next(). You usually do not need to call this function manually. + * + * @param window the window + */ +void asc_window_sync(AscWindow const *window); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif /* ASCENSION_WINDOW_H */ +
--- a/src/core.c Mon Oct 30 18:54:16 2023 +0100 +++ b/src/core.c Wed Nov 01 20:09:49 2023 +0100 @@ -26,31 +26,17 @@ */ #include "ascension/core.h" -#include "ascension/utils.h" #include <cx/linked_list.h> #include <cx/printf.h> -static void asc_gl_debug_callback( - GLenum source, GLenum type, GLuint id, GLenum severity, - GLsizei length, const GLchar* message, - const void* userParam -) { - cxmutstr buf = cx_asprintf( - "source = %d, id = %u, type = %d, severity= %d, message = %.*s", - source, id, type, severity, length, message); - if (type == GL_DEBUG_TYPE_ERROR) { - asc_error(buf.ptr); - } else { - asc_dprintf("GL debug: %*.s", (int)buf.length, buf.ptr); - } - cx_strfree(&buf); -} +#include <SDL2/SDL.h> +#include <SDL2/SDL_ttf.h> AscContext asc_context; -// forward declarations -static void asc_window_destroy_impl(AscWindow* window); +// forward declare the destructor functions that reside in other units +void asc_window_destroy_impl(void* obj); void asc_context_initialize(void) { if (asc_test_flag(asc_context.flags, ASC_FLAG_INITILIZED)) @@ -137,153 +123,3 @@ cxBufferClear(&asc_context.error_buffer); asc_clear_flag(&asc_context.flags, ASC_FLAG_HAS_ERROR); } - -static void asc_event_window_resized(Uint32 id, Sint32 width, Sint32 height) { - CxIterator iter = cxListIterator(asc_context.windows); - cx_foreach(AscWindow*, w, iter) { - if (w->id == id) { - w->dimensions.width = width; - w->dimensions.height = height; - return; - } - } -} - -bool asc_loop_next(void) { - // dispatch SDL events - SDL_Event event; - while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_QUIT:return false; - case SDL_WINDOWEVENT: { - if (event.window.type == SDL_WINDOWEVENT_RESIZED) - asc_event_window_resized( - event.window.windowID, - event.window.data1, - event.window.data2 - ); - break; - } - case SDL_KEYDOWN: - // TODO: remove this code and implement key press map instead - if (event.key.keysym.sym == SDLK_ESCAPE) - return false; - break; - case SDL_KEYUP: - // TODO: implement key press map - break; - } - } - - // sync the windows - CxMutIterator windows = cxListMutIterator(asc_context.windows); - cx_foreach(AscWindow*, w, windows) { - asc_window_sync(w); - } - return true; -} - -void asc_window_settings_init_defaults(AscWindowSettings* settings) { - settings->depth_size = 24; - settings->vsync = 1; - settings->dimensions.width = 800; - settings->dimensions.height = 600; - settings->fullscreen = 0; - settings->gl_major_version = 3; - settings->gl_minor_version = 3; - settings->title = "Ascended Window"; -} - -void asc_window_initialize(AscWindow* window, AscWindowSettings const* settings) { - Uint32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN; - flags |= settings->fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_RESIZABLE; - - window->window = SDL_CreateWindow( - settings->title, - SDL_WINDOWPOS_CENTERED, - SDL_WINDOWPOS_CENTERED, - settings->dimensions.width, - settings->dimensions.height, - flags - ); - if (window->window == NULL) { - asc_error(SDL_GetError()); - return; - } - - window->id = SDL_GetWindowID(window->window); - SDL_GetWindowSize(window->window, - &window->dimensions.width, - &window->dimensions.height - ); - - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, settings->gl_major_version); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, settings->gl_minor_version); - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, settings->depth_size); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - window->glctx = SDL_GL_CreateContext(window->window); - if (window->glctx == NULL) { - asc_dprintf("Creating GL context failed for window %u", window->id); - } else { - glewExperimental = GL_TRUE; - GLenum err = glewInit(); - if (err == GLEW_OK) { - SDL_GL_SetSwapInterval(settings->vsync); - glEnable(GL_DEPTH_TEST); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_DEBUG_OUTPUT); - glDebugMessageCallback(asc_gl_debug_callback, NULL); - asc_dprintf("Window %u initialized", window->id); - cxListAdd(asc_context.windows, window); - return; - } else { - asc_error(glewGetErrorString(err)); - } - } - - // cleanup on error - if (window->glctx != NULL) { - SDL_GL_DeleteContext(window->glctx); - } - window->glctx = NULL; - SDL_DestroyWindow(window->window); - window->window = NULL; - window->id = 0; -} - -void asc_window_destroy_impl(AscWindow* window) { - // destory the GL context and the window - if (window->glctx != NULL) { - SDL_GL_DeleteContext(window->glctx); - } - if (window->window != NULL) { - SDL_DestroyWindow(window->window); - } - - // clean the data - asc_dprintf("Window %u and its OpenGL context destroyed.", window->id); - memset(window, 0, sizeof(AscWindow)); -} - -void asc_window_destroy(AscWindow* window) { - // find the window in the context and remove it - bool found = false; - CxMutIterator iter = cxListMutIterator(asc_context.windows); - cx_foreach(AscWindow*, w, iter) { - if (w == window) { - found = true; - cxIteratorFlagRemoval(iter); - } - } - if (!found) asc_window_destroy_impl(window); -} - -void asc_window_sync(AscWindow const* window) { - SDL_GL_MakeCurrent(window->window, window->glctx); - SDL_GL_SwapWindow(window->window); - glViewport(0, 0, window->dimensions.width, window->dimensions.height); - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/window.c Wed Nov 01 20:09:49 2023 +0100 @@ -0,0 +1,200 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * Copyright 2023 Mike Becker. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "ascension/window.h" + +#include <cx/linked_list.h> +#include <cx/printf.h> + +#include <GL/glew.h> + +static void asc_gl_debug_callback( + GLenum source, GLenum type, GLuint id, GLenum severity, + GLsizei length, const GLchar* message, + const void* userParam +) { + cxmutstr buf = cx_asprintf( + "source = %d, id = %u, type = %d, severity= %d, message = %.*s", + source, id, type, severity, length, message); + if (type == GL_DEBUG_TYPE_ERROR) { + asc_error(buf.ptr); + } else { + asc_dprintf("GL debug: %*.s", (int)buf.length, buf.ptr); + } + cx_strfree(&buf); +} + + +static void asc_event_window_resized(Uint32 id, Sint32 width, Sint32 height) { + CxIterator iter = cxListIterator(asc_context.windows); + cx_foreach(AscWindow*, w, iter) { + if (w->id == id) { + w->dimensions.width = width; + w->dimensions.height = height; + return; + } + } +} + +bool asc_loop_next(void) { + // dispatch SDL events + SDL_Event event; + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_QUIT:return false; + case SDL_WINDOWEVENT: { + if (event.window.type == SDL_WINDOWEVENT_RESIZED) + asc_event_window_resized( + event.window.windowID, + event.window.data1, + event.window.data2 + ); + break; + } + case SDL_KEYDOWN: + // TODO: remove this code and implement key press map instead + if (event.key.keysym.sym == SDLK_ESCAPE) + return false; + break; + case SDL_KEYUP: + // TODO: implement key press map + break; + } + } + + // sync the windows + CxMutIterator windows = cxListMutIterator(asc_context.windows); + cx_foreach(AscWindow*, w, windows) { + asc_window_sync(w); + } + return true; +} + +void asc_window_settings_init_defaults(AscWindowSettings* settings) { + settings->depth_size = 24; + settings->vsync = 1; + settings->dimensions.width = 800; + settings->dimensions.height = 600; + settings->fullscreen = 0; + settings->gl_major_version = 3; + settings->gl_minor_version = 3; + settings->title = "Ascended Window"; +} + +void asc_window_initialize(AscWindow* window, AscWindowSettings const* settings) { + Uint32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN; + flags |= settings->fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_RESIZABLE; + + window->window = SDL_CreateWindow( + settings->title, + SDL_WINDOWPOS_CENTERED, + SDL_WINDOWPOS_CENTERED, + settings->dimensions.width, + settings->dimensions.height, + flags + ); + if (window->window == NULL) { + asc_error(SDL_GetError()); + return; + } + + window->id = SDL_GetWindowID(window->window); + SDL_GetWindowSize(window->window, + &window->dimensions.width, + &window->dimensions.height + ); + + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, settings->gl_major_version); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, settings->gl_minor_version); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, settings->depth_size); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + window->glctx = SDL_GL_CreateContext(window->window); + if (window->glctx == NULL) { + asc_dprintf("Creating GL context failed for window %u", window->id); + } else { + glewExperimental = GL_TRUE; + GLenum err = glewInit(); + if (err == GLEW_OK) { + SDL_GL_SetSwapInterval(settings->vsync); + glEnable(GL_DEPTH_TEST); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_DEBUG_OUTPUT); + glDebugMessageCallback(asc_gl_debug_callback, NULL); + asc_dprintf("Window %u initialized", window->id); + cxListAdd(asc_context.windows, window); + return; + } else { + asc_error(glewGetErrorString(err)); + } + } + + // cleanup on error + if (window->glctx != NULL) { + SDL_GL_DeleteContext(window->glctx); + } + window->glctx = NULL; + SDL_DestroyWindow(window->window); + window->window = NULL; + window->id = 0; +} + +void asc_window_destroy_impl(AscWindow* window) { + // destory the GL context and the window + if (window->glctx != NULL) { + SDL_GL_DeleteContext(window->glctx); + } + if (window->window != NULL) { + SDL_DestroyWindow(window->window); + } + + // clean the data + asc_dprintf("Window %u and its OpenGL context destroyed.", window->id); + memset(window, 0, sizeof(AscWindow)); +} + +void asc_window_destroy(AscWindow* window) { + // find the window in the context and remove it + bool found = false; + CxMutIterator iter = cxListMutIterator(asc_context.windows); + cx_foreach(AscWindow*, w, iter) { + if (w == window) { + found = true; + cxIteratorFlagRemoval(iter); + } + } + if (!found) asc_window_destroy_impl(window); +} + +void asc_window_sync(AscWindow const* window) { + SDL_GL_MakeCurrent(window->window, window->glctx); + SDL_GL_SwapWindow(window->window); + glViewport(0, 0, window->dimensions.width, window->dimensions.height); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +}
--- a/test/Makefile Mon Oct 30 18:54:16 2023 +0100 +++ b/test/Makefile Wed Nov 01 20:09:49 2023 +0100 @@ -33,11 +33,13 @@ @echo "Sandbox demo successfully built." $(BUILD_DIR)/sandbox: $(BUILD_DIR)/sandbox.o $(LIB_ASCENSION) - echo "Linking executable..." + @echo "Linking executable..." $(CC) $(LDFLAGS) -o $@ $^ -$(BUILD_DIR)/sandbox.o: sandbox.c ../src/ascension/core.h - echo "Compiling $<" +FORCE: + +$(BUILD_DIR)/sandbox.o: sandbox.c ../src/ascension/window.h \ + ../src/ascension/core.h ../src/ascension/datatypes.h + @echo "Compiling $<" $(CC) -o $@ $(CFLAGS) -c $< -FORCE: