-
Notifications
You must be signed in to change notification settings - Fork 1
/
shader.c
126 lines (110 loc) · 3.26 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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*
* Copyright © 2022 IGEL Co., Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors:
* Tomohito Esaki <[email protected]>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <GLES3/gl31.h>
#include "shader.h"
#define LOG_LENGTH 1024
static GLuint
compile_shader(const char *src, GLenum type)
{
GLuint shader;
GLint status;
if (!src)
return 0;
shader = glCreateShader(type);
if (!shader) {
fprintf(stderr, "Can't create shader\n");
return 0;
}
glShaderSource(shader, 1, (const char **)&src, NULL);
glCompileShader(shader);
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if (!status) {
char log[LOG_LENGTH];
GLsizei len;
char *type_str;
switch (type) {
case GL_VERTEX_SHADER:
type_str = "vertex";
break;
case GL_FRAGMENT_SHADER:
type_str = "fragment";
break;
case GL_COMPUTE_SHADER:
type_str = "compute";
break;
default:
type_str = "";
}
glGetShaderInfoLog(shader, LOG_LENGTH, &len, log);
fprintf(stderr, "Error: compiling %s: %*s\n", type_str, len,
log);
return 0;
}
return shader;
}
unsigned int
shader_build_program(struct shader_info *shader)
{
GLuint vshader = 0, fshader = 0, cshader = 0, program = 0;
GLint status;
vshader = compile_shader(shader->vertex, GL_VERTEX_SHADER);
fshader = compile_shader(shader->fragment, GL_FRAGMENT_SHADER);
cshader = compile_shader(shader->compute, GL_COMPUTE_SHADER);
if (!fshader && !fshader && !cshader)
goto exit;
program = glCreateProgram();
if (vshader)
glAttachShader(program, vshader);
if (fshader)
glAttachShader(program, fshader);
if (cshader)
glAttachShader(program, cshader);
if (shader->feedback.vars)
glTransformFeedbackVaryings(program, shader->feedback.num,
(const char**)shader->feedback.vars,
shader->feedback.mode);
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &status);
if (!status) {
char log[LOG_LENGTH];
GLsizei len;
glGetProgramInfoLog(program, LOG_LENGTH, &len ,log);
fprintf(stderr, "Error: linking:\n%*s\n", len, log);
glDeleteProgram(program);
program = 0;
}
exit:
if (vshader)
glDeleteShader(vshader);
if (fshader)
glDeleteShader(fshader);
if (cshader)
glDeleteShader(cshader);
return program;
}