Compare commits
7 Commits
Author | SHA1 | Date |
---|---|---|
Ковалев Роман Евгеньевич | 698ad941f5 | |
Ковалев Роман Евгеньевич | ebbfe32c1f | |
Ковалев Роман Евгеньевич | a272461d85 | |
Ковалев Роман Евгеньевич | 1d2a659c46 | |
Ковалев Роман Евгеньевич | 15795389da | |
Ковалев Роман Евгеньевич | ac9e887ab8 | |
Ковалев Роман Евгеньевич | e4b280d9eb |
|
@ -11,7 +11,7 @@
|
||||||
// Ближняя граница области отсечения
|
// Ближняя граница области отсечения
|
||||||
#define CAMERA_NEAR 0.1f
|
#define CAMERA_NEAR 0.1f
|
||||||
// Дальняя граница области отсечения
|
// Дальняя граница области отсечения
|
||||||
#define CAMERA_FAR 15.0f
|
#define CAMERA_FAR 100.0f
|
||||||
// Вектор, задающий верх для камеры
|
// Вектор, задающий верх для камеры
|
||||||
#define CAMERA_UP_VECTOR glm::vec3(0.0f, 1.0f, 0.0f)
|
#define CAMERA_UP_VECTOR glm::vec3(0.0f, 1.0f, 0.0f)
|
||||||
// Вектор, задающий стандартный поворот углами Эйлера (в положительном направлении оси Z)
|
// Вектор, задающий стандартный поворот углами Эйлера (в положительном направлении оси Z)
|
||||||
|
@ -20,6 +20,11 @@
|
||||||
#define CAMERA_FOVy 60.0f
|
#define CAMERA_FOVy 60.0f
|
||||||
// Стандартная чувствительность
|
// Стандартная чувствительность
|
||||||
#define CAMERA_DEFAULT_SENSIVITY 0.005f
|
#define CAMERA_DEFAULT_SENSIVITY 0.005f
|
||||||
|
// Количество каскадов для карт теней
|
||||||
|
#define CAMERA_CASCADE_COUNT 4
|
||||||
|
|
||||||
|
// Данные о дистанциях каскадов
|
||||||
|
extern const float camera_cascade_distances[]; // src/Camera.cpp
|
||||||
|
|
||||||
// Данные о камере для шейдера
|
// Данные о камере для шейдера
|
||||||
struct CameraData
|
struct CameraData
|
||||||
|
@ -54,7 +59,7 @@ class Camera : public Node
|
||||||
static Camera& current(); // Ссылка на текущую используемую камеру
|
static Camera& current(); // Ссылка на текущую используемую камеру
|
||||||
|
|
||||||
CameraData& getData(); // Данные о камере для шейдера
|
CameraData& getData(); // Данные о камере для шейдера
|
||||||
std::pair<bool, const glm::vec4*> getProjCoords(); // Доступ к координатам с флагом изменения, описывающим пространство вида с пересчетом, если это требуется
|
std::pair<bool, const glm::vec4(*)[8]> getProjCoords(); // Доступ к координатам с флагом изменения, описывающим пространство вида с пересчетом, если это требуется
|
||||||
protected:
|
protected:
|
||||||
Camera(const glm::vec3 &position, const glm::vec3 &initialRotation); // Защищенный (protected) конструктор камеры без перспективы
|
Camera(const glm::vec3 &position, const glm::vec3 &initialRotation); // Защищенный (protected) конструктор камеры без перспективы
|
||||||
|
|
||||||
|
@ -63,7 +68,8 @@ class Camera : public Node
|
||||||
glm::mat4 vp; // Матрица произведения вида и проекции
|
glm::mat4 vp; // Матрица произведения вида и проекции
|
||||||
bool requiredRecalcVP; // Необходимость пересчета матрицы вида и проекции камеры
|
bool requiredRecalcVP; // Необходимость пересчета матрицы вида и проекции камеры
|
||||||
bool requiredRecalcCoords; // Необходимость пересчета точек, описывающих пространство камеры
|
bool requiredRecalcCoords; // Необходимость пересчета точек, описывающих пространство камеры
|
||||||
glm::vec4 coords[8]; // Координаты, описывающие пространство камеры
|
glm::vec4 coords[CAMERA_CASCADE_COUNT][8]; // Координаты, описывающие пространство камеры
|
||||||
|
glm::mat4 cascade_proj[CAMERA_CASCADE_COUNT]; // Матрицы проекций каскадов
|
||||||
|
|
||||||
float sensitivity; // Чувствительность мыши
|
float sensitivity; // Чувствительность мыши
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <GLM/glm.hpp>
|
#include <GLM/glm.hpp>
|
||||||
|
|
||||||
#include "Model.h"
|
#include "Model.h"
|
||||||
|
#include "Camera.h"
|
||||||
|
|
||||||
// Максимальное число источников света
|
// Максимальное число источников света
|
||||||
#define MAX_LIGHTS 300
|
#define MAX_LIGHTS 300
|
||||||
|
@ -81,7 +82,7 @@ class Sun
|
||||||
|
|
||||||
alignas(16) glm::vec3 direction; // Направление лучей источника
|
alignas(16) glm::vec3 direction; // Направление лучей источника
|
||||||
alignas(16) glm::vec3 color; // Цвет
|
alignas(16) glm::vec3 color; // Цвет
|
||||||
alignas(16) glm::mat4 vp; // Матрица вида-проекции источника
|
alignas(16) glm::mat4 vp[CAMERA_CASCADE_COUNT]; // Матрица вида-проекции источника
|
||||||
|
|
||||||
void recalcVP(); // Пересчитывает по необходимости матрицу вида-проекции
|
void recalcVP(); // Пересчитывает по необходимости матрицу вида-проекции
|
||||||
|
|
||||||
|
|
|
@ -44,4 +44,18 @@ class Texture : public BaseTexture
|
||||||
virtual void use(); // Привязка текстуры
|
virtual void use(); // Привязка текстуры
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Класс 3D текстуры
|
||||||
|
class TextureArray : public BaseTexture
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TextureArray(GLuint levels, GLuint width, GLuint height, GLuint attachment, GLuint texType = TEX_DIFFUSE, GLint internalformat = GL_RGBA, GLint format = GL_RGBA, GLenum dataType = GL_FLOAT); // Конструктор текстуры заданного размера для использования в буфере
|
||||||
|
TextureArray(const TextureArray& other); // Конструктор копирования
|
||||||
|
|
||||||
|
TextureArray& operator=(const TextureArray& other); // Оператор присваивания
|
||||||
|
|
||||||
|
void reallocate(GLuint levels, GLuint width, GLuint height, GLuint texType = TEX_DIFFUSE, GLint internalformat = GL_RGBA, GLint format = GL_RGBA, GLenum dataType = GL_FLOAT); // Пересоздает текстуру для имеющегося дескриптора
|
||||||
|
|
||||||
|
virtual void use(); // Привязка текстуры
|
||||||
|
};
|
||||||
|
|
||||||
#endif // TEXTURE_H
|
#endif // TEXTURE_H
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -27,14 +27,16 @@ layout(std140, binding = 3) uniform Sun
|
||||||
{
|
{
|
||||||
vec3 direction;
|
vec3 direction;
|
||||||
vec3 color;
|
vec3 color;
|
||||||
mat4 vp;
|
mat4 vp[4];
|
||||||
} sun;
|
} sun;
|
||||||
|
|
||||||
|
uniform float camera_cascade_distances[4]; // Размер массива должен соответствовать количеству каскадов
|
||||||
|
|
||||||
uniform sampler2D gPosition;
|
uniform sampler2D gPosition;
|
||||||
uniform sampler2D gNormal;
|
uniform sampler2D gNormal;
|
||||||
uniform sampler2D gDiffuseP;
|
uniform sampler2D gDiffuseP;
|
||||||
uniform sampler2D gAmbientSpecular;
|
uniform sampler2D gAmbientSpecular;
|
||||||
uniform sampler2D sunShadowDepth;
|
uniform sampler2DArray sunShadowDepth;
|
||||||
|
|
||||||
out vec4 color;
|
out vec4 color;
|
||||||
|
|
||||||
|
@ -60,10 +62,18 @@ void main()
|
||||||
float intensity; // Интенсивность для прожектора
|
float intensity; // Интенсивность для прожектора
|
||||||
vec3 fragPosLightSpace; // Фрагмент в пространстве источника
|
vec3 fragPosLightSpace; // Фрагмент в пространстве источника
|
||||||
float shadowValue; // Значение затененности
|
float shadowValue; // Значение затененности
|
||||||
vec2 texelSize = 1.0 / textureSize(sunShadowDepth, 0); // Размер текселя текстуры теней
|
vec2 texelSize = 1.0 / textureSize(sunShadowDepth, 0).xy; // Размер текселя текстуры теней
|
||||||
int x, y; // Счетчик для PCF
|
int x, y; // Счетчик для PCF
|
||||||
float pcfDepth; // Глубина PCF
|
float pcfDepth; // Глубина PCF
|
||||||
|
|
||||||
|
vec4 fragPosCamSpace = camera.view * vec4(fragPos, 1); // Фрагмент в пространстве камеры
|
||||||
|
int cascade_index; // Индекс текущего каскада для вычисления теней
|
||||||
|
|
||||||
|
// Определение индекса каскада в который попадает фрагмент (цикл на 1 меньше чем кол-во каскадов)
|
||||||
|
for (cascade_index = 0; cascade_index < 3; cascade_index++)
|
||||||
|
if (abs(fragPosCamSpace.z) < camera_cascade_distances[cascade_index])
|
||||||
|
break;
|
||||||
|
|
||||||
// Фоновая освещенность
|
// Фоновая освещенность
|
||||||
color = vec4(ka, 1);
|
color = vec4(ka, 1);
|
||||||
|
|
||||||
|
@ -71,7 +81,7 @@ void main()
|
||||||
if (length(sun.color) > 0)
|
if (length(sun.color) > 0)
|
||||||
{
|
{
|
||||||
// Расположение фрагмента в координатах теневой карты
|
// Расположение фрагмента в координатах теневой карты
|
||||||
fragPosLightSpace = (sun.vp * vec4(fragPos, 1.0)).xyz;
|
fragPosLightSpace = (sun.vp[cascade_index] * vec4(fragPos, 1.0)).xyz;
|
||||||
// Переход от [-1;1] к [0;1]
|
// Переход от [-1;1] к [0;1]
|
||||||
fragPosLightSpace = (fragPosLightSpace + vec3(1.0)) / 2;
|
fragPosLightSpace = (fragPosLightSpace + vec3(1.0)) / 2;
|
||||||
// Сдвиг для решения проблемы акне
|
// Сдвиг для решения проблемы акне
|
||||||
|
@ -82,7 +92,7 @@ void main()
|
||||||
{
|
{
|
||||||
for(y = -1; y <= 1; ++y)
|
for(y = -1; y <= 1; ++y)
|
||||||
{
|
{
|
||||||
pcfDepth = texture(sunShadowDepth, fragPosLightSpace.xy + vec2(x, y) * texelSize).r;
|
pcfDepth = texture(sunShadowDepth, vec3(fragPosLightSpace.xy + vec2(x, y) * texelSize, cascade_index)).r;
|
||||||
shadowValue += fragPosLightSpace.z > pcfDepth ? 1.0 : 0.0;
|
shadowValue += fragPosLightSpace.z > pcfDepth ? 1.0 : 0.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
#version 420 core
|
||||||
|
|
||||||
|
layout(triangles, invocations = 4) in; // здесь invocations должно соответствовать количеству каскадов
|
||||||
|
layout(triangle_strip, max_vertices = 3) out;
|
||||||
|
|
||||||
|
layout(std140, binding = 3) uniform Sun
|
||||||
|
{
|
||||||
|
vec3 direction;
|
||||||
|
vec3 color;
|
||||||
|
mat4 vp[4];
|
||||||
|
} sun;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
|
gl_Position = sun.vp[gl_InvocationID] * gl_in[i].gl_Position;
|
||||||
|
gl_Layer = gl_InvocationID;
|
||||||
|
EmitVertex();
|
||||||
|
}
|
||||||
|
EndPrimitive();
|
||||||
|
}
|
|
@ -4,14 +4,7 @@ layout (location = 0) in vec3 pos;
|
||||||
|
|
||||||
uniform mat4 model;
|
uniform mat4 model;
|
||||||
|
|
||||||
layout(std140, binding = 3) uniform Sun
|
|
||||||
{
|
|
||||||
vec3 direction;
|
|
||||||
vec3 color;
|
|
||||||
mat4 vp;
|
|
||||||
} sun;
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = sun.vp * model * vec4(pos, 1.0);
|
gl_Position = model * vec4(pos, 1.0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
// Указатель на текущую используемую камеру
|
// Указатель на текущую используемую камеру
|
||||||
Camera* Camera::p_current = NULL;
|
Camera* Camera::p_current = NULL;
|
||||||
|
|
||||||
|
// Границы каскадов
|
||||||
|
const float camera_cascade_distances[] = {CAMERA_NEAR, CAMERA_FAR / 50.0f, CAMERA_FAR / 10.0f, CAMERA_FAR / 3.0f, CAMERA_FAR};
|
||||||
|
|
||||||
// Защищенный (protected) конструктор камеры без перспективы
|
// Защищенный (protected) конструктор камеры без перспективы
|
||||||
Camera::Camera(const glm::vec3 &pos, const glm::vec3 &initialRotation) : Node(NULL) // Пусть по умолчанию камера не относится к сцене
|
Camera::Camera(const glm::vec3 &pos, const glm::vec3 &initialRotation) : Node(NULL) // Пусть по умолчанию камера не относится к сцене
|
||||||
{
|
{
|
||||||
|
@ -33,7 +36,8 @@ Camera::Camera(float width, float height, const glm::vec3 &position, const glm::
|
||||||
|
|
||||||
// Конструктор копирования камеры
|
// Конструктор копирования камеры
|
||||||
Camera::Camera(const Camera& copy)
|
Camera::Camera(const Camera& copy)
|
||||||
: Node(copy), projection(copy.projection), requiredRecalcVP(copy.requiredRecalcVP), sensitivity(copy.sensitivity)
|
: Node(copy), projection(copy.projection), requiredRecalcVP(copy.requiredRecalcVP), sensitivity(copy.sensitivity),
|
||||||
|
requiredRecalcCoords(true)
|
||||||
{
|
{
|
||||||
// Если у оригинала не было изменений - перепишем матрицу вида-проекции
|
// Если у оригинала не было изменений - перепишем матрицу вида-проекции
|
||||||
if (!requiredRecalcVP)
|
if (!requiredRecalcVP)
|
||||||
|
@ -90,6 +94,8 @@ void Camera::setPerspective(float fovy, float aspect)
|
||||||
{
|
{
|
||||||
projection = glm::perspective(glm::radians(fovy), aspect, CAMERA_NEAR, CAMERA_FAR);
|
projection = glm::perspective(glm::radians(fovy), aspect, CAMERA_NEAR, CAMERA_FAR);
|
||||||
requiredRecalcVP = true;
|
requiredRecalcVP = true;
|
||||||
|
for (int cascade = 0; cascade < CAMERA_CASCADE_COUNT; cascade++)
|
||||||
|
cascade_proj[cascade] = glm::perspective(glm::radians(fovy), aspect, camera_cascade_distances[cascade], camera_cascade_distances[cascade+1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Устанавливает заданную ортографическую матрицу
|
// Устанавливает заданную ортографическую матрицу
|
||||||
|
@ -98,6 +104,9 @@ void Camera::setOrtho(float width, float height)
|
||||||
const float aspect = width / height;
|
const float aspect = width / height;
|
||||||
projection = glm::ortho(-1.0f, 1.0f, -1.0f/aspect, 1.0f/aspect, CAMERA_NEAR, CAMERA_FAR);
|
projection = glm::ortho(-1.0f, 1.0f, -1.0f/aspect, 1.0f/aspect, CAMERA_NEAR, CAMERA_FAR);
|
||||||
requiredRecalcVP = true;
|
requiredRecalcVP = true;
|
||||||
|
for (int cascade = 0; cascade < CAMERA_CASCADE_COUNT; cascade++)
|
||||||
|
cascade_proj[cascade] = glm::ortho(-1.0f, 1.0f, -1.0f/aspect, 1.0f/aspect, camera_cascade_distances[cascade], camera_cascade_distances[cascade+1]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Изменяет чувствительность мыши
|
// Изменяет чувствительность мыши
|
||||||
|
@ -192,7 +201,7 @@ CameraData& Camera::getData()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Доступ к координатам с флагом изменения, описывающим пространство вида с пересчетом, если это требуется
|
// Доступ к координатам с флагом изменения, описывающим пространство вида с пересчетом, если это требуется
|
||||||
std::pair<bool, const glm::vec4*> Camera::getProjCoords()
|
std::pair<bool, const glm::vec4(*)[8]> Camera::getProjCoords()
|
||||||
{
|
{
|
||||||
const glm::mat4& cam_vp = getVP(); // Получение ссылки на матрицу вида-проекции с пересчетом, если требуется и активацией флага requiredRecalcCoords
|
const glm::mat4& cam_vp = getVP(); // Получение ссылки на матрицу вида-проекции с пересчетом, если требуется и активацией флага requiredRecalcCoords
|
||||||
bool changes = false; // Возвращаемое значение
|
bool changes = false; // Возвращаемое значение
|
||||||
|
@ -210,11 +219,16 @@ std::pair<bool, const glm::vec4*> Camera::getProjCoords()
|
||||||
, {-1, 1,-1,1}
|
, {-1, 1,-1,1}
|
||||||
, {-1,-1, 1,1}
|
, {-1,-1, 1,1}
|
||||||
, {-1,-1,-1,1}};
|
, {-1,-1,-1,1}};
|
||||||
// Цикл по типовым точкам
|
|
||||||
for (int i = 0; i < 8; i++)
|
for (int cascade = 0; cascade < CAMERA_CASCADE_COUNT; cascade++)
|
||||||
{
|
{
|
||||||
coords[i] = inv * typical_points[i];
|
glm::mat4 inv = glm::inverse(cascade_proj[cascade] * getView());
|
||||||
coords[i] /= coords[i].w; // Переход от гомогенных координат к обычным
|
// Цикл по типовым точкам
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
coords[cascade][i] = inv * typical_points[i];
|
||||||
|
coords[cascade][i] /= coords[cascade][i].w;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
requiredRecalcCoords = false; // Сбрасываем флаг
|
requiredRecalcCoords = false; // Сбрасываем флаг
|
||||||
|
|
|
@ -305,38 +305,44 @@ glm::vec3& Sun::e_color()
|
||||||
// Пересчитывает по необходимости матрицу вида-проекции
|
// Пересчитывает по необходимости матрицу вида-проекции
|
||||||
void Sun::recalcVP()
|
void Sun::recalcVP()
|
||||||
{
|
{
|
||||||
std::pair <bool, const glm::vec4*> camProjCoords = Camera::current().getProjCoords();
|
// Точки по краям проекции камеры
|
||||||
|
std::pair <bool, const glm::vec4(*)[8]> camProjCoords = Camera::current().getProjCoords();
|
||||||
|
|
||||||
// Есть изменения по источнику или камере
|
// Есть изменения по источнику или камере
|
||||||
if (uploadReq || camProjCoords.first)
|
if (uploadReq || camProjCoords.first)
|
||||||
{
|
{
|
||||||
uploadReq = true; // Требуется загрузка в следствии пересчета матрицы
|
uploadReq = true; // Требуется загрузка в следствии пересчета матрицы
|
||||||
|
|
||||||
glm::vec3 mean = glm::vec3(0); // Среднее арифметическое
|
glm::vec3 mean; // Среднее арифметическое
|
||||||
glm::vec4 max, min; // макс и мин координаты
|
glm::vec4 max, min; // макс и мин координаты
|
||||||
glm::vec4 point; // Точка приведенная в пространство источника света
|
glm::vec4 point; // Точка приведенная в пространство источника света
|
||||||
|
|
||||||
// Найдем среднее арифметическое от точек для нахождения центра прямоугольника
|
|
||||||
for (int i = 0; i < 8; i++)
|
for (int cascade = 0; cascade < CAMERA_CASCADE_COUNT; cascade++)
|
||||||
mean += glm::vec3(camProjCoords.second[i]);
|
|
||||||
mean /= 8;
|
|
||||||
// Используем среднее арифметическое для получения матрицы вида параллельного источника
|
|
||||||
glm::mat4 lightView = glm::lookAt(mean + glm::normalize(direction), mean, CAMERA_UP_VECTOR);
|
|
||||||
|
|
||||||
// Примем первую точку как минимальную и максимальную (приведя в пространство вида источника)
|
|
||||||
min = max = lightView * camProjCoords.second[0];
|
|
||||||
// Для оставшихся точек
|
|
||||||
for (int i = 1; i < 8; i++)
|
|
||||||
{
|
{
|
||||||
// Приведем в пространство вида источника
|
mean = glm::vec3(0);
|
||||||
point = lightView * camProjCoords.second[i];
|
// Найдем среднее арифметическое от точек для нахождения центра прямоугольника
|
||||||
max = glm::max(max, point);
|
for (int i = 0; i < 8; i++)
|
||||||
min = glm::min(min, point);
|
mean += glm::vec3(camProjCoords.second[cascade][i]);
|
||||||
}
|
mean /= 8;
|
||||||
|
// Используем среднее арифметическое для получения матрицы вида параллельного источника
|
||||||
|
glm::mat4 lightView = glm::lookAt(mean + glm::normalize(direction), mean, CAMERA_UP_VECTOR);
|
||||||
|
|
||||||
|
// Примем первую точку как минимальную и максимальную (приведя в пространство вида источника)
|
||||||
|
min = max = lightView * camProjCoords.second[cascade][0];
|
||||||
|
// Для оставшихся точек
|
||||||
|
for (int i = 1; i < 8; i++)
|
||||||
|
{
|
||||||
|
// Приведем в пространство вида источника
|
||||||
|
point = lightView * camProjCoords.second[cascade][i];
|
||||||
|
max = glm::max(max, point);
|
||||||
|
min = glm::min(min, point);
|
||||||
|
}
|
||||||
|
|
||||||
// Максимальное значение глубины
|
// Максимальное значение глубины
|
||||||
max.z = std::max(fabs(max.z), fabs(min.z));
|
max.z = std::max(fabs(max.z), fabs(min.z));
|
||||||
// На основании максимальных и минимальных координат создадим матрицу проекции источника
|
// На основании максимальных и минимальных координат создадим матрицу проекции источника
|
||||||
vp = glm::ortho(min.x, max.x, min.y, max.y, min.z, max.z) * lightView;
|
vp[cascade] = glm::ortho(min.x, max.x, min.y, max.y, min.z, max.z) * lightView;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,3 +151,62 @@ void BaseTexture::setType(GLuint type)
|
||||||
{
|
{
|
||||||
this->type = type;
|
this->type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Конструктор текстуры заданного размера для использования в буфере
|
||||||
|
TextureArray::TextureArray(GLuint levels, GLuint width, GLuint height, GLuint attachment, GLuint texType, GLint internalformat, GLint format, GLenum dataType)
|
||||||
|
{
|
||||||
|
type = texType;
|
||||||
|
// Генерация текстуры заданного размера
|
||||||
|
glGenTextures(1, &handler);
|
||||||
|
glBindTexture(GL_TEXTURE_2D_ARRAY, handler);
|
||||||
|
glTexImage3D(
|
||||||
|
GL_TEXTURE_2D_ARRAY, 0, internalformat, width, height, levels, 0, format, dataType, 0);
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
|
||||||
|
// Привязка к буферу кадра
|
||||||
|
glFramebufferTexture(GL_FRAMEBUFFER, attachment, handler, 0);
|
||||||
|
|
||||||
|
// Создаем счетчик использований дескриптора
|
||||||
|
handler_count[handler] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Конструктор копирования
|
||||||
|
TextureArray::TextureArray(const TextureArray& other)
|
||||||
|
{
|
||||||
|
handler = other.handler;
|
||||||
|
type = other.type;
|
||||||
|
// Делаем копию и увеличиваем счетчик
|
||||||
|
handler_count[handler]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Оператор присваивания
|
||||||
|
TextureArray& TextureArray::operator=(const TextureArray& other)
|
||||||
|
{
|
||||||
|
// Если это разные текстуры
|
||||||
|
if (handler != other.handler)
|
||||||
|
{
|
||||||
|
this->~TextureArray(); // Уничтожаем имеющуюся
|
||||||
|
// Заменяем новой
|
||||||
|
handler = other.handler;
|
||||||
|
handler_count[handler]++;
|
||||||
|
}
|
||||||
|
type = other.type;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Пересоздает текстуру для имеющегося дескриптора
|
||||||
|
void TextureArray::reallocate(GLuint levels, 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 TextureArray::use()
|
||||||
|
{
|
||||||
|
glActiveTexture(type + GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D_ARRAY, handler); // Привязка текстуры как активной
|
||||||
|
}
|
||||||
|
|
12
src/main.cpp
12
src/main.cpp
|
@ -182,6 +182,8 @@ int main(void)
|
||||||
lightShader.link();
|
lightShader.link();
|
||||||
const char* gtextures_shader_names[] = {"gPosition", "gNormal", "gDiffuseP", "gAmbientSpecular", "sunShadowDepth"};
|
const char* gtextures_shader_names[] = {"gPosition", "gNormal", "gDiffuseP", "gAmbientSpecular", "sunShadowDepth"};
|
||||||
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]);
|
||||||
|
|
||||||
glm::vec3 quadVertices[] = { {-1.0f, 1.0f, 0.0f}
|
glm::vec3 quadVertices[] = { {-1.0f, 1.0f, 0.0f}
|
||||||
, {-1.0f, -1.0f, 0.0f}
|
, {-1.0f, -1.0f, 0.0f}
|
||||||
|
@ -200,12 +202,12 @@ int main(void)
|
||||||
// Создадим буфер кадра для рендера теней
|
// Создадим буфер кадра для рендера теней
|
||||||
FBO sunShadowBuffer;
|
FBO sunShadowBuffer;
|
||||||
// Создадим текстуры для буфера кадра
|
// Создадим текстуры для буфера кадра
|
||||||
Texture sunShadowDepth(sunShadow_resolution, sunShadow_resolution, GL_DEPTH_ATTACHMENT, 4, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT);
|
TextureArray sunShadowDepth(CAMERA_CASCADE_COUNT, sunShadow_resolution, sunShadow_resolution, GL_DEPTH_ATTACHMENT, 4, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT);
|
||||||
// Правка фантомных теней
|
// Правка фантомных теней
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||||
float shadowBorderColor[] = { 1.0, 1.0, 1.0, 1.0 };
|
float shadowBorderColor[] = { 1.0, 1.0, 1.0, 1.0 };
|
||||||
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, shadowBorderColor);
|
glTexParameterfv(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BORDER_COLOR, shadowBorderColor);
|
||||||
// Отключим работу с цветом
|
// Отключим работу с цветом
|
||||||
glDrawBuffer(GL_NONE);
|
glDrawBuffer(GL_NONE);
|
||||||
glReadBuffer(GL_NONE);
|
glReadBuffer(GL_NONE);
|
||||||
|
@ -216,6 +218,8 @@ int main(void)
|
||||||
ShaderProgram sunShadowShader;
|
ShaderProgram sunShadowShader;
|
||||||
// Загрузим шейдер
|
// Загрузим шейдер
|
||||||
sunShadowShader.load(GL_VERTEX_SHADER, "shaders/sun_shadow.vert");
|
sunShadowShader.load(GL_VERTEX_SHADER, "shaders/sun_shadow.vert");
|
||||||
|
sunShadowShader.load(GL_GEOMETRY_SHADER, "shaders/sun_shadow.geom");
|
||||||
|
sunShadowShader.load(GL_FRAGMENT_SHADER, "shaders/empty.frag");
|
||||||
sunShadowShader.link();
|
sunShadowShader.link();
|
||||||
|
|
||||||
// Модель прямоугольника
|
// Модель прямоугольника
|
||||||
|
|
Loading…
Reference in New Issue