Compare commits

..

No commits in common. "master" and "v0.2" have entirely different histories.
master ... v0.2

7 changed files with 8 additions and 339 deletions

View File

@ -1,45 +0,0 @@
#ifndef TRS_H
#define TRS_H
#define T_SENSITIVITY 0.001f
#define R_SENSITIVITY 0.01f
#define S_SENSITIVITY 0.00001f
#include "Scene.h"
// Интерфейс инструмента
class TRS
{
public:
void render(GLuint64 selectedID, ShaderProgram &shaderProgram, UBO &material_buffer); // Рендер инструмента нужного типа для выбранного объекта
virtual void process(GLuint64 selectedID, GLuint etc, const glm::vec4& dpos) = 0; // Взаимодействие с инструментом
protected:
void init_etc(); // Инициализирует дополнительную информацию модели
Scene tool; // Модель
};
// Инструмент трансформации
class Transform : public TRS
{
public:
Transform();
virtual void process(GLuint64 selectedID, GLuint etc, const glm::vec4& dpos); // Взаимодействие с инструментом
};
// Инструмент поворота
class Rotate : public TRS
{
public:
Rotate();
virtual void process(GLuint64 selectedID, GLuint etc, const glm::vec4& drot); // Взаимодействие с инструментом
};
// Инструмент масштабирования
class Scale : public TRS
{
public:
Scale();
virtual void process(GLuint64 selectedID, GLuint etc, const glm::vec4& dscale); // Взаимодействие с инструментом
};
#endif // TRS_H

View File

@ -18,25 +18,16 @@ layout(std140, binding = 4) uniform gamma
float inv_gamma; float inv_gamma;
}; };
layout (location = 1) out vec3 gNormal; out vec4 color;
layout (location = 3) out vec4 gAmbientSpecular;
layout (location = 4) out uvec3 gID;
uniform float angle; uniform float angle;
uniform vec3 direction; uniform vec3 direction;
uniform uvec3 ID = uvec3(0);
void main() void main()
{ {
float cosA = dot(normalize(pos_local), normalize(direction)); float cosA = dot(normalize(pos_local), normalize(direction));
if (degrees(acos(cosA)) <= angle) if (degrees(acos(cosA)) <= angle)
gAmbientSpecular.rgb = pow(ka, vec3(inv_gamma)); color = vec4(pow(ka, vec3(inv_gamma)), 1);
else else
discard; discard;
gNormal = vec3(0);
// Сохранение идентификатора объекта
gID = ID;
} }

View File

@ -40,9 +40,6 @@ uniform sampler2D gAmbientSpecular;
uniform sampler2DArray sunShadowDepth; uniform sampler2DArray sunShadowDepth;
uniform samplerCubeArray pointShadowDepth; uniform samplerCubeArray pointShadowDepth;
uniform sampler2D ssao; uniform sampler2D ssao;
uniform usampler2D gID;
uniform uvec3 selectedID;
layout(std140, binding = 4) uniform gamma layout(std140, binding = 4) uniform gamma
{ {
@ -201,21 +198,4 @@ void main()
// Применение гамма-коррекции // Применение гамма-коррекции
color.rgb = pow(color.rgb, vec3(inv_gamma)); color.rgb = pow(color.rgb, vec3(inv_gamma));
vec3 ID = texture(gID, texCoord).rgb;
// Обводка выбранного объекта
if (length(selectedID.rg) > 0 && selectedID.rg == ID.rg && ID.b == 0)
{
int border_width = 3;
vec2 size = 1.0f / textureSize(gID, 0);
for (int i = -border_width; i <= +border_width; i++)
for (int j = -border_width; j <= +border_width; j++)
{
if (i == 0 && j == 0)
continue;
if (texture(gID, texCoord + vec2(i, j) * size).rg != selectedID.rg)
color.rgb = vec3(1.0);
}
}
} }

View File

@ -1,38 +0,0 @@
#version 420 core
layout(std140, binding = 1) uniform Material
{
vec3 ka;
vec3 kd;
vec3 ks;
float p;
bool normalmapped;
bool parallaxmapped;
bool displacementmapped;
};
layout (location = 1) out vec3 gNormal;
layout (location = 3) out vec4 gAmbientSpecular;
layout (location = 4) out uvec3 gID;
in vec3 vertex; // Позиция вершины в пространстве
in vec3 N; // Нормаль трансформированная
in vec2 texCoord; // Текстурные координаты
in vec3 T; // Касательный вектор
in vec3 B; // Бикасательный вектор
in vec3 view; // Вектор от поверхности к камере
uniform float parallax_heightScale = 0.1;
uniform uvec3 ID = uvec3(0);
void main()
{
gNormal = vec3(0);
// Сохранение фоновой составляющей
gAmbientSpecular.rgb = ka;
// Сохранение идентификатора объекта
gID = ID;
gl_FragDepth = 0.01 * gl_FragCoord.z;
}

