diff --git a/.gitignore b/.gitignore
index 208c8dd..822dd55 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,2 @@
cmake-build-*/
-.idea/workspace.xml
+.idea/
diff --git a/.idea/.name b/.idea/.name
deleted file mode 100644
index 7014074..0000000
--- a/.idea/.name
+++ /dev/null
@@ -1 +0,0 @@
-perlin-shadows
\ No newline at end of file
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
deleted file mode 100644
index 4662818..0000000
--- a/.idea/codeStyles/Project.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
deleted file mode 100644
index 79ee123..0000000
--- a/.idea/codeStyles/codeStyleConfig.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/f.iml b/.idea/f.iml
deleted file mode 100644
index f08604b..0000000
--- a/.idea/f.iml
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
deleted file mode 100644
index e96f6e0..0000000
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
deleted file mode 100644
index 79b3c94..0000000
--- a/.idea/misc.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index 3b5e351..0000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 35eb1dd..0000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 87ce308..ff2abe3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -26,3 +26,14 @@ 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 5567e91..24bd256 100644
--- a/README.md
+++ b/README.md
@@ -2,13 +2,6 @@
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 3857673..72cb936 100644
--- a/src/camera.cpp
+++ b/src/camera.cpp
@@ -5,9 +5,9 @@
using namespace std;
-void Camera::LoadMatrices(Shader *shader) const {
+void Camera::LoadMatrices(const Shader *shader) const {
const auto viewMatrix =
- glm::lookAt(position_, position_ + look_vector(), up_vector());
+ lookAt(position_, position_ + look_vector(), up_vector());
if (!shader->CopyDataToUniform(viewMatrix, "view")) {
cerr << "View matrix not in shader" << endl;
}
@@ -22,5 +22,7 @@ void Camera::LoadMatrices(Shader *shader) const {
cerr << "Camera position not in shader" << endl;
}
- shader->CopyDataToUniform(kFarPlane, "farPlane");
+ if (!shader->CopyDataToUniform(kFarPlane, "farPlane")) {
+ cerr << "Far plane not in shader" << endl;
+ }
}
diff --git a/src/camera.h b/src/camera.h
index cb5ec87..6b8c39d 100644
--- a/src/camera.h
+++ b/src/camera.h
@@ -1,6 +1,5 @@
#pragma once
-#include
#include
#define GLM_ENABLE_EXPERIMENTAL
#include
@@ -14,33 +13,29 @@ class Camera {
set_aspect(width, height);
}
- void LoadMatrices(Shader *shader) const;
+ void LoadMatrices(const Shader *shader) const;
- inline void RelativeRotate(const glm::vec3 amount) { rotation_ += amount; }
- inline void RelativeMove(const glm::vec3 amount) {
+ void RelativeRotate(const glm::vec3 amount) { rotation_ += amount; }
+ void RelativeMove(const glm::vec3 amount) {
position_ += amount.x * look_vector() + amount.y * normal_vector() +
amount.z * up_vector();
}
- inline void AbsoluteMove(const glm::vec3 amount) { position_ += amount; }
+ void AbsoluteMove(const glm::vec3 amount) { position_ += amount; }
- inline void set_aspect(const int width, const int height) {
+ void set_aspect(const int width, const int height) {
aspect_ = static_cast(width) / static_cast(height);
}
- inline const glm::vec3 &getPosition() const { return position_; }
+ const glm::vec3 &getPosition() const { return position_; }
private:
- inline glm::vec3 look_vector() const {
- return glm::rotateZ(glm::rotateY(glm::vec3(1., 0., 0.), rotation_.y),
- rotation_.z);
+ glm::vec3 look_vector() const {
+ return rotateZ(rotateY(glm::vec3(1., 0., 0.), 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 up_vector() const {
+ return rotateZ(rotateY(glm::vec3(0., 0., 1.), rotation_.y), rotation_.z);
}
+ 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 8748008..fe77bfa 100644
--- a/src/final.cpp
+++ b/src/final.cpp
@@ -5,7 +5,7 @@
using namespace std;
-int main(int argc, char *argv[]) {
+int main(const int argc, char *argv[]) {
try {
Renderer(argc, argv);
} catch (const runtime_error &error) {
diff --git a/src/geography.cpp b/src/geography.cpp
index 232a2ab..ef5daf7 100644
--- a/src/geography.cpp
+++ b/src/geography.cpp
@@ -9,9 +9,10 @@
using namespace std;
-Geography::Geography(int x, int y) : Renderable(true), x_(x), y_(y) {
+Geography::Geography(const int x, const int y)
+ : Renderable(true), x_(x), y_(y) {
Randomize(false);
- model_ = glm::translate(
+ model_ = translate(
glm::identity(),
glm::vec3(x * (kGeographyShort - 1), y * (kGeographyLong - 1), 0));
}
@@ -20,19 +21,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, int x, int y,
+void CalculatePerlinNoise(queue *results, const int x, const int y,
vector *factors) {
- auto grid = new Grid();
+ const 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(bool load) {
+void Geography::Randomize(const bool load) {
if (load) {
CleanUp();
}
@@ -43,7 +44,7 @@ void Geography::Randomize(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);
}
@@ -58,7 +59,7 @@ void Geography::Randomize(bool load) {
// Add up all noise levels
while (!results.empty()) {
- auto grid = results.front();
+ const auto grid = results.front();
height_ += *grid;
delete grid;
results.pop();
diff --git a/src/geography.h b/src/geography.h
index bd10570..3c1bcd9 100644
--- a/src/geography.h
+++ b/src/geography.h
@@ -1,19 +1,17 @@
#pragma once
-#include
-
#include "grid.h"
#include "renderable.h"
-class Geography : public Renderable {
+class Geography final : public Renderable {
public:
Geography(int x, int y);
- ~Geography();
+ ~Geography() override;
void Randomize(bool);
- inline float min() const { return height_.min(); }
- inline float max() const { return height_.max(); }
+ float min() const { return height_.min(); }
+ float max() const { return height_.max(); }
protected:
void SetData() override;
diff --git a/src/grid.cpp b/src/grid.cpp
index 2ebd216..b167106 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) {
+void Grid::operator+=(const Grid &other) const {
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) { operator+=(-other); }
+void Grid::operator-=(const Grid &other) const { 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) {
+void Grid::operator*=(const float val) const {
for (size_t i = 0; i < data_->size(); ++i) {
(*data_)[i] *= val;
}
@@ -48,7 +48,7 @@ void Grid::operator*=(const float val) {
Grid Grid::operator/(const float val) const { return operator*(1 / val); }
-void Grid::operator/=(const float val) { operator*=(1 / val); }
+void Grid::operator/=(const float val) const { operator*=(1 / val); }
glm::vec3 Grid::normal_at(const size_t x, const size_t y,
const float amplification) const {
@@ -63,36 +63,37 @@ 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 glm::normalize(glm::cross(x_diff, y_diff));
+ return normalize(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(int globalX, int globalY, std::size_t detail) {
- auto grid = new Grid();
+Grid *Grid::PerlinNoise(const int globalX, const int globalY,
+ const std::size_t detail) {
+ const 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);
- 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;
+ 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;
// 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) {
- auto relativeWorldIndex =
+ const auto relativeWorldIndex =
x + ((major_width - 1) * kGeographyCountShort + 1) * y;
grid->AngleSeed(gridBaseSeed + relativeWorldIndex);
- auto angle = grid->RandomAngle();
- auto i = x + major_width * y;
+ const auto angle = grid->RandomAngle();
+ const auto i = x + major_width * y;
sin_major_angles[i] = sin(angle);
cos_major_angles[i] = cos(angle);
}
@@ -119,7 +120,8 @@ Grid *Grid::PerlinNoise(int globalX, int globalY, std::size_t detail) {
// 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](
- bool high_x, bool high_y) -> float {
+ const bool high_x,
+ const 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 =
@@ -147,12 +149,12 @@ Grid *Grid::PerlinNoise(int globalX, int globalY, std::size_t detail) {
}
array *Grid::vertices() const {
- auto vertices = new array();
+ const auto vertices = new array();
for (size_t x = 0; x < kGeographyShort; ++x) {
for (size_t y = 0; y < kGeographyLong; ++y) {
- auto ind = index(x, y);
- glm::vec3 position = {x, y, (*data_)[ind]};
- glm::vec3 normal = normal_at(x, y);
+ const auto ind = index(x, y);
+ const glm::vec3 position = {x, y, (*data_)[ind]};
+ const glm::vec3 normal = normal_at(x, y);
(*vertices)[ind] = {position, normal};
}
}
@@ -160,10 +162,10 @@ array *Grid::vertices() const {
}
array *Grid::indices() {
- auto indices = new array();
+ const auto indices = new array();
for (size_t x = 0; x < kGeographyShort - 1; ++x) {
for (size_t y = 0; y < kGeographyLong - 1; ++y) {
- auto indexInd = (x + y * (kGeographyShort - 1)) * 6;
+ const 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 3be491b..851f641 100644
--- a/src/grid.h
+++ b/src/grid.h
@@ -9,7 +9,6 @@
#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) {
@@ -18,22 +17,22 @@ constexpr std::size_t index(const std::size_t x, const std::size_t y) {
class Grid {
public:
- inline float get(const std::size_t x, const std::size_t y) const {
+ float get(const std::size_t x, const std::size_t y) const {
return (*data_)[index(x, y)];
}
- inline void set(const std::size_t x, const std::size_t y, float value) {
+ void set(const std::size_t x, const std::size_t y, const float value) const {
(*data_)[index(x, y)] = value;
}
Grid operator+(const Grid &) const;
- void operator+=(const Grid &);
+ void operator+=(const Grid &) const;
Grid operator-() const;
Grid operator-(const Grid &) const;
- void operator-=(const Grid &);
+ void operator-=(const Grid &) const;
Grid operator*(float) const;
- void operator*=(float);
+ void operator*=(float) const;
Grid operator/(float) const;
- void operator/=(float);
+ void operator/=(float) const;
glm::vec3 normal_at(std::size_t, std::size_t, float = 1.) const;
@@ -41,14 +40,10 @@ class Grid {
std::array *vertices() const;
static std::array *indices();
- static inline void RandomizeBase() { base_random_ = device_() << 4; }
+ static void RandomizeBase() { base_random_ = device_() << 4; }
- inline float min() const {
- return *std::min_element(data_->begin(), data_->end());
- }
- inline float max() const {
- return *std::max_element(data_->begin(), data_->end());
- }
+ float min() const { return *std::min_element(data_->begin(), data_->end()); }
+ float max() const { return *std::max_element(data_->begin(), data_->end()); }
private:
std::unique_ptr> data_{
@@ -59,6 +54,6 @@ class Grid {
std::uniform_real_distribution dist_{0, glm::two_pi()};
static std::mt19937::result_type base_random_;
- inline float RandomAngle() { return dist_(engine_); }
- inline void AngleSeed(std::mt19937::result_type seed) { engine_.seed(seed); }
+ float RandomAngle() { return dist_(engine_); }
+ void AngleSeed(const std::mt19937::result_type seed) { engine_.seed(seed); }
};
diff --git a/src/noise_math.h b/src/noise_math.h
index 368f878..b338d3f 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]
-inline constexpr float SmootherStep(const float x) {
+constexpr float SmootherStep(const float x) {
if (x < 0) {
return 0;
}
@@ -17,7 +17,7 @@ inline 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
-inline constexpr float Interpolate(const float x, const float bound_0,
+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 c1e35eb..019e151 100644
--- a/src/point_light.cpp
+++ b/src/point_light.cpp
@@ -1,5 +1,6 @@
#include "point_light.h"
+#include
#include
#include
#include
@@ -47,7 +48,7 @@ PointLight::~PointLight() {
glDeleteFramebuffers(1, &fbo_);
}
-void PointLight::LoadData(Shader *shader) const {
+void PointLight::LoadData(const Shader *shader) const {
if (!shader->CopyDataToUniform(ambient_, "pointLight.ambient")) {
cerr << "Point light ambient not loaded to shader" << endl;
}
@@ -71,37 +72,44 @@ 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)
- auto shadowProj =
+ const auto shadowProj =
glm::perspective(glm::pi() / 2, 1.0f, kNearPlane, kFarPlane);
auto shadowTransforms = array();
shadowTransforms[0] =
- shadowProj * glm::lookAt(pos_, pos_ + glm::vec3(1.0, 0.0, 0.0),
- glm::vec3(0.0, -1.0, 0.0));
+ shadowProj *
+ lookAt(pos_, pos_ + glm::vec3(1.0, 0.0, 0.0), glm::vec3(0.0, -1.0, 0.0));
shadowTransforms[1] =
- shadowProj * glm::lookAt(pos_, pos_ + glm::vec3(-1.0, 0.0, 0.0),
- glm::vec3(0.0, -1.0, 0.0));
+ shadowProj *
+ lookAt(pos_, pos_ + glm::vec3(-1.0, 0.0, 0.0), glm::vec3(0.0, -1.0, 0.0));
shadowTransforms[2] =
- shadowProj * glm::lookAt(pos_, pos_ + glm::vec3(0.0, 1.0, 0.0),
- glm::vec3(0.0, 0.0, 1.0));
+ shadowProj *
+ lookAt(pos_, pos_ + glm::vec3(0.0, 1.0, 0.0), glm::vec3(0.0, 0.0, 1.0));
shadowTransforms[3] =
- shadowProj * glm::lookAt(pos_, pos_ + glm::vec3(0.0, -1.0, 0.0),
- glm::vec3(0.0, 0.0, -1.0));
+ shadowProj *
+ lookAt(pos_, pos_ + glm::vec3(0.0, -1.0, 0.0), glm::vec3(0.0, 0.0, -1.0));
shadowTransforms[4] =
- shadowProj * glm::lookAt(pos_, pos_ + glm::vec3(0.0, 0.0, 1.0),
- glm::vec3(0.0, -1.0, 0.0));
+ shadowProj *
+ lookAt(pos_, pos_ + glm::vec3(0.0, 0.0, 1.0), glm::vec3(0.0, -1.0, 0.0));
shadowTransforms[5] =
- shadowProj * glm::lookAt(pos_, pos_ + glm::vec3(0.0, 0.0, -1.0),
- glm::vec3(0.0, -1.0, 0.0));
+ shadowProj *
+ 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());
- shadow_.CopyDataToUniform(6, shadowTransforms.data(), "shadowMatrices");
- shadow_.CopyDataToUniform(pos_, "lightPos");
- shadow_.CopyDataToUniform(kFarPlane, "farPlane");
+ 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;
+ }
for (const auto renderable : renderables) {
renderable->Render(&shadow_);
diff --git a/src/point_light.h b/src/point_light.in.h
similarity index 64%
rename from src/point_light.h
rename to src/point_light.in.h
index b570293..d04de69 100644
--- a/src/point_light.h
+++ b/src/point_light.in.h
@@ -8,21 +8,21 @@
#include "renderable.h"
#include "shader.h"
-class PointLight : public Renderable {
+class PointLight final : public Renderable {
public:
explicit PointLight(const glm::vec3 &);
- ~PointLight();
+ ~PointLight() override;
- void LoadData(Shader *) const;
+ void LoadData(const Shader *) const;
void GenerateCubeMaps(const std::vector &) const;
- inline GLuint getDepthTexture() const { return depth_; }
- inline void setPosition(const glm::vec3 &pos) {
+ GLuint getDepthTexture() const { return depth_; }
+ void setPosition(const glm::vec3 &pos) {
pos_ = pos;
CleanUp();
InitGeom();
}
- inline void setColors(const glm::vec3 &color) {
+ void setColors(const glm::vec3 &color) {
diffuse_ = color;
specular_ = color;
ambient_ = color / 5.0f;
@@ -37,7 +37,7 @@ class PointLight : public Renderable {
float specularPower_{20};
glm::vec3 pos_;
- Shader shadow_{"shadow.vert", "shadow.frag", "shadow.geom"};
+ Shader shadow_{R"(@SHADOW_VERT@)", R"(@SHADOW_FRAG@)", R"(@SHADOW_GEOM@)"};
GLuint fbo_{0};
GLuint depth_{0};
};
diff --git a/src/renderable.cpp b/src/renderable.cpp
index bd8b8b3..309a7cd 100644
--- a/src/renderable.cpp
+++ b/src/renderable.cpp
@@ -4,7 +4,8 @@
using namespace std;
-Renderable::Renderable(bool drawTriangles) : drawTriangles_(drawTriangles) {}
+Renderable::Renderable(const bool drawTriangles)
+ : drawTriangles_(drawTriangles) {}
Renderable::~Renderable() { CleanUp(); }
@@ -30,7 +31,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_);
@@ -39,19 +40,21 @@ 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),
- (void *)offsetof(Vertex, position));
+ glVertexAttribPointer(
+ attribLoc, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
+ // ReSharper disable once CppZeroValuedExpressionUsedAsNullPointer
+ reinterpret_cast(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),
- (void *)offsetof(Vertex, normal));
+ reinterpret_cast(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 9e0ecc8..e5eb336 100644
--- a/src/renderable.h
+++ b/src/renderable.h
@@ -2,7 +2,6 @@
#include
-#include
#include
#include
@@ -11,7 +10,7 @@
class Renderable {
public:
explicit Renderable(bool);
- ~Renderable();
+ virtual ~Renderable();
void InitGeom();
void Render(const Shader *) const;
diff --git a/src/renderer.h b/src/renderer.h
index de790a5..b68420f 100644
--- a/src/renderer.h
+++ b/src/renderer.h
@@ -3,9 +3,7 @@
#include
#include "camera.h"
-#include "constants.h"
-#include "geography.h"
-#include "point_light.h"
+#include "point_light.in.h"
#include "shader.h"
constexpr auto kInitialWidth = 1280;
diff --git a/src/renderer.cpp b/src/renderer.in.cpp
similarity index 93%
rename from src/renderer.cpp
rename to src/renderer.in.cpp
index 15be99a..92b35c7 100644
--- a/src/renderer.cpp
+++ b/src/renderer.in.cpp
@@ -7,6 +7,8 @@
#include
#include "constants.h"
+#include "geography.h"
+#include "grid.h"
using namespace std;
@@ -41,7 +43,7 @@ Renderer::Renderer(int argc, char *argv[]) {
glutPassiveMotionFunc(PassiveMotionCB);
CheckGLError();
- GLenum res = glewInit();
+ const GLenum res = glewInit();
if (res != GLEW_OK) {
cerr << "Error in glewInit()";
throw runtime_error(
@@ -49,21 +51,26 @@ Renderer::Renderer(int argc, char *argv[]) {
}
CheckGLError();
- shader_ = new Shader("phong.vert", "phong.frag");
+ shader_ = new Shader(R"(
+@PHONG_VERT@
+)",
+ R"(
+@PHONG_FRAG@
+)");
light_ = new PointLight({kGeographyShort * kGeographyCountShort / 2,
kGeographyLong * kGeographyCountLong / 2,
kHeightMultiplier * kGeographyCountShort / 2});
using std::chrono::duration_cast;
using std::chrono::milliseconds;
- auto start_time = chrono::high_resolution_clock::now();
+ const 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));
}
}
- auto end_time = chrono::high_resolution_clock::now();
+ const auto end_time = chrono::high_resolution_clock::now();
cout << "Generation time: "
<< duration_cast(end_time - start_time).count() << "ms\n";
cout << " vertices: "
@@ -118,11 +125,11 @@ void Renderer::Display() const {
for (const auto object : objects_) {
const auto geo = dynamic_cast(object);
if (geo != nullptr) {
- float min = geo->min();
+ const float min = geo->min();
if (min < minHeight) {
minHeight = min;
}
- float max = geo->max();
+ const float max = geo->max();
if (max > maxHeight) {
maxHeight = max;
}
@@ -137,7 +144,7 @@ void Renderer::Display() const {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, light_->getDepthTexture());
- auto depthMap = glGetUniformLocation(shader_->id(), "depthMap");
+ const auto depthMap = glGetUniformLocation(shader_->id(), "depthMap");
glUniform1i(depthMap, 0);
light_->Render(shader_);
@@ -255,7 +262,7 @@ void Renderer::HandleMovementKey(const unsigned char key, const bool down) {
}
}
-void Renderer::Tick(int ticks) {
+void Renderer::Tick(const int ticks) {
bool doneSomething = false;
if (last_mouse_x_ < 0 || last_mouse_x_ > viewport_width_ ||
last_mouse_y_ < 0 || last_mouse_y_ > viewport_height_) {
@@ -290,11 +297,11 @@ void Renderer::Tick(int ticks) {
doneSomething = true;
shadowsChanged_ = true;
} else if (simulating_) {
- auto lightAngle =
+ const auto lightAngle =
fmod(static_cast(ticks) * glm::two_pi() / (kFPS * 20),
glm::pi() * 5 / 4) -
glm::pi() * 5 / 8;
- auto lightRotation =
+ const auto lightRotation =
glm::vec3(0, glm::sin(lightAngle), glm::cos(lightAngle) / 2) *
static_cast(kGeographyLong * kGeographyCountLong);
light_->setPosition(lightRotation +
@@ -335,9 +342,8 @@ void Renderer::PassiveMotionCB(const int w, const int h) {
}
void Renderer::TimerCB(const int ticks) {
- auto tickIncrement = window->simulating_ ? 1 : 0;
- glutTimerFunc(static_cast(1000 / kFPS), TimerCB,
- ticks + tickIncrement);
+ const auto tickIncrement = window->simulating_ ? 1 : 0;
+ glutTimerFunc(1000 / kFPS, TimerCB, ticks + tickIncrement);
window->Tick(ticks);
}
@@ -347,7 +353,7 @@ void Renderer::CheckGLError() {
}
}
-void Renderer::PrintOpenGLError(GLenum errorCode) {
+void Renderer::PrintOpenGLError(const GLenum errorCode) {
switch (errorCode) {
case GL_INVALID_VALUE:
cerr << "GL_INVALID_VALUE" << endl;
diff --git a/src/shader.cpp b/src/shader.cpp
index 2fbd541..1a3d507 100644
--- a/src/shader.cpp
+++ b/src/shader.cpp
@@ -8,11 +8,12 @@
using namespace std;
-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;
+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};
id_ = glCreateProgram();
@@ -21,8 +22,8 @@ Shader::Shader(const string &vertexShaderFile, const string &fragmentShaderFile,
glAttachShader(id_, fragmentShaderId);
CheckGLError("Error in attaching the fragment shader");
- if (!geometryShaderFile.empty()) {
- geometryShaderId = CompileShader(geometryShaderFile, GL_GEOMETRY_SHADER);
+ if (!geometryShader.empty()) {
+ geometryShaderId = CompileShader(geometryShader, GL_GEOMETRY_SHADER);
glAttachShader(id_, geometryShaderId);
CheckGLError("Error in attaching the geometry shader");
}
@@ -33,7 +34,7 @@ Shader::Shader(const string &vertexShaderFile, const string &fragmentShaderFile,
glDeleteShader(vertexShaderId);
glDeleteShader(fragmentShaderId);
- if (!geometryShaderFile.empty()) {
+ if (geometryShaderId != 0) {
glDeleteShader(geometryShaderId);
}
@@ -45,7 +46,7 @@ Shader::~Shader() { glDeleteProgram(id_); }
bool Shader::CopyDataToUniform(const glm::mat4 &data,
const string &name) const {
- auto location = glGetUniformLocation(id_, name.c_str());
+ const auto location = glGetUniformLocation(id_, name.c_str());
if (location == -1) {
return false;
}
@@ -54,8 +55,9 @@ bool Shader::CopyDataToUniform(const glm::mat4 &data,
return true;
}
-bool Shader::CopyDataToUniform(int count, const glm::mat4 *data, const std::string &name) const {
- auto location = glGetUniformLocation(id_, name.c_str());
+bool Shader::CopyDataToUniform(const int count, const glm::mat4 *data,
+ const std::string &name) const {
+ const auto location = glGetUniformLocation(id_, name.c_str());
if (location == -1) {
return false;
}
@@ -66,7 +68,7 @@ bool Shader::CopyDataToUniform(int count, const glm::mat4 *data, const std::stri
bool Shader::CopyDataToUniform(const glm::vec4 &data,
const string &name) const {
- auto location = glGetUniformLocation(id_, name.c_str());
+ const auto location = glGetUniformLocation(id_, name.c_str());
if (location == -1) {
return false;
}
@@ -76,7 +78,7 @@ bool Shader::CopyDataToUniform(const glm::vec4 &data,
bool Shader::CopyDataToUniform(const glm::vec3 &data,
const string &name) const {
- auto location = glGetUniformLocation(id_, name.c_str());
+ const auto location = glGetUniformLocation(id_, name.c_str());
if (location == -1) {
return false;
}
@@ -84,8 +86,8 @@ bool Shader::CopyDataToUniform(const glm::vec3 &data,
return true;
}
-bool Shader::CopyDataToUniform(float data, const string &name) const {
- auto location = glGetUniformLocation(id_, name.c_str());
+bool Shader::CopyDataToUniform(const float data, const string &name) const {
+ const auto location = glGetUniformLocation(id_, name.c_str());
if (location == -1) {
return false;
}
@@ -93,8 +95,8 @@ bool Shader::CopyDataToUniform(float data, const string &name) const {
return true;
}
-bool Shader::CopyDataToUniform(int data, const string &name) const {
- auto location = glGetUniformLocation(id_, name.c_str());
+bool Shader::CopyDataToUniform(const int data, const string &name) const {
+ const auto location = glGetUniformLocation(id_, name.c_str());
if (location == -1) {
return false;
}
@@ -102,42 +104,24 @@ bool Shader::CopyDataToUniform(int data, const string &name) const {
return true;
}
-bool Shader::CopyDataToUniform(bool data, const string &name) const {
- auto location = glGetUniformLocation(id_, name.c_str());
+bool Shader::CopyDataToUniform(const bool data, const string &name) const {
+ const auto location = glGetUniformLocation(id_, name.c_str());
if (location == -1) {
return false;
}
- int actualData = static_cast(data);
+ const int actualData = data;
glUniform1iv(location, 1, &actualData);
return true;
}
-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();
+GLuint Shader::CompileShader(const std::string &shaderSource,
+ const GLenum shaderType) {
+ const GLuint id = glCreateShader(shaderType);
+ const auto shaderC_str = shaderSource.c_str();
glShaderSource(id, 1, &shaderC_str, nullptr);
glCompileShader(id);
CheckShaderivError(id, GL_COMPILE_STATUS,
- "Error when creating shader file " + filename);
+ "Error when compiling shader file:\n" + shaderSource);
return id;
}
@@ -174,7 +158,7 @@ void Shader::PrintStatus() const {
glGetProgramiv(id_, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &bufSize);
GLint size;
GLenum type;
- auto attributeName = new GLchar[bufSize];
+ const 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";
@@ -197,7 +181,7 @@ void Shader::PrintStatus() const {
}
void Shader::CheckGLError(const string &errorMessage) {
- auto rc = glGetError();
+ const auto rc = glGetError();
if (rc != GL_NO_ERROR) {
cerr << errorMessage << endl;
throw runtime_error(reinterpret_cast(gluErrorString(rc)));
@@ -212,7 +196,7 @@ void Shader::CheckProgramivError(const GLuint program, const GLenum pname,
cerr << errorMessage << endl;
GLsizei length, bufSize;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufSize);
- auto error = new GLchar[bufSize];
+ const auto error = new GLchar[bufSize];
glGetProgramInfoLog(program, bufSize, &length, error);
throw runtime_error(error);
}
@@ -226,7 +210,7 @@ void Shader::CheckShaderivError(const GLuint shader, const GLenum pname,
cerr << errorMessage << endl;
GLsizei length, bufSize;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &bufSize);
- auto error = new GLchar[bufSize];
+ const 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 22e6577..49554c0 100644
--- a/src/shader.h
+++ b/src/shader.h
@@ -2,7 +2,6 @@
#include
-#include
#include
#include
@@ -26,12 +25,11 @@ class Shader {
void PrintStatus() const;
- inline GLuint id() const { return id_; }
+ 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 &);