Improve code based on CLion recommendations

This commit is contained in:
Michael Bradley 2025-01-01 20:13:10 +13:00
parent 4fe969e7dd
commit 440b666a56
Signed by: MichaelBradley
SSH key fingerprint: SHA256:cj/YZ5VT+QOKncqSkx+ibKTIn0Obg7OIzwzl9BL8EO8
16 changed files with 151 additions and 147 deletions

View file

@ -5,9 +5,9 @@
using namespace std; using namespace std;
void Camera::LoadMatrices(Shader *shader) const { void Camera::LoadMatrices(const Shader *shader) const {
const auto viewMatrix = const auto viewMatrix =
glm::lookAt(position_, position_ + look_vector(), up_vector()); lookAt(position_, position_ + look_vector(), up_vector());
if (!shader->CopyDataToUniform(viewMatrix, "view")) { if (!shader->CopyDataToUniform(viewMatrix, "view")) {
cerr << "View matrix not in shader" << endl; cerr << "View matrix not in shader" << endl;
} }
@ -22,5 +22,7 @@ void Camera::LoadMatrices(Shader *shader) const {
cerr << "Camera position not in shader" << endl; cerr << "Camera position not in shader" << endl;
} }
shader->CopyDataToUniform(kFarPlane, "farPlane"); if (!shader->CopyDataToUniform(kFarPlane, "farPlane")) {
cerr << "Far plane not in shader" << endl;
}
} }

View file

