/ * Определяет класс шейдеров.* /
Я разрабатываю приложение на C ++ с OpenGL и CMake.Структура моих каталогов:
- tanx
- CMakeLists.txt
- ext (содержит GLFW и рад)
- src
- TanX.cpp
- TanX.h
- математика (содержит несколько математических методов; не очень подходит для моей задачи)
- шейдер
- шейдер.h
- vertex.glsl
- фрагмент.glsl
- CMakeLists.txt
Shader.h в основном предназначен для чтения источников вершинных и фрагментных шейдеров из файлов, их компиляции и связывания с программой Shader.Это выглядит так:
#ifndef _SHADER_H
#define _SHADER_H
#include <string>
#include <exception>
#include <fstream>
#include <glad.h>
class shader_exception :std::exception {
private:
const char* text;
public:
shader_exception(const char* text)
: text(text) {}
virtual const char* what() const {
return text;
}
};
class Shader {
private:
std::string* vertex_source = new std::string();
std::string* fragment_source = new std::string();
unsigned int vao, vbo, vertex_shader, fragment_shader, program;
public:
Shader(const char* vertex_source_path, const char* fragment_source_path) {
std::ifstream file_reader;
file_reader.open(vertex_source_path);
std::string line;
if (file_reader.is_open()) {
while (getline(file_reader, line)) {
vertex_source->append(line + "\n");
}
file_reader.close();
}
else
throw shader_exception("Could not open vertex shader source file");
file_reader.open(fragment_source_path); // this is where I get an unhandled exception dialog box
if (file_reader.is_open()) {
while (getline(file_reader, line)) {
fragment_source->append(line + "\n");
}
file_reader.close();
}
else
throw shader_exception("Could not open fragment shader file");
const char** vertex_source_c = (const char**)malloc(vertex_source->size());
*vertex_source_c = vertex_source->c_str();
const char** fragment_source_c = (const char**)malloc(fragment_source->size());
*fragment_source_c = fragment_source->c_str();
vertex_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex_shader, 1, vertex_source_c, NULL);
glCompileShader(vertex_shader);
int success;
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success);
char infoLog[512];
if (!success) {
glGetShaderInfoLog(vertex_shader, 512, NULL, infoLog);
throw shader_exception(infoLog);
}
glShaderSource(fragment_shader, 1, fragment_source_c, NULL);
glCompileShader(fragment_shader);
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(fragment_shader, 512, NULL, infoLog);
throw shader_exception(infoLog);
}
program = glCreateProgram();
glAttachShader(program, vertex_shader);
glAttachShader(program, fragment_shader);
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(program, 512, NULL, infoLog);
throw shader_exception(infoLog);
}
glDeleteShader(vertex_shader);
glDeleteShader(fragment_shader);
}
Shader() = delete;
void use()
{
glUseProgram(program);
}
~Shader() {
glDeleteProgram(program);
}
};
#endif
В TanX.cpp я пытаюсь создать объект шейдера следующим образом:
Shader shader("vertex.glsl", "fragment.glsl");
Как видите, исходные файлы шейдера я бынравится использовать vertex.glsl и фрагмент.glsl, которые находятся в папке "Shader".Чтобы сделать их пригодными для использования в ifstream, файл CMakeLists.txt в папке Shader выглядит следующим образом (это один из упомянутых вариантов здесь , чтобы сделать файлы пригодными для использования в программе):
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/vertex.glsl ${CMAKE_CURRENT_BINARY_DIR} COPYONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fragment.glsl ${CMAKE_CURRENT_BINARY_DIR} COPYONLY)
Файл CMakeLists.txt верхнего уровня также содержит
add_subdirectory("TanX/src/Shader")
, так что файл CMakeLists.txt в шейдере выполняется.
Проблема заключается в том, что при попыткеЗапустив мой код в Visual Studio, я получаю необработанное исключение в файле Shader.h в строке 45 (где он пытается открыть фрагмент.glsl).Это исключение shader_exception, поэтому, по-видимому, открытие vertex.glsl не удалось.Сведения о диалоговом окне «Исключение необработано»: «Необработанное исключение по адресу 0x00007FFF43E4A388 в TanX.exe: исключение Microsoft C ++: возникло исключение shader_exception в ячейке памяти 0x00000028896FF608.».Теперь у меня есть два вопроса
1) Что мне нужно сделать, чтобы ifstream открыл vertex.glsl (а затем фрагмента.glsl)?
2) Почему я даже получаю необработанное исключениеошибка, разве не должно завершиться создание объекта Shader, как только возникнет исключение, и это приведет к тому, что программа даже не достигнет строки 45?