View File

@ -205,10 +205,6 @@ void Light::render(ShaderProgram &shaderProgram, UBO &material_buffer)
// Цикл по источникам света // Цикл по источникам света
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
// Идентификатор источника как узла сцены для всей модели лампочки
bulb.set_group_id((GLuint64) &lights[i]);
sphere.id.value = (GLuint64) &lights[i];
// Загрузим направление // Загрузим направление
glUniform3fv(direction_uniform, 1, &data[i].direction_angle.x); glUniform3fv(direction_uniform, 1, &data[i].direction_angle.x);
// Угол для лампочки = 180 (рисуем целую модель) // Угол для лампочки = 180 (рисуем целую модель)

View File

@ -1,187 +0,0 @@
#include "TRS.h"
#include <GLM/gtx/matrix_decompose.hpp>
// Инициализирует дополнительную информацию модели
void TRS::init_etc()
{
int value = 1;
for (auto it = tool.models.begin(); it != tool.models.end(); ++it)
it->id.etc = value++;
}
// Рендер инструмента нужного типа для выбранного объекта
void TRS::render(GLuint64 selectedID, ShaderProgram &shaderProgram, UBO &material_buffer)
{
// Если есть выбранная модель - рендерим инструмент для неё
if (selectedID)
{
// Указатель на объект
Node* selectedObject = (Node*) selectedID;
// Смещение выбранного объекта в глобальных координатах из его матрицы трансформации (включая родительские)
tool.root.e_position() = glm::vec3(selectedObject->getTransformMatrix()[3]);
// Замена идентификатора инструмента идентификатором выбранного объекта
tool.set_group_id(selectedID); // без замены доп. информации
// Рендер инструмента
tool.render(shaderProgram, material_buffer);
}
}
Transform::Transform()
{
tool = loadOBJtoScene("../resources/models/tools/transform.obj", "../resources/models/tools/", "../resources/textures/");
// Масштабирование
tool.root.e_scale() = glm::vec3(0.3);
// Инициализация дополнительной информации
init_etc();
}
// Взаимодействие с инструментом
void Transform::process(GLuint64 selectedID, GLuint etc, const glm::vec4& dpos)
{
// Если взаимодействие с осями инструмента
if (etc > 0)
// Если есть выбранная модель - рендерим инструмент для неё
if (selectedID)
{
// Указатель на объект
Node* selectedObject = (Node*) selectedID;
glm::vec3 dVec(0.0f, 0.0f, 0.0f);
// Сдвиг с учетом чувствительности для соответствующих осей
if (etc & 01)
dVec.x = dpos.x * T_SENSITIVITY;
if (etc & 02)
dVec.y = dpos.y * T_SENSITIVITY;
if (etc & 04)
dVec.z = dpos.z * T_SENSITIVITY;
// Если есть родитель - требуется учесть его поворот
Node* parent = selectedObject->getParent();
if (parent)
{
// Извлекаем 3x3 подматрицу, отвечающую за вращение и масштаб
glm::mat3 rotationMatrix = glm::mat3(parent->getTransformMatrix());
// Нормализуем столбцы подматрицы, чтобы исключить масштабирование
for (int i = 0; i < 3; i++)
rotationMatrix[i] = glm::normalize(rotationMatrix[i]);
// Применим поворот родителя к вектору сдвига
dVec = glm::inverse(rotationMatrix) * dVec;
}
// Добавим сдвиг от инструмента к позиции выбранного объекта
selectedObject->e_position() += dVec;
}
}
Rotate::Rotate()
{
tool = loadOBJtoScene("../resources/models/tools/rotate.obj", "../resources/models/tools/", "../resources/textures/");
// Масштабирование
tool.root.e_scale() = glm::vec3(0.3);
int value = 1;
for (auto it = tool.models.begin(); it != tool.models.end(); ++it)
{
it->id.etc = value;
value *= 2;
}
}
// Взаимодействие с инструментом
void Rotate::process(GLuint64 selectedID, GLuint etc, const glm::vec4& drot)
{
// Если взаимодействие с осями инструмента
if (etc > 0)
// Если есть выбранная модель - рендерим инструмент для неё
if (selectedID)
{
// Указатель на объект
Node* selectedObject = (Node*) selectedID;
glm::quat &selectedRot = selectedObject->e_rotation();
// Матрица родительского поворота
glm::mat3 parentRotation(1);
// Учет родительского поворота для вращения
Node* parent = selectedObject->getParent();
if (parent)
{
// Извлекаем 3x3 подматрицу, отвечающую за вращение и масштаб
parentRotation = glm::mat3(parent->getTransformMatrix());
// Нормализуем столбцы подматрицы, чтобы исключить масштабирование
for (int i = 0; i < 3; i++)
parentRotation[i] = glm::normalize(parentRotation[i]);
}
// Поворот по осям
if (etc & 01)
selectedRot = glm::angleAxis(drot.y * R_SENSITIVITY, parentRotation * glm::vec3(1.0f, 0.0f, 0.0f)) * selectedRot;
if (etc & 02)
selectedRot = glm::angleAxis(drot.x * R_SENSITIVITY, parentRotation * glm::vec3(0.0f, 1.0f, 0.0f)) * selectedRot;
if (etc & 04)
selectedRot = glm::angleAxis(drot.z * R_SENSITIVITY, parentRotation * glm::vec3(0.0f, 0.0f, 1.0f)) * selectedRot;
}
}
Scale::Scale()
{
tool = loadOBJtoScene("../resources/models/tools/scale.obj", "../resources/models/tools/", "../resources/textures/");
// Масштабирование
tool.root.e_scale() = glm::vec3(0.3);
// Инициализация дополнительной информации
init_etc();
}
// Взаимодействие с инструментом
void Scale::process(GLuint64 selectedID, GLuint etc, const glm::vec4& dscale)
{
// Если взаимодействие с осями инструмента
if (etc > 0)
// Если есть выбранная модель - рендерим инструмент для неё
if (selectedID)
{
// Указатель на объект
Node* selectedObject = (Node*) selectedID;
// Для хранения результата
glm::vec3 dVec(0);
// Масштабирование с учетом чувствительности для соответствующих осей
if (etc & 01)
dVec.x = dscale.x * S_SENSITIVITY;
if (etc & 02)
dVec.y = dscale.y * S_SENSITIVITY;
if (etc & 04)
dVec.z = dscale.z * S_SENSITIVITY;
// Если есть родитель - требуется учесть его поворот
Node* parent = selectedObject->getParent();
if (parent)
{
// Извлекаем 3x3 подматрицу, отвечающую за вращение и масштаб
glm::mat3 rotationMatrix = glm::mat3(parent->getTransformMatrix());
// Нормализуем столбцы подматрицы, чтобы исключить масштабирование
for (int i = 0; i < 3; i++)
rotationMatrix[i] = glm::normalize(rotationMatrix[i]);
// Применим поворот родителя к вектору сдвига
dVec = glm::inverse(rotationMatrix) * dVec;
}
// Прибавим вектор масштабирования к объекту
selectedObject->e_scale() += dVec;
}
}

