fixes
This commit is contained in:
90
source/opengl/data/shader_program_data.cpp
Executable file
90
source/opengl/data/shader_program_data.cpp
Executable file
@@ -0,0 +1,90 @@
|
||||
|
||||
#include "opengl/data/shader_program_data.hpp"
|
||||
|
||||
#include <fstream>
|
||||
#include "GL/glew.h"
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
#include "util/for_each.hpp"
|
||||
#include "util/logger.hpp"
|
||||
#include "opengl/error.hpp"
|
||||
|
||||
namespace zgl
|
||||
{
|
||||
|
||||
std::error_code shader_program_data::build_from(
|
||||
const shader_handle& vertex_shader,
|
||||
const shader_handle& geometry_shader,
|
||||
const shader_handle& fragment_shader,
|
||||
shader_program_data& data
|
||||
) {
|
||||
auto error = std::error_code{};
|
||||
|
||||
auto check_error = [&error, ec = static_cast<GLenum>(GL_NO_ERROR)]() mutable -> std::error_code&
|
||||
{
|
||||
ec = glGetError();
|
||||
if (ec != GL_NO_ERROR) {
|
||||
error = make_error_code(ec);
|
||||
}
|
||||
return error;
|
||||
};
|
||||
|
||||
const auto program_id = glCreateProgram();
|
||||
if (check_error()) return error;
|
||||
|
||||
using namespace std::string_view_literals;
|
||||
|
||||
constexpr auto shader_names = std::array{
|
||||
"vertex"sv, "geometry"sv, "fragment"sv
|
||||
};
|
||||
|
||||
for (const auto& [shader, name] : {
|
||||
std::tie(vertex_shader, shader_names[0]),
|
||||
std::tie(geometry_shader, shader_names[1]),
|
||||
std::tie(fragment_shader, shader_names[2])
|
||||
}) {
|
||||
if (shader.shader_id) {
|
||||
glAttachShader(program_id, shader.shader_id);
|
||||
} else {
|
||||
ztu::logger::warn("Using default % shader", name);
|
||||
}
|
||||
}
|
||||
|
||||
glLinkProgram(program_id);
|
||||
if (check_error()) return error;
|
||||
|
||||
auto status = GLint{ GL_FALSE };
|
||||
glGetProgramiv(program_id, GL_LINK_STATUS, &status);
|
||||
if (check_error()) return error;
|
||||
|
||||
if (status == GL_FALSE) {
|
||||
GLint log_length{};
|
||||
glGetShaderiv(program_id, GL_INFO_LOG_LENGTH, &log_length);
|
||||
|
||||
auto log = std::string(log_length, ' ');
|
||||
glGetProgramInfoLog(program_id, log_length, nullptr, log.data());
|
||||
|
||||
ztu::logger::warn("Error while linking program: [%] %", log_length, log);
|
||||
|
||||
return std::make_error_code(std::errc::io_error);
|
||||
}
|
||||
|
||||
|
||||
glUseProgram(0);
|
||||
|
||||
ztu::for_each::argument(
|
||||
[&](const auto& shader)
|
||||
{
|
||||
if (shader.shader_id) {
|
||||
glDetachShader(program_id, shader.shader_id);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
vertex_shader, geometry_shader, fragment_shader
|
||||
);
|
||||
|
||||
data = shader_program_data{ program_id };
|
||||
|
||||
return {};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user