diff --git a/shaders/shader.frag b/shaders/shader.frag new file mode 100644 index 0000000..3f0ad51 --- /dev/null +++ b/shaders/shader.frag @@ -0,0 +1,8 @@ +#version 330 core + +out vec3 color; + +void main() +{ + color = vec3(1, 0, 0); +} diff --git a/shaders/shader.vert b/shaders/shader.vert new file mode 100644 index 0000000..16f3963 --- /dev/null +++ b/shaders/shader.vert @@ -0,0 +1,9 @@ +#version 330 core + +layout(location = 0) in vec3 pos; + +void main() +{ + gl_Position.xyz = pos; + gl_Position.w = 1.0; +} diff --git a/src/main.cpp b/src/main.cpp index dd18a3c..399368d 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,9 @@ + #include #include +#include -#include +#include #define WINDOW_WIDTH 800 #define WINDOW_HEIGHT 600 @@ -13,10 +15,105 @@ void framebuffer_size_callback(GLFWwindow* window, int width, int height) glViewport(0, 0, width, height); } +#include +#include + +// Функция чтения шейдера из файла +std::string readFile(const char* filename) +{ + std::string text; + std::ifstream file(filename, std::ios::in); // Открываем файл на чтение + // Если файл доступен и успешно открыт + if (file.is_open()) + { + std::stringstream sstr; // Буфер для чтения + sstr << file.rdbuf(); // Считываем файл + text = sstr.str(); // Преобразуем буфер к строке + file.close(); // Закрываем файл + } + + return text; +} + +// Функция для загрузки шейдеров +// Принимает два адреса вершинного и фрагментного шейдеров +// Возвращает дескриптор шейдерной программы +GLuint LoadShaders(const char *vertex_file, const char *fragment_file) +{ + // Создание дескрипторов вершинного и фрагментного шейдеров + GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER); + GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); + + // Переменные под результат компиляции + GLint result = GL_FALSE; + int infoLogLength; + + // Считываем текст вершинного шейдера + std::string code = readFile(vertex_file); + const char* pointer = code.c_str(); // Преобразование к указателю на const char, так как функция принимает массив си-строк + + // Компиляция кода вершинного шейдера + glShaderSource(vertexShaderID, 1, &pointer, NULL); + glCompileShader(vertexShaderID); + + // Проверка результата компиляции + glGetShaderiv(vertexShaderID, GL_COMPILE_STATUS, &result); + glGetShaderiv(vertexShaderID, GL_INFO_LOG_LENGTH, &infoLogLength); + if (infoLogLength > 0) + { + char* errorMessage = new char[infoLogLength + 1]; + glGetShaderInfoLog(vertexShaderID, infoLogLength, NULL, errorMessage); + std::cout << errorMessage; + delete[] errorMessage; + } + + // Считываем текст вершинного шейдера + code = readFile(fragment_file); + pointer = code.c_str(); // Преобразование к указателю на const char, так как функция принимает массив си-строк + + // Компиляция кода фрагментного шейдера + glShaderSource(fragmentShaderID, 1, &pointer, NULL); + glCompileShader(fragmentShaderID); + + // Проверка результата компиляции + glGetShaderiv(fragmentShaderID, GL_COMPILE_STATUS, &result); + glGetShaderiv(fragmentShaderID, GL_INFO_LOG_LENGTH, &infoLogLength); + if (infoLogLength > 0) + { + char* errorMessage = new char[infoLogLength + 1]; + glGetShaderInfoLog(fragmentShaderID, infoLogLength, NULL, errorMessage); + std::cout << errorMessage; + delete[] errorMessage; + } + + // Привязка скомпилированных шейдеров + GLuint programID = glCreateProgram(); + glAttachShader(programID, vertexShaderID); + glAttachShader(programID, fragmentShaderID); + glLinkProgram(programID); + + // Проверка программы + glGetProgramiv(programID, GL_LINK_STATUS, &result); + glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &infoLogLength); + if (infoLogLength > 0) + { + char* errorMessage = new char[infoLogLength + 1]; + glGetProgramInfoLog(programID, infoLogLength, NULL, errorMessage); + std::cout << errorMessage; + delete[] errorMessage; + } + + // Освобождение дескрипторов шейдеров + glDeleteShader(vertexShaderID); + glDeleteShader(fragmentShaderID); + + return programID; +} + int main(void) { GLFWwindow* window; // Указатель на окно GLFW3 - + // Инициализация GLFW3 if (!glfwInit()) { @@ -53,15 +150,20 @@ int main(void) return -1; } + // Компиляция шейдеров + GLuint shaderProgram = LoadShaders("shaders/shader.vert", "shaders/shader.frag"); + // Активация шейдера + glUseProgram(shaderProgram); + // Установка цвета очистки буфера цвета glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + // Пока не произойдет событие запроса закрытия окна while(!glfwWindowShouldClose(window)) { // Очистка буфера цвета glClear(GL_COLOR_BUFFER_BIT); - // Тут производится рендер // ... @@ -70,6 +172,9 @@ int main(void) // Обработка системных событий glfwPollEvents(); } + + // Удаление шейдерной программы + glDeleteProgram(shaderProgram); + return 0; } - \ No newline at end of file