src/shader.c

changeset 15
362b7659dc76
child 16
c5dde81b6fb2
equal deleted inserted replaced
14:9dbfc0031887 15:362b7659dc76
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 */
27
28 #include "ascension/shader.h"
29 #include "ascension/files.h"
30 #include "ascension/error.h"
31
32 #include <GL/glew.h>
33
34 AscShaderProgram ASC_SHADER_FONT;
35
36
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 }
45
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 }
62
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 }
74
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 }
81
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 }
106
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 }
114
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 }
122
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 }
132
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 }
136
137 void asc_shader_destroy_predefined(void) {
138 asc_shader_program_destroy(ASC_SHADER_FONT);
139 }

mercurial