diff --git a/.gitignore b/.gitignore index 822dd55..208c8dd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ cmake-build-*/ -.idea/ +.idea/workspace.xml diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..7014074 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +perlin-shadows \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..4662818 --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,13 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..79ee123 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/f.iml b/.idea/f.iml new file mode 100644 index 0000000..f08604b --- /dev/null +++ b/.idea/f.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..e96f6e0 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,14 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..79b3c94 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..3b5e351 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index ff2abe3..87ce308 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,14 +26,3 @@ add_executable(perlin-shadows src/renderable.cpp src/renderable.h ) - -file(READ src/phong.vert PHONG_VERT) -file(READ src/phong.frag PHONG_FRAG) -configure_file(src/renderer.in.cpp src/renderer.cpp @ONLY) - -file(READ src/shadow.vert SHADOW_VERT) -file(READ src/shadow.frag SHADOW_FRAG) -file(READ src/shadow.geom SHADOW_GEOM) -configure_file(src/point_light.in.h src/point_light.h @ONLY) - -target_include_directories(perlin-shadows PUBLIC "${CMAKE_CURRENT_BINARY_DIR}/src") \ No newline at end of file diff --git a/README.md b/README.md index 24bd256..5567e91 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,13 @@ Generates several tiles of grids containing Perlin noise, and then renders them with shadows. +## Running + +The shader files (`src/*.{frag,vert,geom}`) are referenced within the code by assuming they are located in the current +working directory. +It is therefore necessary to set the CWD when running the program to the `src/` directory, or copy/symlink the files to +whatever your actual CWD is. + ## Control Sample from console output: diff --git a/src/camera.cpp b/src/camera.cpp index 72cb936..3857673 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -5,9 +5,9 @@ using namespace std; -void Camera::LoadMatrices(const Shader *shader) const { +void Camera::LoadMatrices(Shader *shader) const { const auto viewMatrix = - lookAt(position_, position_ + look_vector(), up_vector()); + glm::lookAt(position_, position_ + look_vector(), up_vector()); if (!shader->CopyDataToUniform(viewMatrix, "view")) { cerr << "View matrix not in shader" << endl; } @@ -22,7 +22,5 @@ void Camera::LoadMatrices(const Shader *shader) const { cerr << "Camera position not in shader" << endl; } - if (!shader->CopyDataToUniform(kFarPlane, "farPlane")) { - cerr << "Far plane not in shader" << endl; - } + shader->CopyDataToUniform(kFarPlane, "farPlane"); } diff --git a/src/camera.h b/src/camera.h index 6b8c39d..cb5ec87 100644 --- a/src/camera.h +++ b/src/camera.h @@ -1,5 +1,6 @@ #pragma once +#include #include #define GLM_ENABLE_EXPERIMENTAL #include @@ -13,29 +14,33 @@ class Camera { set_aspect(width, height); } - void LoadMatrices(const Shader *shader) const; + void LoadMatrices(Shader *shader) const; - void RelativeRotate(const glm::vec3 amount) { rotation_ += amount; } - void RelativeMove(const glm::vec3 amount) { + inline void RelativeRotate(const glm::vec3 amount) { rotation_ += amount; } + inline void RelativeMove(const glm::vec3 amount) { position_ += amount.x * look_vector() + amount.y * normal_vector() + amount.z * up_vector(); } - void AbsoluteMove(const glm::vec3 amount) { position_ += amount; } + inline void AbsoluteMove(const glm::vec3 amount) { position_ += amount; } - void set_aspect(const int width, const int height) { + inline void set_aspect(const int width, const int height) { aspect_ = static_cast(width) / static_cast(height); } - const glm::vec3 &getPosition() const { return position_; } + inline const glm::vec3 &getPosition() const { return position_; } private: - glm::vec3 look_vector() const { - return rotateZ(rotateY(glm::vec3(1., 0., 0.), rotation_.y), rotation_.z); + inline glm::vec3 look_vector() const { + return glm::rotateZ(glm::rotateY(glm::vec3(1., 0., 0.), rotation_.y), + rotation_.z); } - glm::vec3 up_vector() const { - return rotateZ(rotateY(glm::vec3(0., 0., 1.), rotation_.y), rotation_.z); + inline glm::vec3 up_vector() const { + return glm::rotateZ(glm::rotateY(glm::vec3(0., 0., 1.), rotation_.y), + rotation_.z); + } + inline glm::vec3 normal_vector() const { + return glm::cross(up_vector(), look_vector()); } - glm::vec3 normal_vector() const { return cross(up_vector(), look_vector()); } glm::vec3 position_{kGeographyShort / 2, kGeographyLong *kGeographyCountLong / 2, diff --git a/src/final.cpp b/src/final.cpp index fe77bfa..8748008 100644 --- a/src/final.cpp +++ b/src/final.cpp @@ -5,7 +5,7 @@ using namespace std; -int main(const int argc, char *argv[]) { +int main(int argc, char *argv[]) { try { Renderer(argc, argv); } catch (const runtime_error &error) { diff --git a/src/geography.cpp b/src/geography.cpp index ef5daf7..232a2ab 100644 --- a/src/geography.cpp +++ b/src/geography.cpp @@ -9,10 +9,9 @@ using namespace std; -Geography::Geography(const int x, const int y) - : Renderable(true), x_(x), y_(y) { +Geography::Geography(int x, int y) : Renderable(true), x_(x), y_(y) { Randomize(false); - model_ = translate( + model_ = glm::translate( glm::identity(), glm::vec3(x * (kGeographyShort - 1), y * (kGeographyLong - 1), 0)); } @@ -21,19 +20,19 @@ Geography::~Geography() { CleanUp(); } // Sums Perlin noise on a variety of factors, then stores the result in results // Note: Frees factors -void CalculatePerlinNoise(queue *results, const int x, const int y, +void CalculatePerlinNoise(queue *results, int x, int y, vector *factors) { - const auto grid = new Grid(); + auto grid = new Grid(); for (const auto factor : *factors) { const auto noise = Grid::PerlinNoise(x, y, kDetail >> factor); - *grid += *noise / static_cast(1 << factor); + (*grid) += (*noise) / static_cast(1 << factor); delete noise; } results->push(grid); delete factors; } -void Geography::Randomize(const bool load) { +void Geography::Randomize(bool load) { if (load) { CleanUp(); } @@ -44,7 +43,7 @@ void Geography::Randomize(const bool load) { // Set up one thread for each noise scale for (size_t i = 0; i < kMaxThreads; ++i) { auto factors = new vector(); - for (size_t factor = 0; kDetail >> factor > kMinDetail; + for (size_t factor = 0; (kDetail >> factor) > kMinDetail; factor += kMaxThreads) { factors->push_back(factor + i); } @@ -59,7 +58,7 @@ void Geography::Randomize(const bool load) { // Add up all noise levels while (!results.empty()) { - const auto grid = results.front(); + auto grid = results.front(); height_ += *grid; delete grid; results.pop(); diff --git a/src/geography.h b/src/geography.h index 3c1bcd9..bd10570 100644 --- a/src/geography.h +++ b/src/geography.h @@ -1,17 +1,19 @@ #pragma once +#include + #include "grid.h" #include "renderable.h" -class Geography final : public Renderable { +class Geography : public Renderable { public: Geography(int x, int y); - ~Geography() override; + ~Geography(); void Randomize(bool); - float min() const { return height_.min(); } - float max() const { return height_.max(); } + inline float min() const { return height_.min(); } + inline float max() const { return height_.max(); } protected: void SetData() override; diff --git a/src/grid.cpp b/src/grid.cpp index b167106..2ebd216 100644 --- a/src/grid.cpp +++ b/src/grid.cpp @@ -20,7 +20,7 @@ Grid Grid::operator+(const Grid &other) const { return result; } -void Grid::operator+=(const Grid &other) const { +void Grid::operator+=(const Grid &other) { for (size_t i = 0; i < data_->size(); ++i) { (*data_)[i] += (*other.data_)[i]; } @@ -30,7 +30,7 @@ Grid Grid::operator-() const { return operator*(-1); } Grid Grid::operator-(const Grid &other) const { return operator+(-other); } -void Grid::operator-=(const Grid &other) const { operator+=(-other); } +void Grid::operator-=(const Grid &other) { operator+=(-other); } Grid Grid::operator*(const float val) const { Grid result; @@ -40,7 +40,7 @@ Grid Grid::operator*(const float val) const { return result; } -void Grid::operator*=(const float val) const { +void Grid::operator*=(const float val) { for (size_t i = 0; i < data_->size(); ++i) { (*data_)[i] *= val; } @@ -48,7 +48,7 @@ void Grid::operator*=(const float val) const { Grid Grid::operator/(const float val) const { return operator*(1 / val); } -void Grid::operator/=(const float val) const { operator*=(1 / val); } +void Grid::operator/=(const float val) { operator*=(1 / val); } glm::vec3 Grid::normal_at(const size_t x, const size_t y, const float amplification) const { @@ -63,37 +63,36 @@ glm::vec3 Grid::normal_at(const size_t x, const size_t y, const auto y_diff = glm::vec3(0, static_cast(high_y - low_y), amplification * (get(x, high_y) - get(x, low_y))); - return normalize(cross(x_diff, y_diff)); + return glm::normalize(glm::cross(x_diff, y_diff)); } // Implementation based on: https://en.wikipedia.org/wiki/Perlin_noise // Assumes that kGeographyShort and kGeographyLong are equal to 2^n (doesn't // have to be the same n) -Grid *Grid::PerlinNoise(const int globalX, const int globalY, - const std::size_t detail) { - const auto grid = new Grid(); +Grid *Grid::PerlinNoise(int globalX, int globalY, std::size_t detail) { + auto grid = new Grid(); // Store the vectors at grid corners as just angles, they're all normalised - const size_t major_width = kGeographyShort / detail + 1; - const size_t major_length = kGeographyLong / detail + 1; + const size_t major_width = (kGeographyShort / detail) + 1; + const size_t major_length = (kGeographyLong / detail) + 1; const size_t grid_nodes = major_width * major_length; vector sin_major_angles(grid_nodes); vector cos_major_angles(grid_nodes); - const auto worldIndexX = (major_width - 1) * globalX; - const auto worldIndexY = ((major_width - 1) * kGeographyCountShort + 1) * - (major_length - 1) * globalY; - const auto worldIndex = worldIndexX + worldIndexY; - const mt19937::result_type gridBaseSeed = base_random_ * detail + worldIndex; + auto worldIndexX = (major_width - 1) * globalX; + auto worldIndexY = ((major_width - 1) * kGeographyCountShort + 1) * + (major_length - 1) * globalY; + auto worldIndex = worldIndexX + worldIndexY; + mt19937::result_type gridBaseSeed = base_random_ * detail + worldIndex; // Randomly generates corner vector angles [0, 2pi) for (size_t x = 0; x < major_width; ++x) { for (size_t y = 0; y < major_width; ++y) { - const auto relativeWorldIndex = + auto relativeWorldIndex = x + ((major_width - 1) * kGeographyCountShort + 1) * y; grid->AngleSeed(gridBaseSeed + relativeWorldIndex); - const auto angle = grid->RandomAngle(); - const auto i = x + major_width * y; + auto angle = grid->RandomAngle(); + auto i = x + major_width * y; sin_major_angles[i] = sin(angle); cos_major_angles[i] = cos(angle); } @@ -120,8 +119,7 @@ Grid *Grid::PerlinNoise(const int globalX, const int globalY, // Lambda to determine the dot product of the offset vector of the current // point with one of the four grid vectors around the current point const auto dot_major = [=, &cos_major_angles, &sin_major_angles]( - const bool high_x, - const bool high_y) -> float { + bool high_x, bool high_y) -> float { const auto major_x = lower_major_x + (high_x ? 1 : 0); const auto major_y = lower_major_y + (high_y ? 1 : 0); const auto sin_major_angle = @@ -149,12 +147,12 @@ Grid *Grid::PerlinNoise(const int globalX, const int globalY, } array *Grid::vertices() const { - const auto vertices = new array(); + auto vertices = new array(); for (size_t x = 0; x < kGeographyShort; ++x) { for (size_t y = 0; y < kGeographyLong; ++y) { - const auto ind = index(x, y); - const glm::vec3 position = {x, y, (*data_)[ind]}; - const glm::vec3 normal = normal_at(x, y); + auto ind = index(x, y); + glm::vec3 position = {x, y, (*data_)[ind]}; + glm::vec3 normal = normal_at(x, y); (*vertices)[ind] = {position, normal}; } } @@ -162,10 +160,10 @@ array *Grid::vertices() const { } array *Grid::indices() { - const auto indices = new array(); + auto indices = new array(); for (size_t x = 0; x < kGeographyShort - 1; ++x) { for (size_t y = 0; y < kGeographyLong - 1; ++y) { - const auto indexInd = (x + y * (kGeographyShort - 1)) * 6; + auto indexInd = (x + y * (kGeographyShort - 1)) * 6; (*indices)[indexInd] = static_cast(index(x, y)); (*indices)[indexInd + 1] = static_cast(index(x, y + 1)); (*indices)[indexInd + 2] = static_cast(index(x + 1, y)); diff --git a/src/grid.h b/src/grid.h index 851f641..3be491b 100644 --- a/src/grid.h +++ b/src/grid.h @@ -9,6 +9,7 @@ #include #include "constants.h" +#include "noise_math.h" #include "shader.h" constexpr std::size_t index(const std::size_t x, const std::size_t y) { @@ -17,22 +18,22 @@ constexpr std::size_t index(const std::size_t x, const std::size_t y) { class Grid { public: - float get(const std::size_t x, const std::size_t y) const { + inline float get(const std::size_t x, const std::size_t y) const { return (*data_)[index(x, y)]; } - void set(const std::size_t x, const std::size_t y, const float value) const { + inline void set(const std::size_t x, const std::size_t y, float value) { (*data_)[index(x, y)] = value; } Grid operator+(const Grid &) const; - void operator+=(const Grid &) const; + void operator+=(const Grid &); Grid operator-() const; Grid operator-(const Grid &) const; - void operator-=(const Grid &) const; + void operator-=(const Grid &); Grid operator*(float) const; - void operator*=(float) const; + void operator*=(float); Grid operator/(float) const; - void operator/=(float) const; + void operator/=(float); glm::vec3 normal_at(std::size_t, std::size_t, float = 1.) const; @@ -40,10 +41,14 @@ class Grid { std::array *vertices() const; static std::array *indices(); - static void RandomizeBase() { base_random_ = device_() << 4; } + static inline void RandomizeBase() { base_random_ = device_() << 4; } - float min() const { return *std::min_element(data_->begin(), data_->end()); } - float max() const { return *std::max_element(data_->begin(), data_->end()); } + inline float min() const { + return *std::min_element(data_->begin(), data_->end()); + } + inline float max() const { + return *std::max_element(data_->begin(), data_->end()); + } private: std::unique_ptr> data_{ @@ -54,6 +59,6 @@ class Grid { std::uniform_real_distribution dist_{0, glm::two_pi()}; static std::mt19937::result_type base_random_; - float RandomAngle() { return dist_(engine_); } - void AngleSeed(const std::mt19937::result_type seed) { engine_.seed(seed); } + inline float RandomAngle() { return dist_(engine_); } + inline void AngleSeed(std::mt19937::result_type seed) { engine_.seed(seed); } }; diff --git a/src/noise_math.h b/src/noise_math.h index b338d3f..368f878 100644 --- a/src/noise_math.h +++ b/src/noise_math.h @@ -3,7 +3,7 @@ // Based on Ken Perlin's smoother step function: // https://en.wikipedia.org/wiki/Smoothstep#Variations Returns value in range // [0, 1] -constexpr float SmootherStep(const float x) { +inline constexpr float SmootherStep(const float x) { if (x < 0) { return 0; } @@ -17,7 +17,7 @@ constexpr float SmootherStep(const float x) { // Interpolates between two doubles // If x <= 0 returns bound_0, if x >= 1 returns bound_1, // otherwise smoothly transitions between the two -constexpr float Interpolate(const float x, const float bound_0, +inline constexpr float Interpolate(const float x, const float bound_0, const float bound_1) { return bound_0 + SmootherStep(x) * (bound_1 - bound_0); } diff --git a/src/point_light.cpp b/src/point_light.cpp index 019e151..c1e35eb 100644 --- a/src/point_light.cpp +++ b/src/point_light.cpp @@ -1,6 +1,5 @@ #include "point_light.h" -#include #include #include #include @@ -48,7 +47,7 @@ PointLight::~PointLight() { glDeleteFramebuffers(1, &fbo_); } -void PointLight::LoadData(const Shader *shader) const { +void PointLight::LoadData(Shader *shader) const { if (!shader->CopyDataToUniform(ambient_, "pointLight.ambient")) { cerr << "Point light ambient not loaded to shader" << endl; } @@ -72,44 +71,37 @@ void PointLight::GenerateCubeMaps( // https://learnopengl.com/Advanced-Lighting/Shadows/Point-Shadows // By Joey de Vries (https://twitter.com/JoeyDeVriez) // CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/legalcode) - const auto shadowProj = + auto shadowProj = glm::perspective(glm::pi() / 2, 1.0f, kNearPlane, kFarPlane); auto shadowTransforms = array(); shadowTransforms[0] = - shadowProj * - lookAt(pos_, pos_ + glm::vec3(1.0, 0.0, 0.0), glm::vec3(0.0, -1.0, 0.0)); + shadowProj * glm::lookAt(pos_, pos_ + glm::vec3(1.0, 0.0, 0.0), + glm::vec3(0.0, -1.0, 0.0)); shadowTransforms[1] = - shadowProj * - lookAt(pos_, pos_ + glm::vec3(-1.0, 0.0, 0.0), glm::vec3(0.0, -1.0, 0.0)); + shadowProj * glm::lookAt(pos_, pos_ + glm::vec3(-1.0, 0.0, 0.0), + glm::vec3(0.0, -1.0, 0.0)); shadowTransforms[2] = - shadowProj * - lookAt(pos_, pos_ + glm::vec3(0.0, 1.0, 0.0), glm::vec3(0.0, 0.0, 1.0)); + shadowProj * glm::lookAt(pos_, pos_ + glm::vec3(0.0, 1.0, 0.0), + glm::vec3(0.0, 0.0, 1.0)); shadowTransforms[3] = - shadowProj * - lookAt(pos_, pos_ + glm::vec3(0.0, -1.0, 0.0), glm::vec3(0.0, 0.0, -1.0)); + shadowProj * glm::lookAt(pos_, pos_ + glm::vec3(0.0, -1.0, 0.0), + glm::vec3(0.0, 0.0, -1.0)); shadowTransforms[4] = - shadowProj * - lookAt(pos_, pos_ + glm::vec3(0.0, 0.0, 1.0), glm::vec3(0.0, -1.0, 0.0)); + shadowProj * glm::lookAt(pos_, pos_ + glm::vec3(0.0, 0.0, 1.0), + glm::vec3(0.0, -1.0, 0.0)); shadowTransforms[5] = - shadowProj * - lookAt(pos_, pos_ + glm::vec3(0.0, 0.0, -1.0), glm::vec3(0.0, -1.0, 0.0)); + shadowProj * glm::lookAt(pos_, pos_ + glm::vec3(0.0, 0.0, -1.0), + glm::vec3(0.0, -1.0, 0.0)); glViewport(0, 0, kShadowMapSize, kShadowMapSize); glBindFramebuffer(GL_FRAMEBUFFER, fbo_); glClear(GL_DEPTH_BUFFER_BIT); glUseProgram(shadow_.id()); - if (!shadow_.CopyDataToUniform(6, shadowTransforms.data(), - "shadowMatrices")) { - cerr << "Shadow matrix not in shader" << endl; - } - if (!shadow_.CopyDataToUniform(pos_, "lightPos")) { - cerr << "Light position not in shader" << endl; - } - if (!shadow_.CopyDataToUniform(kFarPlane, "farPlane")) { - cerr << "Far plane not in shader" << endl; - } + shadow_.CopyDataToUniform(6, shadowTransforms.data(), "shadowMatrices"); + shadow_.CopyDataToUniform(pos_, "lightPos"); + shadow_.CopyDataToUniform(kFarPlane, "farPlane"); for (const auto renderable : renderables) { renderable->Render(&shadow_); diff --git a/src/point_light.in.h b/src/point_light.h similarity index 64% rename from src/point_light.in.h rename to src/point_light.h index d04de69..b570293 100644 --- a/src/point_light.in.h +++ b/src/point_light.h @@ -8,21 +8,21 @@ #include "renderable.h" #include "shader.h" -class PointLight final : public Renderable { +class PointLight : public Renderable { public: explicit PointLight(const glm::vec3 &); - ~PointLight() override; + ~PointLight(); - void LoadData(const Shader *) const; + void LoadData(Shader *) const; void GenerateCubeMaps(const std::vector &) const; - GLuint getDepthTexture() const { return depth_; } - void setPosition(const glm::vec3 &pos) { + inline GLuint getDepthTexture() const { return depth_; } + inline void setPosition(const glm::vec3 &pos) { pos_ = pos; CleanUp(); InitGeom(); } - void setColors(const glm::vec3 &color) { + inline void setColors(const glm::vec3 &color) { diffuse_ = color; specular_ = color; ambient_ = color / 5.0f; @@ -37,7 +37,7 @@ class PointLight final : public Renderable { float specularPower_{20}; glm::vec3 pos_; - Shader shadow_{R"(@SHADOW_VERT@)", R"(@SHADOW_FRAG@)", R"(@SHADOW_GEOM@)"}; + Shader shadow_{"shadow.vert", "shadow.frag", "shadow.geom"}; GLuint fbo_{0}; GLuint depth_{0}; }; diff --git a/src/renderable.cpp b/src/renderable.cpp index 309a7cd..bd8b8b3 100644 --- a/src/renderable.cpp +++ b/src/renderable.cpp @@ -4,8 +4,7 @@ using namespace std; -Renderable::Renderable(const bool drawTriangles) - : drawTriangles_(drawTriangles) {} +Renderable::Renderable(bool drawTriangles) : drawTriangles_(drawTriangles) {} Renderable::~Renderable() { CleanUp(); } @@ -31,7 +30,7 @@ void Renderable::InitGeom() { void Renderable::Render(const Shader *const shader) const { if (!shader->CopyDataToUniform(model_, "model")) { - cerr << "Model matrix not in shader" << endl; + // cerr << "Model matrix not in shader" << endl; } glBindBuffer(GL_ARRAY_BUFFER, vbo_); @@ -40,21 +39,19 @@ void Renderable::Render(const Shader *const shader) const { GLuint attribLoc = glGetAttribLocation(shader->id(), "vtxPos"); if (attribLoc != -1) { glEnableVertexAttribArray(attribLoc); - glVertexAttribPointer( - attribLoc, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), - // ReSharper disable once CppZeroValuedExpressionUsedAsNullPointer - reinterpret_cast(offsetof(Vertex, position))); + glVertexAttribPointer(attribLoc, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), + (void *)offsetof(Vertex, position)); } else { - cerr << "Not loading vtxPos" << endl; + // cerr << "Not loading vtxPos" << endl; } attribLoc = glGetAttribLocation(shader->id(), "vtxNormal"); if (attribLoc != -1) { glEnableVertexAttribArray(attribLoc); glVertexAttribPointer(attribLoc, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), - reinterpret_cast(offsetof(Vertex, normal))); + (void *)offsetof(Vertex, normal)); } else { - cerr << "Not loading vtxNormal" << endl; + // cerr << "Not loading vtxNormal" << endl; } if (drawTriangles_) { diff --git a/src/renderable.h b/src/renderable.h index e5eb336..9e0ecc8 100644 --- a/src/renderable.h +++ b/src/renderable.h @@ -2,6 +2,7 @@ #include +#include #include #include @@ -10,7 +11,7 @@ class Renderable { public: explicit Renderable(bool); - virtual ~Renderable(); + ~Renderable(); void InitGeom(); void Render(const Shader *) const; diff --git a/src/renderer.in.cpp b/src/renderer.cpp similarity index 93% rename from src/renderer.in.cpp rename to src/renderer.cpp index 92b35c7..15be99a 100644 --- a/src/renderer.in.cpp +++ b/src/renderer.cpp @@ -7,8 +7,6 @@ #include #include "constants.h" -#include "geography.h" -#include "grid.h" using namespace std; @@ -43,7 +41,7 @@ Renderer::Renderer(int argc, char *argv[]) { glutPassiveMotionFunc(PassiveMotionCB); CheckGLError(); - const GLenum res = glewInit(); + GLenum res = glewInit(); if (res != GLEW_OK) { cerr << "Error in glewInit()"; throw runtime_error( @@ -51,26 +49,21 @@ Renderer::Renderer(int argc, char *argv[]) { } CheckGLError(); - shader_ = new Shader(R"( -@PHONG_VERT@ -)", - R"( -@PHONG_FRAG@ -)"); + shader_ = new Shader("phong.vert", "phong.frag"); light_ = new PointLight({kGeographyShort * kGeographyCountShort / 2, kGeographyLong * kGeographyCountLong / 2, kHeightMultiplier * kGeographyCountShort / 2}); using std::chrono::duration_cast; using std::chrono::milliseconds; - const auto start_time = chrono::high_resolution_clock::now(); + auto start_time = chrono::high_resolution_clock::now(); for (auto x = 0; x < kGeographyCountShort; ++x) { for (auto y = 0; y < kGeographyCountLong; ++y) { objects_.push_back(new Geography(x, y)); } } - const auto end_time = chrono::high_resolution_clock::now(); + auto end_time = chrono::high_resolution_clock::now(); cout << "Generation time: " << duration_cast(end_time - start_time).count() << "ms\n"; cout << " vertices: " @@ -125,11 +118,11 @@ void Renderer::Display() const { for (const auto object : objects_) { const auto geo = dynamic_cast(object); if (geo != nullptr) { - const float min = geo->min(); + float min = geo->min(); if (min < minHeight) { minHeight = min; } - const float max = geo->max(); + float max = geo->max(); if (max > maxHeight) { maxHeight = max; } @@ -144,7 +137,7 @@ void Renderer::Display() const { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_CUBE_MAP, light_->getDepthTexture()); - const auto depthMap = glGetUniformLocation(shader_->id(), "depthMap"); + auto depthMap = glGetUniformLocation(shader_->id(), "depthMap"); glUniform1i(depthMap, 0); light_->Render(shader_); @@ -262,7 +255,7 @@ void Renderer::HandleMovementKey(const unsigned char key, const bool down) { } } -void Renderer::Tick(const int ticks) { +void Renderer::Tick(int ticks) { bool doneSomething = false; if (last_mouse_x_ < 0 || last_mouse_x_ > viewport_width_ || last_mouse_y_ < 0 || last_mouse_y_ > viewport_height_) { @@ -297,11 +290,11 @@ void Renderer::Tick(const int ticks) { doneSomething = true; shadowsChanged_ = true; } else if (simulating_) { - const auto lightAngle = + auto lightAngle = fmod(static_cast(ticks) * glm::two_pi() / (kFPS * 20), glm::pi() * 5 / 4) - glm::pi() * 5 / 8; - const auto lightRotation = + auto lightRotation = glm::vec3(0, glm::sin(lightAngle), glm::cos(lightAngle) / 2) * static_cast(kGeographyLong * kGeographyCountLong); light_->setPosition(lightRotation + @@ -342,8 +335,9 @@ void Renderer::PassiveMotionCB(const int w, const int h) { } void Renderer::TimerCB(const int ticks) { - const auto tickIncrement = window->simulating_ ? 1 : 0; - glutTimerFunc(1000 / kFPS, TimerCB, ticks + tickIncrement); + auto tickIncrement = window->simulating_ ? 1 : 0; + glutTimerFunc(static_cast(1000 / kFPS), TimerCB, + ticks + tickIncrement); window->Tick(ticks); } @@ -353,7 +347,7 @@ void Renderer::CheckGLError() { } } -void Renderer::PrintOpenGLError(const GLenum errorCode) { +void Renderer::PrintOpenGLError(GLenum errorCode) { switch (errorCode) { case GL_INVALID_VALUE: cerr << "GL_INVALID_VALUE" << endl; diff --git a/src/renderer.h b/src/renderer.h index b68420f..de790a5 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -3,7 +3,9 @@ #include #include "camera.h" -#include "point_light.in.h" +#include "constants.h" +#include "geography.h" +#include "point_light.h" #include "shader.h" constexpr auto kInitialWidth = 1280; diff --git a/src/shader.cpp b/src/shader.cpp index 1a3d507..2fbd541 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -8,12 +8,11 @@ using namespace std; -Shader::Shader(const string &vertexShader, const string &fragmentShader, - const string &geometryShader) { - const auto vertexShaderId = CompileShader(vertexShader, GL_VERTEX_SHADER); - const auto fragmentShaderId = - CompileShader(fragmentShader, GL_FRAGMENT_SHADER); - GLuint geometryShaderId{0}; +Shader::Shader(const string &vertexShaderFile, const string &fragmentShaderFile, + const string &geometryShaderFile) { + auto vertexShaderId = CompileShader(vertexShaderFile, GL_VERTEX_SHADER); + auto fragmentShaderId = CompileShader(fragmentShaderFile, GL_FRAGMENT_SHADER); + GLuint geometryShaderId; id_ = glCreateProgram(); @@ -22,8 +21,8 @@ Shader::Shader(const string &vertexShader, const string &fragmentShader, glAttachShader(id_, fragmentShaderId); CheckGLError("Error in attaching the fragment shader"); - if (!geometryShader.empty()) { - geometryShaderId = CompileShader(geometryShader, GL_GEOMETRY_SHADER); + if (!geometryShaderFile.empty()) { + geometryShaderId = CompileShader(geometryShaderFile, GL_GEOMETRY_SHADER); glAttachShader(id_, geometryShaderId); CheckGLError("Error in attaching the geometry shader"); } @@ -34,7 +33,7 @@ Shader::Shader(const string &vertexShader, const string &fragmentShader, glDeleteShader(vertexShaderId); glDeleteShader(fragmentShaderId); - if (geometryShaderId != 0) { + if (!geometryShaderFile.empty()) { glDeleteShader(geometryShaderId); } @@ -46,7 +45,7 @@ Shader::~Shader() { glDeleteProgram(id_); } bool Shader::CopyDataToUniform(const glm::mat4 &data, const string &name) const { - const auto location = glGetUniformLocation(id_, name.c_str()); + auto location = glGetUniformLocation(id_, name.c_str()); if (location == -1) { return false; } @@ -55,9 +54,8 @@ bool Shader::CopyDataToUniform(const glm::mat4 &data, return true; } -bool Shader::CopyDataToUniform(const int count, const glm::mat4 *data, - const std::string &name) const { - const auto location = glGetUniformLocation(id_, name.c_str()); +bool Shader::CopyDataToUniform(int count, const glm::mat4 *data, const std::string &name) const { + auto location = glGetUniformLocation(id_, name.c_str()); if (location == -1) { return false; } @@ -68,7 +66,7 @@ bool Shader::CopyDataToUniform(const int count, const glm::mat4 *data, bool Shader::CopyDataToUniform(const glm::vec4 &data, const string &name) const { - const auto location = glGetUniformLocation(id_, name.c_str()); + auto location = glGetUniformLocation(id_, name.c_str()); if (location == -1) { return false; } @@ -78,7 +76,7 @@ bool Shader::CopyDataToUniform(const glm::vec4 &data, bool Shader::CopyDataToUniform(const glm::vec3 &data, const string &name) const { - const auto location = glGetUniformLocation(id_, name.c_str()); + auto location = glGetUniformLocation(id_, name.c_str()); if (location == -1) { return false; } @@ -86,8 +84,8 @@ bool Shader::CopyDataToUniform(const glm::vec3 &data, return true; } -bool Shader::CopyDataToUniform(const float data, const string &name) const { - const auto location = glGetUniformLocation(id_, name.c_str()); +bool Shader::CopyDataToUniform(float data, const string &name) const { + auto location = glGetUniformLocation(id_, name.c_str()); if (location == -1) { return false; } @@ -95,8 +93,8 @@ bool Shader::CopyDataToUniform(const float data, const string &name) const { return true; } -bool Shader::CopyDataToUniform(const int data, const string &name) const { - const auto location = glGetUniformLocation(id_, name.c_str()); +bool Shader::CopyDataToUniform(int data, const string &name) const { + auto location = glGetUniformLocation(id_, name.c_str()); if (location == -1) { return false; } @@ -104,24 +102,42 @@ bool Shader::CopyDataToUniform(const int data, const string &name) const { return true; } -bool Shader::CopyDataToUniform(const bool data, const string &name) const { - const auto location = glGetUniformLocation(id_, name.c_str()); +bool Shader::CopyDataToUniform(bool data, const string &name) const { + auto location = glGetUniformLocation(id_, name.c_str()); if (location == -1) { return false; } - const int actualData = data; + int actualData = static_cast(data); glUniform1iv(location, 1, &actualData); return true; } -GLuint Shader::CompileShader(const std::string &shaderSource, - const GLenum shaderType) { - const GLuint id = glCreateShader(shaderType); - const auto shaderC_str = shaderSource.c_str(); +string Shader::ReadFile(const string &filename) { + string data, line; + ifstream file; + file.open(filename, std::ios::binary); + if (file.is_open()) { + while (getline(file, line)) { + data += line + '\n'; + } + if (data.empty()) { + data.pop_back(); + } + } else { + throw runtime_error("Could not open " + filename); + } + return data; +} + +GLuint Shader::CompileShader(const std::string &filename, + const GLenum shader_type) { + const GLuint id = glCreateShader(shader_type); + auto shaderString = ReadFile(filename); + auto shaderC_str = shaderString.c_str(); glShaderSource(id, 1, &shaderC_str, nullptr); glCompileShader(id); CheckShaderivError(id, GL_COMPILE_STATUS, - "Error when compiling shader file:\n" + shaderSource); + "Error when creating shader file " + filename); return id; } @@ -158,7 +174,7 @@ void Shader::PrintStatus() const { glGetProgramiv(id_, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &bufSize); GLint size; GLenum type; - const auto attributeName = new GLchar[bufSize]; + auto attributeName = new GLchar[bufSize]; for (int i = 0; i < rc; ++i) { glGetActiveAttrib(id_, i, bufSize, &length, &size, &type, attributeName); cout << "\t" << attributeName << ": " << type << "\n"; @@ -181,7 +197,7 @@ void Shader::PrintStatus() const { } void Shader::CheckGLError(const string &errorMessage) { - const auto rc = glGetError(); + auto rc = glGetError(); if (rc != GL_NO_ERROR) { cerr << errorMessage << endl; throw runtime_error(reinterpret_cast(gluErrorString(rc))); @@ -196,7 +212,7 @@ void Shader::CheckProgramivError(const GLuint program, const GLenum pname, cerr << errorMessage << endl; GLsizei length, bufSize; glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufSize); - const auto error = new GLchar[bufSize]; + auto error = new GLchar[bufSize]; glGetProgramInfoLog(program, bufSize, &length, error); throw runtime_error(error); } @@ -210,7 +226,7 @@ void Shader::CheckShaderivError(const GLuint shader, const GLenum pname, cerr << errorMessage << endl; GLsizei length, bufSize; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &bufSize); - const auto error = new GLchar[bufSize]; + auto error = new GLchar[bufSize]; glGetShaderInfoLog(shader, bufSize, &length, error); throw runtime_error(error); } diff --git a/src/shader.h b/src/shader.h index 49554c0..22e6577 100644 --- a/src/shader.h +++ b/src/shader.h @@ -2,6 +2,7 @@ #include +#include #include #include @@ -25,11 +26,12 @@ class Shader { void PrintStatus() const; - GLuint id() const { return id_; } + inline GLuint id() const { return id_; } private: GLuint id_; + static std::string ReadFile(const std::string &); static GLuint CompileShader(const std::string &, GLenum); static void CheckGLError(const std::string &);