summaryrefslogtreecommitdiffstats
path: root/src/graphics
diff options
context:
space:
mode:
Diffstat (limited to 'src/graphics')
-rw-r--r--src/graphics/Camera3D.cpp79
-rw-r--r--src/graphics/Camera3D.hpp66
-rw-r--r--src/graphics/Frustrum.cpp111
-rw-r--r--src/graphics/Frustrum.hpp24
-rw-r--r--src/graphics/Shader.cpp175
-rw-r--r--src/graphics/Shader.hpp2
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();