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
|
#include "shader.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static char *read_file(const char *file_path) {
FILE *file = fopen(file_path, "r");
if (!file) {
printf("Failed to open file: %s\n", file_path);
return NULL;
}
fseek(file, 0, SEEK_END);
long file_size = ftell(file);
fseek(file, 0, SEEK_SET);
char *buffer = (char *)malloc(file_size + 1);
if (!buffer) {
printf("Failed to allocate memory for file: %s\n", file_path);
fclose(file);
return NULL;
}
fread(buffer, 1, file_size, file);
buffer[file_size] = '\0';
fclose(file);
return buffer;
}
static unsigned int compile_shader(const char *source, GLenum shader_type) {
unsigned int shader = glCreateShader(shader_type);
glShaderSource(shader, 1, &source, NULL);
glCompileShader(shader);
int success;
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (!success) {
char info_log[512];
glGetShaderInfoLog(shader, 512, NULL, info_log);
printf("Shader compilation failed: %s\n", info_log);
return 0;
}
return shader;
}
Shader *shader_create(const char *vertex_path, const char *fragment_path) {
Shader *shader = (Shader *)malloc(sizeof(Shader));
if (!shader) {
printf("Failed to allocate memory for shader\n");
return NULL;
}
char *vertex_source = read_file(vertex_path);
char *fragment_source = read_file(fragment_path);
if (!vertex_source || !fragment_source) {
free(shader);
free(vertex_source);
free(fragment_source);
return NULL;
}
unsigned int vertex_shader = compile_shader(vertex_source, GL_VERTEX_SHADER);
unsigned int fragment_shader =
compile_shader(fragment_source, GL_FRAGMENT_SHADER);
free(vertex_source);
free(fragment_source);
if (!vertex_shader || !fragment_shader) {
free(shader);
return NULL;
}
shader->program = glCreateProgram();
glAttachShader(shader->program, vertex_shader);
glAttachShader(shader->program, fragment_shader);
glLinkProgram(shader->program);
int success;
glGetProgramiv(shader->program, GL_LINK_STATUS, &success);
if (!success) {
char info_log[512];
glGetProgramInfoLog(shader->program, 512, NULL, info_log);
printf("Shader program linking failed: %s\n", info_log);
free(shader);
return NULL;
}
glDeleteShader(vertex_shader);
glDeleteShader(fragment_shader);
return shader;
}
void shader_use(Shader *shader) { glUseProgram(shader->program); }
void shader_delete(Shader *shader) {
glDeleteProgram(shader->program);
free(shader);
}
void shader_set_int(Shader *shader, const char *name, int value) {
glUniform1i(glGetUniformLocation(shader->program, name), value);
}
void shader_set_float(Shader *shader, const char *name, float value) {
glUniform1f(glGetUniformLocation(shader->program, name), value);
}
void shader_set_vec3(Shader *shader, const char *name, float x, float y,
float z) {
glUniform3f(glGetUniformLocation(shader->program, name), x, y, z);
}
void shader_set_mat4(Shader *shader, const char *name, const float *value) {
glUniformMatrix4fv(glGetUniformLocation(shader->program, name), 1, GL_FALSE,
value);
}
|