mirror of
https://git.mirrors.martin98.com/https://github.com/syoyo/tinygltf.git
synced 2025-08-11 13:09:04 +08:00
Added basic texture dumper
Signed-off by: Arthur Brainville (Ybalrid) <ybalrid@ybalrid.info>
This commit is contained in:
parent
ea2b1c5e5d
commit
8d8840f809
@ -1,11 +1,9 @@
|
|||||||
cmake_minimum_required (VERSION 3.6)
|
cmake_minimum_required(VERSION 3.6)
|
||||||
project (gltfutil)
|
project(gltfutil)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 11)
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
|
|
||||||
include_directories(
|
include_directories(../../)
|
||||||
../../
|
|
||||||
)
|
|
||||||
|
|
||||||
file(GLOB gltfutil_sources *.cc *.h)
|
file(GLOB gltfutil_sources *.cc *.h)
|
||||||
add_executable(gltfutil ${gltfutil_sources})
|
add_executable(gltfutil ${gltfutil_sources})
|
||||||
|
@ -1,9 +1,45 @@
|
|||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace gltfutil {
|
namespace gltfutil {
|
||||||
enum class ui_mode { cli, interactive };
|
|
||||||
|
|
||||||
|
enum class ui_mode { cli, interactive };
|
||||||
enum class cli_action { not_set, help, dump };
|
enum class cli_action { not_set, help, dump };
|
||||||
|
enum class FileType { Ascii, Binary, Unknown };
|
||||||
|
|
||||||
|
/// Probe inside the file, or check the extension to determine if we have to
|
||||||
|
/// load a text file, or a binary file
|
||||||
|
FileType detectType(const std::string& path) {
|
||||||
|
// Quickly open the file as binary and chekc if there's the gltf binary magic
|
||||||
|
// number
|
||||||
|
{
|
||||||
|
auto probe = std::ifstream(path, std::ios_base::binary);
|
||||||
|
if (!probe) throw std::runtime_error("Could not open " + path);
|
||||||
|
|
||||||
|
std::array<char, 5> buffer;
|
||||||
|
for (size_t i{0}; i < 4; ++i) probe >> buffer[i];
|
||||||
|
buffer[4] = 0;
|
||||||
|
|
||||||
|
if (std::string("glTF") == std::string(buffer.data())) {
|
||||||
|
std::cout
|
||||||
|
<< "Detected binary file thanks to the magic number at the start!\n";
|
||||||
|
return FileType::Binary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we don't have any better, check the file extension.
|
||||||
|
auto extension = path.substr(path.find_last_of('.') + 1);
|
||||||
|
std::transform(std::begin(extension), std::end(extension),
|
||||||
|
std::begin(extension),
|
||||||
|
[](char c) { return char(::tolower(int(c))); });
|
||||||
|
if (extension == "gltf") return FileType::Ascii;
|
||||||
|
if (extension == "glb") return FileType::Binary;
|
||||||
|
|
||||||
|
return FileType::Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
struct configuration {
|
struct configuration {
|
||||||
std::string input_path, output_dir;
|
std::string input_path, output_dir;
|
||||||
@ -12,7 +48,8 @@ struct configuration {
|
|||||||
bool has_output_dir;
|
bool has_output_dir;
|
||||||
bool is_valid() {
|
bool is_valid() {
|
||||||
// TODO impl check
|
// TODO impl check
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gltfutil
|
} // namespace gltfutil
|
||||||
|
@ -2,6 +2,14 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "gltfuilconfig.h"
|
#include "gltfuilconfig.h"
|
||||||
|
#include "texture_dumper.h"
|
||||||
|
|
||||||
|
#define TINYGLTF_IMPLEMENTATION
|
||||||
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
|
#include <tiny_gltf.h>
|
||||||
|
|
||||||
|
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||||
|
#include "stb_image_write.h"
|
||||||
|
|
||||||
namespace gltfutil {
|
namespace gltfutil {
|
||||||
int usage() {
|
int usage() {
|
||||||
@ -31,18 +39,44 @@ int parse_args(int argc, char** argv) {
|
|||||||
config.mode = ui_mode::cli;
|
config.mode = ui_mode::cli;
|
||||||
config.action = cli_action::help;
|
config.action = cli_action::help;
|
||||||
case 'd':
|
case 'd':
|
||||||
// TODO impl
|
config.mode = ui_mode::cli;
|
||||||
|
config.action = cli_action::dump;
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
config.mode = ui_mode::interactive;
|
config.mode = ui_mode::interactive;
|
||||||
break;
|
break;
|
||||||
|
case 'o':
|
||||||
// TODO impl
|
// TODO impl
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return arg_error();
|
return arg_error();
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// set the input path
|
||||||
|
config.input_path = argv[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.is_valid()) {
|
if (config.is_valid()) {
|
||||||
|
tinygltf::TinyGLTF loader;
|
||||||
|
tinygltf::Model model;
|
||||||
|
std::string error;
|
||||||
|
bool state;
|
||||||
|
switch (detectType(config.input_path)) {
|
||||||
|
case FileType::Ascii:
|
||||||
|
state = loader.LoadASCIIFromFile(&model, &error, config.input_path);
|
||||||
|
break;
|
||||||
|
case FileType::Binary:
|
||||||
|
state = loader.LoadBinaryFromFile(&model, &error, config.input_path);
|
||||||
|
break;
|
||||||
|
case FileType::Unknown:
|
||||||
|
default:
|
||||||
|
return arg_error();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cerr << "state is " << state << '\n';
|
||||||
|
|
||||||
if (config.mode == ui_mode::interactive) {
|
if (config.mode == ui_mode::interactive) {
|
||||||
// interactive usage now;
|
// interactive usage now;
|
||||||
// TODO impl
|
// TODO impl
|
||||||
@ -50,9 +84,13 @@ int parse_args(int argc, char** argv) {
|
|||||||
switch (config.action) {
|
switch (config.action) {
|
||||||
case cli_action::help:
|
case cli_action::help:
|
||||||
return usage();
|
return usage();
|
||||||
case cli_action::dump:
|
case cli_action::dump: {
|
||||||
// TODO impl
|
texture_dumper dumper(model);
|
||||||
break;
|
if (config.output_dir.empty())
|
||||||
|
dumper.dump_to_folder();
|
||||||
|
else
|
||||||
|
dumper.dump_to_folder(config.output_dir);
|
||||||
|
} break;
|
||||||
default:
|
default:
|
||||||
return arg_error();
|
return arg_error();
|
||||||
}
|
}
|
||||||
|
1830
examples/gltfutil/stb_image_write.h
Normal file
1830
examples/gltfutil/stb_image_write.h
Normal file
File diff suppressed because it is too large
Load Diff
47
examples/gltfutil/texture_dumper.cc
Normal file
47
examples/gltfutil/texture_dumper.cc
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "stb_image_write.h"
|
||||||
|
#include "texture_dumper.h"
|
||||||
|
|
||||||
|
using namespace gltfutil;
|
||||||
|
using namespace tinygltf;
|
||||||
|
using std::cout;
|
||||||
|
|
||||||
|
texture_dumper::texture_dumper(const Model& input)
|
||||||
|
: model(input), configured_format(texture_output_format::png) {
|
||||||
|
cout << "Texture dumper\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void texture_dumper::dump_to_folder(const std::string& path) {
|
||||||
|
cout << "dumping to folder " << path << '\n';
|
||||||
|
cout << "model file has " << model.textures.size() << " textures.\n";
|
||||||
|
size_t index;
|
||||||
|
for (const auto& texture : model.textures) {
|
||||||
|
index++;
|
||||||
|
const auto& image = model.images[texture.source];
|
||||||
|
cout << "image name is: \"" << image.name << "\"\n";
|
||||||
|
cout << "image size is: " << image.width << 'x' << image.height << '\n';
|
||||||
|
cout << "pixel channel count :" << image.component << '\n';
|
||||||
|
std::string name = image.name.empty() ? std::to_string(index) : image.name;
|
||||||
|
switch (configured_format) {
|
||||||
|
case texture_output_format::png:
|
||||||
|
name = path + "/" + name + ".png";
|
||||||
|
std::cout << "Image will be written to " << name << '\n';
|
||||||
|
stbi_write_png(name.c_str(), image.width, image.height, image.component,
|
||||||
|
image.image.data(), 0);
|
||||||
|
break;
|
||||||
|
case texture_output_format::bmp:
|
||||||
|
std::cout << "Image will be written to " << name << '\n';
|
||||||
|
name = path + "/" + name + ".bmp";
|
||||||
|
stbi_write_bmp(name.c_str(), image.width, image.height, image.component,
|
||||||
|
image.image.data());
|
||||||
|
break;
|
||||||
|
case texture_output_format::tga:
|
||||||
|
std::cout << "Image will be written to " << name << '\n';
|
||||||
|
name = path + "/" + name + ".tga";
|
||||||
|
stbi_write_tga(name.c_str(), image.width, image.height, image.component,
|
||||||
|
image.image.data());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
20
examples/gltfutil/texture_dumper.h
Normal file
20
examples/gltfutil/texture_dumper.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <tiny_gltf.h>
|
||||||
|
|
||||||
|
namespace gltfutil {
|
||||||
|
class texture_dumper {
|
||||||
|
public:
|
||||||
|
enum class texture_output_format { png, bmp, tga };
|
||||||
|
|
||||||
|
private:
|
||||||
|
const tinygltf::Model& model;
|
||||||
|
texture_output_format configured_format;
|
||||||
|
|
||||||
|
public:
|
||||||
|
texture_dumper(const tinygltf::Model& inputModel);
|
||||||
|
void dump_to_folder(const std::string& path = "./");
|
||||||
|
};
|
||||||
|
} // namespace gltfutil
|
Loading…
x
Reference in New Issue
Block a user