Compare commits
No commits in common. "master" and "v0.2" have entirely different histories.
|
@ -80,8 +80,6 @@ class RBO
|
||||||
RBO(int w, int h, GLuint component = GL_DEPTH_COMPONENT); // Создает буфер рендера с заданными параметрами размеров и используемых компонент
|
RBO(int w, int h, GLuint component = GL_DEPTH_COMPONENT); // Создает буфер рендера с заданными параметрами размеров и используемых компонент
|
||||||
~RBO(); // Уничтожение буфера
|
~RBO(); // Уничтожение буфера
|
||||||
|
|
||||||
void reallocate(int w, int h, GLuint component = GL_DEPTH_COMPONENT); // Изменяет размеры буфера рендера
|
|
||||||
|
|
||||||
GLuint getHandler(); // Возвращает дескриптор буфера рендера
|
GLuint getHandler(); // Возвращает дескриптор буфера рендера
|
||||||
protected:
|
protected:
|
||||||
GLuint handler; // Дескриптор
|
GLuint handler; // Дескриптор
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include <GLM/glm.hpp>
|
#include <GLM/glm.hpp>
|
||||||
|
|
||||||
#include "Model.h"
|
#include "Buffers.h"
|
||||||
|
|
||||||
// Максимальное число источников света
|
// Максимальное число источников света
|
||||||
#define MAX_LIGHTS 300
|
#define MAX_LIGHTS 300
|
||||||
|
@ -13,47 +13,17 @@ struct LightData
|
||||||
{
|
{
|
||||||
alignas(16) glm::vec3 position; // Позиция
|
alignas(16) glm::vec3 position; // Позиция
|
||||||
alignas(16) glm::vec3 color; // Цвет
|
alignas(16) glm::vec3 color; // Цвет
|
||||||
alignas(16) glm::vec3 attenuation; // Радиус действия источника, линейный и квадратичный коэф. угасания
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Источник света
|
// Источник света
|
||||||
class Light : public Node
|
class Light
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static int getUBOsize(); // Возвращает размер буфера в байтах
|
static int getUBOsize(); // Возвращает размер буфера в байтах
|
||||||
static void upload(UBO& lights_data); // Загрузка данных в буфер
|
static void upload(UBO& lights_data); // Загрузка данных в буфер
|
||||||
|
|
||||||
static Light& getNew(); // Возвращает ссылку на новый источник света
|
|
||||||
void destroy(); // Уничтожает источник света
|
|
||||||
|
|
||||||
const glm::vec3& c_color() const; // Константный доступ к цвету
|
|
||||||
glm::vec3& e_color(); // Неконстантная ссылка для изменений цвета
|
|
||||||
|
|
||||||
const float& c_radius() const; // Константный доступ к радиусу
|
|
||||||
float& e_radius(); // Неконстантная ссылка для изменений радиуса
|
|
||||||
|
|
||||||
static void render(ShaderProgram &shaderProgram, UBO &material_buffer); // Рисование отладочных лампочек
|
|
||||||
private:
|
|
||||||
Light(); // Конструктор без параметров
|
|
||||||
Light(const Light& copy) = delete; // Конструктор копирования ОТКЛЮЧЕН
|
|
||||||
Light& operator=(const Light& other); // Оператор присваивания
|
|
||||||
virtual ~Light();
|
|
||||||
|
|
||||||
glm::vec3 color; // Цвет
|
|
||||||
float radius; // Радиус действия источника
|
|
||||||
|
|
||||||
int index; // Индекс в массиве отправки (может не совпадать с lights) для дефрагментированного доступа
|
|
||||||
static Light& findByIndex(GLuint index); // Возвращает ссылку на источник с нужным индексом
|
|
||||||
|
|
||||||
bool uploadReq; // Необходимость загрузки в следствии изменений
|
|
||||||
void check_id(); // Проверка что не взаимодествуем с пустым источником
|
|
||||||
void toData(); // Преобразует информацию об источнике в структуру LightData
|
|
||||||
|
|
||||||
virtual void recalcMatrices(); // Метод пересчета матрицы трансформации по необходимости, должен сбрасывать флаг changed
|
|
||||||
|
|
||||||
static GLuint count; // количество используемых источников (должно быть <= MAX_LIGHTS)
|
static GLuint count; // количество используемых источников (должно быть <= MAX_LIGHTS)
|
||||||
static LightData data[MAX_LIGHTS]; // Массив данных по источникам света
|
static LightData data[MAX_LIGHTS]; // Массив данных по источникам света
|
||||||
static Light lights[MAX_LIGHTS]; // Массив источников-узлов сцены
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LIGHTS_H
|
#endif // LIGHTS_H
|
||||||
|
|
|
@ -11,8 +11,6 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class Model genShpere(float radius, int sectorsCount, class Node* parent = NULL); // Генерирует сферу заданного радиуса с определенным количеством сегментов
|
|
||||||
|
|
||||||
// Класс узла сцены
|
// Класс узла сцены
|
||||||
class Node
|
class Node
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,8 +23,6 @@ class Texture
|
||||||
|
|
||||||
Texture& operator=(const Texture& other); // Оператор присваивания
|
Texture& operator=(const Texture& other); // Оператор присваивания
|
||||||
|
|
||||||
void reallocate(GLuint width, GLuint height, GLuint texType = TEX_DIFFUSE, GLint internalformat = GL_RGBA, GLint format = GL_RGBA, GLenum dataType = GL_FLOAT); // Пересоздает текстуру для имеющегося дескриптора
|
|
||||||
|
|
||||||
void use(); // Привязка текстуры
|
void use(); // Привязка текстуры
|
||||||
static void disable(GLuint type); // Отвязка текстуры по типу
|
static void disable(GLuint type); // Отвязка текстуры по типу
|
||||||
GLuint getType(); // Возвращает тип текстуры
|
GLuint getType(); // Возвращает тип текстуры
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
#version 420 core
|
|
||||||
|
|
||||||
layout(std140, binding = 1) uniform Material
|
|
||||||
{
|
|
||||||
vec3 ka;
|
|
||||||
vec3 kd;
|
|
||||||
vec3 ks;
|
|
||||||
float p;
|
|
||||||
};
|
|
||||||
|
|
||||||
out vec4 color;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
color = vec4(ka, 1);
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
#version 420 core
|
|
||||||
|
|
||||||
layout(location = 0) in vec3 pos;
|
|
||||||
|
|
||||||
layout(std140, binding = 0) uniform Camera
|
|
||||||
{
|
|
||||||
mat4 projection;
|
|
||||||
mat4 view;
|
|
||||||
vec3 position;
|
|
||||||
} camera;
|
|
||||||
|
|
||||||
uniform mat4 model;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
gl_Position = camera.projection * camera.view * model * vec4(pos, 1.0);
|
|
||||||
}
|
|
|
@ -13,7 +13,6 @@ struct LightData
|
||||||
{
|
{
|
||||||
vec3 position;
|
vec3 position;
|
||||||
vec3 color;
|
vec3 color;
|
||||||
vec3 attenuation;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(std140, binding = 2) uniform Light
|
layout(std140, binding = 2) uniform Light
|
||||||
|
@ -45,8 +44,6 @@ void main()
|
||||||
float diffuse; // Диффузная составляющая
|
float diffuse; // Диффузная составляющая
|
||||||
vec3 H; // Вектор половины пути
|
vec3 H; // Вектор половины пути
|
||||||
float specular; // Зеркальная составляющая
|
float specular; // Зеркальная составляющая
|
||||||
float L_distance; // Расстояние от поверхности до источника
|
|
||||||
float attenuation; // Коэф. угасания
|
|
||||||
|
|
||||||
// Фоновая освещенность
|
// Фоновая освещенность
|
||||||
color = vec4(ka, 1);
|
color = vec4(ka, 1);
|
||||||
|
@ -58,12 +55,6 @@ void main()
|
||||||
// Данные об источнике относительно фрагмента
|
// Данные об источнике относительно фрагмента
|
||||||
L_vertex = light_f.data[i].position - fragPos;
|
L_vertex = light_f.data[i].position - fragPos;
|
||||||
|
|
||||||
// Расстояние от поверхности до источника
|
|
||||||
L_distance = length(L_vertex);
|
|
||||||
|
|
||||||
// Проверка на дистанцию
|
|
||||||
if (L_distance < light_f.data[i].attenuation.r)
|
|
||||||
{
|
|
||||||
// Нормирование вектора
|
// Нормирование вектора
|
||||||
L_vertex = normalize(L_vertex);
|
L_vertex = normalize(L_vertex);
|
||||||
|
|
||||||
|
@ -75,11 +66,7 @@ void main()
|
||||||
// Зеркальная составляющая
|
// Зеркальная составляющая
|
||||||
specular = pow(max(dot(H, N), 0.0), p*4); // скалярное произведение с отсеканием значений < 0 в степени p
|
specular = pow(max(dot(H, N), 0.0), p*4); // скалярное произведение с отсеканием значений < 0 в степени p
|
||||||
|
|
||||||
// Угасание с учетом расстояния
|
color += vec4(light_f.data[i].color*kd*diffuse, 1)
|
||||||
attenuation = 1 / (1 + light_f.data[i].attenuation[1] * L_distance + light_f.data[i].attenuation[2] * L_distance * L_distance);
|
+ vec4(light_f.data[i].color*ks*specular, 1);
|
||||||
|
|
||||||
color += vec4(light_f.data[i].color*kd*diffuse * attenuation, 1)
|
|
||||||
+ vec4(light_f.data[i].color*ks*specular * attenuation, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -189,13 +189,6 @@ RBO::~RBO()
|
||||||
glDeleteRenderbuffers(1, &handler);
|
glDeleteRenderbuffers(1, &handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Изменяет размеры буфера рендера
|
|
||||||
void RBO::reallocate(int w, int h, GLuint component)
|
|
||||||
{
|
|
||||||
glBindRenderbuffer(GL_RENDERBUFFER, handler); // Привязка элементного буфера
|
|
||||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, w, h);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Возвращает дескриптор буфера рендера
|
// Возвращает дескриптор буфера рендера
|
||||||
GLuint RBO::getHandler()
|
GLuint RBO::getHandler()
|
||||||
{
|
{
|
||||||
|
|
197
src/Lights.cpp
197
src/Lights.cpp
|
@ -1,12 +1,7 @@
|
||||||
#include "Lights.h"
|
#include "Lights.h"
|
||||||
|
|
||||||
#include "Scene.h" // Для отладочного вывода лампочек
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
GLuint Light::count = 0; // количество используемых источников (должно быть <= MAX_LIGHTS)
|
GLuint Light::count = 0; // количество используемых источников (должно быть <= MAX_LIGHTS)
|
||||||
LightData Light::data[MAX_LIGHTS]; // Массив данных по источникам света
|
LightData Light::data[MAX_LIGHTS]; // Массив данных по источникам света
|
||||||
Light Light::lights[MAX_LIGHTS]; // Массив источников-узлов сцены
|
|
||||||
|
|
||||||
// возвращает размер буфера в байтах
|
// возвращает размер буфера в байтах
|
||||||
int Light::getUBOsize()
|
int Light::getUBOsize()
|
||||||
|
@ -18,200 +13,10 @@ int Light::getUBOsize()
|
||||||
void Light::upload(UBO& lights_data)
|
void Light::upload(UBO& lights_data)
|
||||||
{
|
{
|
||||||
GLuint LightDataSize = sizeof(LightData); // Одного экземпляра структуры LightData
|
GLuint LightDataSize = sizeof(LightData); // Одного экземпляра структуры LightData
|
||||||
int first = MAX_LIGHTS, last = -1; // Начало и конец диапазона загрузки источников
|
|
||||||
static GLuint prev_count = -1; // Кол-во источников в прошлую посылку
|
|
||||||
|
|
||||||
if (count)
|
if (count)
|
||||||
{
|
lights_data.loadSub(data, sizeof(LightData)*count); // Загрузка данных об источниках
|
||||||
for (int i = 0; i < MAX_LIGHTS; i++)
|
|
||||||
{
|
|
||||||
lights[i].recalcMatrices(); // Пересчитаем матрицы по необходимости (проверка внутри метода)
|
|
||||||
|
|
||||||
// Если требуется загрузка
|
|
||||||
if (lights[i].uploadReq)
|
|
||||||
{
|
|
||||||
lights[i].toData(); // Перевод ноды в данные для шейдера
|
|
||||||
|
|
||||||
// Определение диапазона загрузки
|
|
||||||
if (first > lights[i].index)
|
|
||||||
first = lights[i].index;
|
|
||||||
if (last < lights[i].index)
|
|
||||||
last = lights[i].index;
|
|
||||||
|
|
||||||
lights[i].uploadReq = false; // Сброс флага
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Если есть что загрузить (определен диапазон)
|
|
||||||
if (last > -1)
|
|
||||||
lights_data.loadSub(data + first, LightDataSize*(last - first +1), LightDataSize*(first)); // Загрузка данных об источниках
|
|
||||||
}
|
|
||||||
|
|
||||||
// Если кол-во изменилось
|
|
||||||
if (prev_count != count)
|
|
||||||
{
|
|
||||||
prev_count = count;
|
|
||||||
|
|
||||||
// Загружаем кол-во источников
|
// Загружаем кол-во источников
|
||||||
lights_data.loadSub(&count, sizeof(count), LightDataSize*MAX_LIGHTS);
|
lights_data.loadSub(&count, sizeof(count), LightDataSize*MAX_LIGHTS);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Метод пересчета матрицы трансформации по необходимости, должен сбрасывать флаг changed
|
|
||||||
void Light::recalcMatrices()
|
|
||||||
{
|
|
||||||
// Если были изменения - необходимо загрузить данные
|
|
||||||
if (changed || parent_changed)
|
|
||||||
uploadReq = true;
|
|
||||||
|
|
||||||
// Выполняем вычисление матриц методом родительского класса
|
|
||||||
Node::recalcMatrices();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Константный доступ к цвету
|
|
||||||
const glm::vec3& Light::c_color() const
|
|
||||||
{
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Неконстантная ссылка для изменений цвета
|
|
||||||
glm::vec3& Light::e_color()
|
|
||||||
{
|
|
||||||
uploadReq = true;
|
|
||||||
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Проверка что не взаимодествуем с пустым источником
|
|
||||||
void Light::check_id()
|
|
||||||
{
|
|
||||||
if (index < 0
|
|
||||||
|| index >= count)
|
|
||||||
throw std::runtime_error("Попытка использовать ссылку на пустой или некорректный источник");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Преобразует информацию об источнике в структуру LightData
|
|
||||||
void Light::toData()
|
|
||||||
{
|
|
||||||
check_id(); // Проверка на работу с корректным индексом
|
|
||||||
|
|
||||||
data[index].position = glm::vec3(result_transform[3]); // Позиция из матрицы трансформации
|
|
||||||
data[index].color = color; // Цвет
|
|
||||||
// Если радиус изменился
|
|
||||||
if (data[index].attenuation.r != radius)
|
|
||||||
{
|
|
||||||
data[index].attenuation.r = radius; // Радиус действия источника
|
|
||||||
data[index].attenuation[1] = 4.5/radius; // Линейный коэф. угасания
|
|
||||||
data[index].attenuation[2] = 4 * data[index].attenuation[1] * data[index].attenuation[1]; // Квадратичный коэф. угасания
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Возвращает ссылку на новый источник света
|
|
||||||
Light& Light::getNew()
|
|
||||||
{
|
|
||||||
Light& refNew = findByIndex(-1);
|
|
||||||
|
|
||||||
refNew.index = count++;
|
|
||||||
refNew.uploadReq = true;
|
|
||||||
|
|
||||||
return refNew;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Уничтожает источник света
|
|
||||||
void Light::destroy()
|
|
||||||
{
|
|
||||||
check_id(); // Проверка на работу с корректным индексом
|
|
||||||
// Если удаляемый элемент не последний
|
|
||||||
if (count-1 != index)
|
|
||||||
{
|
|
||||||
// Найдем элемент для замены
|
|
||||||
Light& replace = findByIndex(--count);
|
|
||||||
|
|
||||||
replace.uploadReq = true; // Требуется загрузить данные
|
|
||||||
replace.index = index; // Заменяем индекс данных
|
|
||||||
}
|
|
||||||
|
|
||||||
operator=(Light()); // Обнулим источник путем замены на новый
|
|
||||||
}
|
|
||||||
|
|
||||||
// Возвращает ссылку на источник с нужным индексом
|
|
||||||
Light& Light::findByIndex(GLuint index)
|
|
||||||
{
|
|
||||||
// Если нет источников - возвращаем нулевой
|
|
||||||
if (!count)
|
|
||||||
return lights[0];
|
|
||||||
|
|
||||||
// Цикл по перебору источников
|
|
||||||
for (int i = 0; i < MAX_LIGHTS; i++)
|
|
||||||
if (lights[i].index == index)
|
|
||||||
return lights[i];
|
|
||||||
|
|
||||||
throw std::runtime_error("Запрашиваемый источник освещения не найден, либо достигнут лимит");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Конструктор без параметров
|
|
||||||
Light::Light() : Node(), index(-1), uploadReq(false), color(1.0f), radius(10.0f)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Оператор присваивания
|
|
||||||
Light& Light::operator=(const Light& other)
|
|
||||||
{
|
|
||||||
// Проверка на самоприсваивание
|
|
||||||
if (this != &other)
|
|
||||||
{
|
|
||||||
index = other.index; // Переносим индекс
|
|
||||||
uploadReq = other.uploadReq; // Необходимость загрузки
|
|
||||||
color = other.color;
|
|
||||||
radius = other.radius;
|
|
||||||
|
|
||||||
Node::operator=(other);
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Light::~Light()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Рисование отладочных лампочек
|
|
||||||
void Light::render(ShaderProgram &shaderProgram, UBO &material_buffer)
|
|
||||||
{
|
|
||||||
// Загрузка модели лампочки при первом вызове функции
|
|
||||||
static Scene bulb = loadOBJtoScene("../resources/models/bulb.obj", "../resources/models/", "../resources/textures/");
|
|
||||||
static Model sphere = genShpere(1, 16, &bulb.root);
|
|
||||||
|
|
||||||
// Цикл по источникам света
|
|
||||||
for (int i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
// Сдвиг на позицию источника
|
|
||||||
bulb.root.e_position() = data[i].position;
|
|
||||||
sphere.e_scale() = glm::vec3(data[i].attenuation.r); // Масштабирование сферы
|
|
||||||
// Задание цвета
|
|
||||||
bulb.models.begin()->material.ka = sphere.material.ka = data[i].color;
|
|
||||||
|
|
||||||
// Вызов отрисовки
|
|
||||||
bulb.render(shaderProgram, material_buffer);
|
|
||||||
|
|
||||||
// Рисование сферы покрытия источника в режиме линий
|
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
|
||||||
sphere.render(shaderProgram, material_buffer);
|
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Константный доступ к радиусу
|
|
||||||
const float& Light::c_radius() const
|
|
||||||
{
|
|
||||||
return radius;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Неконстантная ссылка для изменений радиуса
|
|
||||||
float& Light::e_radius()
|
|
||||||
{
|
|
||||||
uploadReq = true;
|
|
||||||
|
|
||||||
return radius;
|
|
||||||
}
|
|
||||||
|
|
|
@ -402,77 +402,3 @@ void Model::set_texture(Texture& texture)
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Генерирует сферу заданного радиуса с определенным количеством сегментов
|
|
||||||
Model genShpere(float radius, int sectorsCount, Node* parent)
|
|
||||||
{
|
|
||||||
Model result(parent);
|
|
||||||
|
|
||||||
std::vector<glm::vec3> vertices;
|
|
||||||
std::vector<glm::vec3> normals;
|
|
||||||
std::vector<GLuint> indices;
|
|
||||||
|
|
||||||
float x, y, z, xy; // Позиция вершины
|
|
||||||
float nx, ny, nz, lengthInv = 1.0f / radius; // Нормаль вершины
|
|
||||||
float PI = 3.14159265;
|
|
||||||
float sectorStep = PI / sectorsCount; // Шаг сектора
|
|
||||||
float longAngle, latAngle; // Углы
|
|
||||||
|
|
||||||
for(int i = 0; i <= sectorsCount; ++i)
|
|
||||||
{
|
|
||||||
latAngle = PI / 2 - i * sectorStep; // Начиная с pi/2 до -pi/2
|
|
||||||
xy = radius * cos(latAngle); // r * cos(lat)
|
|
||||||
z = radius * sin(latAngle); // r * sin(lat)
|
|
||||||
|
|
||||||
// добавляем (sectorCount+1) вершин на сегмент
|
|
||||||
// Последняя и первая вершины имеют одинаковые нормали и координаты
|
|
||||||
for(int j = 0; j <= sectorsCount; ++j)
|
|
||||||
{
|
|
||||||
longAngle = j * 2 * sectorStep; // Начиная с 0 до 2*pi
|
|
||||||
|
|
||||||
// Положение вершины (x, y, z)
|
|
||||||
x = xy * cos(longAngle); // r * cos(lat) * cos(long)
|
|
||||||
y = xy * sin(longAngle); // r * cos(lat) * sin(long)
|
|
||||||
vertices.push_back({x, y, z});
|
|
||||||
|
|
||||||
// Нормали (nx, ny, nz)
|
|
||||||
nx = x * lengthInv;
|
|
||||||
ny = y * lengthInv;
|
|
||||||
nz = z * lengthInv;
|
|
||||||
normals.push_back({nx, ny, nz});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int k1, k2;
|
|
||||||
for(int i = 0; i < sectorsCount; ++i)
|
|
||||||
{
|
|
||||||
k1 = i * (sectorsCount + 1); // начало текущего сегмента
|
|
||||||
k2 = k1 + sectorsCount + 1; // начало следующего сегмента
|
|
||||||
|
|
||||||
for(int j = 0; j < sectorsCount; ++j, ++k1, ++k2)
|
|
||||||
{
|
|
||||||
// 2 треугольника на один сегмент
|
|
||||||
// k1, k2, k1+1
|
|
||||||
if(i != 0)
|
|
||||||
{
|
|
||||||
indices.push_back(k1);
|
|
||||||
indices.push_back(k2);
|
|
||||||
indices.push_back(k1 + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// k1+1, k2, k2+1
|
|
||||||
if(i != (sectorsCount-1))
|
|
||||||
{
|
|
||||||
indices.push_back(k1 + 1);
|
|
||||||
indices.push_back(k2);
|
|
||||||
indices.push_back(k2 + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Загрузка в модель
|
|
||||||
result.load_verteces(&vertices[0], vertices.size());
|
|
||||||
result.load_normals(&normals[0], normals.size());
|
|
||||||
result.load_indices(&indices[0], indices.size());
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
|
@ -115,13 +115,6 @@ Texture::~Texture()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Пересоздает текстуру для имеющегося дескриптора
|
|
||||||
void Texture::reallocate(GLuint width, GLuint height, GLuint texType, GLint internalformat, GLint format, GLenum dataType)
|
|
||||||
{
|
|
||||||
use();
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, internalformat, width, height, 0, format, dataType, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Привязка текстуры
|
// Привязка текстуры
|
||||||
void Texture::use()
|
void Texture::use()
|
||||||
{
|
{
|
||||||
|
|
74
src/main.cpp
74
src/main.cpp
|
@ -9,42 +9,14 @@
|
||||||
#include "Shader.h"
|
#include "Shader.h"
|
||||||
#include "Lights.h"
|
#include "Lights.h"
|
||||||
|
|
||||||
|
#define WINDOW_WIDTH 800
|
||||||
|
#define WINDOW_HEIGHT 600
|
||||||
#define WINDOW_CAPTION "OPENGL notes on rekovalev.site"
|
#define WINDOW_CAPTION "OPENGL notes on rekovalev.site"
|
||||||
|
|
||||||
// Указатели на текстуры для изменения размеров окна
|
|
||||||
Texture* pgPosition = NULL;
|
|
||||||
Texture* pgNormal = NULL;
|
|
||||||
Texture* pgDiffuseP = NULL;
|
|
||||||
Texture* pgAmbientSpecular = NULL;
|
|
||||||
RBO* pgrbo = NULL;
|
|
||||||
// Размеры окна
|
|
||||||
int WINDOW_WIDTH = 800;
|
|
||||||
int WINDOW_HEIGHT = 600;
|
|
||||||
|
|
||||||
// Функция-callback для изменения размеров буфера кадра в случае изменения размеров поверхности окна
|
// Функция-callback для изменения размеров буфера кадра в случае изменения размеров поверхности окна
|
||||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
||||||
{
|
{
|
||||||
glViewport(0, 0, width, height);
|
glViewport(0, 0, width, height);
|
||||||
|
|
||||||
// Изменение размеров текстур для G-буфера
|
|
||||||
if (pgPosition)
|
|
||||||
pgPosition->reallocate(width, height, 0, GL_RGB32F, GL_RGB);
|
|
||||||
if (pgNormal)
|
|
||||||
pgNormal->reallocate(width, height, 1, GL_RGB16F, GL_RGB);
|
|
||||||
if (pgDiffuseP)
|
|
||||||
pgDiffuseP->reallocate(width, height, 2, GL_RGBA16F);
|
|
||||||
if (pgAmbientSpecular)
|
|
||||||
pgAmbientSpecular->reallocate(width, height, 3);
|
|
||||||
// И буфера глубины
|
|
||||||
if (pgrbo)
|
|
||||||
pgrbo->reallocate(width, height);
|
|
||||||
|
|
||||||
// Запомним новые размеры окна
|
|
||||||
WINDOW_WIDTH = width;
|
|
||||||
WINDOW_HEIGHT = height;
|
|
||||||
|
|
||||||
// Изменим параметры перспективной матрицы проекции для камеры
|
|
||||||
Camera::current().setPerspective(CAMERA_FOVy, (float)width/height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool firstMouse = true;
|
bool firstMouse = true;
|
||||||
|
@ -122,6 +94,7 @@ int main(void)
|
||||||
const char* textures_base_shader_names[] = {"tex_diffuse", "tex_ambient", "tex_specular"};
|
const char* textures_base_shader_names[] = {"tex_diffuse", "tex_ambient", "tex_specular"};
|
||||||
gShader.bindTextures(textures_base_shader_names, sizeof(textures_base_shader_names)/sizeof(const char*));
|
gShader.bindTextures(textures_base_shader_names, sizeof(textures_base_shader_names)/sizeof(const char*));
|
||||||
|
|
||||||
|
|
||||||
// Загрузка сцены из obj файла
|
// Загрузка сцены из obj файла
|
||||||
Scene scene = loadOBJtoScene("../resources/models/blob.obj", "../resources/models/", "../resources/textures/");
|
Scene scene = loadOBJtoScene("../resources/models/blob.obj", "../resources/models/", "../resources/textures/");
|
||||||
scene.root.e_scale() = glm::vec3(0.01);
|
scene.root.e_scale() = glm::vec3(0.01);
|
||||||
|
@ -133,12 +106,14 @@ int main(void)
|
||||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
// Источники света
|
// Источники света
|
||||||
Light& first = Light::getNew();
|
// Первый способ измений
|
||||||
first.e_color() = {1.0f, 0.0f, 0.0f}; // цвет
|
Light::data[0] = { {0.3f, 0.1f, 0.5f} // позиция
|
||||||
first.e_position() = {0.3f, 0.1f, 0.5f}; // Позиция
|
, {1.0f, 0.0f, 0.0f} // цвет
|
||||||
Light& second = Light::getNew();
|
};
|
||||||
second.e_color() = {0.0f, 0.0f, 1.0f}; // цвет
|
Light::count++;
|
||||||
second.e_position() = {-0.3f, -0.1f, 0.5f}; // Позиция
|
// Второй способ
|
||||||
|
Light::data[Light::count].position = {-0.3f, -0.1f, 0.5f}; // позиция
|
||||||
|
Light::data[Light::count++].color = { 0.0f, 0.0f, 1.0f}; // цвет
|
||||||
|
|
||||||
// Uniform-буферы
|
// Uniform-буферы
|
||||||
UBO cameraUB(sizeof(CameraData), 0);
|
UBO cameraUB(sizeof(CameraData), 0);
|
||||||
|
@ -151,7 +126,7 @@ int main(void)
|
||||||
GLuint attachments[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 };
|
GLuint attachments[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 };
|
||||||
FBO gbuffer(attachments, sizeof(attachments) / sizeof(GLuint));
|
FBO gbuffer(attachments, sizeof(attachments) / sizeof(GLuint));
|
||||||
// Создадим текстуры для буфера кадра
|
// Создадим текстуры для буфера кадра
|
||||||
Texture gPosition(WINDOW_WIDTH, WINDOW_HEIGHT, GL_COLOR_ATTACHMENT0, 0, GL_RGB32F, GL_RGB); // Позиция вершины
|
Texture gPosition(WINDOW_WIDTH, WINDOW_HEIGHT, GL_COLOR_ATTACHMENT0, 0, GL_RGB16F, GL_RGB); // Позиция вершины
|
||||||
Texture gNormal(WINDOW_WIDTH, WINDOW_HEIGHT, GL_COLOR_ATTACHMENT1, 1, GL_RGB16F, GL_RGB); // Нормали
|
Texture gNormal(WINDOW_WIDTH, WINDOW_HEIGHT, GL_COLOR_ATTACHMENT1, 1, GL_RGB16F, GL_RGB); // Нормали
|
||||||
Texture gDiffuseP(WINDOW_WIDTH, WINDOW_HEIGHT, GL_COLOR_ATTACHMENT2, 2, GL_RGBA16F); // Диффузная составляющая и коэф. глянцевости
|
Texture gDiffuseP(WINDOW_WIDTH, WINDOW_HEIGHT, GL_COLOR_ATTACHMENT2, 2, GL_RGBA16F); // Диффузная составляющая и коэф. глянцевости
|
||||||
Texture gAmbientSpecular(WINDOW_WIDTH, WINDOW_HEIGHT, GL_COLOR_ATTACHMENT3, 3); // Фоновая составляющая и один канал зеркальной
|
Texture gAmbientSpecular(WINDOW_WIDTH, WINDOW_HEIGHT, GL_COLOR_ATTACHMENT3, 3); // Фоновая составляющая и один канал зеркальной
|
||||||
|
@ -161,13 +136,6 @@ int main(void)
|
||||||
// Активируем базовый буфер кадра
|
// Активируем базовый буфер кадра
|
||||||
FBO::useDefault();
|
FBO::useDefault();
|
||||||
|
|
||||||
// Сохраним указатели на текстуры для изменения размеров окна
|
|
||||||
pgPosition = &gPosition;
|
|
||||||
pgNormal = &gNormal;
|
|
||||||
pgDiffuseP = &gDiffuseP;
|
|
||||||
pgAmbientSpecular = &gAmbientSpecular;
|
|
||||||
pgrbo = &grbo;
|
|
||||||
|
|
||||||
// Шейдер для расчета освещенности
|
// Шейдер для расчета освещенности
|
||||||
ShaderProgram lightShader;
|
ShaderProgram lightShader;
|
||||||
// Загрузка и компиляция шейдеров
|
// Загрузка и компиляция шейдеров
|
||||||
|
@ -189,13 +157,6 @@ int main(void)
|
||||||
quadModel.load_verteces(quadVertices, 4);
|
quadModel.load_verteces(quadVertices, 4);
|
||||||
quadModel.load_indices(quadIndices, 6);
|
quadModel.load_indices(quadIndices, 6);
|
||||||
|
|
||||||
// Шейдер для рисования отладочных лампочек
|
|
||||||
ShaderProgram bulbShader;
|
|
||||||
// Загрузка и компиляция шейдеров
|
|
||||||
bulbShader.load(GL_VERTEX_SHADER, "shaders/bulb.vert");
|
|
||||||
bulbShader.load(GL_FRAGMENT_SHADER, "shaders/bulb.frag");
|
|
||||||
bulbShader.link();
|
|
||||||
|
|
||||||
// Пока не произойдет событие запроса закрытия окна
|
// Пока не произойдет событие запроса закрытия окна
|
||||||
while(!glfwWindowShouldClose(window))
|
while(!glfwWindowShouldClose(window))
|
||||||
{
|
{
|
||||||
|
@ -228,17 +189,6 @@ int main(void)
|
||||||
// Рендерим прямоугольник с расчетом освещения
|
// Рендерим прямоугольник с расчетом освещения
|
||||||
quadModel.render();
|
quadModel.render();
|
||||||
|
|
||||||
// Перенос буфера глубины
|
|
||||||
FBO::useDefault(GL_DRAW_FRAMEBUFFER); // Базовый в режиме записи
|
|
||||||
gbuffer.use(GL_READ_FRAMEBUFFER); // Буфер геометрии в режиме чтения
|
|
||||||
// Копирование значений глубины
|
|
||||||
glBlitFramebuffer(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
|
|
||||||
FBO::useDefault(); // Использование базового буфера для дальнейших работ
|
|
||||||
|
|
||||||
// Отрисовка отладочных лампочек со специальным шейдером
|
|
||||||
bulbShader.use();
|
|
||||||
Light::render(bulbShader, material_data);
|
|
||||||
|
|
||||||
// Представление содержимого буфера цепочки показа на окно
|
// Представление содержимого буфера цепочки показа на окно
|
||||||
glfwSwapBuffers(window);
|
glfwSwapBuffers(window);
|
||||||
// Обработка системных событий
|
// Обработка системных событий
|
||||||
|
|
Loading…
Reference in New Issue