@ -1,6 +1,5 @@
#pragma once #pragma once
#include <glm/ext/matrix_transform.hpp>
#include <glm/gtc/constants.hpp> #include <glm/gtc/constants.hpp>
#define GLM_ENABLE_EXPERIMENTAL #define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/rotate_vector.hpp> #include <glm/gtx/rotate_vector.hpp>
@ -14,33 +13,29 @@ class Camera {
set_aspect(width, height); set_aspect(width, height);
} }
void LoadMatrices(Shader *shader) const; void LoadMatrices(const Shader *shader) const;
inline void RelativeRotate(const glm::vec3 amount) { rotation_ += amount; } void RelativeRotate(const glm::vec3 amount) { rotation_ += amount; }
inline void RelativeMove(const glm::vec3 amount) { void RelativeMove(const glm::vec3 amount) {
position_ += amount.x * look_vector() + amount.y * normal_vector() + position_ += amount.x * look_vector() + amount.y * normal_vector() +
amount.z * up_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<float>(width) / static_cast<float>(height); aspect_ = static_cast<float>(width) / static_cast<float>(height);
} }
inline const glm::vec3 &getPosition() const { return position_; } const glm::vec3 &getPosition() const { return position_; }
private: private:
inline glm::vec3 look_vector() const { glm::vec3 look_vector() const {
return glm::rotateZ(glm::rotateY(glm::vec3(1., 0., 0.), rotation_.y), return rotateZ(rotateY(glm::vec3(1., 0., 0.), rotation_.y), rotation_.z);
rotation_.z);
} }
inline glm::vec3 up_vector() const { glm::vec3 up_vector() const {
return glm::rotateZ(glm::rotateY(glm::vec3(0., 0., 1.), rotation_.y), return rotateZ(rotateY(glm::vec3(0., 0., 1.), rotation_.y), rotation_.z);
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, glm::vec3 position_{kGeographyShort / 2,
kGeographyLong *kGeographyCountLong / 2, kGeographyLong *kGeographyCountLong / 2,

View file

@ -5,7 +5,7 @@
using namespace std; using namespace std;
int main(int argc, char *argv[]) { int main(const int argc, char *argv[]) {
try { try {
Renderer(argc, argv); Renderer(argc, argv);
} catch (const runtime_error &error) { } catch (const runtime_error &error) {

View file

@ -9,9 +9,10 @@
using namespace std; 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); Randomize(false);
model_ = glm::translate( model_ = translate(
glm::identity<glm::mat4>(), glm::identity<glm::mat4>(),
glm::vec3(x * (kGeographyShort - 1), y * (kGeographyLong - 1), 0)); 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 // Sums Perlin noise on a variety of factors, then stores the result in results
// Note: Frees factors // Note: Frees factors
void CalculatePerlinNoise(queue<Grid *> *results, int x, int y, void CalculatePerlinNoise(queue<Grid *> *results, const int x, const int y,
vector<size_t> *factors) { vector<size_t> *factors) {
auto grid = new Grid(); const auto grid = new Grid();
for (const auto factor : *factors) { for (const auto factor : *factors) {
const auto noise = Grid::PerlinNoise(x, y, kDetail >> factor); const auto noise = Grid::PerlinNoise(x, y, kDetail >> factor);
(*grid) += (*noise) / static_cast<float>(1 << factor); *grid += *noise / static_cast<float>(1 << factor);
delete noise; delete noise;
} }
results->push(grid); results->push(grid);
delete factors; delete factors;
} }
void Geography::Randomize(bool load) { void Geography::Randomize(const bool load) {
if (load) { if (load) {
CleanUp(); CleanUp();
} }
@ -43,7 +44,7 @@ void Geography::Randomize(bool load) {
// Set up one thread for each noise scale // Set up one thread for each noise scale
for (size_t i = 0; i < kMaxThreads; ++i) { for (size_t i = 0; i < kMaxThreads; ++i) {
auto factors = new vector<size_t>(); auto factors = new vector<size_t>();
for (size_t factor = 0; (kDetail >> factor) > kMinDetail; for (size_t factor = 0; kDetail >> factor > kMinDetail;
factor += kMaxThreads) { factor += kMaxThreads) {
factors->push_back(factor + i); factors->push_back(factor + i);
} }
@ -58,7 +59,7 @@ void Geography::Randomize(bool load) {
// Add up all noise levels // Add up all noise levels
while (!results.empty()) { while (!results.empty()) {
auto grid = results.front(); const auto grid = results.front();
height_ += *grid; height_ += *grid;
delete grid; delete grid;
results.pop(); results.pop();

View file

@ -1,19 +1,17 @@
#pragma once #pragma once
#include <GL/glew.h>
#include "grid.h" #include "grid.h"
#include "renderable.h" #include "renderable.h"
class Geography : public Renderable { class Geography final : public Renderable {
public: public:
Geography(int x, int y); Geography(int x, int y);
~Geography(); ~Geography() override;
void Randomize(bool); void Randomize(bool);
inline float min() const { return height_.min(); } float min() const { return height_.min(); }
inline float max() const { return height_.max(); } float max() const { return height_.max(); }
protected: protected:
void SetData() override; void SetData() override;

View file

@ -20,7 +20,7 @@ Grid Grid::operator+(const Grid &other) const {
return result; return result;
} }
void Grid::operator+=(const Grid &other) { void Grid::operator+=(const Grid &other) const {
for (size_t i = 0; i < data_->size(); ++i) { for (size_t i = 0; i < data_->size(); ++i) {
(*data_)[i] += (*other.data_)[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); } 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 Grid::operator*(const float val) const {
Grid result; Grid result;
@ -40,7 +40,7 @@ Grid Grid::operator*(const float val) const {
return result; return result;
} }
void Grid::operator*=(const float val) { void Grid::operator*=(const float val) const {
for (size_t i = 0; i < data_->size(); ++i) { for (size_t i = 0; i < data_->size(); ++i) {
(*data_)[i] *= val; (*data_)[i] *= val;
} }
@ -48,7 +48,7 @@ void Grid::operator*=(const float val) {
Grid Grid::operator/(const float val) const { return operator*(1 / 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, glm::vec3 Grid::normal_at(const size_t x, const size_t y,
const float amplification) const { 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 = const auto y_diff =
glm::vec3(0, static_cast<float>(high_y - low_y), glm::vec3(0, static_cast<float>(high_y - low_y),
amplification * (get(x, high_y) - get(x, 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 // Implementation based on: https://en.wikipedia.org/wiki/Perlin_noise
// Assumes that kGeographyShort and kGeographyLong are equal to 2^n (doesn't // Assumes that kGeographyShort and kGeographyLong are equal to 2^n (doesn't
// have to be the same n) // have to be the same n)
Grid *Grid::PerlinNoise(int globalX, int globalY, std::size_t detail) { Grid *Grid::PerlinNoise(const int globalX, const int globalY,
auto grid = new Grid(); const std::size_t detail) {
const auto grid = new Grid();
// Store the vectors at grid corners as just angles, they're all normalised // 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_width = kGeographyShort / detail + 1;
const size_t major_length = (kGeographyLong / detail) + 1; const size_t major_length = kGeographyLong / detail + 1;
const size_t grid_nodes = major_width * major_length; const size_t grid_nodes = major_width * major_length;
vector<float> sin_major_angles(grid_nodes); vector<float> sin_major_angles(grid_nodes);
vector<float> cos_major_angles(grid_nodes); vector<float> cos_major_angles(grid_nodes);
auto worldIndexX = (major_width - 1) * globalX; const auto worldIndexX = (major_width - 1) * globalX;
auto worldIndexY = ((major_width - 1) * kGeographyCountShort + 1) * const auto worldIndexY = ((major_width - 1) * kGeographyCountShort + 1) *
(major_length - 1) * globalY; (major_length - 1) * globalY;
auto worldIndex = worldIndexX + worldIndexY; const auto worldIndex = worldIndexX + worldIndexY;
mt19937::result_type gridBaseSeed = base_random_ * detail + worldIndex; const mt19937::result_type gridBaseSeed = base_random_ * detail + worldIndex;
// Randomly generates corner vector angles [0, 2pi) // Randomly generates corner vector angles [0, 2pi)
for (size_t x = 0; x < major_width; ++x) { for (size_t x = 0; x < major_width; ++x) {
for (size_t y = 0; y < major_width; ++y) { for (size_t y = 0; y < major_width; ++y) {
auto relativeWorldIndex = const auto relativeWorldIndex =
x + ((major_width - 1) * kGeographyCountShort + 1) * y; x + ((major_width - 1) * kGeographyCountShort + 1) * y;
grid->AngleSeed(gridBaseSeed + relativeWorldIndex); grid->AngleSeed(gridBaseSeed + relativeWorldIndex);
auto angle = grid->RandomAngle(); const auto angle = grid->RandomAngle();
auto i = x + major_width * y; const auto i = x + major_width * y;
sin_major_angles[i] = sin(angle); sin_major_angles[i] = sin(angle);
cos_major_angles[i] = cos(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 // 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 // point with one of the four grid vectors around the current point
const auto dot_major = [=, &cos_major_angles, &sin_major_angles]( 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_x = lower_major_x + (high_x ? 1 : 0);
const auto major_y = lower_major_y + (high_y ? 1 : 0); const auto major_y = lower_major_y + (high_y ? 1 : 0);
const auto sin_major_angle = const auto sin_major_angle =
@ -147,12 +149,12 @@ Grid *Grid::PerlinNoise(int globalX, int globalY, std::size_t detail) {
} }
array<Vertex, kTotalVertices> *Grid::vertices() const { array<Vertex, kTotalVertices> *Grid::vertices() const {
auto vertices = new array<Vertex, kTotalVertices>(); const auto vertices = new array<Vertex, kTotalVertices>();
for (size_t x = 0; x < kGeographyShort; ++x) { for (size_t x = 0; x < kGeographyShort; ++x) {
for (size_t y = 0; y < kGeographyLong; ++y) { for (size_t y = 0; y < kGeographyLong; ++y) {
auto ind = index(x, y); const auto ind = index(x, y);
glm::vec3 position = {x, y, (*data_)[ind]}; const glm::vec3 position = {x, y, (*data_)[ind]};
glm::vec3 normal = normal_at(x, y); const glm::vec3 normal = normal_at(x, y);
(*vertices)[ind] = {position, normal}; (*vertices)[ind] = {position, normal};
} }
} }
@ -160,10 +162,10 @@ array<Vertex, kTotalVertices> *Grid::vertices() const {
} }
array<unsigned int, kTotalIndices> *Grid::indices() { array<unsigned int, kTotalIndices> *Grid::indices() {
auto indices = new array<unsigned int, kTotalIndices>(); const auto indices = new array<unsigned int, kTotalIndices>();
for (size_t x = 0; x < kGeographyShort - 1; ++x) { for (size_t x = 0; x < kGeographyShort - 1; ++x) {
for (size_t y = 0; y < kGeographyLong - 1; ++y) { 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<int>(index(x, y)); (*indices)[indexInd] = static_cast<int>(index(x, y));
(*indices)[indexInd + 1] = static_cast<int>(index(x, y + 1)); (*indices)[indexInd + 1] = static_cast<int>(index(x, y + 1));
(*indices)[indexInd + 2] = static_cast<int>(index(x + 1, y)); (*indices)[indexInd + 2] = static_cast<int>(index(x + 1, y));

View file

@ -9,7 +9,6 @@
#include <random> #include <random>
#include "constants.h" #include "constants.h"
#include "noise_math.h"
#include "shader.h" #include "shader.h"
constexpr std::size_t index(const std::size_t x, const std::size_t y) { 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 { class Grid {
public: 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)]; 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; (*data_)[index(x, y)] = value;
} }
Grid operator+(const Grid &) const; Grid operator+(const Grid &) const;
void operator+=(const Grid &); void operator+=(const Grid &) const;
Grid operator-() const; Grid operator-() const;
Grid operator-(const Grid &) const; Grid operator-(const Grid &) const;
void operator-=(const Grid &); void operator-=(const Grid &) const;
Grid operator*(float) const; Grid operator*(float) const;
void operator*=(float); void operator*=(float) const;
Grid 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; glm::vec3 normal_at(std::size_t, std::size_t, float = 1.) const;
@ -41,14 +40,10 @@ class Grid {
std::array<Vertex, kTotalVertices> *vertices() const; std::array<Vertex, kTotalVertices> *vertices() const;
static std::array<unsigned int, kTotalIndices> *indices(); static std::array<unsigned int, kTotalIndices> *indices();
static inline void RandomizeBase() { base_random_ = device_() << 4; } static void RandomizeBase() { base_random_ = device_() << 4; }
inline float min() const { float min() const { return *std::min_element(data_->begin(), data_->end()); }
return *std::min_element(data_->begin(), data_->end()); float max() const { return *std::max_element(data_->begin(), data_->end()); }
}
inline float max() const {
return *std::max_element(data_->begin(), data_->end());
}
private: private:
std::unique_ptr<std::array<float, kGeographyShort * kGeographyLong>> data_{ std::unique_ptr<std::array<float, kGeographyShort * kGeographyLong>> data_{
@ -59,6 +54,6 @@ class Grid {
std::uniform_real_distribution<float> dist_{0, glm::two_pi<float>()}; std::uniform_real_distribution<float> dist_{0, glm::two_pi<float>()};
static std::mt19937::result_type base_random_; static std::mt19937::result_type base_random_;
inline float RandomAngle() { return dist_(engine_); } float RandomAngle() { return dist_(engine_); }
inline void AngleSeed(std::mt19937::result_type seed) { engine_.seed(seed); } void AngleSeed(const std::mt19937::result_type seed) { engine_.seed(seed); }
}; };

View file

@ -3,7 +3,7 @@
// Based on Ken Perlin's smoother step function: // Based on Ken Perlin's smoother step function:
// https://en.wikipedia.org/wiki/Smoothstep#Variations Returns value in range // https://en.wikipedia.org/wiki/Smoothstep#Variations Returns value in range
// [0, 1] // [0, 1]
inline constexpr float SmootherStep(const float x) { constexpr float SmootherStep(const float x) {
if (x < 0) { if (x < 0) {
return 0; return 0;
} }
@ -17,7 +17,7 @@ inline constexpr float SmootherStep(const float x) {
// Interpolates between two doubles // Interpolates between two doubles
// If x <= 0 returns bound_0, if x >= 1 returns bound_1, // If x <= 0 returns bound_0, if x >= 1 returns bound_1,
// otherwise smoothly transitions between the two // 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) { const float bound_1) {
return bound_0 + SmootherStep(x) * (bound_1 - bound_0); return bound_0 + SmootherStep(x) * (bound_1 - bound_0);
} }

View file

@ -1,5 +1,6 @@
#include "point_light.h" #include "point_light.h"
#include <array>
#include <glm/ext/matrix_clip_space.hpp> #include <glm/ext/matrix_clip_space.hpp>
#include <glm/ext/matrix_transform.hpp> #include <glm/ext/matrix_transform.hpp>
#include <iostream> #include <iostream>
@ -47,7 +48,7 @@ PointLight::~PointLight() {
glDeleteFramebuffers(1, &fbo_); glDeleteFramebuffers(1, &fbo_);
} }
void PointLight::LoadData(Shader *shader) const { void PointLight::LoadData(const Shader *shader) const {
if (!shader->CopyDataToUniform(ambient_, "pointLight.ambient")) { if (!shader->CopyDataToUniform(ambient_, "pointLight.ambient")) {
cerr << "Point light ambient not loaded to shader" << endl; cerr << "Point light ambient not loaded to shader" << endl;
} }
@ -71,37 +72,44 @@ void PointLight::GenerateCubeMaps(
// https://learnopengl.com/Advanced-Lighting/Shadows/Point-Shadows // https://learnopengl.com/Advanced-Lighting/Shadows/Point-Shadows
// By Joey de Vries (https://twitter.com/JoeyDeVriez) // By Joey de Vries (https://twitter.com/JoeyDeVriez)
// CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/legalcode) // CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/legalcode)
auto shadowProj = const auto shadowProj =
glm::perspective(glm::pi<float>() / 2, 1.0f, kNearPlane, kFarPlane); glm::perspective(glm::pi<float>() / 2, 1.0f, kNearPlane, kFarPlane);
auto shadowTransforms = array<glm::mat4, 6>(); auto shadowTransforms = array<glm::mat4, 6>();
shadowTransforms[0] = shadowTransforms[0] =
shadowProj * glm::lookAt(pos_, pos_ + glm::vec3(1.0, 0.0, 0.0), shadowProj *
glm::vec3(0.0, -1.0, 0.0)); lookAt(pos_, pos_ + glm::vec3(1.0, 0.0, 0.0), glm::vec3(0.0, -1.0, 0.0));
shadowTransforms[1] = shadowTransforms[1] =
shadowProj * glm::lookAt(pos_, pos_ + glm::vec3(-1.0, 0.0, 0.0), shadowProj *
glm::vec3(0.0, -1.0, 0.0)); lookAt(pos_, pos_ + glm::vec3(-1.0, 0.0, 0.0), glm::vec3(0.0, -1.0, 0.0));
shadowTransforms[2] = shadowTransforms[2] =
shadowProj * glm::lookAt(pos_, pos_ + glm::vec3(0.0, 1.0, 0.0), shadowProj *
glm::vec3(0.0, 0.0, 1.0)); lookAt(pos_, pos_ + glm::vec3(0.0, 1.0, 0.0), glm::vec3(0.0, 0.0, 1.0));
shadowTransforms[3] = shadowTransforms[3] =
shadowProj * glm::lookAt(pos_, pos_ + glm::vec3(0.0, -1.0, 0.0), shadowProj *
glm::vec3(0.0, 0.0, -1.0)); lookAt(pos_, pos_ + glm::vec3(0.0, -1.0, 0.0), glm::vec3(0.0, 0.0, -1.0));
shadowTransforms[4] = shadowTransforms[4] =
shadowProj * glm::lookAt(pos_, pos_ + glm::vec3(0.0, 0.0, 1.0), shadowProj *
glm::vec3(0.0, -1.0, 0.0)); lookAt(pos_, pos_ + glm::vec3(0.0, 0.0, 1.0), glm::vec3(0.0, -1.0, 0.0));
shadowTransforms[5] = shadowTransforms[5] =
shadowProj * glm::lookAt(pos_, pos_ + glm::vec3(0.0, 0.0, -1.0), shadowProj *
glm::vec3(0.0, -1.0, 0.0)); lookAt(pos_, pos_ + glm::vec3(0.0, 0.0, -1.0), glm::vec3(0.0, -1.0, 0.0));
glViewport(0, 0, kShadowMapSize, kShadowMapSize); glViewport(0, 0, kShadowMapSize, kShadowMapSize);
glBindFramebuffer(GL_FRAMEBUFFER, fbo_); glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
glClear(GL_DEPTH_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT);
glUseProgram(shadow_.id()); glUseProgram(shadow_.id());
shadow_.CopyDataToUniform(6, shadowTransforms.data(), "shadowMatrices"); if (!shadow_.CopyDataToUniform(6, shadowTransforms.data(),
shadow_.CopyDataToUniform(pos_, "lightPos"); "shadowMatrices")) {
shadow_.CopyDataToUniform(kFarPlane, "farPlane"); 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) { for (const auto renderable : renderables) {
renderable->Render(&shadow_); renderable->Render(&shadow_);

View file

@ -8,21 +8,21 @@
#include "renderable.h" #include "renderable.h"
#include "shader.h" #include "shader.h"
class PointLight : public Renderable { class PointLight final : public Renderable {
public: public:
explicit PointLight(const glm::vec3 &); explicit PointLight(const glm::vec3 &);
~PointLight(); ~PointLight() override;
void LoadData(Shader *) const; void LoadData(const Shader *) const;
void GenerateCubeMaps(const std::vector<Renderable *> &) const; void GenerateCubeMaps(const std::vector<Renderable *> &) const;
inline GLuint getDepthTexture() const { return depth_; } GLuint getDepthTexture() const { return depth_; }
inline void setPosition(const glm::vec3 &pos) { void setPosition(const glm::vec3 &pos) {
pos_ = pos; pos_ = pos;
CleanUp(); CleanUp();
InitGeom(); InitGeom();
} }
inline void setColors(const glm::vec3 &color) { void setColors(const glm::vec3 &color) {
diffuse_ = color; diffuse_ = color;
specular_ = color; specular_ = color;
ambient_ = color / 5.0f; ambient_ = color / 5.0f;

View file

@ -4,7 +4,8 @@
using namespace std; using namespace std;
Renderable::Renderable(bool drawTriangles) : drawTriangles_(drawTriangles) {} Renderable::Renderable(const bool drawTriangles)
: drawTriangles_(drawTriangles) {}
Renderable::~Renderable() { CleanUp(); } Renderable::~Renderable() { CleanUp(); }
@ -30,7 +31,7 @@ void Renderable::InitGeom() {
void Renderable::Render(const Shader *const shader) const { void Renderable::Render(const Shader *const shader) const {
if (!shader->CopyDataToUniform(model_, "model")) { if (!shader->CopyDataToUniform(model_, "model")) {
// cerr << "Model matrix not in shader" << endl; cerr << "Model matrix not in shader" << endl;
} }
glBindBuffer(GL_ARRAY_BUFFER, vbo_); glBindBuffer(GL_ARRAY_BUFFER, vbo_);
@ -39,19 +40,21 @@ void Renderable::Render(const Shader *const shader) const {
GLuint attribLoc = glGetAttribLocation(shader->id(), "vtxPos"); GLuint attribLoc = glGetAttribLocation(shader->id(), "vtxPos");
if (attribLoc != -1) { if (attribLoc != -1) {
glEnableVertexAttribArray(attribLoc); glEnableVertexAttribArray(attribLoc);
glVertexAttribPointer(attribLoc, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), glVertexAttribPointer(
(void *)offsetof(Vertex, position)); attribLoc, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
// ReSharper disable once CppZeroValuedExpressionUsedAsNullPointer
reinterpret_cast<void *>(offsetof(Vertex, position)));
} else { } else {
// cerr << "Not loading vtxPos" << endl; cerr << "Not loading vtxPos" << endl;
} }
attribLoc = glGetAttribLocation(shader->id(), "vtxNormal"); attribLoc = glGetAttribLocation(shader->id(), "vtxNormal");
if (attribLoc != -1) { if (attribLoc != -1) {
glEnableVertexAttribArray(attribLoc); glEnableVertexAttribArray(attribLoc);
glVertexAttribPointer(attribLoc, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), glVertexAttribPointer(attribLoc, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
(void *)offsetof(Vertex, normal)); reinterpret_cast<void *>(offsetof(Vertex, normal)));
} else { } else {
// cerr << "Not loading vtxNormal" << endl; cerr << "Not loading vtxNormal" << endl;
} }
if (drawTriangles_) { if (drawTriangles_) {

View file

@ -2,7 +2,6 @@
#include <GL/glew.h> #include <GL/glew.h>
#include <array>
#include <glm/ext/matrix_transform.hpp> #include <glm/ext/matrix_transform.hpp>
#include <glm/glm.hpp> #include <glm/glm.hpp>
@ -11,7 +10,7 @@
class Renderable { class Renderable {
public: public:
explicit Renderable(bool); explicit Renderable(bool);
~Renderable(); virtual ~Renderable();
void InitGeom(); void InitGeom();
void Render(const Shader *) const; void Render(const Shader *) const;

View file

@ -7,6 +7,8 @@
#include <stdexcept> #include <stdexcept>
#include "constants.h" #include "constants.h"
#include "geography.h"
#include "grid.h"
using namespace std; using namespace std;
@ -41,7 +43,7 @@ Renderer::Renderer(int argc, char *argv[]) {
glutPassiveMotionFunc(PassiveMotionCB); glutPassiveMotionFunc(PassiveMotionCB);
CheckGLError(); CheckGLError();
GLenum res = glewInit(); const GLenum res = glewInit();
if (res != GLEW_OK) { if (res != GLEW_OK) {
cerr << "Error in glewInit()"; cerr << "Error in glewInit()";
throw runtime_error( throw runtime_error(
@ -56,14 +58,14 @@ Renderer::Renderer(int argc, char *argv[]) {
using std::chrono::duration_cast; using std::chrono::duration_cast;
using std::chrono::milliseconds; 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 x = 0; x < kGeographyCountShort; ++x) {
for (auto y = 0; y < kGeographyCountLong; ++y) { for (auto y = 0; y < kGeographyCountLong; ++y) {
objects_.push_back(new Geography(x, 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: " cout << "Generation time: "
<< duration_cast<milliseconds>(end_time - start_time).count() << "ms\n"; << duration_cast<milliseconds>(end_time - start_time).count() << "ms\n";
cout << " vertices: " cout << " vertices: "
@ -118,11 +120,11 @@ void Renderer::Display() const {
for (const auto object : objects_) { for (const auto object : objects_) {
const auto geo = dynamic_cast<Geography *>(object); const auto geo = dynamic_cast<Geography *>(object);
if (geo != nullptr) { if (geo != nullptr) {
float min = geo->min(); const float min = geo->min();
if (min < minHeight) { if (min < minHeight) {
minHeight = min; minHeight = min;
} }
float max = geo->max(); const float max = geo->max();
if (max > maxHeight) { if (max > maxHeight) {
maxHeight = max; maxHeight = max;
} }
@ -137,7 +139,7 @@ void Renderer::Display() const {
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, light_->getDepthTexture()); glBindTexture(GL_TEXTURE_CUBE_MAP, light_->getDepthTexture());
auto depthMap = glGetUniformLocation(shader_->id(), "depthMap"); const auto depthMap = glGetUniformLocation(shader_->id(), "depthMap");
glUniform1i(depthMap, 0); glUniform1i(depthMap, 0);
light_->Render(shader_); light_->Render(shader_);
@ -255,7 +257,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; bool doneSomething = false;
if (last_mouse_x_ < 0 || last_mouse_x_ > viewport_width_ || if (last_mouse_x_ < 0 || last_mouse_x_ > viewport_width_ ||
last_mouse_y_ < 0 || last_mouse_y_ > viewport_height_) { last_mouse_y_ < 0 || last_mouse_y_ > viewport_height_) {
@ -290,11 +292,11 @@ void Renderer::Tick(int ticks) {
doneSomething = true; doneSomething = true;
shadowsChanged_ = true; shadowsChanged_ = true;
} else if (simulating_) { } else if (simulating_) {
auto lightAngle = const auto lightAngle =
fmod(static_cast<float>(ticks) * glm::two_pi<float>() / (kFPS * 20), fmod(static_cast<float>(ticks) * glm::two_pi<float>() / (kFPS * 20),
glm::pi<float>() * 5 / 4) - glm::pi<float>() * 5 / 4) -
glm::pi<float>() * 5 / 8; glm::pi<float>() * 5 / 8;
auto lightRotation = const auto lightRotation =
glm::vec3(0, glm::sin(lightAngle), glm::cos(lightAngle) / 2) * glm::vec3(0, glm::sin(lightAngle), glm::cos(lightAngle) / 2) *
static_cast<float>(kGeographyLong * kGeographyCountLong); static_cast<float>(kGeographyLong * kGeographyCountLong);
light_->setPosition(lightRotation + light_->setPosition(lightRotation +
@ -335,9 +337,8 @@ void Renderer::PassiveMotionCB(const int w, const int h) {
} }
void Renderer::TimerCB(const int ticks) { void Renderer::TimerCB(const int ticks) {
auto tickIncrement = window->simulating_ ? 1 : 0; const auto tickIncrement = window->simulating_ ? 1 : 0;
glutTimerFunc(static_cast<unsigned int>(1000 / kFPS), TimerCB, glutTimerFunc(1000 / kFPS, TimerCB, ticks + tickIncrement);
ticks + tickIncrement);
window->Tick(ticks); window->Tick(ticks);
} }
@ -347,7 +348,7 @@ void Renderer::CheckGLError() {
} }
} }
void Renderer::PrintOpenGLError(GLenum errorCode) { void Renderer::PrintOpenGLError(const GLenum errorCode) {
switch (errorCode) { switch (errorCode) {
case GL_INVALID_VALUE: case GL_INVALID_VALUE:
cerr << "GL_INVALID_VALUE" << endl; cerr << "GL_INVALID_VALUE" << endl;

View file

@ -3,8 +3,6 @@
#include <vector> #include <vector>
#include "camera.h" #include "camera.h"
#include "constants.h"
#include "geography.h"
#include "point_light.h" #include "point_light.h"
#include "shader.h" #include "shader.h"

View file

@ -10,9 +10,10 @@ using namespace std;
Shader::Shader(const string &vertexShaderFile, const string &fragmentShaderFile, Shader::Shader(const string &vertexShaderFile, const string &fragmentShaderFile,
const string &geometryShaderFile) { const string &geometryShaderFile) {
auto vertexShaderId = CompileShader(vertexShaderFile, GL_VERTEX_SHADER); const auto vertexShaderId = CompileShader(vertexShaderFile, GL_VERTEX_SHADER);
auto fragmentShaderId = CompileShader(fragmentShaderFile, GL_FRAGMENT_SHADER); const auto fragmentShaderId =
GLuint geometryShaderId; CompileShader(fragmentShaderFile, GL_FRAGMENT_SHADER);
GLuint geometryShaderId{0};
id_ = glCreateProgram(); id_ = glCreateProgram();
@ -45,7 +46,7 @@ Shader::~Shader() { glDeleteProgram(id_); }
bool Shader::CopyDataToUniform(const glm::mat4 &data, bool Shader::CopyDataToUniform(const glm::mat4 &data,
const string &name) const { const string &name) const {
auto location = glGetUniformLocation(id_, name.c_str()); const auto location = glGetUniformLocation(id_, name.c_str());
if (location == -1) { if (location == -1) {
return false; return false;
} }
@ -54,8 +55,9 @@ bool Shader::CopyDataToUniform(const glm::mat4 &data,
return true; return true;
} }
bool Shader::CopyDataToUniform(int count, const glm::mat4 *data, const std::string &name) const { bool Shader::CopyDataToUniform(const int count, const glm::mat4 *data,
auto location = glGetUniformLocation(id_, name.c_str()); const std::string &name) const {
const auto location = glGetUniformLocation(id_, name.c_str());
if (location == -1) { if (location == -1) {
return false; 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, bool Shader::CopyDataToUniform(const glm::vec4 &data,
const string &name) const { const string &name) const {
auto location = glGetUniformLocation(id_, name.c_str()); const auto location = glGetUniformLocation(id_, name.c_str());
if (location == -1) { if (location == -1) {
return false; return false;
} }
@ -76,7 +78,7 @@ bool Shader::CopyDataToUniform(const glm::vec4 &data,
bool Shader::CopyDataToUniform(const glm::vec3 &data, bool Shader::CopyDataToUniform(const glm::vec3 &data,
const string &name) const { const string &name) const {
auto location = glGetUniformLocation(id_, name.c_str()); const auto location = glGetUniformLocation(id_, name.c_str());
if (location == -1) { if (location == -1) {
return false; return false;
} }
@ -84,8 +86,8 @@ bool Shader::CopyDataToUniform(const glm::vec3 &data,
return true; return true;
} }
bool Shader::CopyDataToUniform(float data, const string &name) const { bool Shader::CopyDataToUniform(const float data, const string &name) const {
auto location = glGetUniformLocation(id_, name.c_str()); const auto location = glGetUniformLocation(id_, name.c_str());
if (location == -1) { if (location == -1) {
return false; return false;
} }
@ -93,8 +95,8 @@ bool Shader::CopyDataToUniform(float data, const string &name) const {
return true; return true;
} }
bool Shader::CopyDataToUniform(int data, const string &name) const { bool Shader::CopyDataToUniform(const int data, const string &name) const {
auto location = glGetUniformLocation(id_, name.c_str()); const auto location = glGetUniformLocation(id_, name.c_str());
if (location == -1) { if (location == -1) {
return false; return false;
} }
@ -102,21 +104,22 @@ bool Shader::CopyDataToUniform(int data, const string &name) const {
return true; return true;
} }
bool Shader::CopyDataToUniform(bool data, const string &name) const { bool Shader::CopyDataToUniform(const bool data, const string &name) const {
auto location = glGetUniformLocation(id_, name.c_str()); const auto location = glGetUniformLocation(id_, name.c_str());
if (location == -1) { if (location == -1) {
return false; return false;
} }
int actualData = static_cast<int>(data); const int actualData = data;
glUniform1iv(location, 1, &actualData); glUniform1iv(location, 1, &actualData);
return true; return true;
} }
string Shader::ReadFile(const string &filename) { string Shader::ReadFile(const string &filename) {
string data, line; string data;
ifstream file; ifstream file;
file.open(filename, std::ios::binary); file.open(filename, std::ios::binary);
if (file.is_open()) { if (file.is_open()) {
string line;
while (getline(file, line)) { while (getline(file, line)) {
data += line + '\n'; data += line + '\n';
} }
@ -132,8 +135,8 @@ string Shader::ReadFile(const string &filename) {
GLuint Shader::CompileShader(const std::string &filename, GLuint Shader::CompileShader(const std::string &filename,
const GLenum shader_type) { const GLenum shader_type) {
const GLuint id = glCreateShader(shader_type); const GLuint id = glCreateShader(shader_type);
auto shaderString = ReadFile(filename); const auto shaderString = ReadFile(filename);
auto shaderC_str = shaderString.c_str(); const auto shaderC_str = shaderString.c_str();
glShaderSource(id, 1, &shaderC_str, nullptr); glShaderSource(id, 1, &shaderC_str, nullptr);
glCompileShader(id); glCompileShader(id);
CheckShaderivError(id, GL_COMPILE_STATUS, CheckShaderivError(id, GL_COMPILE_STATUS,
@ -174,7 +177,7 @@ void Shader::PrintStatus() const {
glGetProgramiv(id_, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &bufSize); glGetProgramiv(id_, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &bufSize);
GLint size; GLint size;
GLenum type; GLenum type;
auto attributeName = new GLchar[bufSize]; const auto attributeName = new GLchar[bufSize];
for (int i = 0; i < rc; ++i) { for (int i = 0; i < rc; ++i) {
glGetActiveAttrib(id_, i, bufSize, &length, &size, &type, attributeName); glGetActiveAttrib(id_, i, bufSize, &length, &size, &type, attributeName);
cout << "\t" << attributeName << ": " << type << "\n"; cout << "\t" << attributeName << ": " << type << "\n";
@ -197,7 +200,7 @@ void Shader::PrintStatus() const {
} }
void Shader::CheckGLError(const string &errorMessage) { void Shader::CheckGLError(const string &errorMessage) {
auto rc = glGetError(); const auto rc = glGetError();
if (rc != GL_NO_ERROR) { if (rc != GL_NO_ERROR) {
cerr << errorMessage << endl; cerr << errorMessage << endl;
throw runtime_error(reinterpret_cast<const char *>(gluErrorString(rc))); throw runtime_error(reinterpret_cast<const char *>(gluErrorString(rc)));
@ -212,7 +215,7 @@ void Shader::CheckProgramivError(const GLuint program, const GLenum pname,
cerr << errorMessage << endl; cerr << errorMessage << endl;
GLsizei length, bufSize; GLsizei length, bufSize;
glGetProgramiv(program, GL_INFO_LOG_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); glGetProgramInfoLog(program, bufSize, &length, error);
throw runtime_error(error); throw runtime_error(error);
} }
@ -226,7 +229,7 @@ void Shader::CheckShaderivError(const GLuint shader, const GLenum pname,
cerr << errorMessage << endl; cerr << errorMessage << endl;
GLsizei length, bufSize; GLsizei length, bufSize;
glGetShaderiv(shader, GL_INFO_LOG_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); glGetShaderInfoLog(shader, bufSize, &length, error);
throw runtime_error(error); throw runtime_error(error);
} }

View file

@ -2,7 +2,6 @@
#include <GL/glew.h> #include <GL/glew.h>
#include <array>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <string> #include <string>
@ -26,7 +25,7 @@ class Shader {
void PrintStatus() const; void PrintStatus() const;
inline GLuint id() const { return id_; } GLuint id() const { return id_; }
private: private:
GLuint id_; GLuint id_;