-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathshader_utils.h
93 lines (74 loc) · 2.35 KB
/
shader_utils.h
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
// Copyright 2019-2020 David Robillard <[email protected]>
// SPDX-License-Identifier: ISC
#ifndef EXAMPLES_SHADER_UTILS_H
#define EXAMPLES_SHADER_UTILS_H
#include "glad/glad.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
GLuint vertexShader;
GLuint fragmentShader;
GLuint program;
} Program;
static GLuint
compileShader(const char* header, const char* source, const GLenum type)
{
const GLchar* sources[] = {header, source};
const GLint lengths[] = {(GLint)strlen(header), (GLint)strlen(source)};
GLuint shader = glCreateShader(type);
glShaderSource(shader, 2, sources, lengths);
glCompileShader(shader);
int status = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE) {
GLint length = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
char* log = (char*)calloc(1, (size_t)length);
glGetShaderInfoLog(shader, length, &length, log);
fprintf(stderr, "error: Failed to compile shader (%s)\n", log);
free(log);
return 0;
}
return shader;
}
static void
deleteProgram(Program program)
{
glDeleteShader(program.vertexShader);
glDeleteShader(program.fragmentShader);
glDeleteProgram(program.program);
}
static Program
compileProgram(const char* headerSource,
const char* vertexSource,
const char* fragmentSource)
{
static const Program nullProgram = {0, 0, 0};
Program program = {
compileShader(headerSource, vertexSource, GL_VERTEX_SHADER),
compileShader(headerSource, fragmentSource, GL_FRAGMENT_SHADER),
glCreateProgram(),
};
if (!program.vertexShader || !program.fragmentShader || !program.program) {
deleteProgram(program);
return nullProgram;
}
glAttachShader(program.program, program.vertexShader);
glAttachShader(program.program, program.fragmentShader);
glLinkProgram(program.program);
GLint status = 0;
glGetProgramiv(program.program, GL_LINK_STATUS, &status);
if (status == GL_FALSE) {
GLint length = 0;
glGetProgramiv(program.program, GL_INFO_LOG_LENGTH, &length);
char* log = (char*)calloc(1, (size_t)length);
glGetProgramInfoLog(program.program, length, &length, &log[0]);
fprintf(stderr, "error: Failed to link program (%s)\n", log);
free(log);
deleteProgram(program);
return nullProgram;
}
return program;
}
#endif // EXAMPLES_SHADER_UTILS_H