diff options
Diffstat (limited to 'src/graphics')
-rw-r--r-- | src/graphics/Camera3D.cpp | 79 | ||||
-rw-r--r-- | src/graphics/Camera3D.hpp | 66 | ||||
-rw-r--r-- | src/graphics/Frustrum.cpp | 111 | ||||
-rw-r--r-- | src/graphics/Frustrum.hpp | 24 | ||||
-rw-r--r-- | src/graphics/Shader.cpp | 175 | ||||
-rw-r--r-- | src/graphics/Shader.hpp | 2 |
6 files changed, 101 insertions, 356 deletions
diff --git a/src/graphics/Camera3D.cpp b/src/graphics/Camera3D.cpp deleted file mode 100644 index eb740e4..0000000 --- a/src/graphics/Camera3D.cpp +++ /dev/null @@ -1,79 +0,0 @@ -#include "Camera3D.hpp" - -Camera3D::Camera3D(glm::vec3 position, glm::vec3 up, GLfloat yaw, GLfloat pitch) : Front(glm::vec3(0.0f, 0.0f, -1.0f)), - MovementSpeed(SPEED), - MouseSensitivity(SENSITIVTY), - Zoom(ZOOM) { - this->Position = position; - this->WorldUp = up; - this->Yaw = yaw; - this->Pitch = pitch; - this->updateCameraVectors(); -} - -Camera3D::Camera3D(GLfloat posX, GLfloat posY, GLfloat posZ, GLfloat upX, GLfloat upY, GLfloat upZ, GLfloat yaw, - GLfloat pitch) : Front(glm::vec3(0.0f, 0.0f, -1.0f)), MovementSpeed(SPEED), MouseSensitivity(SENSITIVTY), - Zoom(ZOOM) { - this->Position = glm::vec3(posX, posY, posZ); - this->WorldUp = glm::vec3(upX, upY, upZ); - this->Yaw = yaw; - this->Pitch = pitch; - this->updateCameraVectors(); -} - -glm::mat4 Camera3D::GetViewMatrix() { - return glm::lookAt(this->Position, this->Position + this->Front, this->Up); -} - -void Camera3D::ProcessKeyboard(Camera_Movement direction, GLfloat deltaTime) { - GLfloat velocity = this->MovementSpeed * deltaTime; - if (direction == FORWARD) - this->Position += this->Front * velocity; - if (direction == BACKWARD) - this->Position -= this->Front * velocity; - if (direction == LEFT) - this->Position -= this->Right * velocity; - if (direction == RIGHT) - this->Position += this->Right * velocity; -} - -void Camera3D::ProcessMouseMovement(GLfloat xoffset, GLfloat yoffset, GLboolean constrainPitch) { - xoffset *= this->MouseSensitivity; - yoffset *= this->MouseSensitivity; - - this->Yaw += xoffset; - this->Pitch += yoffset; - - // Make sure that when pitch is out of bounds, screen doesn't get flipped - if (constrainPitch) { - if (this->Pitch > 89.0f) - this->Pitch = 89.0f; - if (this->Pitch < -89.0f) - this->Pitch = -89.0f; - } - - // Update Front, Right and Up Vectors using the updated Eular angles - this->updateCameraVectors(); -} - -void Camera3D::ProcessMouseScroll(GLfloat yoffset) { - if (this->Zoom >= 1.0f && this->Zoom <= 45.0f) - this->Zoom -= yoffset/5.0f; - if (this->Zoom <= 1.0f) - this->Zoom = 1.0f; - if (this->Zoom >= 45.0f) - this->Zoom = 45.0f; -} - -void Camera3D::updateCameraVectors() { - // Calculate the new Front vector - glm::vec3 front; - front.x = cos(glm::radians(this->Yaw)) * cos(glm::radians(this->Pitch)); - front.y = sin(glm::radians(this->Pitch)); - front.z = sin(glm::radians(this->Yaw)) * cos(glm::radians(this->Pitch)); - this->Front = glm::normalize(front); - // Also re-calculate the Right and Up vector - this->Right = glm::normalize(glm::cross(this->Front, - this->WorldUp)); // Normalize the vectors, because their length gets closer to 0 the more you look up or down which results in slower movement. - this->Up = glm::normalize(glm::cross(this->Right, this->Front)); -} diff --git a/src/graphics/Camera3D.hpp b/src/graphics/Camera3D.hpp deleted file mode 100644 index eac1f47..0000000 --- a/src/graphics/Camera3D.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#pragma once - -// Std. Includes -#include <vector> - -// GL Includes -#include <GL/glew.h> -#include <glm/glm.hpp> -#include <glm/gtc/matrix_transform.hpp> - - -// Defines several possible options for camera movement. Used as abstraction to stay away from window-system specific input methods -enum Camera_Movement { - FORWARD, - BACKWARD, - LEFT, - RIGHT -}; - -// Default camera values -const GLfloat YAW = -90.0f; -const GLfloat PITCH = 0.0f; -const GLfloat SPEED = 30.0f; -const GLfloat SENSITIVTY = 0.2f; -const GLfloat ZOOM = 45.0f; - -// An abstract camera class that processes input and calculates the corresponding Eular Angles, Vectors and Matrices for use in OpenGL -class Camera3D { -public: - // Camera3D Attributes - glm::vec3 Position; - glm::vec3 Front; - glm::vec3 Up; - glm::vec3 Right; - glm::vec3 WorldUp; - // Eular Angles - GLfloat Yaw; - GLfloat Pitch; - // Camera3D options - GLfloat MovementSpeed; - GLfloat MouseSensitivity; - GLfloat Zoom; - - // Constructor with vectors - explicit Camera3D(glm::vec3 position = glm::vec3(0.0f, 0.0f, 3.0f), glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f), - GLfloat yaw = YAW, GLfloat pitch = PITCH); - - // Constructor with scalar values - Camera3D(GLfloat posX, GLfloat posY, GLfloat posZ, GLfloat upX, GLfloat upY, GLfloat upZ, GLfloat yaw, GLfloat pitch); - - // Returns the view matrix calculated using Eular Angles and the LookAt Matrix - glm::mat4 GetViewMatrix(); - - // Processes input received from any keyboard-like input system. Accepts input parameter in the form of camera defined ENUM (to abstract it from windowing systems) - void ProcessKeyboard(Camera_Movement direction, GLfloat deltaTime); - - // Processes input received from a mouse input system. Expects the offset value in both the x and y direction. - void ProcessMouseMovement(GLfloat xoffset, GLfloat yoffset, GLboolean constrainPitch = true); - - // Processes input received from a mouse scroll-wheel event. Only requires input on the vertical wheel-axis - void ProcessMouseScroll(GLfloat yoffset); - -private: - // Calculates the front vector from the Camera3D's (updated) Eular Angles - void updateCameraVectors(); -};
\ No newline at end of file diff --git a/src/graphics/Frustrum.cpp b/src/graphics/Frustrum.cpp deleted file mode 100644 index 75f47c5..0000000 --- a/src/graphics/Frustrum.cpp +++ /dev/null @@ -1,111 +0,0 @@ -#include "Frustrum.hpp" - -enum FrustumSide { - RIGHT = 0, // The RIGHT side of the frustum - LEFT = 1, // The LEFT side of the frustum - BOTTOM = 2, // The BOTTOM side of the frustum - TOP = 3, // The TOP side of the frustum - BACK = 4, // The BACK side of the frustum - FRONT = 5 // The FRONT side of the frustum -}; - -enum PlaneData { - A = 0, // The X value of the plane's normal - B = 1, // The Y value of the plane's normal - C = 2, // The Z value of the plane's normal - D = 3 // The distance the plane is from the origin -}; - -void normalizePlane(glm::vec4 &frustum_plane) { - float magnitude = (float) sqrt(frustum_plane[A] * frustum_plane[A] + frustum_plane[B] * frustum_plane[B] + - frustum_plane[C] * frustum_plane[C]); - frustum_plane[A] /= magnitude; - frustum_plane[B] /= magnitude; - frustum_plane[C] /= magnitude; - frustum_plane[D] /= magnitude; -} - -void Frustum::CalculateFrustum(glm::mat4 &view_matrix, glm::mat4 &proj_matrix) { - float proj[16]; - float modl[16]; - const float *projP = glm::value_ptr(proj_matrix); - const float *modlP = glm::value_ptr(view_matrix); - for (int i = 0; i < 16; i++) { - proj[i]=projP[i]; - modl[i]=modlP[i]; - } - - float clip[16]; //clipping planes - - clip[0] = modl[0] * proj[0] + modl[1] * proj[4] + modl[2] * proj[8] + modl[3] * proj[12]; - clip[1] = modl[0] * proj[1] + modl[1] * proj[5] + modl[2] * proj[9] + modl[3] * proj[13]; - clip[2] = modl[0] * proj[2] + modl[1] * proj[6] + modl[2] * proj[10] + modl[3] * proj[14]; - clip[3] = modl[0] * proj[3] + modl[1] * proj[7] + modl[2] * proj[11] + modl[3] * proj[15]; - - clip[4] = modl[4] * proj[0] + modl[5] * proj[4] + modl[6] * proj[8] + modl[7] * proj[12]; - clip[5] = modl[4] * proj[1] + modl[5] * proj[5] + modl[6] * proj[9] + modl[7] * proj[13]; - clip[6] = modl[4] * proj[2] + modl[5] * proj[6] + modl[6] * proj[10] + modl[7] * proj[14]; - clip[7] = modl[4] * proj[3] + modl[5] * proj[7] + modl[6] * proj[11] + modl[7] * proj[15]; - - clip[8] = modl[8] * proj[0] + modl[9] * proj[4] + modl[10] * proj[8] + modl[11] * proj[12]; - clip[9] = modl[8] * proj[1] + modl[9] * proj[5] + modl[10] * proj[9] + modl[11] * proj[13]; - clip[10] = modl[8] * proj[2] + modl[9] * proj[6] + modl[10] * proj[10] + modl[11] * proj[14]; - clip[11] = modl[8] * proj[3] + modl[9] * proj[7] + modl[10] * proj[11] + modl[11] * proj[15]; - - clip[12] = modl[12] * proj[0] + modl[13] * proj[4] + modl[14] * proj[8] + modl[15] * proj[12]; - clip[13] = modl[12] * proj[1] + modl[13] * proj[5] + modl[14] * proj[9] + modl[15] * proj[13]; - clip[14] = modl[12] * proj[2] + modl[13] * proj[6] + modl[14] * proj[10] + modl[15] * proj[14]; - clip[15] = modl[12] * proj[3] + modl[13] * proj[7] + modl[14] * proj[11] + modl[15] * proj[15]; - - frustum_planes[RIGHT][A] = clip[3] - clip[0]; - frustum_planes[RIGHT][B] = clip[7] - clip[4]; - frustum_planes[RIGHT][C] = clip[11] - clip[8]; - frustum_planes[RIGHT][D] = clip[15] - clip[12]; - normalizePlane(frustum_planes[RIGHT]); - - frustum_planes[LEFT][A] = clip[3] + clip[0]; - frustum_planes[LEFT][B] = clip[7] + clip[4]; - frustum_planes[LEFT][C] = clip[11] + clip[8]; - frustum_planes[LEFT][D] = clip[15] + clip[12]; - normalizePlane(frustum_planes[LEFT]); - - frustum_planes[BOTTOM][A] = clip[3] + clip[1]; - frustum_planes[BOTTOM][B] = clip[7] + clip[5]; - frustum_planes[BOTTOM][C] = clip[11] + clip[9]; - frustum_planes[BOTTOM][D] = clip[15] + clip[13]; - normalizePlane(frustum_planes[BOTTOM]); - - frustum_planes[TOP][A] = clip[3] - clip[1]; - frustum_planes[TOP][B] = clip[7] - clip[5]; - frustum_planes[TOP][C] = clip[11] - clip[9]; - frustum_planes[TOP][D] = clip[15] - clip[13]; - normalizePlane(frustum_planes[TOP]); - - frustum_planes[BACK][A] = clip[3] - clip[2]; - frustum_planes[BACK][B] = clip[7] - clip[6]; - frustum_planes[BACK][C] = clip[11] - clip[10]; - frustum_planes[BACK][D] = clip[15] - clip[14]; - normalizePlane(frustum_planes[BACK]); - - frustum_planes[FRONT][A] = clip[3] + clip[2]; - frustum_planes[FRONT][B] = clip[7] + clip[6]; - frustum_planes[FRONT][C] = clip[11] + clip[10]; - frustum_planes[FRONT][D] = clip[15] + clip[14]; - normalizePlane(frustum_planes[FRONT]); -} - -bool Frustum::TestInsideFrustrum(glm::vec4 Min, glm::vec4 Max) { - bool inside = true; - //test all 6 frustum planes - for (int i = 0; i < 6; i++) { - //pick closest point to plane and check if it behind the plane - //if yes - object outside frustum - float d = std::max(Min.x * frustum_planes[i].x, Max.x * frustum_planes[i].x) - + std::max(Min.y * frustum_planes[i].y, Max.y * frustum_planes[i].y) - + std::max(Min.z * frustum_planes[i].z, Max.z * frustum_planes[i].z) - + frustum_planes[i].w; - inside &= d > 0; - //return false; //with flag works faster - } - return inside; -} diff --git a/src/graphics/Frustrum.hpp b/src/graphics/Frustrum.hpp deleted file mode 100644 index e8a6fd6..0000000 --- a/src/graphics/Frustrum.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef _FRUSTUM_H -#define _FRUSTUM_H - - -#include <cmath> -#include <algorithm> -#include <GL/glew.h> -#include <glm/glm.hpp> -#include <glm/gtc/type_ptr.hpp> - -class Frustum { -public: - Frustum() = default; - - ~Frustum() = default; - - void CalculateFrustum(glm::mat4 &view_matrix, glm::mat4 &proj_matrix); - - glm::vec4 frustum_planes[6]; - - bool TestInsideFrustrum(glm::vec4 Min, glm::vec4 Max); -}; - -#endif
\ No newline at end of file diff --git a/src/graphics/Shader.cpp b/src/graphics/Shader.cpp index 83eb93f..cf43115 100644 --- a/src/graphics/Shader.cpp +++ b/src/graphics/Shader.cpp @@ -1,90 +1,115 @@ #include "Shader.hpp" -Shader::Shader(const GLchar *vertexPath, const GLchar *fragmentPath) { - vertex = vertexPath; - fragment = fragmentPath; - // 1. Получаем исходный код шейдера из filePath - std::string vertexCode; - std::string fragmentCode; - std::ifstream vShaderFile; - std::ifstream fShaderFile; - // Удостоверимся, что ifstream объекты могут выкидывать исключения - vShaderFile.exceptions(std::ifstream::failbit); - fShaderFile.exceptions(std::ifstream::failbit); - try { - // Открываем файлы - vShaderFile.open(vertexPath); - fShaderFile.open(fragmentPath); - std::stringstream vShaderStream, fShaderStream; - // Считываем данные в потоки - vShaderStream << vShaderFile.rdbuf(); - fShaderStream << fShaderFile.rdbuf(); - // Закрываем файлы - vShaderFile.close(); - fShaderFile.close(); - // Преобразовываем потоки в массив GLchar - vertexCode = vShaderStream.str(); - fragmentCode = fShaderStream.str(); - } - catch (std::ifstream::failure e) { - LOG(ERROR) << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ"; - } - const GLchar *vShaderCode = vertexCode.c_str(); - const GLchar *fShaderCode = fragmentCode.c_str(); +Shader::Shader(const GLchar *vertexPath, const GLchar *fragmentPath, const GLchar *geometryPath) { + vertex = vertexPath; + fragment = fragmentPath; + // 1. Получаем исходный код шейдера из filePath + std::string vertexCode; + std::string fragmentCode; + std::string geometryCode; + std::ifstream vShaderFile; + std::ifstream fShaderFile; + std::ifstream gShaderFile; + // Удостоверимся, что ifstream объекты могут выкидывать исключения + vShaderFile.exceptions(std::ifstream::failbit); + fShaderFile.exceptions(std::ifstream::failbit); + gShaderFile.exceptions(std::ifstream::failbit); + try { + // Открываем файлы + vShaderFile.open(vertexPath); + fShaderFile.open(fragmentPath); + if (geometryPath != nullptr) + gShaderFile.open(geometryPath); + std::stringstream vShaderStream, fShaderStream, gShaderStream; + // Считываем данные в потоки + vShaderStream << vShaderFile.rdbuf(); + fShaderStream << fShaderFile.rdbuf(); + if (geometryPath != nullptr) + gShaderStream << gShaderFile.rdbuf(); + // Закрываем файлы + vShaderFile.close(); + fShaderFile.close(); + if (geometryPath != nullptr) + gShaderFile.close(); + // Преобразовываем потоки в массив GLchar + vertexCode = vShaderStream.str(); + fragmentCode = fShaderStream.str(); + if (geometryPath != nullptr) + geometryCode = gShaderStream.str(); + } + catch (std::ifstream::failure e) { + LOG(ERROR) << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ"; + } + const GLchar *vShaderCode = vertexCode.c_str(); + const GLchar *fShaderCode = fragmentCode.c_str(); + const GLchar *gShaderCode = geometryCode.c_str(); + // 2. Сборка шейдеров + GLuint vertex, fragment, geometry; + GLint success; + GLchar infoLog[512]; - // 2. Сборка шейдеров - GLuint vertex, fragment; - GLint success; - GLchar infoLog[512]; + // Вершинный шейдер + vertex = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertex, 1, &vShaderCode, NULL); + glCompileShader(vertex); + // Если есть ошибки - вывести их + glGetShaderiv(vertex, GL_COMPILE_STATUS, &success); + if (!success) { + glGetShaderInfoLog(vertex, 512, NULL, infoLog); + LOG(ERROR) << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog; + }; - // Вершинный шейдер - vertex = glCreateShader(GL_VERTEX_SHADER); - glShaderSource(vertex, 1, &vShaderCode, NULL); - glCompileShader(vertex); - // Если есть ошибки - вывести их - glGetShaderiv(vertex, GL_COMPILE_STATUS, &success); - if (!success) { - glGetShaderInfoLog(vertex, 512, NULL, infoLog); - LOG(ERROR) << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog; - }; + // Вершинный шейдер + fragment = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragment, 1, &fShaderCode, NULL); + glCompileShader(fragment); + // Если есть ошибки - вывести их + glGetShaderiv(fragment, GL_COMPILE_STATUS, &success); + if (!success) { + glGetShaderInfoLog(fragment, 512, NULL, infoLog); + LOG(ERROR) << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog; + }; - // Вершинный шейдер - fragment = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(fragment, 1, &fShaderCode, NULL); - glCompileShader(fragment); - // Если есть ошибки - вывести их - glGetShaderiv(fragment, GL_COMPILE_STATUS, &success); - if (!success) { - glGetShaderInfoLog(fragment, 512, NULL, infoLog); - LOG(ERROR) << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog; - }; + if (geometryPath != nullptr) { + geometry = glCreateShader(GL_GEOMETRY_SHADER); + glShaderSource(geometry, 1, &gShaderCode, NULL); + glCompileShader(geometry); + // Если есть ошибки - вывести их + glGetShaderiv(geometry, GL_COMPILE_STATUS, &success); + if (!success) { + glGetShaderInfoLog(geometry, 512, NULL, infoLog); + LOG(ERROR) << "ERROR::SHADER::GEOMETRY::COMPILATION_FAILED\n" << infoLog; + }; + } - // Шейдерная программа - this->Program = glCreateProgram(); - glAttachShader(this->Program, vertex); - glAttachShader(this->Program, fragment); - glLinkProgram(this->Program); - //Если есть ошибки - вывести их - glGetProgramiv(this->Program, GL_LINK_STATUS, &success); - if (!success) { - glGetProgramInfoLog(this->Program, 512, NULL, infoLog); - LOG(FATAL) << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog; - } + // Шейдерная программа + this->Program = glCreateProgram(); + glAttachShader(this->Program, vertex); + glAttachShader(this->Program, fragment); + if (geometryPath != nullptr) + glAttachShader(this->Program, geometry); + glLinkProgram(this->Program); + //Если есть ошибки - вывести их + glGetProgramiv(this->Program, GL_LINK_STATUS, &success); + if (!success) { + glGetProgramInfoLog(this->Program, 512, NULL, infoLog); + LOG(FATAL) << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog; + } - // Удаляем шейдеры, поскольку они уже в программу и нам больше не нужны. - glDeleteShader(vertex); - glDeleteShader(fragment); + // Удаляем шейдеры, поскольку они уже в программу и нам больше не нужны. + glDeleteShader(vertex); + glDeleteShader(fragment); } void Shader::Use() { - glUseProgram(this->Program); + glUseProgram(this->Program); } void Shader::Reload() { - const GLchar *vertexPath = vertex; - const GLchar *fragmentPath = fragment; - this->~Shader(); - new(this) Shader(vertexPath, fragmentPath); - LOG(INFO) << "Shader is realoded!"; + const GLchar *vertexPath = vertex; + const GLchar *fragmentPath = fragment; + this->~Shader(); + new(this) Shader(vertexPath, fragmentPath); + LOG(INFO) << "Shader is realoded!"; } diff --git a/src/graphics/Shader.hpp b/src/graphics/Shader.hpp index a336b1a..1bcee3a 100644 --- a/src/graphics/Shader.hpp +++ b/src/graphics/Shader.hpp @@ -14,7 +14,7 @@ public: // Идентификатор программы GLuint Program; // Конструктор считывает и собирает шейдер - Shader(const GLchar* vertexPath, const GLchar* fragmentPath); + Shader(const GLchar* vertexPath, const GLchar* fragmentPath, const GLchar* geometryPath = nullptr); // Использование программы void Use(); |