summaryrefslogtreecommitdiff
path: root/assetFactory
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2023-04-14 18:03:34 +0100
committerDan Goodliffe <dan@randomdan.homeip.net>2023-04-14 18:03:34 +0100
commit5776a36b454fac04617313da011d7aa2b0e834d3 (patch)
tree1eb96d07e9a17a51e5763f397fc003f762cd2e75 /assetFactory
parentMerge branch 'model-factory-textures' (diff)
parentAdd an asset template and use it to define all the foliage assets in the plan... (diff)
downloadilt-5776a36b454fac04617313da011d7aa2b0e834d3.tar.bz2
ilt-5776a36b454fac04617313da011d7aa2b0e834d3.tar.xz
ilt-5776a36b454fac04617313da011d7aa2b0e834d3.zip
Merge branch 'assimp'
Diffstat (limited to 'assetFactory')
-rw-r--r--assetFactory/asset.h4
-rw-r--r--assetFactory/assetFactory.cpp63
-rw-r--r--assetFactory/assetFactory.h8
-rw-r--r--assetFactory/assimp.cpp130
-rw-r--r--assetFactory/assimp.h14
-rw-r--r--assetFactory/factoryMesh.cpp61
-rw-r--r--assetFactory/modelFactoryMesh.cpp1
-rw-r--r--assetFactory/modelFactoryMesh.h2
-rw-r--r--assetFactory/style.cpp9
-rw-r--r--assetFactory/textureFragment.cpp10
-rw-r--r--assetFactory/textureFragment.h6
-rw-r--r--assetFactory/texturePacker.cpp29
-rw-r--r--assetFactory/texturePacker.h1
13 files changed, 271 insertions, 67 deletions
diff --git a/assetFactory/asset.h b/assetFactory/asset.h
index 30f40cd..dba4974 100644
--- a/assetFactory/asset.h
+++ b/assetFactory/asset.h
@@ -4,11 +4,11 @@
#include "persistence.h"
#include <stdTypeDefs.hpp>
-class Texture;
+class TextureAtlas;
class Asset : public Persistence::Persistable, public StdTypeDefs<Asset> {
public:
- using TexturePtr = std::shared_ptr<Texture>;
+ using TexturePtr = std::shared_ptr<TextureAtlas>;
std::string id;
std::string name;
diff --git a/assetFactory/assetFactory.cpp b/assetFactory/assetFactory.cpp
index ed1af58..af0cd54 100644
--- a/assetFactory/assetFactory.cpp
+++ b/assetFactory/assetFactory.cpp
@@ -11,7 +11,7 @@
#include "resource.h"
#include "saxParse-persistence.h"
#include "texturePacker.h"
-#include <stb/stb_image.h>
+#include <numeric>
AssetFactory::AssetFactory() :
shapes {
@@ -30,6 +30,18 @@ AssetFactory::loadXML(const std::filesystem::path & filename)
return Persistence::SAXParsePersistence {}.loadState<std::shared_ptr<AssetFactory>>(file);
}
+AssetFactory::Assets
+AssetFactory::loadAll(const std::filesystem::path & root)
+{
+ return std::accumulate(std::filesystem::recursive_directory_iterator {root},
+ std::filesystem::recursive_directory_iterator {}, Assets {}, [](auto && out, auto && path) {
+ if (path.path().extension() == ".xml") {
+ out.merge(loadXML(path)->assets);
+ }
+ return std::move(out);
+ });
+}
+
AssetFactory::Colours
AssetFactory::parseX11RGB(const char * path)
{
@@ -81,17 +93,11 @@ AssetFactory::parseColour(std::string_view in) const
throw std::runtime_error("No such asset factory colour");
}
-AssetFactory::TextureFragmentCoords
-AssetFactory::getTextureCoords(std::string_view id) const
+GLuint
+AssetFactory::getMaterialIndex(std::string_view id) const
{
createTexutre();
- const auto & fragmentUV = textureFragmentPositions.at(id);
- return {
- fragmentUV.xy(),
- fragmentUV.zy(),
- fragmentUV.zw(),
- fragmentUV.xw(),
- };
+ return textureFragmentPositions.at(id);
}
Asset::TexturePtr
@@ -104,33 +110,31 @@ AssetFactory::getTexture() const
void
AssetFactory::createTexutre() const
{
- if (!textureFragments.empty() && (!texture || textureFragmentPositions.empty())) {
- // * load images
- std::vector<std::unique_ptr<Image>> images;
+ if (!textureFragments.empty() && !texture) {
+ // * layout images
+ std::map<const TextureFragment *, std::unique_ptr<const Image>> images;
std::transform(
- textureFragments.begin(), textureFragments.end(), std::back_inserter(images), [](const auto & tf) {
- return std::make_unique<Image>(Resource::mapPath(tf.second->path), STBI_rgb_alpha);
+ textureFragments.begin(), textureFragments.end(), std::inserter(images, images.end()), [](auto && tf) {
+ return decltype(images)::value_type {tf.second.get(), tf.second->image->get()};
});
- // * layout images
std::vector<TexturePacker::Image> imageSizes;
- std::transform(images.begin(), images.end(), std::back_inserter(imageSizes), [](const auto & image) {
- return TexturePacker::Image {image->width, image->height};
+ std::transform(images.begin(), images.end(), std::back_inserter(imageSizes), [](const auto & i) {
+ return TexturePacker::Image {i.second->width, i.second->height};
});
const auto [layout, outSize] = TexturePacker {imageSizes}.pack();
// * create texture
- texture = std::make_shared<Texture>(outSize.x, outSize.y, TextureOptions {.wrap = GL_CLAMP_TO_EDGE});
- std::transform(textureFragments.begin(), textureFragments.end(),
+ texture = std::make_shared<TextureAtlas>(outSize.x, outSize.y, layout.size());
+ std::transform(images.begin(), images.end(),
std::inserter(textureFragmentPositions, textureFragmentPositions.end()),
- [position = layout.begin(), image = images.begin(), size = imageSizes.begin(),
- outSize = glm::vec2 {outSize}](const auto & tf) mutable {
- const auto positionFraction = glm::vec4 {*position, *position + *size} / outSize.xyxy();
- glTexSubImage2D(GL_TEXTURE_2D, 0, static_cast<GLint>(position->x), static_cast<GLint>(position->y),
- static_cast<GLint>(size->x), static_cast<GLint>(size->y), GL_RGBA, GL_UNSIGNED_BYTE,
- image->get()->data.data());
+ [position = layout.begin(), size = imageSizes.begin(), this](const auto & i) mutable {
+ const auto m = texture->add(*position, *size, i.second->data.data(),
+ {
+ .wrapU = i.first->mapmodeU,
+ .wrapV = i.first->mapmodeV,
+ });
position++;
- image++;
size++;
- return decltype(textureFragmentPositions)::value_type {tf.first, positionFraction};
+ return decltype(textureFragmentPositions)::value_type {i.first->id, m};
});
}
}
@@ -141,7 +145,8 @@ AssetFactory::persist(Persistence::PersistenceStore & store)
using MapObjects = Persistence::MapByMember<Shapes, std::shared_ptr<Object>>;
using MapAssets = Persistence::MapByMember<Assets>;
using MapTextureFragments = Persistence::MapByMember<TextureFragments>;
+ using MapAssImp = Persistence::MapByMember<AssImps, std::shared_ptr<AssImp>, &AssImp::path>;
return STORE_TYPE && STORE_NAME_HELPER("object", shapes, MapObjects)
&& STORE_NAME_HELPER("textureFragment", textureFragments, MapTextureFragments)
- && STORE_NAME_HELPER("asset", assets, MapAssets);
+ && STORE_NAME_HELPER("assimp", assimps, MapAssImp) && STORE_NAME_HELPER("asset", assets, MapAssets);
}
diff --git a/assetFactory/assetFactory.h b/assetFactory/assetFactory.h
index 52692c4..e449ce2 100644
--- a/assetFactory/assetFactory.h
+++ b/assetFactory/assetFactory.h
@@ -1,6 +1,7 @@
#pragma once
#include "asset.h"
+#include "assimp.h"
#include "persistence.h"
#include "shape.h"
#include "textureFragment.h"
@@ -12,6 +13,7 @@ class AssetFactory : public Persistence::Persistable {
public:
using Shapes = std::map<std::string, Shape::Ptr, std::less<>>;
using Assets = std::map<std::string, Asset::Ptr, std::less<>>;
+ using AssImps = std::map<std::string, AssImp::Ptr, std::less<>>;
using TextureFragments = std::map<std::string, TextureFragment::Ptr, std::less<>>;
using Colour = glm::vec3;
using ColourAlpha = glm::vec4;
@@ -20,12 +22,14 @@ public:
AssetFactory();
[[nodiscard]] static std::shared_ptr<AssetFactory> loadXML(const std::filesystem::path &);
+ [[nodiscard]] static Assets loadAll(const std::filesystem::path &);
[[nodiscard]] ColourAlpha parseColour(std::string_view) const;
- [[nodiscard]] TextureFragmentCoords getTextureCoords(std::string_view) const;
+ [[nodiscard]] GLuint getMaterialIndex(std::string_view) const;
[[nodiscard]] Asset::TexturePtr getTexture() const;
Shapes shapes;
Assets assets;
+ AssImps assimps;
Colours colours;
TextureFragments textureFragments;
@@ -39,5 +43,5 @@ private:
void createTexutre() const;
mutable Asset::TexturePtr texture;
- mutable std::map<std::string_view, glm::vec4, std::less<>> textureFragmentPositions;
+ mutable std::map<std::string_view, GLuint, std::less<>> textureFragmentPositions;
};
diff --git a/assetFactory/assimp.cpp b/assetFactory/assimp.cpp
new file mode 100644
index 0000000..840c5a9
--- /dev/null
+++ b/assetFactory/assimp.cpp
@@ -0,0 +1,130 @@
+#include "assimp.h"
+#include "assetFactory.h"
+#include "collections.hpp"
+#include "ptr.hpp"
+#include "resource.h"
+#include <assimp/cimport.h>
+#include <assimp/postprocess.h>
+#include <assimp/scene.h>
+#include <future>
+#include <stb/stb_image.h>
+
+template<typename T>
+glm::vec<3, T>
+operator*(const aiVector3t<T> & v)
+{
+ return {v.x, v.y, v.z};
+}
+
+template<typename T>
+glm::vec<2, T>
+operator!(const aiVector3t<T> & v)
+{
+ return {v.x, v.y};
+}
+
+#define AIRANGE(parent, member) \
+ std::span \
+ { \
+ (parent)->m##member, (parent)->mNum##member \
+ }
+
+using SceneCPtr = std::shared_ptr<const aiScene>;
+class AssImpNode : public Shape {
+public:
+ AssImpNode(SceneCPtr scene, const aiNode * node) : scene(std::move(scene)), node(node) { }
+
+ SceneCPtr scene;
+ const aiNode * node;
+
+ CreatedFaces
+ createMesh(ModelFactoryMesh & mesh, float) const
+ {
+ CreatedFaces faces;
+ addMesh(faces, mesh, node);
+ return faces;
+ }
+
+ void
+ addMesh(CreatedFaces & faces, ModelFactoryMesh & mesh, const aiNode * node) const
+ {
+ for (const auto & m : AIRANGE(node, Meshes)) {
+ addMesh(faces, mesh, scene->mMeshes[m]);
+ }
+ for (const auto & n : AIRANGE(node, Children)) {
+ addMesh(faces, mesh, n);
+ }
+ }
+
+ void
+ addMesh(CreatedFaces & faces, ModelFactoryMesh & mesh, const aiMesh * amesh) const
+ {
+ const auto vhs = AIRANGE(amesh, Vertices) * [&mesh](auto && v) {
+ return mesh.add_vertex(*v);
+ };
+ const auto & m = scene->mMaterials[amesh->mMaterialIndex]->GetName();
+
+ GLuint material {};
+ if (auto mf = Persistence::ParseBase::getShared<AssetFactory>("assetFactory")) {
+ material = mf->getMaterialIndex(m.C_Str());
+ }
+
+ for (const auto & f : AIRANGE(amesh, Faces)) {
+ const auto fvhs = AIRANGE(&f, Indices) * [&vhs](auto && i) {
+ return vhs[i];
+ };
+ const auto fh = faces.emplace(mesh.add_namedFace(amesh->mName.C_Str(), fvhs))->second;
+ if (amesh->HasTextureCoords(0)) {
+ for (auto idx = f.mIndices; const auto fheh : mesh.fh_range(fh)) {
+ const auto ouv = !amesh->mTextureCoords[0][*idx++];
+ mesh.set_texcoord2D(fheh, ouv);
+ mesh.property(mesh.materialFaceProperty, fh) = material;
+ }
+ }
+ }
+ }
+};
+
+static_assert(TextureOptions::MapMode::Repeat == static_cast<TextureOptions::MapMode>(aiTextureMapMode_Wrap));
+static_assert(TextureOptions::MapMode::Clamp == static_cast<TextureOptions::MapMode>(aiTextureMapMode_Clamp));
+static_assert(TextureOptions::MapMode::Decal == static_cast<TextureOptions::MapMode>(aiTextureMapMode_Decal));
+static_assert(TextureOptions::MapMode::Mirror == static_cast<TextureOptions::MapMode>(aiTextureMapMode_Mirror));
+
+void
+AssImp::postLoad()
+{
+ SceneCPtr scene {
+ aiImportFile(Resource::mapPath(path).c_str(), aiProcess_RemoveRedundantMaterials), &aiReleaseImport};
+ if (!scene) {
+ throw std::runtime_error("Failed to load asset library: " + path);
+ }
+ if (auto mf = Persistence::ParseBase::getShared<AssetFactory>("assetFactory")) {
+ const auto root = AIRANGE(scene->mRootNode, Children);
+ std::transform(
+ root.begin(), root.end(), std::inserter(mf->shapes, mf->shapes.end()), [&scene](const aiNode * m) {
+ return AssetFactory::Shapes::value_type {m->mName.C_Str(), std::make_shared<AssImpNode>(scene, m)};
+ });
+ const auto materials = AIRANGE(scene, Materials);
+ std::transform(materials.begin(), materials.end(),
+ std::inserter(mf->textureFragments, mf->textureFragments.end()), [&scene](const aiMaterial * m) {
+ aiString path;
+ m->Get(AI_MATKEY_TEXTURE_DIFFUSE(0), path);
+ auto texture = std::make_shared<TextureFragment>();
+ texture->id = m->GetName().C_Str();
+ texture->path = path.C_Str();
+ m->Get(AI_MATKEY_MAPPINGMODE_U_DIFFUSE(0), texture->mapmodeU);
+ m->Get(AI_MATKEY_MAPPINGMODE_V_DIFFUSE(0), texture->mapmodeV);
+ texture->image = Worker::addWork([t = scene->GetEmbeddedTexture(path.C_Str())]() {
+ return std::make_unique<Image>(
+ std::span {reinterpret_cast<unsigned char *>(t->pcData), t->mWidth}, STBI_rgb_alpha);
+ });
+ return AssetFactory::TextureFragments::value_type {texture->id, texture};
+ });
+ }
+}
+
+bool
+AssImp::persist(Persistence::PersistenceStore & store)
+{
+ return STORE_TYPE && STORE_MEMBER(path);
+}
diff --git a/assetFactory/assimp.h b/assetFactory/assimp.h
new file mode 100644
index 0000000..55b551d
--- /dev/null
+++ b/assetFactory/assimp.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "persistence.h"
+
+class AssImp : public Persistence::Persistable {
+public:
+ using Ptr = std::shared_ptr<AssImp>;
+
+ void postLoad() override;
+
+ bool persist(Persistence::PersistenceStore & store) override;
+
+ std::string path;
+};
diff --git a/assetFactory/factoryMesh.cpp b/assetFactory/factoryMesh.cpp
index 8869efd..f7bc7c8 100644
--- a/assetFactory/factoryMesh.cpp
+++ b/assetFactory/factoryMesh.cpp
@@ -6,43 +6,46 @@
Mesh::Ptr
FactoryMesh::createMesh() const
{
- ModelFactoryMesh mesh;
+ std::vector<Vertex> vertices;
+ std::vector<unsigned int> indices;
+
for (const auto & use : uses) {
+ ModelFactoryMesh mesh;
use->createMesh(mesh, 1);
- }
- mesh.update_face_normals();
- mesh.update_vertex_normals();
- std::vector<Vertex> vertices;
- std::vector<unsigned int> indices;
- for (const auto & face : mesh.faces()) {
- const auto & smooth = mesh.property(mesh.smoothFaceProperty, face);
- const auto & colour = mesh.color(face);
+ mesh.update_face_normals();
+ mesh.update_vertex_normals();
+ for (const auto & face : mesh.faces()) {
+ const auto & smooth = mesh.property(mesh.smoothFaceProperty, face);
+ const auto & colour = mesh.color(face);
+ const auto & material = mesh.property(mesh.materialFaceProperty, face);
- std::vector<unsigned int> faceIndices;
- for (const auto & heh : mesh.fh_range(face)) {
- const auto & vertex = mesh.to_vertex_handle(heh);
- const auto & textureUV = mesh.texcoord2D(heh);
- const auto & point = mesh.point(vertex);
- const auto & normal = smooth ? mesh.property(mesh.vertex_normals_pph(), vertex)
- : mesh.property(mesh.face_normals_pph(), face);
- Vertex outVertex {point, textureUV, normal, colour};
- if (const auto existingItr = std::find(vertices.rbegin(), vertices.rend(), outVertex);
- existingItr != vertices.rend()) {
- faceIndices.push_back(static_cast<unsigned int>(std::distance(existingItr, vertices.rend()) - 1));
- }
- else {
- faceIndices.push_back(static_cast<unsigned int>(vertices.size()));
- vertices.emplace_back(outVertex);
+ std::vector<unsigned int> faceIndices;
+ for (const auto & heh : mesh.fh_range(face)) {
+ const auto & vertex = mesh.to_vertex_handle(heh);
+ const auto & textureUV = mesh.texcoord2D(heh);
+ const auto & point = mesh.point(vertex);
+ const auto & normal = smooth ? mesh.property(mesh.vertex_normals_pph(), vertex)
+ : mesh.property(mesh.face_normals_pph(), face);
+ Vertex outVertex {point, textureUV, normal, colour, material};
+ if (const auto existingItr = std::find(vertices.rbegin(), vertices.rend(), outVertex);
+ existingItr != vertices.rend()) {
+ faceIndices.push_back(static_cast<unsigned int>(std::distance(existingItr, vertices.rend()) - 1));
+ }
+ else {
+ faceIndices.push_back(static_cast<unsigned int>(vertices.size()));
+ vertices.emplace_back(outVertex);
+ }
}
- }
- for (unsigned int i = 2; i < faceIndices.size(); i++) {
- indices.push_back(faceIndices[0]);
- indices.push_back(faceIndices[i - 1]);
- indices.push_back(faceIndices[i]);
+ for (unsigned int i = 2; i < faceIndices.size(); i++) {
+ indices.push_back(faceIndices[0]);
+ indices.push_back(faceIndices[i - 1]);
+ indices.push_back(faceIndices[i]);
+ }
}
}
+
return std::make_shared<Mesh>(vertices, indices);
}
diff --git a/assetFactory/modelFactoryMesh.cpp b/assetFactory/modelFactoryMesh.cpp
index e640502..3d4b5f3 100644
--- a/assetFactory/modelFactoryMesh.cpp
+++ b/assetFactory/modelFactoryMesh.cpp
@@ -3,6 +3,7 @@
ModelFactoryMesh::ModelFactoryMesh()
{
add_property(smoothFaceProperty);
+ add_property(materialFaceProperty);
add_property(nameFaceProperty);
add_property(nameAdjFaceProperty);
}
diff --git a/assetFactory/modelFactoryMesh.h b/assetFactory/modelFactoryMesh.h
index 8ac2edd..4eac7ee 100644
--- a/assetFactory/modelFactoryMesh.h
+++ b/assetFactory/modelFactoryMesh.h
@@ -1,6 +1,7 @@
#pragma once
#include "modelFactoryMesh_fwd.h"
+#include <GL/glew.h>
#include <OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh>
#include <OpenMesh/Core/Mesh/Traits.hh>
#include <glm/geometric.hpp>
@@ -47,6 +48,7 @@ struct ModelFactoryMesh : public OpenMesh::PolyMesh_ArrayKernelT<ModelFactoryTra
ModelFactoryMesh();
OpenMesh::FPropHandleT<bool> smoothFaceProperty;
+ OpenMesh::FPropHandleT<GLuint> materialFaceProperty;
OpenMesh::FPropHandleT<std::string> nameFaceProperty;
OpenMesh::HPropHandleT<std::string> nameAdjFaceProperty;
diff --git a/assetFactory/style.cpp b/assetFactory/style.cpp
index 12346a6..ea67fc2 100644
--- a/assetFactory/style.cpp
+++ b/assetFactory/style.cpp
@@ -30,7 +30,14 @@ Style::applyStyle(
else {
mesh.set_color(face, {});
if (auto mf = Persistence::ParseBase::getShared<const AssetFactory>("assetFactory")) {
- auto coords = mf->getTextureCoords(texture);
+ const auto material = mf->getMaterialIndex(texture);
+ mesh.property(mesh.materialFaceProperty, face) = material;
+ static constexpr std::array<ModelFactoryTraits::TexCoord2D, 4> coords {{
+ {0.f, 0.f},
+ {1.f, 0.f},
+ {1.f, 1.f},
+ {0.f, 1.f},
+ }};
auto coord = coords.begin();
// Wild assumption that face is a quad and the texture should apply linearly
for (const auto & heh : mesh.fh_range(face)) {
diff --git a/assetFactory/textureFragment.cpp b/assetFactory/textureFragment.cpp
index 72107a5..0a4ec1d 100644
--- a/assetFactory/textureFragment.cpp
+++ b/assetFactory/textureFragment.cpp
@@ -1,7 +1,17 @@
#include "textureFragment.h"
+#include "resource.h"
+#include <stb/stb_image.h>
bool
TextureFragment::persist(Persistence::PersistenceStore & store)
{
return STORE_TYPE && STORE_MEMBER(id) && STORE_MEMBER(path);
}
+
+void
+TextureFragment::postLoad()
+{
+ image = Worker::addWork([this]() {
+ return std::make_unique<Image>(Resource::mapPath(path), STBI_rgb_alpha);
+ });
+}
diff --git a/assetFactory/textureFragment.h b/assetFactory/textureFragment.h
index 52f2591..e6f07f3 100644
--- a/assetFactory/textureFragment.h
+++ b/assetFactory/textureFragment.h
@@ -1,14 +1,20 @@
#pragma once
+#include "gfx/image.h"
+#include "gfx/models/texture.h"
#include "persistence.h"
#include "stdTypeDefs.hpp"
+#include "worker.h"
class TextureFragment : public Persistence::Persistable, public StdTypeDefs<TextureFragment> {
public:
std::string id;
std::string path;
+ TextureOptions::MapMode mapmodeU, mapmodeV;
+ Worker::WorkPtrT<std::unique_ptr<Image>> image;
private:
friend Persistence::SelectionPtrBase<Ptr>;
bool persist(Persistence::PersistenceStore & store) override;
+ void postLoad() override;
};
diff --git a/assetFactory/texturePacker.cpp b/assetFactory/texturePacker.cpp
index 68a6010..fcc935f 100644
--- a/assetFactory/texturePacker.cpp
+++ b/assetFactory/texturePacker.cpp
@@ -1,7 +1,9 @@
#include "texturePacker.h"
#include "collections.hpp"
+#include <GL/glew.h>
#include <algorithm>
#include <cstdio>
+#include <glm/common.hpp>
#include <numeric>
#include <ostream>
#include <set>
@@ -12,6 +14,9 @@ TexturePacker::TexturePacker(std::span<const Image> in) :
std::sort(sortedIndexes.rbegin(), sortedIndexes.rend(), [this](const auto a, const auto b) {
return area(inputImages[a]) < area(inputImages[b]);
});
+ int mts;
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mts);
+ maxTextureSize = static_cast<unsigned int>(mts);
}
TexturePacker::Result
@@ -23,6 +28,9 @@ TexturePacker::pack() const
TexturePacker::Result
TexturePacker::pack(Size size) const
{
+ if (size.x > maxTextureSize || size.y > maxTextureSize) {
+ return {};
+ }
using Spaces = std::set<Space>;
Spaces spaces {{{}, size}};
@@ -47,14 +55,27 @@ TexturePacker::pack(Size size) const
}
}
else {
- if (size.x < size.y) {
- return pack({size.x * 2, size.y});
+ const auto x = pack({size.x * 2, size.y}), y = pack({size.x, size.y * 2});
+ if (!x.first.empty() && (y.first.empty() || area(x.second) < area(y.second))) {
+ return x;
}
- else {
- return pack({size.x, size.y * 2});
+ else if (!y.first.empty()) {
+ return y;
}
+ return {};
}
}
+ if (GLEW_ARB_texture_non_power_of_two) {
+ // Crop the size back to minimum size
+ size = std::transform_reduce(
+ result.begin(), result.end(), inputImages.begin(), Size {},
+ [](auto && max, auto && limit) {
+ return glm::max(max, limit);
+ },
+ [](auto && pos, auto && size) {
+ return pos + size;
+ });
+ }
return {result, size};
}
diff --git a/assetFactory/texturePacker.h b/assetFactory/texturePacker.h
index ca0d67a..a1b270b 100644
--- a/assetFactory/texturePacker.h
+++ b/assetFactory/texturePacker.h
@@ -38,4 +38,5 @@ public:
private:
std::span<const Image> inputImages;
std::vector<size_t> sortedIndexes;
+ unsigned int maxTextureSize;
};