2023-07-06 16:46:07 +03:00
|
|
|
#include "shader.hpp"
|
|
|
|
#include "common.hpp"
|
|
|
|
#include "vendor/glad/glad.h"
|
|
|
|
#include <cstdio>
|
|
|
|
#include <cstring>
|
|
|
|
#include <cerrno>
|
|
|
|
#include <cstdlib>
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int create_shader(unsigned int type, const char **source)
|
|
|
|
{
|
|
|
|
unsigned int shader = glCreateShader(type);
|
|
|
|
if (!shader) {
|
|
|
|
printf("err: create_shader: glCreateShader returned 0\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
glShaderSource(shader, 1, source, NULL);
|
|
|
|
glCompileShader(shader);
|
|
|
|
|
|
|
|
int success;
|
|
|
|
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
|
|
|
|
if (!success) {
|
|
|
|
char log[512];
|
|
|
|
glGetShaderInfoLog(shader, 512, NULL, log);
|
|
|
|
printf("err: create_shader: compilation failed, log: %s\n", log);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return shader;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int create_program_source(const char *vertex_shader_source, const char *fragment_shader_source)
|
|
|
|
{
|
|
|
|
unsigned int program = glCreateProgram();
|
|
|
|
if (!program) {
|
|
|
|
printf("err: create_program: glCreateProgram returned 0\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int vertex_shader = create_shader(GL_VERTEX_SHADER, &vertex_shader_source);
|
|
|
|
if (!vertex_shader) {
|
|
|
|
printf("err: create_program: create_shader failed returned 0 (vertex_shader)\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
unsigned int fragment_shader = create_shader(GL_FRAGMENT_SHADER, &fragment_shader_source);
|
|
|
|
if (!fragment_shader) {
|
|
|
|
printf("err: create_program: create_shader failed returned 0 (fragment_shader)\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
glAttachShader(program, vertex_shader);
|
|
|
|
glAttachShader(program, fragment_shader);
|
|
|
|
glLinkProgram(program);
|
|
|
|
|
|
|
|
int success;
|
|
|
|
glGetProgramiv(program, GL_LINK_STATUS, &success);
|
|
|
|
if (!success) {
|
|
|
|
char log[512];
|
|
|
|
glGetProgramInfoLog(program, 512, NULL, log);
|
|
|
|
printf("err: create_program: link failed, log: %s\n", log);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return program;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int create_program(const char *vertex_shader_path, const char *fragment_shader_path)
|
|
|
|
{
|
|
|
|
FILE *vertex_shader_file, *fragment_shader_file = NULL;
|
|
|
|
char *vertex_shader_source = NULL;
|
|
|
|
char *fragment_shader_source = NULL;
|
|
|
|
Errno err = 0;
|
|
|
|
unsigned int ret = 0;
|
|
|
|
|
|
|
|
vertex_shader_file = fopen(vertex_shader_path, "r");
|
|
|
|
if (!vertex_shader_file) {
|
|
|
|
fprintf(stderr, "create_program: failed to open vertex shader file (%s): %s\n", vertex_shader_path, strerror(errno));
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
err = read_entire_file(vertex_shader_file, &vertex_shader_source);
|
|
|
|
if (err) {
|
|
|
|
fprintf(stderr, "create_program: failed to read vertex shader file (%s): %s\n", vertex_shader_path, strerror(err));
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
fragment_shader_file = fopen(fragment_shader_path, "r");
|
|
|
|
if (!fragment_shader_file) {
|
|
|
|
fprintf(stderr, "create_program: failed to open fragment shader file (%s): %s\n", fragment_shader_path, strerror(errno));
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
err = read_entire_file(fragment_shader_file, &fragment_shader_source);
|
|
|
|
if (err) {
|
|
|
|
fprintf(stderr, "create_program: failed to read fragment shader file (%s): %s\n", fragment_shader_path, strerror(err));
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = create_program_source(vertex_shader_source, fragment_shader_source);
|
|
|
|
|
|
|
|
done:
|
|
|
|
if (vertex_shader_file) fclose(vertex_shader_file);
|
|
|
|
if (fragment_shader_file) fclose(fragment_shader_file);
|
|
|
|
if (vertex_shader_source) free(vertex_shader_source);
|
|
|
|
if (fragment_shader_source) free(fragment_shader_source);
|
|
|
|
return ret;
|
|
|
|
}
|
2023-08-21 17:43:31 +03:00
|
|
|
|
|
|
|
void program_set(unsigned int program, const char *uniform, int value)
|
|
|
|
{
|
|
|
|
glUniform1i(glGetUniformLocation(program, uniform), value);
|
|
|
|
}
|
|
|
|
|
|
|
|
void program_set(unsigned int program, const char *uniform, float value)
|
|
|
|
{
|
|
|
|
glUniform1f(glGetUniformLocation(program, uniform), value);
|
|
|
|
}
|
|
|
|
|
|
|
|
void program_set(unsigned int program, const char *uniform, glm::vec3 vec)
|
|
|
|
{
|
|
|
|
glUniform3fv(glGetUniformLocation(program, uniform), 1, &vec[0]);
|
|
|
|
}
|
|
|
|
|
|
|
|
void program_set(unsigned int program, const char *uniform, float x, float y, float z)
|
|
|
|
{
|
|
|
|
glUniform3f(glGetUniformLocation(program, uniform), x, y, z);
|
|
|
|
}
|
|
|
|
|
|
|
|
void program_set(unsigned int program, const char *uniform, const glm::mat4 &mat)
|
|
|
|
{
|
|
|
|
glUniformMatrix4fv(glGetUniformLocation(program, uniform), 1, GL_FALSE, &mat[0][0]);
|
|
|
|
}
|