Я пытаюсь вызвать исключение и прервать свою программу, если что-то не получается во время компиляции и компоновки шейдера. Я ввел опечатку: присвоение имени выходной переменной моего вершинного шейдера чем-то отличным от ожидаемой входной переменной в моем фрагментном шейдере. Я ожидал бы, что это потерпит неудачу на ссылке, но все работает нормально (и значение переменной в фрагментном шейдере просто заканчивается 0). В частности, glGetProgramiv(id, GL_LINK_STATUS, &success);
устанавливает успех на true. Что происходит?
Вершинный шейдер :
#version 330 core
layout (location = 0) in vec3 aPos;
out vec4 vertexColo; // NOTE THE MISSPELLING HERE
void main()
{
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
vertexColo = vec4(1.0 - aPos.y, 0.8 - aPos.y, aPos.x, 1.0);
}
Фрагмент шейдера :
#version 330 core
out vec4 FragColor;
in vec4 vertexColor;
void main()
{
FragColor = vertexColor;
}
Код теста:
namespace btv {
namespace {
static void test_compile(unsigned id, const char* path)
{
int success;
glGetShaderiv(id, GL_COMPILE_STATUS, &success);
if (!success) {
constexpr size_t BUF_SIZE = 1024;
char buf[BUF_SIZE];
glGetShaderInfoLog(id, BUF_SIZE, NULL, buf);
std::stringstream ss;
ss << "Shader at path: " << path << " failed with message: "
<< buf;
throw std::runtime_error(ss.str());
}
}
static void test_link(unsigned id, const char* v_path, const char* f_path)
{
int success;
glGetProgramiv(id, GL_LINK_STATUS, &success);
if (!success) {
constexpr size_t BUF_SIZE = 1024;
char buf[BUF_SIZE];
glGetProgramInfoLog(id, BUF_SIZE, NULL, buf);
std::stringstream ss;
ss << "Program with v shader: " << v_path << ", f shader: " << f_path
<< " failed with message: " << buf;
throw std::runtime_error(ss.str());
}
}
}
Program::Program(const char* v_path, const char* f_path)
{
std::string v_src = slurp(v_path);
std::string f_src = slurp(f_path);
const char *v_c = v_src.data();
const char *f_c = f_src.data();
unsigned v_shdr = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(v_shdr, 1, &v_c, nullptr);
glCompileShader(v_shdr);
test_compile(v_shdr, v_path);
unsigned f_shdr = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(f_shdr, 1, &f_c, nullptr);
glCompileShader(f_shdr);
test_compile(f_shdr, f_path);
id = glCreateProgram();
glAttachShader(id, v_shdr);
glAttachShader(id, f_shdr);
glLinkProgram(id);
test_link(id, v_path, f_path);
}
} // namespace btv