From d1ce8718f67c51fc8e00d5ca2e9ea59e64630fba Mon Sep 17 00:00:00 2001 From: "R.E. Kovalev" Date: Wed, 5 Apr 2023 16:07:09 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=B4=D0=B5=D0=BB?= =?UTF-8?q?=D0=BA=D0=B0=20=D1=81=D0=B2=D0=B5=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/Lights.h | 23 ++++++++---- shaders/bulb.frag | 13 +++++-- src/Lights.cpp | 92 +++++++++++++++++++++++++---------------------- src/main.cpp | 14 +++++--- 4 files changed, 87 insertions(+), 55 deletions(-) diff --git a/include/Lights.h b/include/Lights.h index c859113..ead98fe 100644 --- a/include/Lights.h +++ b/include/Lights.h @@ -12,24 +12,35 @@ // Максимальное число образцов для SSAO #define MAX_SSAO 64 -// Класс лампочки (точечный источник с возможностью отладочного вывода) class Bulb { public: Bulb(const glm::vec3 &pos = glm::vec3(0.0f, 0.0f, 0.0f), const glm::vec3 &color = glm::vec3(0.0f, 0.0f, 0.0f), float radius = 10.0f, float angle = 180, const glm::vec3 &direction = glm::vec3(0,0,1)); // Конструктор с координатами, цветом, радиусом и направлением - void render(ShaderProgram &shaderProgram, UBO &material_buffer); // Отрисовка отладочной лампы и сферы - + void setRadius(float radius); // Задание радиуса и расчет коэф. угасания + void recalc_pov(); // Пересчитывает матрицы проекции и трансформации в пространство источника + alignas(16) glm::vec3 position; // Позиция alignas(16) glm::vec3 color; // Цвет - void setRadius(float radius); // Задание радиуса и расчет коэф. угасания float angle; // Угол освещенности alignas(16) glm::vec3 direction; // Направление для прожектора - void recalc_pov(); // Пересчитывает матрицы проекции и трансформации в пространство источника private: float radius; // Радиус действия источника alignas(16) glm::vec2 K; // линейный и квадратичный компоненты затухания - alignas(16) glm::mat4 vp[6]; // Матрицы проекции и трансформации в пространство источника + alignas(16) glm::mat4 vp[6]; // Матрицы проекции и трансформации в пространство источника + friend class BulbDebug; +}; + +// Класс лампочки (точечный источник с возможностью отладочного вывода) +class BulbDebug +{ + public: + BulbDebug(Bulb* ref = NULL); // Конструктор с привязкой к источнику + + void render(ShaderProgram &shaderProgram, UBO &material_buffer); // Отрисовка отладочной лампы и сферы + + Bulb* data; + private: static GrouptedModel bulb_model; }; diff --git a/shaders/bulb.frag b/shaders/bulb.frag index 533af2b..98efb6d 100644 --- a/shaders/bulb.frag +++ b/shaders/bulb.frag @@ -15,16 +15,25 @@ layout(std140, binding = 4) uniform gamma float inv_gamma; }; -out vec4 color; +layout (location = 1) out vec3 gNormal; +layout (location = 3) out vec4 gAmbientSpecular; +layout (location = 4) out uvec3 gID; uniform float angle; uniform vec3 direction; +uniform uvec3 ID = uvec3(0); + void main() { float cosA = dot(normalize(pos_local), normalize(direction)); if (degrees(acos(cosA)) <= angle) - color = vec4(pow(ka, vec3(inv_gamma)), 1); + gAmbientSpecular.rgb = pow(ka, vec3(inv_gamma)); else discard; + + gNormal = vec3(0); + + // Сохранение идентификатора объекта + gID = ID; } \ No newline at end of file diff --git a/src/Lights.cpp b/src/Lights.cpp index 3421b65..312ce10 100644 --- a/src/Lights.cpp +++ b/src/Lights.cpp @@ -6,10 +6,23 @@ void genShpere(Model& model, float radius, int sectorsCount); // Model.cpp // Статическое поле для модели лампочки -GrouptedModel Bulb::bulb_model; +GrouptedModel BulbDebug::bulb_model; // Конструктор с координатами, цветом и радиусом Bulb::Bulb(const glm::vec3 &pos, const glm::vec3 &c, float r, float a, const glm::vec3 &dir) +{ + // Сохраним данные о параметрах источника: + position = pos; + color = c; + radius = r; + K[0] = 4.5/radius; + K[1] = 4 * K[0] * K[0]; + angle = a; + direction = dir; +} + +// Конструктор отладочной лампочки с координатами, цветом, радиусом и направлением +BulbDebug::BulbDebug(Bulb* ref) : data(ref) { // Если отладочная модель не загружена - загрузим if (!bulb_model.parts.size()) @@ -21,52 +34,47 @@ Bulb::Bulb(const glm::vec3 &pos, const glm::vec3 &c, float r, float a, const glm genShpere(radius_sphere, 1, 16); bulb_model.parts.insert(bulb_model.parts.begin(), radius_sphere); } - - // Сохраним данные о параметрах источника: - position = pos; - color = c; - radius = r; - K[0] = 4.5/radius; - K[1] = 4 * K[0] * K[0]; - angle = a; - direction = dir; } // Отрисовка отладочной лампы и сферы -void Bulb::render(ShaderProgram &shaderProgram, UBO &material_buffer) +void BulbDebug::render(ShaderProgram &shaderProgram, UBO &material_buffer) { - // Расположение uniform-переменных - GLuint model_uniform = shaderProgram.getUniformLoc("model"); - GLuint angle_uniform = shaderProgram.getUniformLoc("angle"); - GLuint direction_uniform = shaderProgram.getUniformLoc("direction"); - - // Загрузим направление - glUniform3fv(direction_uniform, 1, &direction[0]); - - // Зададим параметры материала сфере действия - bulb_model.parts[0].material.ka = color; - bulb_model.parts[0].position = position; - bulb_model.parts[0].scale = {radius, radius, radius}; - - // Угол для сферы (рисуем направленный конус) - glUniform1f(angle_uniform, angle); - - // Рисование сферы покрытия источника в режиме линий - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - bulb_model.parts[0].render(shaderProgram, material_buffer); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - - // Угол для лампочки = 180 (рисуем целую модель) - glUniform1f(angle_uniform, 180); // Зададим параметры материала сфере действия - - // Зададим цвет для колбы (первая в составе модели) - bulb_model.parts[1].material.ka = color; - - bulb_model.position = position; - glm::mat4 transform = bulb_model.getTransformMatrix(); - for (int i = 1; i < bulb_model.parts.size(); i++) + bulb_model.set_group_id((GLuint64) this); + if (data) { - bulb_model.parts[i].render(shaderProgram, material_buffer, transform); + // Расположение uniform-переменных + GLuint model_uniform = shaderProgram.getUniformLoc("model"); + GLuint angle_uniform = shaderProgram.getUniformLoc("angle"); + GLuint direction_uniform = shaderProgram.getUniformLoc("direction"); + + // Загрузим направление + glUniform3fv(direction_uniform, 1, &data->direction[0]); + + // Зададим параметры материала сфере действия + bulb_model.parts[0].material.ka = data->color; + bulb_model.parts[0].position = data->position; + bulb_model.parts[0].scale = glm::vec3(data->radius); + + // Угол для сферы (рисуем направленный конус) + glUniform1f(angle_uniform, data->angle); + + // Рисование сферы покрытия источника в режиме линий + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + bulb_model.parts[0].render(shaderProgram, material_buffer); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + // Угол для лампочки = 180 (рисуем целую модель) + glUniform1f(angle_uniform, 180); // Зададим параметры материала сфере действия + + // Зададим цвет для колбы (первая в составе модели) + bulb_model.parts[1].material.ka = data->color; + + bulb_model.position = data->position; + glm::mat4 transform = bulb_model.getTransformMatrix(); + for (int i = 1; i < bulb_model.parts.size(); i++) + { + bulb_model.parts[i].render(shaderProgram, material_buffer, transform); + } } } diff --git a/src/main.cpp b/src/main.cpp index 6733c23..4ef21b4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -150,6 +150,10 @@ int main(void) lights[lights_count].position = {-0.3f, 0.3f, 0.5f}; // позиция lights[lights_count++].color = {0.0f, 0.0f, 1.0f}; // цвет + BulbDebug lightsDebug[MAX_LIGHTS]; + for (int i = 0; i < MAX_LIGHTS; i++) + lightsDebug[i].data = &lights[i]; + // Uniform-буферы UBO cameraUB(sizeof(CameraData), 0); UBO material_data(sizeof(Material), 1); @@ -430,6 +434,11 @@ int main(void) scene.render(gShader, material_data); rectangle.render(gShader, material_data); + // Отрисовка отладочных лампочек со специальным шейдером + bulbShader.use(); + for (int i = 0; i < lights_count; i++) + lightsDebug[i].render(bulbShader, material_data); + // Используем шейдер для инструментов toolsShader.use(); // Рендерим инструменты для выбранного объекта @@ -544,11 +553,6 @@ int main(void) skybox.render(); // Возвращаем запись глубины glDepthMask(GL_TRUE); - - // Отрисовка отладочных лампочек со специальным шейдером - bulbShader.use(); - for (int i = 0; i < lights_count; i++) - lights[i].render(bulbShader, material_data); // Дополнительная обработка мыши process_mouse_button(mouse.left);