View File

@ -9,7 +9,6 @@
#include "Scene.h" #include "Scene.h"
#include "Shader.h" #include "Shader.h"
#include "Lights.h" #include "Lights.h"
#include "TRS.h"
#define WINDOW_CAPTION "OPENGL notes on rekovalev.site" #define WINDOW_CAPTION "OPENGL notes on rekovalev.site"
@ -155,7 +154,6 @@ int main(void)
scene.root.e_position().z = 1; scene.root.e_position().z = 1;
scene.models.begin()->material.kd = {0.5,0.5,0.5}; scene.models.begin()->material.kd = {0.5,0.5,0.5};
scene.models.begin()->material.ka = {0.05,0.05,0.05}; scene.models.begin()->material.ka = {0.05,0.05,0.05};
scene.set_group_id((GLuint64) &scene);
// Установка цвета очистки буфера цвета // Установка цвета очистки буфера цвета
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
@ -211,7 +209,7 @@ int main(void)
lightShader.load(GL_FRAGMENT_SHADER, "shaders/lighting.frag"); lightShader.load(GL_FRAGMENT_SHADER, "shaders/lighting.frag");
lightShader.link(); lightShader.link();
// Привязка текстур // Привязка текстур
const char* gtextures_shader_names[] = {"gPosition", "gNormal", "gDiffuseP", "gAmbientSpecular", "sunShadowDepth", "pointShadowDepth", "ssao", "gID"}; const char* gtextures_shader_names[] = {"gPosition", "gNormal", "gDiffuseP", "gAmbientSpecular", "sunShadowDepth", "pointShadowDepth", "ssao"};
lightShader.bindTextures(gtextures_shader_names, sizeof(gtextures_shader_names)/sizeof(const char*)); lightShader.bindTextures(gtextures_shader_names, sizeof(gtextures_shader_names)/sizeof(const char*));
// Загрузка данных о границах каскадов // Загрузка данных о границах каскадов
glUniform1fv(lightShader.getUniformLoc("camera_cascade_distances"), CAMERA_CASCADE_COUNT, &camera_cascade_distances[1]); glUniform1fv(lightShader.getUniformLoc("camera_cascade_distances"), CAMERA_CASCADE_COUNT, &camera_cascade_distances[1]);
@ -435,19 +433,6 @@ int main(void)
ID selected; // Выбранная модель ID selected; // Выбранная модель
// Шейдер для инструментов
ShaderProgram toolsShader;
// Загрузим шейдеры
toolsShader.load(GL_VERTEX_SHADER, "shaders/gshader.vert");
toolsShader.load(GL_FRAGMENT_SHADER, "shaders/tools.frag");
toolsShader.link();
// Инструменты
Transform transform;
Rotate rotate;
Scale scale;
TRS& currentTool = transform;
// Пока не произойдет событие запроса закрытия окна // Пока не произойдет событие запроса закрытия окна
while(!glfwWindowShouldClose(window)) while(!glfwWindowShouldClose(window))
{ {
@ -469,15 +454,6 @@ int main(void)
scene.render(gShader, material_data); scene.render(gShader, material_data);
rectangle.render(gShader, material_data); rectangle.render(gShader, material_data);
// Отрисовка отладочных лампочек со специальным шейдером
bulbShader.use();
Light::render(bulbShader, material_data);
// Используем шейдер для инструментов
toolsShader.use();
// Рендерим инструменты для выбранного объекта
currentTool.render(selected.value, toolsShader, material_data);
// Выбор объекта // Выбор объекта
if (mouse.left == 0100000) if (mouse.left == 0100000)
{ {
@ -553,9 +529,6 @@ int main(void)
gNormal.use(); gNormal.use();
gDiffuseP.use(); gDiffuseP.use();
gAmbientSpecular.use(); gAmbientSpecular.use();
gID.use();
// Идентификатор выбранного объекта для обводки
glUniform3uiv(lightShader.getUniformLoc("selectedID"), 1, (GLuint*) &selected);
// Подключаем текстуры теней // Подключаем текстуры теней
sunShadowDepth.use(); sunShadowDepth.use();
pointShadowDepth.use(); pointShadowDepth.use();
@ -582,6 +555,10 @@ int main(void)
// Возвращаем запись глубины // Возвращаем запись глубины
glDepthMask(GL_TRUE); glDepthMask(GL_TRUE);
// Отрисовка отладочных лампочек со специальным шейдером
bulbShader.use();
Light::render(bulbShader, material_data);
// Дополнительная обработка мыши // Дополнительная обработка мыши
process_mouse_button(mouse.left); process_mouse_button(mouse.left);
process_mouse_button(mouse.right); process_mouse_button(mouse.right);
@ -598,11 +575,6 @@ int main(void)
&& mouse.x != mouse.prev_x && mouse.x != mouse.prev_x
&& mouse.y != mouse.prev_y) && mouse.y != mouse.prev_y)
Camera::current().rotate(glm::vec2(mouse.x - mouse.prev_x, mouse.prev_y - mouse.y)); Camera::current().rotate(glm::vec2(mouse.x - mouse.prev_x, mouse.prev_y - mouse.y));
// Взаимодействие с инструментом при зажатой левой кнопке
if (mouse.left > 0100000)
if (selected.etc)
currentTool.process(selected.value, selected.etc, glm::transpose(Camera::current().getVP()) * glm::vec4(mouse.x - mouse.prev_x, mouse.prev_y - mouse.y, 0, 1));
} }
return 0; return 0;