Skip to content

Commit

Permalink
Add: C interface
Browse files Browse the repository at this point in the history
  • Loading branch information
spnda committed Nov 5, 2022
1 parent 1018ec5 commit ac1fdce
Show file tree
Hide file tree
Showing 5 changed files with 195 additions and 1 deletion.
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ the CMake script. The library is tested on GCC 9, GCC 10, Clang 12, and MSVC 14
using CI. The project uses a simple CMake 3.11, and can be simply used by adding fastgltf as a
subdirectory. Also, fastgltf is available from [vcpkg](https://github.com/microsoft/vcpkg).

### C++ API

```cpp
#include <fastgltf_parser.hpp>
#include <fastgltf_types.hpp>
Expand Down Expand Up @@ -84,6 +86,41 @@ All the nodes, meshes, buffers, textures, ... can now be accessed through the `f
type. References in between objects are done with a single `size_t`, which is used to index into
the various vectors in the asset.
### C89 API
```c
#include <fastgltf_c.h>
void load(const char* path, const char* directory) {
// Creates a parser object
fastgltf_parser* parser = fastgltf_create_parser(0);
fastgltf_json_data* data = fastgltf_create_json_data_from_file(path);
// For GLB files, use fastgltf_load_binary_gltf
fastgltf_gltf* gltf = fastgltf_load_gltf(parser, data, directory, OptionsDontRequireValidAssetMember);
if (fastgltf_get_parser_error(parser) != ErrorNone) {
// error
}
// Tell fastgltf to parse the whole glTF structure. Optionally, you can parse individual
// aspects of glTF files by calling the various parse methods.
fastgltf_parse_all(gltf);
// You can now destroy the parser and JSON data. It is advised, however, to reuse parsers.
fastgltf_destroy_json_data(data);
fastgltf_destroy_parser(parser);
// You can now query the parsed asset and destroy the glTF object.
fastgltf_asset* asset = fastgltf_get_parsed_asset(gltf);
fastgltf_destroy_gltf(gltf);
// Use the parsed asset here.
fastgltf_destroy_asset(asset);
}
```

## Performance

[spreadsheet-link]: https://docs.google.com/spreadsheets/d/1ocdHGoty-rF0N46ZlAlswzcPHVRsqG_tncy8paD3iMY/edit?usp=sharing
Expand Down
8 changes: 7 additions & 1 deletion cmake/compiler_flags.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@ macro(compiler_flags)
# cpuid, meaning no architecture flags or other compile flags need to be passed.
# See https://github.com/simdjson/simdjson/blob/master/doc/implementation-selection.md.
if (MSVC)
target_compile_options(${PARAM_TARGET} PRIVATE /EHsc $<$<CONFIG:RELEASE>:/O2 /Ob2 /Ot>)
target_compile_options(${PARAM_TARGET} PRIVATE /EHsc $<$<CONFIG:RELEASE>:/O2>)
if (MSVC_VERSION GREATER_EQUAL 1920)
# With VS 16 (2019) /Ob3 was added to more aggressively inline functions.
target_compile_options(${PARAM_TARGET} PRIVATE $<$<CONFIG:RELEASE>:/Ob3>)
else()
target_compile_options(${PARAM_TARGET} PRIVATE $<$<CONFIG:RELEASE>:/Ob2>)
endif()
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
target_compile_options(${PARAM_TARGET} PRIVATE $<$<CONFIG:RELEASE>:-O3>)
endif()
Expand Down
65 changes: 65 additions & 0 deletions src/fastgltf_c.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#include <fastgltf_c.h>

#include <fastgltf_parser.hpp>
#include <fastgltf_types.hpp>

fastgltf_parser* fastgltf_create_parser(fastgltf_extensions extensions) {
return reinterpret_cast<fastgltf_parser*>(
new fastgltf::Parser(static_cast<fastgltf::Extensions>(extensions)));
}

void fastgltf_destroy_parser(fastgltf_parser* parser) {
delete reinterpret_cast<fastgltf::Parser*>(parser);
}

fastgltf_gltf_data_buffer* fastgltf_create_gltf_data_buffer(unsigned char* bytes, size_t size) {
auto data = new (std::nothrow) fastgltf::GltfDataBuffer();
data->copyBytes(bytes, size);
return reinterpret_cast<fastgltf_gltf_data_buffer*>(data);
}

fastgltf_gltf_data_buffer* fastgltf_create_gltf_data_buffer_from_file(const char* file) {
auto data = new (std::nothrow) fastgltf::GltfDataBuffer();
data->loadFromFile(std::string_view { file });
return reinterpret_cast<fastgltf_gltf_data_buffer*>(data);
}

void fastgltf_destroy_json_data(fastgltf_gltf_data_buffer* data) {
delete reinterpret_cast<fastgltf::GltfDataBuffer*>(data);
}

fastgltf_error fastgltf_get_parser_error(fastgltf_parser* parser) {
return static_cast<fastgltf_error>(
reinterpret_cast<fastgltf::Parser*>(parser)->getError());
}

fastgltf_gltf* fastgltf_load_gltf(fastgltf_parser* parser, fastgltf_gltf_data_buffer* json, const char* directory, fastgltf_options options) {
auto gltf = reinterpret_cast<fastgltf::Parser*>(parser)->loadGLTF(
reinterpret_cast<fastgltf::GltfDataBuffer*>(json), std::string_view { directory }, static_cast<fastgltf::Options>(options));
return reinterpret_cast<fastgltf_gltf*>(gltf.release());
}

fastgltf_gltf* fastgltf_load_binary_gltf(fastgltf_parser* parser, fastgltf_gltf_data_buffer* data, const char* directory, fastgltf_options options) {
auto gltf = reinterpret_cast<fastgltf::Parser*>(parser)->loadBinaryGLTF(
reinterpret_cast<fastgltf::GltfDataBuffer*>(data), std::string_view { directory }, static_cast<fastgltf::Options>(options));
return reinterpret_cast<fastgltf_gltf*>(gltf.release());
}

void fastgltf_destroy_gltf(fastgltf_gltf* gltf) {
delete reinterpret_cast<fastgltf::glTF*>(gltf);
}

fastgltf_error fastgltf_parse(fastgltf_gltf* gltf, fastgltf_category categories) {
return static_cast<fastgltf_error>(reinterpret_cast<fastgltf::glTF*>(gltf)->parse(static_cast<fastgltf::Category>(categories)));
}

fastgltf_asset* fastgltf_get_parsed_asset(fastgltf_gltf* gltf) {
// Obtain the unique_ptr from the glTF and release it. Otherwise, it gets destroyed with the
// destructor of fastgltf::glTF.
auto asset = reinterpret_cast<fastgltf::glTF*>(gltf)->getParsedAsset();
return reinterpret_cast<fastgltf_asset*>(asset.release());
}

void fastgltf_destroy_asset(fastgltf_asset* asset) {
delete reinterpret_cast<fastgltf::Asset*>(asset);
}
85 changes: 85 additions & 0 deletions src/fastgltf_c.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
enum fastgltf_extensions {
KHR_texture_transform = 1 << 1,
KHR_texture_basisu = 1 << 2,
MSFT_texture_dds = 1 << 3,
KHR_mesh_quantization = 1 << 4,
EXT_meshopt_compression = 1 << 5,
};

enum fastgltf_options {
OptionsAllowDouble = 1 << 0,
OptionsDontRequireValidAssetMember = 1 << 1,
OptionsDontUseSIMD = 1 << 2,
OptionsLoadGLBBuffers = 1 << 3,
OptionsLoadExternalBuffers = 1 << 4,
OptionsDecomposeNodeMatrices = 1 << 5,
};

enum fastgltf_error {
ErrorNone = 0,
ErrorInvalidPath = 1,
ErrorMissingExtensions = 2,
ErrorUnsupportedExtensions = 3,
ErrorInvalidJson = 4,
ErrorInvalidGltf = 5,
ErrorInvalidOrMissingAssetField = 6,
ErrorInvalidGLB = 6,
ErrorMissingField = 7,
ErrorMissingExternalBuffer = 8,
ErrorUnsupportedVersion = 9,
};

enum fastgltf_category {
CategoryNone = 0,

CategoryBuffers = 1 << 0,
CategoryBufferViews = 1 << 1 | CategoryBuffers,
CategoryAccessors = 1 << 2 | CategoryBufferViews,
CategoryImages = 1 << 3 | CategoryBufferViews,
CategorySamplers = 1 << 4,
CategoryTextures = 1 << 5 | CategoryImages | CategorySamplers,
CategoryAnimations = 1 << 6 | CategoryAccessors,
CategoryCameras = 1 << 7,
CategoryMaterials = 1 << 8 | CategoryTextures,
CategoryMeshes = 1 << 9 | CategoryAccessors | CategoryMaterials,
CategorySkins = 1 << 10 | CategoryAccessors | (1 << 11),
CategoryNodes = 1 << 11 | CategoryCameras | CategoryMeshes | CategorySkins,
CategoryScenes = 1 << 12 | CategoryNodes,
CategoryAsset = 1 << 13,

CategoryAll = CategoryAsset | CategoryScenes | CategoryAnimations,
};

#define FASTGLTF_EXPORT

#ifdef __cplusplus
extern "C" {
#endif

typedef struct fastgltf_parser_s fastgltf_parser;
typedef struct fastgltf_gltf_data_buffer_s fastgltf_gltf_data_buffer;
typedef struct fastgltf_gltf_s fastgltf_gltf;
typedef struct fastgltf_asset_s fastgltf_asset;

FASTGLTF_EXPORT fastgltf_parser* fastgltf_create_parser(fastgltf_extensions extensions);
FASTGLTF_EXPORT void fastgltf_destroy_parser(fastgltf_parser* parser);

FASTGLTF_EXPORT fastgltf_gltf_data_buffer_s* fastgltf_create_gltf_data_buffer(unsigned char* bytes, size_t size);
FASTGLTF_EXPORT fastgltf_gltf_data_buffer_s* fastgltf_create_gltf_data_buffer_from_file(const char* filePath);
FASTGLTF_EXPORT void fastgltf_destroy_json_data(fastgltf_gltf_data_buffer* data);

FASTGLTF_EXPORT fastgltf_error fastgltf_get_parser_error(fastgltf_parser* parser);
FASTGLTF_EXPORT fastgltf_gltf* fastgltf_load_gltf(fastgltf_parser* parser, fastgltf_gltf_data_buffer* json, const char* directory, fastgltf_options options);
FASTGLTF_EXPORT fastgltf_gltf* fastgltf_load_binary_gltf(fastgltf_parser* parser, fastgltf_gltf_data_buffer* data, const char* directory, fastgltf_options options);
FASTGLTF_EXPORT void fastgltf_destroy_gltf(fastgltf_gltf* gltf);

FASTGLTF_EXPORT fastgltf_error fastgltf_parse(fastgltf_gltf* gltf, fastgltf_category categories);

FASTGLTF_EXPORT fastgltf_asset* fastgltf_get_parsed_asset(fastgltf_gltf* gltf);
FASTGLTF_EXPORT void fastgltf_destroy_asset(fastgltf_asset* asset);

#ifdef __cplusplus
}
#endif

#undef FASTGLTF_EXPORT
1 change: 1 addition & 0 deletions src/fastgltf_types.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <array>
#include <cassert>
#include <cstdint>
#include <filesystem>
#include <optional>
Expand Down

0 comments on commit ac1fdce

Please sign in to comment.