Дефрагментация данных по источникам

This commit is contained in:
parent cdcc729d16
commit 1866027900
2 changed files with 81 additions and 1 deletions

View File

@ -22,12 +22,21 @@ class Light : public Node
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; // Константный доступ к цвету const glm::vec3& c_color() const; // Константный доступ к цвету
glm::vec3& e_color(); // Неконстантная ссылка для изменений цвета glm::vec3& e_color(); // Неконстантная ссылка для изменений цвета
private: private:
Light(); // Конструктор без параметров
Light(const Light& copy) = delete; // Конструктор копирования ОТКЛЮЧЕН
Light& operator=(const Light& other); // Оператор присваивания
virtual ~Light();
glm::vec3 color; // Цвет glm::vec3 color; // Цвет
int index; // Индекс в массиве отправки (может не совпадать с lights) для дефрагментированного доступа int index; // Индекс в массиве отправки (может не совпадать с lights) для дефрагментированного доступа
static Light& findByIndex(GLuint index); // Возвращает ссылку на источник с нужным индексом
bool uploadReq; // Необходимость загрузки в следствии изменений bool uploadReq; // Необходимость загрузки в следствии изменений
void check_id(); // Проверка что не взаимодествуем с пустым источником void check_id(); // Проверка что не взаимодествуем с пустым источником
@ -37,6 +46,7 @@ class Light : public Node
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

View File

@ -4,6 +4,7 @@
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()
@ -15,7 +16,7 @@ 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
if (count) if (count)
lights_data.loadSub(data, sizeof(LightData)*count); // Загрузка данных об источниках lights_data.loadSub(data, sizeof(LightData)*count); // Загрузка данных об источниках
@ -64,3 +65,72 @@ void Light::toData()
data[index].position = glm::vec3(result_transform[3]); // Позиция из матрицы трансформации data[index].position = glm::vec3(result_transform[3]); // Позиция из матрицы трансформации
data[index].color = color; // Цвет data[index].color = color; // Цвет
} }
// Возвращает ссылку на новый источник света
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)
{
}
// Оператор присваивания
Light& Light::operator=(const Light& other)
{
// Проверка на самоприсваивание
if (this != &other)
{
index = other.index; // Переносим индекс
uploadReq = other.uploadReq; // Необходимость загрузки
color = other.color;
Node::operator=(other);
}
return *this;
}
Light::~Light()
{
}