diff options
-rw-r--r-- | game/terrain.cpp | 26 | ||||
-rw-r--r-- | gfx/image.cpp | 20 | ||||
-rw-r--r-- | gfx/image.h | 21 | ||||
-rw-r--r-- | gfx/models/obj_loader.cpp | 7 | ||||
-rw-r--r-- | gfx/models/obj_loader.h | 3 | ||||
-rw-r--r-- | gfx/models/texture.cpp | 15 | ||||
-rw-r--r-- | gfx/models/texture.h | 4 | ||||
-rw-r--r-- | lib/resource.cpp | 16 | ||||
-rw-r--r-- | lib/resource.h | 23 | ||||
-rw-r--r-- | test/Jamfile.jam | 5 | ||||
-rw-r--r-- | test/fixtures/height/V0txo.jpg | bin | 0 -> 38235 bytes |
11 files changed, 108 insertions, 32 deletions
diff --git a/game/terrain.cpp b/game/terrain.cpp index 3e5c187..092374c 100644 --- a/game/terrain.cpp +++ b/game/terrain.cpp @@ -6,14 +6,14 @@ #include <cstddef> #include <gfx/gl/shader.h> #include <gfx/gl/transform.h> +#include <gfx/image.h> #include <gfx/models/vertex.hpp> #include <glm/glm.hpp> #include <random> #include <stb_image.h> -#include <stdexcept> Terrain::Terrain() : - m_vertexArrayObject {}, m_vertexArrayBuffers {}, texture {Texture::cachedTexture.get("res/terrain.png")} + m_vertexArrayObject {}, m_vertexArrayBuffers {}, texture {Texture::cachedTexture.get("terrain.png")} { constexpr auto size {241}; // Vertices constexpr auto offset {(size - 1) / 2}; @@ -65,33 +65,27 @@ Terrain::Terrain() : } Terrain::Terrain(const std::string & fileName) : - m_vertexArrayObject {}, m_vertexArrayBuffers {}, texture {Texture::cachedTexture.get("res/terrain.png")} + m_vertexArrayObject {}, m_vertexArrayBuffers {}, texture {Texture::cachedTexture.get("terrain.png")} { constexpr auto resolution {100}; - int width, height, numComponents; - unsigned char * data = stbi_load((fileName).c_str(), &width, &height, &numComponents, STBI_grey); - - if (!data) { - throw std::runtime_error {"Unable to load heightmap: " + fileName}; - } + const Image map {fileName.c_str(), STBI_grey}; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - vertices.reserve((width * height) + 4); + vertices.reserve((map.width * map.height) + 4); - for (auto z = 0; z < height; z += 1) { - for (auto x = 0; x < width; x += 1) { + for (auto z = 0; z < map.height; z += 1) { + for (auto x = 0; x < map.width; x += 1) { vertices.emplace_back( - glm::vec3 {resolution * (x - (width / 2)), ((float)data[x + (z * width)] * 0.1F) - 1.5F, - resolution * (z - (height / 2))}, + glm::vec3 {resolution * (x - (map.width / 2)), ((float)map.data[x + (z * map.width)] * 0.1F) - 1.5F, + resolution * (z - (map.height / 2))}, glm::vec2 {(x % 2) / 2.01, (z % 2) / 2.01}, glm::vec3 {0, 1, 0}); } } - stbi_image_free(data); - finish(width, height, resolution); + finish(map.width, map.height, resolution); } void diff --git a/gfx/image.cpp b/gfx/image.cpp new file mode 100644 index 0000000..20c862f --- /dev/null +++ b/gfx/image.cpp @@ -0,0 +1,20 @@ +#include "image.h" +#include <cstddef> +#include <stb_image.h> +#include <stdexcept> + +Image::Image(const char * fileName, int flags) : width {}, height {}, numComponents {} +{ + unsigned char * bytes = stbi_load(fileName, &width, &height, &numComponents, flags); + + if (!bytes) { + throw std::runtime_error {std::string {"Unable to load image: "} + fileName}; + } + + data = {bytes, static_cast<size_t>(width * height * numComponents)}; +} + +Image::~Image() +{ + stbi_image_free(data.data()); +} diff --git a/gfx/image.h b/gfx/image.h new file mode 100644 index 0000000..d43737f --- /dev/null +++ b/gfx/image.h @@ -0,0 +1,21 @@ +#ifndef IMAGE_H +#define IMAGE_H + +#include <span> // IWYU pragma: export +#include <special_members.hpp> +#include <string> + +class Image { +public: + Image(const char * fileName, int flags); + Image(const std::string & fileName, int flags) : Image(fileName.c_str(), flags) { } + ~Image(); + + NO_COPY(Image); + NO_MOVE(Image); + + int width, height, numComponents; + std::span<unsigned char> data; +}; + +#endif diff --git a/gfx/models/obj_loader.cpp b/gfx/models/obj_loader.cpp index 7611a2c..75ab251 100644 --- a/gfx/models/obj_loader.cpp +++ b/gfx/models/obj_loader.cpp @@ -3,6 +3,7 @@ #include <fstream> #include <map> #include <memory> +#include <resource.h> #include <stdexcept> #include <utility> @@ -12,12 +13,12 @@ static inline unsigned int ParseOBJIndexValue(const std::string & token, unsigne static inline float ParseOBJFloatValue(const std::string & token, unsigned int start, unsigned int end); static inline std::vector<std::string> SplitString(const std::string & s, char delim); -OBJModel::OBJModel(const std::string & fileName) +OBJModel::OBJModel(const std::filesystem::path & fileName) { hasUVs = false; hasNormals = false; std::ifstream file; - file.open(fileName.c_str()); + file.open(Resource::mapPath(fileName).c_str()); std::string line; if (file.is_open()) { @@ -55,7 +56,7 @@ OBJModel::OBJModel(const std::string & fileName) } } else { - throw std::runtime_error {"Unable to load mesh: " + fileName}; + throw std::runtime_error {"Unable to load mesh: " + fileName.string()}; } } diff --git a/gfx/models/obj_loader.h b/gfx/models/obj_loader.h index 0523a95..2fe3d35 100644 --- a/gfx/models/obj_loader.h +++ b/gfx/models/obj_loader.h @@ -1,6 +1,7 @@ #ifndef OBJ_LOADER_H_INCLUDED #define OBJ_LOADER_H_INCLUDED +#include <filesystem> #include <glm/glm.hpp> #include <string> #include <vector> @@ -36,7 +37,7 @@ public: bool hasUVs; bool hasNormals; - explicit OBJModel(const std::string & fileName); + explicit OBJModel(const std::filesystem::path & fileName); IndexedModel ToIndexedModel(); diff --git a/gfx/models/texture.cpp b/gfx/models/texture.cpp index bc80a1c..342f890 100644 --- a/gfx/models/texture.cpp +++ b/gfx/models/texture.cpp @@ -1,18 +1,14 @@ #include "texture.h"
#include "stb_image.h"
#include <cache.h>
-#include <stdexcept>
+#include <gfx/image.h>
+#include <resource.h>
Cache<Texture> Texture::cachedTexture;
-Texture::Texture(const std::string & fileName) : m_texture {}
+Texture::Texture(const std::filesystem::path & fileName) : m_texture {}
{
- int width, height, numComponents;
- unsigned char * data = stbi_load((fileName).c_str(), &width, &height, &numComponents, STBI_rgb_alpha);
-
- if (!data) {
- throw std::runtime_error {"Unable to load texture: " + fileName};
- }
+ const Image tex {Resource::mapPath(fileName).c_str(), STBI_rgb_alpha};
glGenTextures(1, &m_texture);
glBindTexture(GL_TEXTURE_2D, m_texture);
@@ -22,8 +18,7 @@ Texture::Texture(const std::string & fileName) : m_texture {} glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
- stbi_image_free(data);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width, tex.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex.data.data());
}
Texture::~Texture()
diff --git a/gfx/models/texture.h b/gfx/models/texture.h index 30ba953..8bbba85 100644 --- a/gfx/models/texture.h +++ b/gfx/models/texture.h @@ -2,14 +2,14 @@ #define TEXTURE_H
#include <GL/glew.h>
+#include <filesystem>
#include <special_members.hpp>
-#include <string>
template<typename Obj> class Cache;
class Texture {
public:
- explicit Texture(const std::string & fileName);
+ explicit Texture(const std::filesystem::path & fileName);
virtual ~Texture();
diff --git a/lib/resource.cpp b/lib/resource.cpp new file mode 100644 index 0000000..b9aa4fa --- /dev/null +++ b/lib/resource.cpp @@ -0,0 +1,16 @@ +#include "resource.h" +#include <utility> + +std::filesystem::path base {std::filesystem::current_path() / "res"}; + +void +Resource::setBasePath(std::filesystem::path newbase) +{ + base = std::move(newbase); +} + +std::filesystem::path +Resource::mapPath(const std::filesystem::path & rel) +{ + return std::filesystem::canonical(base / rel); +} diff --git a/lib/resource.h b/lib/resource.h new file mode 100644 index 0000000..958c49d --- /dev/null +++ b/lib/resource.h @@ -0,0 +1,23 @@ +#ifndef RESOURCE_H +#define RESOURCE_H + +#include <filesystem> + +class Resource { +public: + static void setBasePath(std::filesystem::path); + static std::filesystem::path mapPath(const std::filesystem::path &); +}; + +#if defined(RESDIR) && defined(BOOST_TEST_MODULE) +class SetResourcePath { +public: + SetResourcePath() + { + Resource::setBasePath(RESDIR); + } +}; +BOOST_GLOBAL_FIXTURE(SetResourcePath); +#endif + +#endif diff --git a/test/Jamfile.jam b/test/Jamfile.jam index 0dbbc4e..f5d56eb 100644 --- a/test/Jamfile.jam +++ b/test/Jamfile.jam @@ -2,8 +2,13 @@ import testing ; lib boost_unit_test_framework ; +path-constant res : ../res ; +path-constant fixtures : fixtures ; + project : requirements <define>BOOST_TEST_DYN_LINK + <define>RESDIR=\\\"$(res)/\\\" + <define>FIXTURESDIR=\\\"$(fixtures)/\\\" <library>boost_unit_test_framework <library>..//ilt <toolset>tidy:<xcheckxx>hicpp-vararg diff --git a/test/fixtures/height/V0txo.jpg b/test/fixtures/height/V0txo.jpg Binary files differnew file mode 100644 index 0000000..cb4b045 --- /dev/null +++ b/test/fixtures/height/V0txo.jpg |