Skip to content

Commit

Permalink
Single texture atlas generation.
Browse files Browse the repository at this point in the history
  • Loading branch information
donlk committed Jun 10, 2023
1 parent d398d7c commit de5e3af
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 43 deletions.
63 changes: 21 additions & 42 deletions libs/tex/generate_texture_atlases.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#include "texture_patch.h"
#include "texture_atlas.h"

#define MAX_TEXTURE_SIZE (8 * 1024)
#define MAX_TEXTURE_SIZE (32 * 1024)
#define PREF_TEXTURE_SIZE (4 * 1024)
#define MIN_TEXTURE_SIZE (256)

Expand All @@ -40,7 +40,7 @@ calculate_texture_size(std::list<TexturePatch::ConstPtr> const & texture_patches
unsigned int total_area = 0;
unsigned int max_width = 0;
unsigned int max_height = 0;
unsigned int padding = size >> 7;
unsigned int padding = std::min(size >> 7, 32U);

for (TexturePatch::ConstPtr texture_patch : texture_patches) {
unsigned int width = texture_patch->get_width() + 2 * padding;
Expand All @@ -62,22 +62,12 @@ calculate_texture_size(std::list<TexturePatch::ConstPtr> const & texture_patches
total_area += area;
}

assert(max_width < MAX_TEXTURE_SIZE);
assert(max_height < MAX_TEXTURE_SIZE);
if (size > PREF_TEXTURE_SIZE &&
max_width < PREF_TEXTURE_SIZE &&
max_height < PREF_TEXTURE_SIZE &&
total_area / (PREF_TEXTURE_SIZE * PREF_TEXTURE_SIZE) < 8) {
size = PREF_TEXTURE_SIZE;
continue;
}

if (size <= MIN_TEXTURE_SIZE) {
return MIN_TEXTURE_SIZE;
}

if (max_height < size / 2 && max_width < size / 2 &&
static_cast<double>(total_area) / (size * size) < 0.2) {
static_cast<double>(total_area) / (double(size) * size) < 0.2) {
size = size / 2;
continue;
}
Expand Down Expand Up @@ -116,17 +106,9 @@ generate_texture_atlases(std::vector<TexturePatch::Ptr> * orig_texture_patches,
std::size_t remaining_patches = texture_patches.size();
std::ofstream tty("/dev/tty", std::ios_base::out);

#pragma omp parallel
{
#pragma omp single
{

while (!texture_patches.empty()) {
unsigned int texture_size = calculate_texture_size(texture_patches);

texture_atlases->push_back(TextureAtlas::create(texture_size));
TextureAtlas::Ptr texture_atlas = texture_atlases->back();

unsigned int texture_size = calculate_texture_size(texture_patches);
TextureAtlas::Ptr texture_atlas = TextureAtlas::create(texture_size);
while (remaining_patches > 0) {
/* Try to insert each of the texture patches into the texture atlas. */
std::list<TexturePatch::ConstPtr>::iterator it = texture_patches.begin();
for (; it != texture_patches.end();) {
Expand All @@ -136,33 +118,30 @@ generate_texture_atlases(std::vector<TexturePatch::Ptr> * orig_texture_patches,
if (total_num_patches > 100
&& done_patches % (total_num_patches / 100) == 0) {

tty << "\r\tWorking on atlas " << texture_atlases->size() << " "
<< precent << "%... " << std::flush;
tty << "\r\tWorking on atlas " << precent << "%... " << std::flush;
}

if (texture_atlas->insert(*it)) {
it = texture_patches.erase(it);
++it;
remaining_patches -= 1;
} else {
++it;
/* Texture atlas was too small, try again. */
texture_size *= 2;
if (texture_size > MAX_TEXTURE_SIZE) {
std::cerr << "Exceeded maximum texture size (" << MAX_TEXTURE_SIZE << ")." << std::endl;
std::exit(EXIT_FAILURE);
}

remaining_patches = texture_patches.size();
it = texture_patches.begin();
texture_atlas = TextureAtlas::create(texture_size);
break;
}
}

#pragma omp task
texture_atlas->finalize();
}

std::cout << "\r\tWorking on atlas " << texture_atlases->size()
<< " 100%... done." << std::endl;
util::WallTimer timer;
std::cout << "\tFinalizing texture atlases... " << std::flush;
#pragma omp taskwait
std::cout << "done. (Took: " << timer.get_elapsed_sec() << "s)" << std::endl;

/* End of single region */
}
/* End of parallel region. */
}
texture_atlases->push_back(texture_atlas);
texture_atlas->finalize();
}

TEX_NAMESPACE_END
2 changes: 1 addition & 1 deletion libs/tex/texture_atlas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#include "texture_atlas.h"

TextureAtlas::TextureAtlas(unsigned int size) :
size(size), padding(size >> 7), finalized(false) {
size(size), padding(std::min(size >> 7, 32U)), finalized(false) {

bin = RectangularBin::create(size, size);
image = mve::ByteImage::create(size, size, 3);
Expand Down

0 comments on commit de5e3af

Please sign in to comment.