create own compilation unit for GL context - fixes shader not being created per context

Tue, 26 Mar 2024 20:37:21 +0100

author
Mike Becker <universe@uap-core.de>
date
Tue, 26 Mar 2024 20:37:21 +0100
changeset 44
b3da4096c607
parent 43
5a8c31904e44
child 45
18de2af03531

create own compilation unit for GL context - fixes shader not being created per context

src/Makefile file | annotate | diff | comparison | revisions
src/ascension/glcontext.h file | annotate | diff | comparison | revisions
src/ascension/shader.h file | annotate | diff | comparison | revisions
src/ascension/window.h file | annotate | diff | comparison | revisions
src/context.c file | annotate | diff | comparison | revisions
src/glcontext.c file | annotate | diff | comparison | revisions
src/primitives.c file | annotate | diff | comparison | revisions
src/scene.c file | annotate | diff | comparison | revisions
src/shader.c file | annotate | diff | comparison | revisions
src/text.c file | annotate | diff | comparison | revisions
src/window.c file | annotate | diff | comparison | revisions
test/Makefile file | annotate | diff | comparison | revisions
test/snake.c file | annotate | diff | comparison | revisions
     1.1 --- a/src/Makefile	Thu Mar 21 23:01:09 2024 +0100
     1.2 +++ b/src/Makefile	Tue Mar 26 20:37:21 2024 +0100
     1.3 @@ -27,7 +27,7 @@
     1.4  
     1.5  BUILD_DIR=../build/lib
     1.6  
     1.7 -SRC = context.c error.c window.c files.c shader.c font.c text.c \
     1.8 +SRC = context.c glcontext.c error.c window.c files.c shader.c font.c text.c \
     1.9        scene.c camera.c primitives.c
    1.10  
    1.11  OBJ = $(SRC:%.c=$(BUILD_DIR)/%.o)
    1.12 @@ -46,17 +46,18 @@
    1.13  	$(CC) -o $@ $(CFLAGS) -c $<
    1.14  
    1.15  $(BUILD_DIR)/context.o: context.c ascension/context.h \
    1.16 - ascension/datatypes.h ascension/window.h ascension/primitives.h \
    1.17 - ascension/mesh.h ascension/scene.h ascension/transform.h \
    1.18 - ascension/camera.h ascension/font.h ascension/error.h ascension/utils.h \
    1.19 - ascension/shader.h
    1.20 + ascension/datatypes.h ascension/window.h ascension/glcontext.h \
    1.21 + ascension/primitives.h ascension/mesh.h ascension/shader.h \
    1.22 + ascension/scene.h ascension/transform.h ascension/camera.h \
    1.23 + ascension/font.h ascension/error.h ascension/utils.h ascension/shader.h
    1.24  	@echo "Compiling $<"
    1.25  	$(CC) -o $@ $(CFLAGS) -c $<
    1.26  
    1.27  $(BUILD_DIR)/error.o: error.c ascension/context.h ascension/datatypes.h \
    1.28 - ascension/window.h ascension/primitives.h ascension/mesh.h \
    1.29 - ascension/scene.h ascension/transform.h ascension/camera.h \
    1.30 - ascension/font.h ascension/error.h ascension/utils.h
    1.31 + ascension/window.h ascension/glcontext.h ascension/primitives.h \
    1.32 + ascension/mesh.h ascension/shader.h ascension/scene.h \
    1.33 + ascension/transform.h ascension/camera.h ascension/font.h \
    1.34 + ascension/error.h ascension/utils.h
    1.35  	@echo "Compiling $<"
    1.36  	$(CC) -o $@ $(CFLAGS) -c $<
    1.37  
    1.38 @@ -65,24 +66,32 @@
    1.39  	$(CC) -o $@ $(CFLAGS) -c $<
    1.40  
    1.41  $(BUILD_DIR)/font.o: font.c ascension/font.h ascension/context.h \
    1.42 - ascension/datatypes.h ascension/window.h ascension/primitives.h \
    1.43 - ascension/mesh.h ascension/scene.h ascension/transform.h \
    1.44 - ascension/camera.h ascension/font.h ascension/error.h
    1.45 + ascension/datatypes.h ascension/window.h ascension/glcontext.h \
    1.46 + ascension/primitives.h ascension/mesh.h ascension/shader.h \
    1.47 + ascension/scene.h ascension/transform.h ascension/camera.h \
    1.48 + ascension/font.h ascension/error.h
    1.49 +	@echo "Compiling $<"
    1.50 +	$(CC) -o $@ $(CFLAGS) -c $<
    1.51 +
    1.52 +$(BUILD_DIR)/glcontext.o: glcontext.c ascension/glcontext.h \
    1.53 + ascension/primitives.h ascension/mesh.h ascension/shader.h \
    1.54 + ascension/error.h
    1.55  	@echo "Compiling $<"
    1.56  	$(CC) -o $@ $(CFLAGS) -c $<
    1.57  
    1.58  $(BUILD_DIR)/primitives.o: primitives.c ascension/primitives.h \
    1.59   ascension/mesh.h ascension/error.h ascension/context.h \
    1.60 - ascension/datatypes.h ascension/window.h ascension/primitives.h \
    1.61 - ascension/scene.h ascension/transform.h ascension/camera.h \
    1.62 - ascension/font.h
    1.63 + ascension/datatypes.h ascension/window.h ascension/glcontext.h \
    1.64 + ascension/primitives.h ascension/shader.h ascension/scene.h \
    1.65 + ascension/transform.h ascension/camera.h ascension/font.h
    1.66  	@echo "Compiling $<"
    1.67  	$(CC) -o $@ $(CFLAGS) -c $<
    1.68  
    1.69  $(BUILD_DIR)/scene.o: scene.c ascension/scene.h ascension/datatypes.h \
    1.70   ascension/transform.h ascension/camera.h ascension/error.h \
    1.71 - ascension/context.h ascension/window.h ascension/primitives.h \
    1.72 - ascension/mesh.h ascension/scene.h ascension/font.h ascension/shader.h
    1.73 + ascension/context.h ascension/window.h ascension/glcontext.h \
    1.74 + ascension/primitives.h ascension/mesh.h ascension/shader.h \
    1.75 + ascension/scene.h ascension/font.h ascension/shader.h
    1.76  	@echo "Compiling $<"
    1.77  	$(CC) -o $@ $(CFLAGS) -c $<
    1.78  
    1.79 @@ -94,15 +103,16 @@
    1.80  $(BUILD_DIR)/text.o: text.c ascension/text.h ascension/font.h \
    1.81   ascension/scene.h ascension/datatypes.h ascension/transform.h \
    1.82   ascension/camera.h ascension/context.h ascension/window.h \
    1.83 - ascension/primitives.h ascension/mesh.h ascension/error.h \
    1.84 - ascension/shader.h
    1.85 + ascension/glcontext.h ascension/primitives.h ascension/mesh.h \
    1.86 + ascension/shader.h ascension/error.h ascension/shader.h
    1.87  	@echo "Compiling $<"
    1.88  	$(CC) -o $@ $(CFLAGS) -c $<
    1.89  
    1.90  $(BUILD_DIR)/window.o: window.c ascension/window.h ascension/datatypes.h \
    1.91 - ascension/primitives.h ascension/mesh.h ascension/scene.h \
    1.92 - ascension/transform.h ascension/camera.h ascension/context.h \
    1.93 - ascension/window.h ascension/font.h ascension/error.h ascension/utils.h
    1.94 + ascension/glcontext.h ascension/primitives.h ascension/mesh.h \
    1.95 + ascension/shader.h ascension/scene.h ascension/transform.h \
    1.96 + ascension/camera.h ascension/context.h ascension/window.h \
    1.97 + ascension/font.h ascension/error.h ascension/utils.h
    1.98  	@echo "Compiling $<"
    1.99  	$(CC) -o $@ $(CFLAGS) -c $<
   1.100  
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/ascension/glcontext.h	Tue Mar 26 20:37:21 2024 +0100
     2.3 @@ -0,0 +1,67 @@
     2.4 +/*
     2.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     2.6 + * Copyright 2023 Mike Becker. All rights reserved.
     2.7 + *
     2.8 + * Redistribution and use in source and binary forms, with or without
     2.9 + * modification, are permitted provided that the following conditions are met:
    2.10 + *
    2.11 + *   1. Redistributions of source code must retain the above copyright
    2.12 + *      notice, this list of conditions and the following disclaimer.
    2.13 + *
    2.14 + *   2. Redistributions in binary form must reproduce the above copyright
    2.15 + *      notice, this list of conditions and the following disclaimer in the
    2.16 + *      documentation and/or other materials provided with the distribution.
    2.17 + *
    2.18 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    2.19 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    2.20 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    2.21 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    2.22 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    2.23 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    2.24 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    2.25 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    2.26 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    2.27 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    2.28 + * POSSIBILITY OF SUCH DAMAGE.
    2.29 + */
    2.30 +
    2.31 +#ifndef ASCENSION_GLCONTEXT_H
    2.32 +#define ASCENSION_GLCONTEXT_H
    2.33 +
    2.34 +#include <SDL2/SDL.h>
    2.35 +
    2.36 +#include "primitives.h"
    2.37 +#include "shader.h"
    2.38 +
    2.39 +typedef struct AscGLContextSettings {
    2.40 +    int gl_major_version;
    2.41 +    int gl_minor_version;
    2.42 +    int vsync;
    2.43 +    int depth_size;
    2.44 +} AscGLContextSettings;
    2.45 +
    2.46 +typedef struct AscGLContext {
    2.47 +    SDL_Window *window;
    2.48 +    SDL_GLContext glctx;
    2.49 +    AscPrimitives primitives;
    2.50 +    struct {
    2.51 +        AscShaderSprite sprite;
    2.52 +    } shader;
    2.53 +} AscGLContext;
    2.54 +
    2.55 +__attribute__((__nonnull__, __warn_unused_result__))
    2.56 +bool asc_gl_context_initialize(
    2.57 +        AscGLContext *ctx,
    2.58 +        SDL_Window *window,
    2.59 +        AscGLContextSettings const *settings
    2.60 +);
    2.61 +
    2.62 +__attribute__((__nonnull__))
    2.63 +void asc_gl_context_destroy(AscGLContext *ctx);
    2.64 +
    2.65 +__attribute__((__nonnull__))
    2.66 +static inline void asc_gl_context_activate(AscGLContext *ctx) {
    2.67 +    SDL_GL_MakeCurrent(ctx->window, ctx->glctx);
    2.68 +}
    2.69 +
    2.70 +#endif //ASCENSION_GLCONTEXT_H
     3.1 --- a/src/ascension/shader.h	Thu Mar 21 23:01:09 2024 +0100
     3.2 +++ b/src/ascension/shader.h	Tue Mar 26 20:37:21 2024 +0100
     3.3 @@ -46,9 +46,6 @@
     3.4  } AscShaderSprite;
     3.5  
     3.6  
     3.7 -extern AscShaderSprite ASC_SHADER_SPRITE;
     3.8 -
     3.9 -
    3.10  /**
    3.11   * Compiles a shader from the given source code.
    3.12   *
    3.13 @@ -98,17 +95,10 @@
    3.14   */
    3.15  void asc_shader_program_destroy(AscShaderProgram program);
    3.16  
    3.17 -/**
    3.18 - * Initializes shaders that already come with the engine.
    3.19 - */
    3.20 -void asc_shader_initialize_predefined(void);
    3.21  
    3.22 -/**
    3.23 - * You do not need to do this manually.
    3.24 - *
    3.25 - * When the ascension context is destroyed, this function is called automatically.
    3.26 - * When you did not initialize the predefined shaders, this function does nothing.
    3.27 - */
    3.28 -void asc_shader_destroy_predefined(void);
    3.29 +AscShaderProgram asc_shader_easy_compile_and_link(
    3.30 +        char const *vtxName,
    3.31 +        char const *fragName
    3.32 +);
    3.33  
    3.34  #endif //ASCENSION_SHADER_H
     4.1 --- a/src/ascension/window.h	Thu Mar 21 23:01:09 2024 +0100
     4.2 +++ b/src/ascension/window.h	Tue Mar 26 20:37:21 2024 +0100
     4.3 @@ -31,7 +31,7 @@
     4.4  #include <SDL2/SDL.h>
     4.5  
     4.6  #include "datatypes.h"
     4.7 -#include "primitives.h"
     4.8 +#include "glcontext.h"
     4.9  #include "scene.h"
    4.10  
    4.11  #ifndef ASC_MAX_WINDOWS
    4.12 @@ -40,22 +40,18 @@
    4.13  #endif // ASC_MAX_WINDOWS
    4.14  
    4.15  typedef struct AscWindowSettings {
    4.16 -    int depth_size;
    4.17 -    int vsync;
    4.18      asc_vec2i dimensions;
    4.19      int fullscreen;
    4.20 -    int gl_major_version;
    4.21 -    int gl_minor_version;
    4.22      char const* title;
    4.23 +    AscGLContextSettings glsettings;
    4.24  } AscWindowSettings;
    4.25  
    4.26  typedef struct AscWindow {
    4.27      Uint32 id;
    4.28      SDL_Window* window;
    4.29 -    SDL_GLContext glctx;
    4.30 -    AscPrimitives primitives;
    4.31      asc_vec2i dimensions;
    4.32      bool resized;
    4.33 +    AscGLContext glctx;
    4.34      AscScene ui;
    4.35  } AscWindow;
    4.36  
    4.37 @@ -112,7 +108,7 @@
    4.38   *
    4.39   * @param the window to activate
    4.40   */
    4.41 -void asc_window_activate(AscWindow const *window);
    4.42 +void asc_window_activate(AscWindow *window);
    4.43  
    4.44  #endif /* ASCENSION_WINDOW_H */
    4.45  
     5.1 --- a/src/context.c	Thu Mar 21 23:01:09 2024 +0100
     5.2 +++ b/src/context.c	Tue Mar 26 20:37:21 2024 +0100
     5.3 @@ -63,7 +63,6 @@
     5.4  }
     5.5  
     5.6  void asc_context_destroy(void) {
     5.7 -    asc_shader_destroy_predefined();
     5.8      for (unsigned int i = 0 ; i < ASC_MAX_WINDOWS ; i++) {
     5.9          asc_window_destroy(&asc_context.windows[i]);
    5.10      }
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/glcontext.c	Tue Mar 26 20:37:21 2024 +0100
     6.3 @@ -0,0 +1,111 @@
     6.4 +/*
     6.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     6.6 + * Copyright 2023 Mike Becker. All rights reserved.
     6.7 + *
     6.8 + * Redistribution and use in source and binary forms, with or without
     6.9 + * modification, are permitted provided that the following conditions are met:
    6.10 + *
    6.11 + *   1. Redistributions of source code must retain the above copyright
    6.12 + *      notice, this list of conditions and the following disclaimer.
    6.13 + *
    6.14 + *   2. Redistributions in binary form must reproduce the above copyright
    6.15 + *      notice, this list of conditions and the following disclaimer in the
    6.16 + *      documentation and/or other materials provided with the distribution.
    6.17 + *
    6.18 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    6.19 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    6.20 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    6.21 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    6.22 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    6.23 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    6.24 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    6.25 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    6.26 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    6.27 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    6.28 + * POSSIBILITY OF SUCH DAMAGE.
    6.29 + */
    6.30 +
    6.31 +#include "ascension/glcontext.h"
    6.32 +#include "ascension/error.h"
    6.33 +
    6.34 +#include <cx/printf.h>
    6.35 +
    6.36 +#include <GL/glew.h>
    6.37 +
    6.38 +static void asc_gl_debug_callback(
    6.39 +        GLenum source, GLenum type, GLuint id, GLenum severity,
    6.40 +        GLsizei length, const GLchar* message,
    6.41 +        const void* userParam
    6.42 +) {
    6.43 +    cxmutstr buf = cx_asprintf(
    6.44 +            "source = %d, id = %u, type = %d, severity= %d, message = %.*s",
    6.45 +            source, id, type, severity, length, message);
    6.46 +    if (type == GL_DEBUG_TYPE_ERROR) {
    6.47 +        asc_error(buf.ptr);
    6.48 +    } else {
    6.49 +        asc_dprintf("GL debug: %.*s", (int)buf.length, buf.ptr);
    6.50 +    }
    6.51 +    cx_strfree(&buf);
    6.52 +}
    6.53 +
    6.54 +static void asc_shader_initialize_predefined(AscGLContext *ctx) {
    6.55 +    AscShaderSprite *sprite = &ctx->shader.sprite;
    6.56 +    sprite->base = asc_shader_easy_compile_and_link("shader/sprite_vtx.glsl", "shader/sprite_frag.glsl");
    6.57 +    sprite->surface = glGetUniformLocation(sprite->base.id, "surface");
    6.58 +    sprite->depth = glGetUniformLocation(sprite->base.id, "depth");
    6.59 +}
    6.60 +
    6.61 +static void asc_shader_destroy_predefined(AscGLContext *ctx) {
    6.62 +    asc_shader_program_destroy(ctx->shader.sprite.base);
    6.63 +}
    6.64 +
    6.65 +bool asc_gl_context_initialize(
    6.66 +        AscGLContext *ctx,
    6.67 +        SDL_Window *window,
    6.68 +        AscGLContextSettings const *settings
    6.69 +) {
    6.70 +    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
    6.71 +    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, settings->gl_major_version);
    6.72 +    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, settings->gl_minor_version);
    6.73 +    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, settings->depth_size);
    6.74 +    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    6.75 +    ctx->glctx = SDL_GL_CreateContext(window);
    6.76 +    if (ctx->glctx == NULL) return false;
    6.77 +    ctx->window = window;
    6.78 +
    6.79 +    glewExperimental = GL_TRUE;
    6.80 +    GLenum err = glewInit();
    6.81 +    if (err == GLEW_OK) {
    6.82 +        SDL_GL_SetSwapInterval(settings->vsync);
    6.83 +
    6.84 +        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    6.85 +        glEnable(GL_DEBUG_OUTPUT);
    6.86 +        glDebugMessageCallback(asc_gl_debug_callback, NULL);
    6.87 +
    6.88 +        if (!asc_primitives_init(&ctx->primitives)) {
    6.89 +            asc_error("Creating primitive meshes failed");
    6.90 +            SDL_GL_DeleteContext(ctx->glctx);
    6.91 +            return false;
    6.92 +        }
    6.93 +
    6.94 +        asc_shader_initialize_predefined(ctx);
    6.95 +
    6.96 +        return true;
    6.97 +    } else {
    6.98 +        asc_error(glewGetErrorString(err));
    6.99 +        SDL_GL_DeleteContext(ctx->glctx);
   6.100 +        return false;
   6.101 +    }
   6.102 +}
   6.103 +
   6.104 +void asc_gl_context_destroy(AscGLContext *ctx) {
   6.105 +    if (ctx->glctx == NULL) return;
   6.106 +    SDL_GL_MakeCurrent(ctx->window, ctx->glctx);
   6.107 +
   6.108 +    asc_shader_destroy_predefined(ctx);
   6.109 +    asc_primitives_destroy(&ctx->primitives);
   6.110 +
   6.111 +    // destroy the GL context and the window
   6.112 +    SDL_GL_DeleteContext(ctx->glctx);
   6.113 +    ctx->glctx = NULL;
   6.114 +}
     7.1 --- a/src/primitives.c	Thu Mar 21 23:01:09 2024 +0100
     7.2 +++ b/src/primitives.c	Tue Mar 26 20:37:21 2024 +0100
     7.3 @@ -87,7 +87,7 @@
     7.4  }
     7.5  
     7.6  void asc_primitives_draw_plane(void) {
     7.7 -    AscMesh const *mesh = &(asc_context.active_window->primitives.plane);
     7.8 +    AscMesh const *mesh = &(asc_context.active_window->glctx.primitives.plane);
     7.9      glBindVertexArray(mesh->vao);
    7.10      glDrawArrays(GL_TRIANGLE_STRIP, 0, mesh->vertices);
    7.11  }
    7.12 \ No newline at end of file
     8.1 --- a/src/scene.c	Thu Mar 21 23:01:09 2024 +0100
     8.2 +++ b/src/scene.c	Tue Mar 26 20:37:21 2024 +0100
     8.3 @@ -159,6 +159,7 @@
     8.4      // -----------------------------------------
     8.5      // process the render groups for each camera
     8.6      // -----------------------------------------
     8.7 +    AscShaderProgram *shader;
     8.8      cx_for_n(cam_id, ASC_SCENE_CAMERAS_MAX) {
     8.9          // update camera parameters, first
    8.10          AscCamera *camera = &scene->cameras[cam_id];
    8.11 @@ -173,8 +174,9 @@
    8.12          // Sprites
    8.13          // -------
    8.14          // TODO: see if we can really always ignore the view matrix
    8.15 -        glUseProgram(ASC_SHADER_SPRITE.base.id);
    8.16 -        glUniformMatrix4fv(ASC_SHADER_SPRITE.base.projection, 1,
    8.17 +        shader = &asc_context.active_window->glctx.shader.sprite;
    8.18 +        glUseProgram(shader->id);
    8.19 +        glUniformMatrix4fv(shader->projection, 1,
    8.20                             GL_FALSE, camera->projection);
    8.21  
    8.22          // render opaque sprites from front to back
     9.1 --- a/src/shader.c	Thu Mar 21 23:01:09 2024 +0100
     9.2 +++ b/src/shader.c	Tue Mar 26 20:37:21 2024 +0100
     9.3 @@ -126,7 +126,7 @@
     9.4      program.id = 0;
     9.5  }
     9.6  
     9.7 -static AscShaderProgram asc_shader_compile_link_discard(
     9.8 +AscShaderProgram asc_shader_easy_compile_and_link(
     9.9          char const *vtxName, char const *fragName) {
    9.10      AscShader font_vtx = asc_shader_compilef(GL_VERTEX_SHADER, vtxName);
    9.11      AscShader font_frag = asc_shader_compilef(GL_FRAGMENT_SHADER, fragName);
    9.12 @@ -135,13 +135,3 @@
    9.13      asc_shader_destroy(font_frag);
    9.14      return prog;
    9.15  }
    9.16 -
    9.17 -void asc_shader_initialize_predefined(void) {
    9.18 -    ASC_SHADER_SPRITE.base = asc_shader_compile_link_discard("shader/sprite_vtx.glsl", "shader/sprite_frag.glsl");
    9.19 -    ASC_SHADER_SPRITE.surface = glGetUniformLocation(ASC_SHADER_SPRITE.base.id, "surface");
    9.20 -    ASC_SHADER_SPRITE.depth = glGetUniformLocation(ASC_SHADER_SPRITE.base.id, "depth");
    9.21 -}
    9.22 -
    9.23 -void asc_shader_destroy_predefined(void) {
    9.24 -    asc_shader_program_destroy(ASC_SHADER_SPRITE.base);
    9.25 -}
    9.26 \ No newline at end of file
    10.1 --- a/src/text.c	Thu Mar 21 23:01:09 2024 +0100
    10.2 +++ b/src/text.c	Tue Mar 26 20:37:21 2024 +0100
    10.3 @@ -37,17 +37,20 @@
    10.4          return;
    10.5      }
    10.6  
    10.7 +    // Obtain shader
    10.8 +    AscShaderSprite *shader = &asc_context.active_window->glctx.shader.sprite;
    10.9 +
   10.10      // Upload model matrix
   10.11 -    glUniformMatrix4fv(ASC_SHADER_SPRITE.base.model, 1,
   10.12 +    glUniformMatrix4fv(shader->base.model, 1,
   10.13                         GL_FALSE, node->base.final_transform);
   10.14  
   10.15      // Upload surface
   10.16      glActiveTexture(GL_TEXTURE0);
   10.17      glBindTexture(GL_TEXTURE_RECTANGLE, node->tex_id);
   10.18 -    glUniform1i(ASC_SHADER_SPRITE.surface, 0);
   10.19 +    glUniform1i(shader->surface, 0);
   10.20  
   10.21      // Apply depth
   10.22 -    glUniform1f(ASC_SHADER_SPRITE.depth, (float)(node->base.depth));
   10.23 +    glUniform1f(shader->depth, (float)(node->base.depth));
   10.24  
   10.25      // Draw mesh
   10.26      asc_primitives_draw_plane();
    11.1 --- a/src/window.c	Thu Mar 21 23:01:09 2024 +0100
    11.2 +++ b/src/window.c	Tue Mar 26 20:37:21 2024 +0100
    11.3 @@ -30,34 +30,16 @@
    11.4  #include "ascension/error.h"
    11.5  #include "ascension/utils.h"
    11.6  
    11.7 -#include <cx/printf.h>
    11.8 -
    11.9  #include <GL/glew.h>
   11.10  
   11.11 -static void asc_gl_debug_callback(
   11.12 -        GLenum source, GLenum type, GLuint id, GLenum severity,
   11.13 -        GLsizei length, const GLchar* message,
   11.14 -        const void* userParam
   11.15 -) {
   11.16 -    cxmutstr buf = cx_asprintf(
   11.17 -            "source = %d, id = %u, type = %d, severity= %d, message = %.*s",
   11.18 -            source, id, type, severity, length, message);
   11.19 -    if (type == GL_DEBUG_TYPE_ERROR) {
   11.20 -        asc_error(buf.ptr);
   11.21 -    } else {
   11.22 -        asc_dprintf("GL debug: %.*s", (int)buf.length, buf.ptr);
   11.23 -    }
   11.24 -    cx_strfree(&buf);
   11.25 -}
   11.26 -
   11.27  void asc_window_settings_init_defaults(AscWindowSettings* settings) {
   11.28 -    settings->depth_size = 24;
   11.29 -    settings->vsync = 1;
   11.30      settings->dimensions.width = 800;
   11.31      settings->dimensions.height = 600;
   11.32      settings->fullscreen = 0;
   11.33 -    settings->gl_major_version = 4;
   11.34 -    settings->gl_minor_version = 0;
   11.35 +    settings->glsettings.depth_size = 24;
   11.36 +    settings->glsettings.vsync = 1;
   11.37 +    settings->glsettings.gl_major_version = 4;
   11.38 +    settings->glsettings.gl_minor_version = 0;
   11.39      settings->title = "Ascended Window";
   11.40  }
   11.41  
   11.42 @@ -103,44 +85,19 @@
   11.43      );
   11.44      window->resized = true; // count initial sizing as resize
   11.45  
   11.46 -    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
   11.47 -    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, settings->gl_major_version);
   11.48 -    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, settings->gl_minor_version);
   11.49 -    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, settings->depth_size);
   11.50 -    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
   11.51 -    window->glctx = SDL_GL_CreateContext(window->window);
   11.52 -    if (window->glctx == NULL) {
   11.53 +    if (asc_gl_context_initialize(&window->glctx, window->window, &settings->glsettings)) {
   11.54 +        asc_dprintf("Window %u initialized", window->id);
   11.55 +        asc_context.active_window = window;
   11.56 +        asc_window_init_scenes(window);
   11.57 +        return window;
   11.58 +    } else {
   11.59          asc_dprintf("Creating GL context failed for window %u", window->id);
   11.60 -    } else {
   11.61 -        glewExperimental = GL_TRUE;
   11.62 -        GLenum err = glewInit();
   11.63 -        if (err == GLEW_OK) {
   11.64 -            SDL_GL_SetSwapInterval(settings->vsync);
   11.65 -            glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
   11.66 -            glEnable(GL_DEBUG_OUTPUT);
   11.67 -            glDebugMessageCallback(asc_gl_debug_callback, NULL);
   11.68 -
   11.69 -            asc_dprintf("Window %u initialized", window->id);
   11.70 -            if (asc_primitives_init(&window->primitives)) {
   11.71 -                asc_context.active_window = window;
   11.72 -                asc_window_init_scenes(window);
   11.73 -                return window;
   11.74 -            } else {
   11.75 -                asc_dprintf("!!! Creating primitives for window %u failed !!!", window->id);
   11.76 -            }
   11.77 -        } else {
   11.78 -            asc_error(glewGetErrorString(err));
   11.79 -        }
   11.80 +        // cleanup on error
   11.81 +        SDL_DestroyWindow(window->window);
   11.82 +        window->window = NULL;
   11.83 +        window->id = 0;
   11.84 +        return NULL;
   11.85      }
   11.86 -
   11.87 -    // cleanup on error
   11.88 -    if (window->glctx != NULL) {
   11.89 -        SDL_GL_DeleteContext(window->glctx);
   11.90 -    }
   11.91 -    window->glctx = NULL;
   11.92 -    SDL_DestroyWindow(window->window);
   11.93 -    window->window = NULL;
   11.94 -    window->id = 0;
   11.95  }
   11.96  
   11.97  void asc_window_destroy(AscWindow* window) {
   11.98 @@ -155,22 +112,17 @@
   11.99      // destroy all scenes
  11.100      asc_scene_destroy(&window->ui);
  11.101  
  11.102 -    // release context related data (we have to make the GL context current for this)
  11.103 -    SDL_GL_MakeCurrent(window->window, window->glctx);
  11.104 -    asc_primitives_destroy(&window->primitives);
  11.105 +    // release context related data
  11.106 +    asc_gl_context_destroy(&window->glctx);
  11.107  
  11.108 -    // destroy the GL context and the window
  11.109 -    if (window->glctx != NULL) {
  11.110 -        SDL_GL_DeleteContext(window->glctx);
  11.111 -    }
  11.112 +    // destroy window
  11.113      if (window->window != NULL) {
  11.114          SDL_DestroyWindow(window->window);
  11.115      }
  11.116  
  11.117      // if another window was active, make the other context current again
  11.118      if (asc_context.active_window != NULL) {
  11.119 -        AscWindow const *aw = asc_context.active_window;
  11.120 -        SDL_GL_MakeCurrent(aw->window, aw->glctx);
  11.121 +        asc_gl_context_activate(&asc_context.active_window->glctx);
  11.122      }
  11.123  
  11.124      // clean the data
  11.125 @@ -179,7 +131,7 @@
  11.126  }
  11.127  
  11.128  void asc_window_sync(AscWindow* window) {
  11.129 -    AscWindow const *active_window = asc_context.active_window;
  11.130 +    AscWindow *active_window = asc_context.active_window;
  11.131      if (window != active_window) {
  11.132          asc_window_activate(window);
  11.133      }
  11.134 @@ -198,7 +150,7 @@
  11.135      }
  11.136  }
  11.137  
  11.138 -void asc_window_activate(AscWindow const *window) {
  11.139 -    SDL_GL_MakeCurrent(window->window, window->glctx);
  11.140 +void asc_window_activate(AscWindow *window) {
  11.141 +    asc_gl_context_activate(&window->glctx);
  11.142      asc_context.active_window = (AscWindow *)window;
  11.143  }
    12.1 --- a/test/Makefile	Thu Mar 21 23:01:09 2024 +0100
    12.2 +++ b/test/Makefile	Tue Mar 26 20:37:21 2024 +0100
    12.3 @@ -44,10 +44,11 @@
    12.4  $(BUILD_DIR)/snake.o: snake.c ../src/ascension/ascension.h \
    12.5   ../src/ascension/error.h ../src/ascension/context.h \
    12.6   ../src/ascension/datatypes.h ../src/ascension/window.h \
    12.7 - ../src/ascension/primitives.h ../src/ascension/mesh.h \
    12.8 + ../src/ascension/glcontext.h ../src/ascension/primitives.h \
    12.9 + ../src/ascension/mesh.h ../src/ascension/shader.h \
   12.10   ../src/ascension/scene.h ../src/ascension/transform.h \
   12.11   ../src/ascension/camera.h ../src/ascension/font.h \
   12.12 - ../src/ascension/shader.h ../src/ascension/text.h
   12.13 + ../src/ascension/text.h
   12.14  	@echo "Compiling $<"
   12.15  	$(CC) -o $@ $(CFLAGS) -c $<
   12.16  
    13.1 --- a/test/snake.c	Thu Mar 21 23:01:09 2024 +0100
    13.2 +++ b/test/snake.c	Tue Mar 26 20:37:21 2024 +0100
    13.3 @@ -82,12 +82,11 @@
    13.4          return 1;
    13.5      }
    13.6  
    13.7 +    // create window
    13.8      AscWindowSettings settings;
    13.9      asc_window_settings_init_defaults(&settings);
   13.10      settings.title = "Snake";
   13.11 -
   13.12      AscWindow *window = asc_window_initialize(0, &settings);
   13.13 -    asc_shader_initialize_predefined();
   13.14  
   13.15      // create UI elements
   13.16      create_fps_counter();

mercurial