add shader loading and unloading

Wed, 08 Nov 2023 23:17:07 +0100

author
Mike Becker <universe@uap-core.de>
date
Wed, 08 Nov 2023 23:17:07 +0100
changeset 15
362b7659dc76
parent 14
9dbfc0031887
child 16
c5dde81b6fb2

add shader loading and unloading

shader/font_frag.glsl file | annotate | diff | comparison | revisions
shader/font_vtx.glsl file | annotate | diff | comparison | revisions
src/Makefile file | annotate | diff | comparison | revisions
src/ascension/ascension.h file | annotate | diff | comparison | revisions
src/ascension/error.h file | annotate | diff | comparison | revisions
src/ascension/files.h file | annotate | diff | comparison | revisions
src/ascension/shader.h file | annotate | diff | comparison | revisions
src/context.c file | annotate | diff | comparison | revisions
src/error.c file | annotate | diff | comparison | revisions
src/files.c file | annotate | diff | comparison | revisions
src/shader.c file | annotate | diff | comparison | revisions
test/Makefile file | annotate | diff | comparison | revisions
test/sandbox.c file | annotate | diff | comparison | revisions
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/shader/font_frag.glsl	Wed Nov 08 23:17:07 2023 +0100
     1.3 @@ -0,0 +1,10 @@
     1.4 +#version 400 core
     1.5 +
     1.6 +in vec2 texcoord;
     1.7 +out vec4 fragment;
     1.8 +
     1.9 +uniform sampler2DRect surface;
    1.10 +
    1.11 +void main(void) {
    1.12 +    fragment = texture(surface, texcoord);
    1.13 +}
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/shader/font_vtx.glsl	Wed Nov 08 23:17:07 2023 +0100
     2.3 @@ -0,0 +1,12 @@
     2.4 +#version 400 core
     2.5 +
     2.6 +in vec2 position;
     2.7 +out vec2 texcoord;
     2.8 +
     2.9 +uniform mat4 projection;
    2.10 +uniform mat4 model;
    2.11 +
    2.12 +void main(void) {
    2.13 +    gl_Position = projection*model*vec4(position, 0.0, 1.0);
    2.14 +    texcoord = position;
    2.15 +}
     3.1 --- a/src/Makefile	Wed Nov 08 21:53:43 2023 +0100
     3.2 +++ b/src/Makefile	Wed Nov 08 23:17:07 2023 +0100
     3.3 @@ -27,7 +27,7 @@
     3.4  
     3.5  BUILD_DIR=../build/lib
     3.6  
     3.7 -SRC  = context.c error.c window.c font.c
     3.8 +SRC  = context.c error.c window.c font.c files.c shader.c
     3.9  
    3.10  OBJ = $(SRC:%.c=$(BUILD_DIR)/%.o)
    3.11  
    3.12 @@ -42,7 +42,7 @@
    3.13  
    3.14  $(BUILD_DIR)/context.o: context.c ascension/context.h ascension/window.h \
    3.15   ascension/datatypes.h ascension/font.h ascension/error.h \
    3.16 - ascension/utils.h
    3.17 + ascension/utils.h ascension/shader.h
    3.18  	@echo "Compiling $<"
    3.19  	$(CC) -o $@ $(CFLAGS) -c $<
    3.20  
    3.21 @@ -52,12 +52,21 @@
    3.22  	@echo "Compiling $<"
    3.23  	$(CC) -o $@ $(CFLAGS) -c $<
    3.24  
    3.25 +$(BUILD_DIR)/files.o: files.c ascension/files.h ascension/error.h
    3.26 +	@echo "Compiling $<"
    3.27 +	$(CC) -o $@ $(CFLAGS) -c $<
    3.28 +
    3.29  $(BUILD_DIR)/font.o: font.c ascension/font.h ascension/context.h \
    3.30   ascension/window.h ascension/datatypes.h ascension/font.h \
    3.31   ascension/error.h
    3.32  	@echo "Compiling $<"
    3.33  	$(CC) -o $@ $(CFLAGS) -c $<
    3.34  
    3.35 +$(BUILD_DIR)/shader.o: shader.c ascension/shader.h ascension/files.h \
    3.36 + ascension/error.h
    3.37 +	@echo "Compiling $<"
    3.38 +	$(CC) -o $@ $(CFLAGS) -c $<
    3.39 +
    3.40  $(BUILD_DIR)/window.o: window.c ascension/window.h ascension/datatypes.h \
    3.41   ascension/context.h ascension/window.h ascension/font.h \
    3.42   ascension/error.h ascension/utils.h
     4.1 --- a/src/ascension/ascension.h	Wed Nov 08 21:53:43 2023 +0100
     4.2 +++ b/src/ascension/ascension.h	Wed Nov 08 23:17:07 2023 +0100
     4.3 @@ -28,8 +28,9 @@
     4.4  #ifndef ASCENSION_H
     4.5  #define ASCENSION_H
     4.6  
     4.7 +#include "error.h"
     4.8  #include "context.h"
     4.9 -#include "error.h"
    4.10 +#include "shader.h"
    4.11  
    4.12  #endif /* ASCENSION_H */
    4.13  
     5.1 --- a/src/ascension/error.h	Wed Nov 08 21:53:43 2023 +0100
     5.2 +++ b/src/ascension/error.h	Wed Nov 08 23:17:07 2023 +0100
     5.3 @@ -29,6 +29,7 @@
     5.4  #define ASCENSION_ERROR_H
     5.5  
     5.6  #include <cx/string.h>
     5.7 +#include <stdio.h>
     5.8  
     5.9  void asc_error_cxstr(cxstring text);
    5.10  void asc_error_cchar(char const* text);
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/ascension/files.h	Wed Nov 08 23:17:07 2023 +0100
     6.3 @@ -0,0 +1,38 @@
     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 +#ifndef ASCENSION_FILES_H
    6.32 +#define ASCENSION_FILES_H
    6.33 +
    6.34 +#include <cx/string.h>
    6.35 +
    6.36 +typedef cxstring asc_file;
    6.37 +
    6.38 +asc_file asc_file_mmap_rdonly(char const *filename);
    6.39 +void asc_file_unmap(asc_file ptr);
    6.40 +
    6.41 +#endif //ASCENSION_FILES_H
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/src/ascension/shader.h	Wed Nov 08 23:17:07 2023 +0100
     7.3 @@ -0,0 +1,107 @@
     7.4 +/*
     7.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     7.6 + * Copyright 2023 Mike Becker. All rights reserved.
     7.7 + *
     7.8 + * Redistribution and use in source and binary forms, with or without
     7.9 + * modification, are permitted provided that the following conditions are met:
    7.10 + *
    7.11 + *   1. Redistributions of source code must retain the above copyright
    7.12 + *      notice, this list of conditions and the following disclaimer.
    7.13 + *
    7.14 + *   2. Redistributions in binary form must reproduce the above copyright
    7.15 + *      notice, this list of conditions and the following disclaimer in the
    7.16 + *      documentation and/or other materials provided with the distribution.
    7.17 + *
    7.18 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    7.19 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    7.20 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    7.21 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    7.22 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    7.23 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    7.24 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    7.25 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    7.26 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    7.27 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    7.28 + * POSSIBILITY OF SUCH DAMAGE.
    7.29 + */
    7.30 +
    7.31 +#ifndef ASCENSION_SHADER_H
    7.32 +#define ASCENSION_SHADER_H
    7.33 +
    7.34 +typedef struct AscShader {
    7.35 +    unsigned int id;
    7.36 +} AscShader;
    7.37 +
    7.38 +typedef struct AscShaderProgram {
    7.39 +    unsigned int id;
    7.40 +    AscShader vertex;
    7.41 +    AscShader fragment;
    7.42 +} AscShaderProgram;
    7.43 +
    7.44 +
    7.45 +extern AscShaderProgram ASC_SHADER_FONT;
    7.46 +
    7.47 +
    7.48 +/**
    7.49 + * Compiles a shader from the given source code.
    7.50 + *
    7.51 + * The ID of the returned shader will be zero when something went wrong.
    7.52 + *
    7.53 + * @param type the shader type (use the GL enum)
    7.54 + * @param code the source code
    7.55 + * @param length the length of the source code
    7.56 + * @return the compiled shader
    7.57 + */
    7.58 +AscShader asc_shader_compile(unsigned int type, char const *code, int length);
    7.59 +
    7.60 +/**
    7.61 + * Compiles a shader from the given source file.
    7.62 + *
    7.63 + * The ID of the returned shader will be zero when something went wrong.
    7.64 + * The file is mapped into memory for compilation and then unmapped again.
    7.65 + *
    7.66 + * @param type the shader type (use the GL enum)
    7.67 + * @param filename the path to the shader file
    7.68 + * @return the compiled shader
    7.69 + */
    7.70 +AscShader asc_shader_compilef(unsigned int type, char const *filename);
    7.71 +
    7.72 +/**
    7.73 + * This function links shaders into a program.
    7.74 + *
    7.75 + * The ID of the returned program will be zero when something went wrong.
    7.76 + *
    7.77 + * @param vertex the vertex shader
    7.78 + * @param fragment the fragment shader
    7.79 + * @return a compiled program
    7.80 + */
    7.81 +AscShaderProgram asc_shader_link(AscShader vertex, AscShader fragment);
    7.82 +
    7.83 +/**
    7.84 + * Destroys the shader.
    7.85 + *
    7.86 + * @param shader the shader
    7.87 + */
    7.88 +void asc_shader_destroy(AscShader shader);
    7.89 +
    7.90 +/**
    7.91 + * Destroys the shader program.
    7.92 + *
    7.93 + * @param program the program
    7.94 + */
    7.95 +void asc_shader_program_destroy(AscShaderProgram program);
    7.96 +
    7.97 +/**
    7.98 + * Initializes shaders that already come with the engine.
    7.99 + */
   7.100 +void asc_shader_initialize_predefined(void);
   7.101 +
   7.102 +/**
   7.103 + * You do not need to do this manually.
   7.104 + *
   7.105 + * When the ascension context is destroyed, this function is called automatically.
   7.106 + * When you did not initialize the predefined shaders, this function does nothing.
   7.107 + */
   7.108 +void asc_shader_destroy_predefined(void);
   7.109 +
   7.110 +#endif //ASCENSION_SHADER_H
     8.1 --- a/src/context.c	Wed Nov 08 21:53:43 2023 +0100
     8.2 +++ b/src/context.c	Wed Nov 08 23:17:07 2023 +0100
     8.3 @@ -28,6 +28,7 @@
     8.4  #include "ascension/context.h"
     8.5  #include "ascension/error.h"
     8.6  #include "ascension/utils.h"
     8.7 +#include "ascension/shader.h"
     8.8  
     8.9  #include <cx/linked_list.h>
    8.10  
    8.11 @@ -64,7 +65,7 @@
    8.12  }
    8.13  
    8.14  void asc_context_destroy(void) {
    8.15 -    // destroy data
    8.16 +    asc_shader_destroy_predefined();
    8.17      for (unsigned int i = 0 ; i < ASC_MAX_WINDOWS ; i++) {
    8.18          asc_window_destroy(&asc_context.windows[i]);
    8.19      }
     9.1 --- a/src/error.c	Wed Nov 08 21:53:43 2023 +0100
     9.2 +++ b/src/error.c	Wed Nov 08 23:17:07 2023 +0100
     9.3 @@ -43,7 +43,7 @@
     9.4      if (text.length == 0) return;
     9.5  
     9.6      // write error to debug output
     9.7 -    asc_dprintf("ERROR: %*.s", (int)text.length, text.ptr);
     9.8 +    asc_dprintf("ERROR: %.*s", (int)text.length, text.ptr);
     9.9  
    9.10      // write error to buffer
    9.11      CxBuffer* buf = &asc_context.error_buffer;
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/src/files.c	Wed Nov 08 23:17:07 2023 +0100
    10.3 @@ -0,0 +1,64 @@
    10.4 +/*
    10.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    10.6 + * Copyright 2023 Mike Becker. All rights reserved.
    10.7 + *
    10.8 + * Redistribution and use in source and binary forms, with or without
    10.9 + * modification, are permitted provided that the following conditions are met:
   10.10 + *
   10.11 + *   1. Redistributions of source code must retain the above copyright
   10.12 + *      notice, this list of conditions and the following disclaimer.
   10.13 + *
   10.14 + *   2. Redistributions in binary form must reproduce the above copyright
   10.15 + *      notice, this list of conditions and the following disclaimer in the
   10.16 + *      documentation and/or other materials provided with the distribution.
   10.17 + *
   10.18 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   10.19 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   10.20 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   10.21 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   10.22 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   10.23 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   10.24 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   10.25 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   10.26 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   10.27 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   10.28 + * POSSIBILITY OF SUCH DAMAGE.
   10.29 + */
   10.30 +
   10.31 +#include "ascension/files.h"
   10.32 +#include "ascension/error.h"
   10.33 +
   10.34 +#include <sys/mman.h>
   10.35 +#include <sys/stat.h>
   10.36 +#include <fcntl.h>
   10.37 +#include <unistd.h>
   10.38 +
   10.39 +asc_file asc_file_mmap_rdonly(char const *filename) {
   10.40 +    int fd = open(filename, O_RDONLY);
   10.41 +    if (fd < 0) {
   10.42 +        asc_dprintf("Failed to open file %s", filename);
   10.43 +        return (cxstring) {NULL, 0};
   10.44 +    }
   10.45 +
   10.46 +    struct stat statbuf;
   10.47 +    int err = fstat(fd, &statbuf);
   10.48 +    if (err < 0) {
   10.49 +        close(fd);
   10.50 +        asc_dprintf("Failed to stat file %s", filename);
   10.51 +        return (cxstring) {NULL, 0};
   10.52 +    }
   10.53 +
   10.54 +    char const *data = mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
   10.55 +    if (data == MAP_FAILED) {
   10.56 +        close(fd);
   10.57 +        asc_dprintf("Failed to map file %s into memory", filename);
   10.58 +        return (cxstring) {NULL, 0};
   10.59 +    }
   10.60 +    close(fd);
   10.61 +
   10.62 +    return cx_strn(data, statbuf.st_size);
   10.63 +}
   10.64 +
   10.65 +void asc_file_unmap(asc_file file) {
   10.66 +    munmap((void *) file.ptr, file.length);
   10.67 +}
   10.68 \ No newline at end of file
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/src/shader.c	Wed Nov 08 23:17:07 2023 +0100
    11.3 @@ -0,0 +1,139 @@
    11.4 +/*
    11.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    11.6 + * Copyright 2023 Mike Becker. All rights reserved.
    11.7 + *
    11.8 + * Redistribution and use in source and binary forms, with or without
    11.9 + * modification, are permitted provided that the following conditions are met:
   11.10 + *
   11.11 + *   1. Redistributions of source code must retain the above copyright
   11.12 + *      notice, this list of conditions and the following disclaimer.
   11.13 + *
   11.14 + *   2. Redistributions in binary form must reproduce the above copyright
   11.15 + *      notice, this list of conditions and the following disclaimer in the
   11.16 + *      documentation and/or other materials provided with the distribution.
   11.17 + *
   11.18 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   11.19 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   11.20 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   11.21 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   11.22 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   11.23 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   11.24 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   11.25 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   11.26 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   11.27 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   11.28 + * POSSIBILITY OF SUCH DAMAGE.
   11.29 + */
   11.30 +
   11.31 +#include "ascension/shader.h"
   11.32 +#include "ascension/files.h"
   11.33 +#include "ascension/error.h"
   11.34 +
   11.35 +#include <GL/glew.h>
   11.36 +
   11.37 +AscShaderProgram ASC_SHADER_FONT;
   11.38 +
   11.39 +
   11.40 +AscShader asc_shader_compile(unsigned int type,
   11.41 +                             char const *code,
   11.42 +                             int length) {
   11.43 +    GLuint id = glCreateShader(type);
   11.44 +    if (id == 0) {
   11.45 +        asc_error("glCreateShader failed");
   11.46 +        return (AscShader) {0};
   11.47 +    }
   11.48 +
   11.49 +    GLint success;
   11.50 +    glShaderSource(id, 1, &code, &length);
   11.51 +    glCompileShader(id);
   11.52 +    glGetShaderiv(id, GL_COMPILE_STATUS, &success);
   11.53 +    if (success) {
   11.54 +        asc_dprintf("Shader %u compiled", id);
   11.55 +        return (AscShader) {id};
   11.56 +    } else {
   11.57 +        char *log = malloc(1024);
   11.58 +        glGetShaderInfoLog(id, 1024, NULL, log);
   11.59 +        glDeleteShader(id);
   11.60 +        asc_error(log);
   11.61 +        free(log);
   11.62 +        return (AscShader) {0};
   11.63 +    }
   11.64 +}
   11.65 +
   11.66 +AscShader asc_shader_compilef(unsigned int type,
   11.67 +                              char const *filename) {
   11.68 +    asc_file code = asc_file_mmap_rdonly(filename);
   11.69 +    if (code.ptr == NULL) {
   11.70 +        asc_error("Mapping shader file into memory failed");
   11.71 +        return (AscShader) {0};
   11.72 +    }
   11.73 +    AscShader ret = asc_shader_compile(type, code.ptr, code.length);
   11.74 +    asc_file_unmap(code);
   11.75 +    return ret;
   11.76 +}
   11.77 +
   11.78 +AscShaderProgram asc_shader_link(AscShader vertex,
   11.79 +                                 AscShader fragment) {
   11.80 +    if (vertex.id == 0 || fragment.id == 0) {
   11.81 +        asc_dprintf("Skip linking shader program - shaders have not been loaded correctly.");
   11.82 +        return (AscShaderProgram) {0};
   11.83 +    }
   11.84 +
   11.85 +    GLint success;
   11.86 +    GLint id = glCreateProgram();
   11.87 +    if (id <= 0) {
   11.88 +        asc_error("glCreateProgram failed");
   11.89 +        return (AscShaderProgram) {0};
   11.90 +    }
   11.91 +    glAttachShader(id, vertex.id);
   11.92 +    glAttachShader(id, fragment.id);
   11.93 +    glLinkProgram(id);
   11.94 +    glGetProgramiv(id, GL_LINK_STATUS, &success);
   11.95 +    glDetachShader(id, vertex.id);
   11.96 +    glDetachShader(id, fragment.id);
   11.97 +    if (success) {
   11.98 +        asc_dprintf("Shader Program %u linked (vtf: %u, frag: %u)", id, vertex.id, fragment.id);
   11.99 +        return (AscShaderProgram) {id};
  11.100 +    } else {
  11.101 +        char *log = malloc(1024);
  11.102 +        glGetProgramInfoLog(id, 1024, NULL, log);
  11.103 +        glDeleteShader(id);
  11.104 +        asc_error(log);
  11.105 +        free(log);
  11.106 +        return (AscShaderProgram) {0};
  11.107 +    }
  11.108 +}
  11.109 +
  11.110 +void asc_shader_destroy(AscShader shader) {
  11.111 +    if (shader.id > 0) {
  11.112 +        asc_dprintf("Delete Shader %u", shader.id);
  11.113 +        glDeleteShader(shader.id);
  11.114 +    }
  11.115 +    shader.id = 0;
  11.116 +}
  11.117 +
  11.118 +void asc_shader_program_destroy(AscShaderProgram program) {
  11.119 +    if (program.id > 0) {
  11.120 +        asc_dprintf("Delete Shader Program %u", program.id);
  11.121 +        glDeleteProgram(program.id);
  11.122 +    }
  11.123 +    program.id = 0;
  11.124 +}
  11.125 +
  11.126 +static AscShaderProgram asc_shader_compile_link_discard(
  11.127 +        char const *vtxName, char const *fragName) {
  11.128 +    AscShader font_vtx = asc_shader_compilef(GL_VERTEX_SHADER, vtxName);
  11.129 +    AscShader font_frag = asc_shader_compilef(GL_FRAGMENT_SHADER, fragName);
  11.130 +    AscShaderProgram prog = asc_shader_link(font_vtx, font_frag);
  11.131 +    asc_shader_destroy(font_vtx);
  11.132 +    asc_shader_destroy(font_frag);
  11.133 +    return prog;
  11.134 +}
  11.135 +
  11.136 +void asc_shader_initialize_predefined(void) {
  11.137 +    ASC_SHADER_FONT = asc_shader_compile_link_discard("shader/font_vtx.glsl", "shader/font_frag.glsl");
  11.138 +}
  11.139 +
  11.140 +void asc_shader_destroy_predefined(void) {
  11.141 +    asc_shader_program_destroy(ASC_SHADER_FONT);
  11.142 +}
  11.143 \ No newline at end of file
    12.1 --- a/test/Makefile	Wed Nov 08 21:53:43 2023 +0100
    12.2 +++ b/test/Makefile	Wed Nov 08 23:17:07 2023 +0100
    12.3 @@ -39,9 +39,9 @@
    12.4  FORCE:
    12.5  
    12.6  $(BUILD_DIR)/sandbox.o: sandbox.c ../src/ascension/ascension.h \
    12.7 - ../src/ascension/context.h ../src/ascension/window.h \
    12.8 - ../src/ascension/datatypes.h ../src/ascension/font.h \
    12.9 - ../src/ascension/error.h
   12.10 + ../src/ascension/error.h ../src/ascension/context.h \
   12.11 + ../src/ascension/window.h ../src/ascension/datatypes.h \
   12.12 + ../src/ascension/font.h ../src/ascension/shader.h
   12.13  	@echo "Compiling $<"
   12.14  	$(CC) -o $@ $(CFLAGS) -c $<
   12.15  
    13.1 --- a/test/sandbox.c	Wed Nov 08 21:53:43 2023 +0100
    13.2 +++ b/test/sandbox.c	Wed Nov 08 23:17:07 2023 +0100
    13.3 @@ -49,7 +49,7 @@
    13.4      settings.title = "Sandbox Application";
    13.5  
    13.6      AscWindow *window = asc_window_initialize(0, &settings);
    13.7 -
    13.8 +    asc_shader_initialize_predefined();
    13.9      while (asc_loop_next()) {
   13.10          // quit application on any error
   13.11          if (show_message_box_on_error(window->window)) break;

mercurial