src/shader.c

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
child 16
c5dde81b6fb2
permissions
-rw-r--r--

add shader loading and unloading

     1 /*
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  * Copyright 2023 Mike Becker. All rights reserved.
     4  *
     5  * Redistribution and use in source and binary forms, with or without
     6  * modification, are permitted provided that the following conditions are met:
     7  *
     8  *   1. Redistributions of source code must retain the above copyright
     9  *      notice, this list of conditions and the following disclaimer.
    10  *
    11  *   2. Redistributions in binary form must reproduce the above copyright
    12  *      notice, this list of conditions and the following disclaimer in the
    13  *      documentation and/or other materials provided with the distribution.
    14  *
    15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    18  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    25  * POSSIBILITY OF SUCH DAMAGE.
    26  */
    28 #include "ascension/shader.h"
    29 #include "ascension/files.h"
    30 #include "ascension/error.h"
    32 #include <GL/glew.h>
    34 AscShaderProgram ASC_SHADER_FONT;
    37 AscShader asc_shader_compile(unsigned int type,
    38                              char const *code,
    39                              int length) {
    40     GLuint id = glCreateShader(type);
    41     if (id == 0) {
    42         asc_error("glCreateShader failed");
    43         return (AscShader) {0};
    44     }
    46     GLint success;
    47     glShaderSource(id, 1, &code, &length);
    48     glCompileShader(id);
    49     glGetShaderiv(id, GL_COMPILE_STATUS, &success);
    50     if (success) {
    51         asc_dprintf("Shader %u compiled", id);
    52         return (AscShader) {id};
    53     } else {
    54         char *log = malloc(1024);
    55         glGetShaderInfoLog(id, 1024, NULL, log);
    56         glDeleteShader(id);
    57         asc_error(log);
    58         free(log);
    59         return (AscShader) {0};
    60     }
    61 }
    63 AscShader asc_shader_compilef(unsigned int type,
    64                               char const *filename) {
    65     asc_file code = asc_file_mmap_rdonly(filename);
    66     if (code.ptr == NULL) {
    67         asc_error("Mapping shader file into memory failed");
    68         return (AscShader) {0};
    69     }
    70     AscShader ret = asc_shader_compile(type, code.ptr, code.length);
    71     asc_file_unmap(code);
    72     return ret;
    73 }
    75 AscShaderProgram asc_shader_link(AscShader vertex,
    76                                  AscShader fragment) {
    77     if (vertex.id == 0 || fragment.id == 0) {
    78         asc_dprintf("Skip linking shader program - shaders have not been loaded correctly.");
    79         return (AscShaderProgram) {0};
    80     }
    82     GLint success;
    83     GLint id = glCreateProgram();
    84     if (id <= 0) {
    85         asc_error("glCreateProgram failed");
    86         return (AscShaderProgram) {0};
    87     }
    88     glAttachShader(id, vertex.id);
    89     glAttachShader(id, fragment.id);
    90     glLinkProgram(id);
    91     glGetProgramiv(id, GL_LINK_STATUS, &success);
    92     glDetachShader(id, vertex.id);
    93     glDetachShader(id, fragment.id);
    94     if (success) {
    95         asc_dprintf("Shader Program %u linked (vtf: %u, frag: %u)", id, vertex.id, fragment.id);
    96         return (AscShaderProgram) {id};
    97     } else {
    98         char *log = malloc(1024);
    99         glGetProgramInfoLog(id, 1024, NULL, log);
   100         glDeleteShader(id);
   101         asc_error(log);
   102         free(log);
   103         return (AscShaderProgram) {0};
   104     }
   105 }
   107 void asc_shader_destroy(AscShader shader) {
   108     if (shader.id > 0) {
   109         asc_dprintf("Delete Shader %u", shader.id);
   110         glDeleteShader(shader.id);
   111     }
   112     shader.id = 0;
   113 }
   115 void asc_shader_program_destroy(AscShaderProgram program) {
   116     if (program.id > 0) {
   117         asc_dprintf("Delete Shader Program %u", program.id);
   118         glDeleteProgram(program.id);
   119     }
   120     program.id = 0;
   121 }
   123 static AscShaderProgram asc_shader_compile_link_discard(
   124         char const *vtxName, char const *fragName) {
   125     AscShader font_vtx = asc_shader_compilef(GL_VERTEX_SHADER, vtxName);
   126     AscShader font_frag = asc_shader_compilef(GL_FRAGMENT_SHADER, fragName);
   127     AscShaderProgram prog = asc_shader_link(font_vtx, font_frag);
   128     asc_shader_destroy(font_vtx);
   129     asc_shader_destroy(font_frag);
   130     return prog;
   131 }
   133 void asc_shader_initialize_predefined(void) {
   134     ASC_SHADER_FONT = asc_shader_compile_link_discard("shader/font_vtx.glsl", "shader/font_frag.glsl");
   135 }
   137 void asc_shader_destroy_predefined(void) {
   138     asc_shader_program_destroy(ASC_SHADER_FONT);
   139 }

mercurial