#include #include #include #include #include "Buffers.h" #define WINDOW_WIDTH 800 #define WINDOW_HEIGHT 600 #define WINDOW_CAPTION "OPENGL notes on rekovalev.site" // Функция-callback для изменения размеров буфера кадра в случае изменения размеров поверхности окна 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; } // Функция для конфигурации атрибутов void attrib_config() { // Включаем необходимый атрибут у выбранного VAO glEnableVertexAttribArray(0); // Устанавливаем связь между VAO и привязанным VBO glVertexAttribPointer( 0 // индекс атрибута, должен совпадать с Layout шейдера , 3 // количество компонент одного элемента , GL_FLOAT // тип , GL_FALSE // нормализованность значений , 0 // шаг , (void *)0 // отступ с начала массива ); } int main(void) { GLFWwindow* window; // Указатель на окно GLFW3 // Инициализация GLFW3 if (!glfwInit()) { std::cout << "GLFW init error\n"; return -1; } glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); // Мажорная версия спецификаций OpenGL glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); // Минорная версия спецификаций OpenGL glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // Контекст OpenGL, который поддерживает только основные функции // Создание окна GLFW3 с заданными шириной, высотой и заголовком окна window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_CAPTION, NULL, NULL); if (!window) { std::cout << "GLFW create window error\n"; glfwTerminate(); // Завершение работы с GLFW3 в случае ошибки return -1; } // Установка основного контекста окна glfwMakeContextCurrent(window); // Установка callback-функции для изменения размеров окна и буфера кадра glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); glfwSwapInterval(1); // Вертикальная синхронизация // Загрузка функций OpenGL с помощью GLAD if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { std::cout << "GLAD load GL error\n"; glfwTerminate(); // Завершение работы с GLFW3 в случае ошибки return -1; } // Компиляция шейдеров GLuint shaderProgram = LoadShaders("shaders/shader.vert", "shaders/shader.frag"); // Активация шейдера glUseProgram(shaderProgram); // Вершины треугольника glm::vec3 verticies[] = { {-0.5f, -0.5f, 0.0f} , { 0.5f, -0.5f, 0.0f} , { 0.5f, 0.5f, 0.0f} , {-0.5f, 0.5f, 0.0f} }; // VAO VAO vao; // VBO вершинный VBO vbo_vert(VERTEX, attrib_config); // Загрузка вершин в используемый буфер вершин vbo_vert.load(verticies, sizeof(verticies)); // индексы вершин GLuint indices[] = {0, 1, 2, 2, 3, 0}; // VBO элементный (индексы вершин) VBO vbo_elem(ELEMENT); // Загрузка индексов в используемый элементный буфер vbo_elem.load(indices, sizeof(indices)); // Установка цвета очистки буфера цвета glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Пока не произойдет событие запроса закрытия окна while(!glfwWindowShouldClose(window)) { // Очистка буфера цвета glClear(GL_COLOR_BUFFER_BIT); // Тут производится рендер vao.use(); glDrawElements(GL_TRIANGLES, sizeof(indices)/sizeof(GLuint), GL_UNSIGNED_INT, (void*)0); vao.disable(); // Представление содержимого буфера цепочки показа на окно glfwSwapBuffers(window); // Обработка системных событий glfwPollEvents(); } // Удаление шейдерной программы glDeleteProgram(shaderProgram); // Отключение атрибутов glDisableVertexAttribArray(0); // Завершение работы с GLFW3 перед выходом glfwTerminate(); }