-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathshader.c
93 lines (76 loc) · 3.61 KB
/
shader.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/*
shader - Open and interact with shaders
Copyright (C) 2019 Aidan Prangnell (AidoP)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
A full copy of the license should be included with the source. If not see https://www.gnu.org/licenses/.
*/
#include "shader.h"
#include "shader_read.h"
char* get_default_shader(GLenum shader_type) {
if (shader_type == GL_FRAGMENT_SHADER)
return SKYPAPER_DEFAULT_FRAGMENT_SHADER;
else
return SKYPAPER_DEFAULT_VERTEX_SHADER;
}
GLuint compile_shader(GLenum shader_type, char** shader_source) {
GLuint shader_object = glCreateShader(shader_type);
// Compile the shader
glShaderSource(shader_object, 1, (const char* const*)shader_source, NULL);
glCompileShader(shader_object);
// Get log output
GLint compile_status, error_message_length;
glGetShaderiv(shader_object, GL_COMPILE_STATUS, &compile_status);
glGetShaderiv(shader_object, GL_INFO_LOG_LENGTH, &error_message_length);
if (compile_status != GL_TRUE) {
char error_message[error_message_length + 1];
error_message[0] = '\0';
glGetShaderInfoLog(shader_object, error_message_length, NULL, error_message);
warning("Unable to compile shader: ");
printf("------ %s Shader ------\n%s%s------------\n\n", shader_type == GL_FRAGMENT_SHADER ? "Fragment" : "Vertex", *shader_source == NULL ? "No shader provided\n" : "", error_message);
}
return shader_object;
}
GLuint load_shaders(char** fragment_shader_path, char** vertex_shader_path) {
char* fragment_shader_source = NULL;
char* vertex_shader_source = NULL;
if (*fragment_shader_path)
read_file(fragment_shader_path, &fragment_shader_source);
else {
if (!try_read_stdin(&fragment_shader_source))
fragment_shader_source = get_default_shader(GL_FRAGMENT_SHADER);
}
if (*vertex_shader_path)
read_file(vertex_shader_path, &vertex_shader_source);
else
vertex_shader_source = get_default_shader(GL_VERTEX_SHADER);
// Compile the shaders into a shader program
GLuint shader_program_object = glCreateProgram();
glAttachShader(shader_program_object, compile_shader(GL_FRAGMENT_SHADER, &fragment_shader_source));
glAttachShader(shader_program_object, compile_shader(GL_VERTEX_SHADER, &vertex_shader_source));
// Bind output and link
glBindFragDataLocation(shader_program_object, 0, "fragColor");
glLinkProgram(shader_program_object);
if (*fragment_shader_path)
free(fragment_shader_source);
if (*vertex_shader_path)
free(vertex_shader_source);
// Get log output
GLint program_link_status, error_message_length;
glGetProgramiv(shader_program_object, GL_LINK_STATUS, &program_link_status);
glGetProgramiv(shader_program_object, GL_INFO_LOG_LENGTH, &error_message_length);
if (program_link_status != GL_TRUE) {
char error_message[error_message_length + 1];
error_message[0] = '\0';
glGetProgramInfoLog(shader_program_object, error_message_length, NULL, error_message);
warning("Shader program linking failed:");
printf("------------\n%s\n------------\n\n", error_message);
}
return shader_program_object;
}