08/src/main.cpp

197 lines
7.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <GLM/glm.hpp>
#include <iostream>
#include "Camera.h"
#include "Model.h"
#include "Texture.h"
#include "Shader.h"
#include "Lights.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);
}
Camera camera(800.0f/600.0f);
bool firstMouse = true;
float lastX, lastY;
void mouse_callback(GLFWwindow* window, double xpos, double ypos)
{
if (firstMouse)
{
lastX = xpos;
lastY = ypos;
firstMouse = false;
}
glm::vec2 offset(xpos - lastX, lastY - ypos);
lastX = xpos;
lastY = ypos;
camera.rotate(offset);
}
int main(void)
{
GLFWwindow* window; // Указатель на окно GLFW3
// Инициализация GLFW3
if (!glfwInit())
{
std::cout << "GLFW init error\n";
return -1;
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // Мажорная версия спецификаций OpenGL
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // Минорная версия спецификаций 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); // Вертикальная синхронизация
// Установка callback-функции для мыши и камеры
glfwSetCursorPosCallback(window, mouse_callback);
// Загрузка функций OpenGL с помощью GLAD
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "GLAD load GL error\n";
glfwTerminate(); // Завершение работы с GLFW3 в случае ошибки
return -1;
}
// Включаем проверку по буферу глубины
glEnable(GL_DEPTH_TEST);
// Базовый шейдер
ShaderProgram base;
// Загрузка и компиляция шейдеров
base.load(GL_VERTEX_SHADER, "shaders/shader.vert");
base.load(GL_FRAGMENT_SHADER, "shaders/shader.frag");
base.link();
// Установим значения текстур
const char* textures_base_shader_names[] = {"tex_diffuse", "tex_ambient", "tex_specular"};
base.bindTextures(textures_base_shader_names, sizeof(textures_base_shader_names)/sizeof(const char*));
// Загрузка сцены из obj файла
GrouptedModel scene = loadOBJtoGroupted("../resources/models/blob.obj", "../resources/models/", "../resources/textures/");
scene.scale = glm::vec3(0.01);
scene.position.z = 1;
// Установка цвета очистки буфера цвета
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// Расположение Uniform-переменной
GLuint model_uniform = base.getUniformLoc("model");
// Источник света
PointLight light = { {1.0f, 3.0f, 0.0f} // позиция
, {1.0f, 1.0f, 1.0f} // цвет
};
// Uniform-буферы
UBO cameraUB(sizeof(CameraData), 0);
UBO material_data(sizeof(Material), 1);
UBO light_data(&light, sizeof(PointLight), 2);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // Использование уменьшенных версий mipmap
// Создадим буфер кадра с данными о используемых привязках
GLuint attachments[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
FBO fbo(attachments, sizeof(attachments) / sizeof(GLuint));
// Создадим текстуры для буфера кадра
Texture colors(WINDOW_WIDTH, WINDOW_HEIGHT, GL_COLOR_ATTACHMENT0);
Texture normals(WINDOW_WIDTH, WINDOW_HEIGHT, GL_COLOR_ATTACHMENT1, 0, GL_RGBA16F);
// Создадим буфер рендера под буфер глубины и привяжем его
unsigned int rbo;
glGenRenderbuffers(1, &rbo);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, WINDOW_WIDTH, WINDOW_HEIGHT);
fbo.assignRenderBuffer(rbo);
// Активируем базовый буфер кадра
FBO::useDefault();
// Шейдер для переноса текстуры на прямоугольник
ShaderProgram quadProgram;
// Загрузка и компиляция шейдеров
quadProgram.load(GL_VERTEX_SHADER, "shaders/quad.vert");
quadProgram.load(GL_FRAGMENT_SHADER, "shaders/quad.frag");
quadProgram.link();
glm::vec3 quadVertices[] = { {-1.0f, 1.0f, 0.0f}
, {-1.0f, -1.0f, 0.0f}
, { 1.0f, 1.0f, 0.0f}
, { 1.0f, -1.0f, 0.0f}
};
GLuint quadIndices[] = {0,1,2,2,1,3};
Model quadModel;
quadModel.load_verteces(quadVertices, 4);
quadModel.load_indices(quadIndices, 6);
// Пока не произойдет событие запроса закрытия окна
while(!glfwWindowShouldClose(window))
{
// Активируем буфер кадра
fbo.use();
// Используем шейдер с освещением
base.use();
// Очистка буфера цвета и глубины
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Загрузка данных о камере
cameraUB.loadSub(&camera.getData(), sizeof(CameraData));
// Тут производится рендер
scene.render(model_uniform, material_data);
// Активируем базовый буфер кадра
FBO::useDefault();
// Подключаем шейдер для прямоугольника
quadProgram.use();
// Очистка буфера цвета и глубины
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Подключаем текстуру цветов
colors.use();
// Рендерим прямоугольник
quadModel.render();
// Представление содержимого буфера цепочки показа на окно
glfwSwapBuffers(window);
// Обработка системных событий
glfwPollEvents();
}
// Отключение атрибутов
glDisableVertexAttribArray(0);
// Завершение работы с GLFW3 перед выходом
glfwTerminate();
}