From 174334eaf4722613e0e497f24c1891585b79851b Mon Sep 17 00:00:00 2001 From: Nicholas Yue Date: Tue, 25 Dec 2018 09:15:13 +1100 Subject: [PATCH 1/6] Fix GLFW3 handling on CentOS --- examples/glview/CMakeLists.txt | 15 ++++-- examples/glview/cmake/GLFW3Config.cmake | 71 +++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 examples/glview/cmake/GLFW3Config.cmake diff --git a/examples/glview/CMakeLists.txt b/examples/glview/CMakeLists.txt index 06308ca..91cb465 100644 --- a/examples/glview/CMakeLists.txt +++ b/examples/glview/CMakeLists.txt @@ -1,12 +1,17 @@ cmake_minimum_required(VERSION 3.6) project(glview) +set ( CMAKE_PREFIX_PATH cmake ) + find_package ( GLEW REQUIRED ) +find_package ( GLFW3 REQUIRED ) find_package ( OpenGL REQUIRED ) -find_library(COCOA_LIBRARY Cocoa) -find_library(COREVIDEO_LIBRARY CoreVideo) -find_library(IOKIT_LIBRARY IOKit) +if (apple) + find_library(COCOA_LIBRARY Cocoa) + find_library(COREVIDEO_LIBRARY CoreVideo) + find_library(IOKIT_LIBRARY IOKit) +endif (apple) set(CMAKE_CXX_STANDARD 11) @@ -15,7 +20,7 @@ include_directories( ../common # ${OPENGL_INCLUDE_DIR} ${GLEW_INCLUDE_DIR} - ${GLFW_INCLUDE_DIR} + ${GLFW3_INCLUDE_DIR} ) add_executable(glview @@ -25,7 +30,7 @@ add_executable(glview target_link_libraries ( glview ${GLEW_LIBRARY} - ${GLFW_LIBRARY} + ${GLFW3_glfw_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${COCOA_LIBRARY} diff --git a/examples/glview/cmake/GLFW3Config.cmake b/examples/glview/cmake/GLFW3Config.cmake new file mode 100644 index 0000000..ffc54fb --- /dev/null +++ b/examples/glview/cmake/GLFW3Config.cmake @@ -0,0 +1,71 @@ +#-*-cmake-*- +# +# yue.nicholas@gmail.com +# +# This auxiliary CMake file helps in find the glfw3 headers and libraries +# +# GLFW3_FOUND set if glfw3 is found. +# GLFW3_INCLUDE_DIR glfw3's include directory +# GLFW3_LIBRARY_DIR glfw3's library directory +# GLFW3_LIBRARIES all glfw3 libraries + +FIND_PACKAGE (Threads) + +FIND_PACKAGE ( PackageHandleStandardArgs ) + +FIND_PATH( GLFW3_LOCATION include/GLFW/glfw3.h + "$ENV{GLFW3_HOME}" +) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS ( GLFW3 + REQUIRED_VARS GLFW3_LOCATION + ) + +IF (GLFW3_FOUND) + SET( GLFW3_INCLUDE_DIR "${GLFW3_LOCATION}/include" CACHE STRING "GLFW3 include path") + IF (GLFW3_USE_STATIC_LIBS) + FIND_LIBRARY ( GLFW3_glfw_LIBRARY libglfw3.a ${GLFW3_LOCATION}/lib + ) + ELSE (GLFW3_USE_STATIC_LIBS) + # On windows build, we need to look for glfw3 + IF (WIN32) + SET ( GLFW3_LIBRARY_NAME glfw3 ) + ELSE () + SET ( GLFW3_LIBRARY_NAME glfw ) + ENDIF() + FIND_LIBRARY ( GLFW3_glfw_LIBRARY ${GLFW3_LIBRARY_NAME} ${GLFW3_LOCATION}/lib + ) + ENDIF (GLFW3_USE_STATIC_LIBS) + + IF (APPLE) + FIND_LIBRARY ( COCOA_LIBRARY Cocoa ) + FIND_LIBRARY ( IOKIT_LIBRARY IOKit ) + FIND_LIBRARY ( COREVIDEO_LIBRARY CoreVideo ) + ELSEIF (UNIX AND NOT APPLE) + SET ( GLFW3_REQUIRED_X11_LIBRARIES + X11 + Xi + Xrandr + Xinerama + Xcursor + Xxf86vm + m + ${CMAKE_DL_LIBS} + ${CMAKE_THREAD_LIBS_INIT} + ) + ENDIF () + + SET ( GLFW3_LIBRARIES + ${OPENGL_gl_LIBRARY} + ${OPENGL_glu_LIBRARY} + ${GLFW3_glfw_LIBRARY} + # UNIX + ${GLFW3_REQUIRED_X11_LIBRARIES} + # APPLE + ${COCOA_LIBRARY} + ${IOKIT_LIBRARY} + ${COREVIDEO_LIBRARY} + CACHE STRING "GLFW3 required libraries" + ) + +ENDIF () From f1b5bb12fd5c627968108aba9266b1b346fc27cf Mon Sep 17 00:00:00 2001 From: Nicholas Yue Date: Tue, 25 Dec 2018 09:48:26 +1100 Subject: [PATCH 2/6] Add support for static GLFW3 library linking --- examples/glview/CMakeLists.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/examples/glview/CMakeLists.txt b/examples/glview/CMakeLists.txt index 91cb465..10851ae 100644 --- a/examples/glview/CMakeLists.txt +++ b/examples/glview/CMakeLists.txt @@ -11,6 +11,12 @@ if (apple) find_library(COCOA_LIBRARY Cocoa) find_library(COREVIDEO_LIBRARY CoreVideo) find_library(IOKIT_LIBRARY IOKit) +else () + if (NOT win32) + # This means it is Unices + set ( GLFW3_UNIX_LINK_LIBRARIES X11 Xxf86vm Xrandr Xi Xinerama Xcursor ) + find_package (Threads) + endif() endif (apple) set(CMAKE_CXX_STANDARD 11) @@ -29,6 +35,7 @@ add_executable(glview ) target_link_libraries ( glview + ${GLFW3_UNIX_LINK_LIBRARIES} ${GLEW_LIBRARY} ${GLFW3_glfw_LIBRARY} ${OPENGL_gl_LIBRARY} @@ -36,6 +43,8 @@ target_link_libraries ( glview ${COCOA_LIBRARY} ${COREVIDEO_LIBRARY} ${IOKIT_LIBRARY} + ${CMAKE_DL_LIBS} + ${CMAKE_THREAD_LIBS_INIT} ) install ( TARGETS From 80a85af6613de98ce49fb45b78dfd076ce9d5d8d Mon Sep 17 00:00:00 2001 From: Tan Meng Yue Date: Tue, 25 Dec 2018 17:03:58 +1100 Subject: [PATCH 3/6] Fix bug in handling OS X build via CMake The OS macros needs to be upper case for the if statement to work as expected --- examples/glview/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/glview/CMakeLists.txt b/examples/glview/CMakeLists.txt index 10851ae..ae353cb 100644 --- a/examples/glview/CMakeLists.txt +++ b/examples/glview/CMakeLists.txt @@ -7,17 +7,17 @@ find_package ( GLEW REQUIRED ) find_package ( GLFW3 REQUIRED ) find_package ( OpenGL REQUIRED ) -if (apple) +if (APPLE) find_library(COCOA_LIBRARY Cocoa) find_library(COREVIDEO_LIBRARY CoreVideo) find_library(IOKIT_LIBRARY IOKit) else () - if (NOT win32) + if (NOT WIN32) # This means it is Unices set ( GLFW3_UNIX_LINK_LIBRARIES X11 Xxf86vm Xrandr Xi Xinerama Xcursor ) find_package (Threads) endif() -endif (apple) +endif (APPLE) set(CMAKE_CXX_STANDARD 11) From d96b45df06164393dc65285cf56cc61ba925733c Mon Sep 17 00:00:00 2001 From: Tan Meng Yue Date: Thu, 27 Dec 2018 10:24:13 +1100 Subject: [PATCH 4/6] Renamed glTFConfig to TinyGLTFConfig This renaming is done so that the config file matches the project name which is TinyGLTF. This is done to prevent future name collision should the Khronos glTF project decides to provide their own CMake configuration file. --- CMakeLists.txt | 2 +- cmake/TinyGLTFConfig.cmake | 15 +++++++++++++++ cmake/glTFConfig.cmake | 17 ----------------- 3 files changed, 16 insertions(+), 18 deletions(-) create mode 100644 cmake/TinyGLTFConfig.cmake delete mode 100644 cmake/glTFConfig.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 31647f5..75411f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,7 +22,7 @@ INSTALL ( FILES ) INSTALL ( FILES - cmake/glTFConfig.cmake + cmake/TinyGLTFConfig.cmake DESTINATION cmake ) diff --git a/cmake/TinyGLTFConfig.cmake b/cmake/TinyGLTFConfig.cmake new file mode 100644 index 0000000..2c2a75d --- /dev/null +++ b/cmake/TinyGLTFConfig.cmake @@ -0,0 +1,15 @@ +# -*- cmake -*- +# - Find TinyGLTF + +# TinyGLTF_INCLUDE_DIR TinyGLTF's include directory + + +FIND_PACKAGE ( PackageHandleStandardArgs ) + +SET ( TinyGLTF_INCLUDE_DIR "${TinyGLTF_DIR}/../include" CACHE STRING "TinyGLTF include directory") + +FIND_FILE ( TinyGLTF_HEADER tiny_gltf.h PATHS ${TinyGLTF_INCLUDE_DIR} ) + +IF (NOT TinyGLTF_HEADER) + MESSAGE ( FATAL_ERROR "Unable to find tiny_gltf.h, TinyGLTF_INCLUDE_DIR = ${TinyGLTF_INCLUDE_DIR}") +ENDIF () diff --git a/cmake/glTFConfig.cmake b/cmake/glTFConfig.cmake deleted file mode 100644 index c1502ee..0000000 --- a/cmake/glTFConfig.cmake +++ /dev/null @@ -1,17 +0,0 @@ -# -*- cmake -*- -# - Find glTF - -# glTF_INCLUDE_DIR glTF's include directory - - -FIND_PACKAGE ( PackageHandleStandardArgs ) - -SET ( glTF_INCLUDE_DIR "${glTF_DIR}/../include" CACHE STRING "glTF include directory") - -FIND_FILE ( glTF_HEADER tiny_gltf.h PATHS ${glTF_INCLUDE_DIR} ) - -IF (glTF_HEADER) - # MESSAGE ( STATUS "FOUND tiny_gltf.h, glTF_INCLUDE_DIR = ${glTF_INCLUDE_DIR}") -ELSE () - MESSAGE ( FATAL_ERROR "Unable to find tiny_gltf.h, glTF_INCLUDE_DIR = ${glTF_INCLUDE_DIR}") -ENDIF () From 5f9cb2424503a30f3b9c10a26383800f9252895a Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Fri, 28 Dec 2018 20:53:41 +0100 Subject: [PATCH 5/6] Added new feature for loading all gltf related files (including textures, binaries, etc.) from assets packaged with an Android app --- README.md | 1 + tiny_gltf.h | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/README.md b/README.md index d30af0c..1b0a516 100644 --- a/README.md +++ b/README.md @@ -128,6 +128,7 @@ if (!ret) { * `TINYGLTF_NO_STB_IMAGE` : Do not load images with stb_image. Instead use `TinyGLTF::SetImageLoader(LoadimageDataFunction LoadImageData, void *user_data)` to set a callback for loading images. * `TINYGLTF_NO_STB_IMAGE_WRITE` : Do not write images with stb_image_write. Instead use `TinyGLTF::SetImageWriter(WriteimageDataFunction WriteImageData, void *user_data)` to set a callback for writing images. * `TINYGLTF_NO_EXTERNAL_IMAGE` : Do not try to load external image file. This option woulde be helpful if you do not want load image file during glTF parsing. +* `TINYGLTF_ANDROID_LOAD_FROM_ASSETS`: Load all files from packaged app assets instead of the regular file system. **Note:** You must pass a valid asset manager from your android app to `tinygltf::asset_manager` beforehand. ### Saving gltTF 2.0 model * [ ] Buffers. diff --git a/tiny_gltf.h b/tiny_gltf.h index d70060b..ad32ee4 100644 --- a/tiny_gltf.h +++ b/tiny_gltf.h @@ -47,6 +47,12 @@ #include #include +#ifdef __ANDROID__ +#ifdef TINYGLTF_ANDROID_LOAD_FROM_ASSETS +#include +#endif +#endif + namespace tinygltf { #define TINYGLTF_MODE_POINTS (0) @@ -139,6 +145,12 @@ namespace tinygltf { #define TINYGLTF_DOUBLE_EPS (1.e-12) #define TINYGLTF_DOUBLE_EQUAL(a, b) (std::fabs((b) - (a)) < TINYGLTF_DOUBLE_EPS) +#ifdef __ANDROID__ +#ifdef TINYGLTF_ANDROID_LOAD_FROM_ASSETS + AAssetManager* asset_manager = nullptr; +#endif +#endif + typedef enum { NULL_TYPE = 0, NUMBER_TYPE = 1, @@ -1729,6 +1741,18 @@ void TinyGLTF::SetFsCallbacks(FsCallbacks callbacks) { fs = callbacks; } bool FileExists(const std::string &abs_filename, void *) { bool ret; +#ifdef TINYGLTF_ANDROID_LOAD_FROM_ASSETS + if (asset_manager) { + AAsset* asset = AAssetManager_open(asset_manager, abs_filename.c_str(), AASSET_MODE_STREAMING); + if (!asset) { + return false; + } + AAsset_close(asset); + ret = true; + } else { + return false; + } +#else #ifdef _WIN32 FILE *fp; errno_t err = fopen_s(&fp, abs_filename.c_str(), "rb"); @@ -1744,6 +1768,7 @@ bool FileExists(const std::string &abs_filename, void *) { } else { ret = false; } +#endif return ret; } @@ -1797,6 +1822,33 @@ std::string ExpandFilePath(const std::string &filepath, void *) { bool ReadWholeFile(std::vector *out, std::string *err, const std::string &filepath, void *) { +#ifdef TINYGLTF_ANDROID_LOAD_FROM_ASSETS + if (asset_manager) { + AAsset* asset = AAssetManager_open(asset_manager, filepath.c_str(), AASSET_MODE_STREAMING); + if (!asset) { + if (err) { + (*err) += "File open error : " + filepath + "\n"; + } + return false; + } + size_t size = AAsset_getLength(asset); + if (size <= 0) { + if (err) { + (*err) += "Invalid file size : " + filepath + + " (does the path point to a directory?)"; + } + } + out->resize(size); + AAsset_read(asset, reinterpret_cast(&out->at(0)), size); + AAsset_close(asset); + return true; + } else { + if (err) { + (*err) += "No asset manager specified : " + filepath + "\n"; + } + return false; + } +#else std::ifstream f(filepath.c_str(), std::ifstream::binary); if (!f) { if (err) { @@ -1828,6 +1880,7 @@ bool ReadWholeFile(std::vector *out, std::string *err, f.close(); return true; +#endif } bool WriteWholeFile(std::string *err, const std::string &filepath, From af3ebb2e76fd2bc7c4afcdf58b21d5b33590542f Mon Sep 17 00:00:00 2001 From: Syoyo Fujita Date: Sun, 6 Jan 2019 18:55:57 +0900 Subject: [PATCH 6/6] Show more expressive messages when parsing `image`. --- tiny_gltf.h | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/tiny_gltf.h b/tiny_gltf.h index ad32ee4..42c64a7 100644 --- a/tiny_gltf.h +++ b/tiny_gltf.h @@ -801,7 +801,7 @@ enum SectionCheck { /// /// LoadImageDataFunction type. Signature for custom image loading callbacks. /// -typedef bool (*LoadImageDataFunction)(Image *, std::string *, std::string *, +typedef bool (*LoadImageDataFunction)(Image *, const int, std::string *, std::string *, int, int, const unsigned char *, int, void *); @@ -813,7 +813,7 @@ typedef bool (*WriteImageDataFunction)(const std::string *, const std::string *, #ifndef TINYGLTF_NO_STB_IMAGE // Declaration of default image loader callback -bool LoadImageData(Image *image, std::string *err, std::string *warn, +bool LoadImageData(Image *image, const int image_idx, std::string *err, std::string *warn, int req_width, int req_height, const unsigned char *bytes, int size, void *); #endif @@ -1588,9 +1588,9 @@ void TinyGLTF::SetImageLoader(LoadImageDataFunction func, void *user_data) { } #ifndef TINYGLTF_NO_STB_IMAGE -bool LoadImageData(Image *image, std::string *err, std::string *warn, +bool LoadImageData(Image *image, const int image_idx, std::string *err, std::string *warn, int req_width, int req_height, const unsigned char *bytes, - int size, void *) { + int size, void *user_data) { (void)warn; int w, h, comp, req_comp; @@ -1610,7 +1610,7 @@ bool LoadImageData(Image *image, std::string *err, std::string *warn, if (!data) { // NOTE: you can use `warn` instead of `err` if (err) { - (*err) += "Unknown image format.\n"; + (*err) += "Unknown image format. STB cannot decode image data for image[" + std::to_string(image_idx) + "] name = \"" + image->name + "\". Proably 16bit PNG?\n"; } return false; } @@ -1618,7 +1618,7 @@ bool LoadImageData(Image *image, std::string *err, std::string *warn, if (w < 1 || h < 1) { free(data); if (err) { - (*err) += "Invalid image data.\n"; + (*err) += "Invalid image data for image[" + std::to_string(image_idx) + "] name = \"" + image->name + "\"\n"; } return false; } @@ -1627,7 +1627,7 @@ bool LoadImageData(Image *image, std::string *err, std::string *warn, if (req_width != w) { free(data); if (err) { - (*err) += "Image width mismatch.\n"; + (*err) += "Image width mismatch for image[" + std::to_string(image_idx) + "] name = \"" + image->name + "\"\n"; } return false; } @@ -1637,7 +1637,7 @@ bool LoadImageData(Image *image, std::string *err, std::string *warn, if (req_height != h) { free(data); if (err) { - (*err) += "Image height mismatch.\n"; + (*err) += "Image height mismatch. for image[" + std::to_string(image_idx) + "] name = \"" + image->name + "\"\n"; } return false; } @@ -2427,7 +2427,7 @@ static bool ParseAsset(Asset *asset, std::string *err, const json &o) { return true; } -static bool ParseImage(Image *image, std::string *err, std::string *warn, +static bool ParseImage(Image *image, const int image_idx, std::string *err, std::string *warn, const json &o, const std::string &basedir, FsCallbacks *fs, LoadImageDataFunction *LoadImageData = nullptr, @@ -2439,24 +2439,25 @@ static bool ParseImage(Image *image, std::string *err, std::string *warn, bool hasBufferView = (o.find("bufferView") != o.end()); bool hasURI = (o.find("uri") != o.end()); + ParseStringProperty(&image->name, err, o, "name", false); + if (hasBufferView && hasURI) { // Should not both defined. if (err) { (*err) += "Only one of `bufferView` or `uri` should be defined, but both are " - "defined for Image.\n"; + "defined for image[" + std::to_string(image_idx) + "] name = \"" + image->name + "\"\n"; } return false; } if (!hasBufferView && !hasURI) { if (err) { - (*err) += "Neither required `bufferView` nor `uri` defined for Image.\n"; + (*err) += "Neither required `bufferView` nor `uri` defined for image[" + std::to_string(image_idx) + "] name = \"" + image->name + "\"\n"; } return false; } - ParseStringProperty(&image->name, err, o, "name", false); ParseExtensionsProperty(&image->extensions, err, o); ParseExtrasProperty(&image->extras, o); @@ -2464,7 +2465,7 @@ static bool ParseImage(Image *image, std::string *err, std::string *warn, double bufferView = -1; if (!ParseNumberProperty(&bufferView, err, o, "bufferView", true)) { if (err) { - (*err) += "Failed to parse `bufferView` for Image.\n"; + (*err) += "Failed to parse `bufferView` for image[" + std::to_string(image_idx) + "] name = \"" + image->name + "\"\n"; } return false; } @@ -2494,7 +2495,7 @@ static bool ParseImage(Image *image, std::string *err, std::string *warn, std::string tmp_err; if (!ParseStringProperty(&uri, &tmp_err, o, "uri", true)) { if (err) { - (*err) += "Failed to parse `uri` for Image.\n"; + (*err) += "Failed to parse `uri` for image[" + std::to_string(image_idx) + "] name = \"" + image->name + "\".\n"; } return false; } @@ -2504,7 +2505,7 @@ static bool ParseImage(Image *image, std::string *err, std::string *warn, if (IsDataURI(uri)) { if (!DecodeDataURI(&img, image->mimeType, uri, 0, false)) { if (err) { - (*err) += "Failed to decode 'uri' for image parameter.\n"; + (*err) += "Failed to decode 'uri' for image[" + std::to_string(image_idx) + "] name = [" + image->name + "]\n"; } return false; } @@ -2517,7 +2518,7 @@ static bool ParseImage(Image *image, std::string *err, std::string *warn, #endif if (!LoadExternalFile(&img, err, warn, uri, basedir, false, 0, false, fs)) { if (warn) { - (*warn) += "Failed to load external 'uri' for image parameter\n"; + (*warn) += "Failed to load external 'uri' for image[" + std::to_string(image_idx) + "] name = [" + image->name + "]\n"; } // If the image cannot be loaded, keep uri as image->uri. return true; @@ -2525,7 +2526,7 @@ static bool ParseImage(Image *image, std::string *err, std::string *warn, if (img.empty()) { if (warn) { - (*warn) += "Image is empty.\n"; + (*warn) += "Image data is empty for image[" + std::to_string(image_idx) + "] name = [" + image->name + "] \n"; } return false; } @@ -2537,7 +2538,7 @@ static bool ParseImage(Image *image, std::string *err, std::string *warn, } return false; } - return (*LoadImageData)(image, err, warn, 0, 0, &img.at(0), + return (*LoadImageData)(image, image_idx, err, warn, 0, 0, &img.at(0), static_cast(img.size()), load_image_user_data); } @@ -3665,15 +3666,16 @@ bool TinyGLTF::LoadFromString(Model *model, std::string *err, std::string *warn, json::const_iterator it(root.begin()); json::const_iterator itEnd(root.end()); - for (; it != itEnd; it++) { + int idx = 0; + for (; it != itEnd; it++, idx++) { if (!it.value().is_object()) { if (err) { - (*err) += "`images' does not contain an JSON object."; + (*err) += "image[" + std::to_string(idx) + "] is not a JSON object."; } return false; } Image image; - if (!ParseImage(&image, err, warn, it.value(), base_dir, &fs, + if (!ParseImage(&image, idx, err, warn, it.value(), base_dir, &fs, &this->LoadImageData, load_image_user_data_)) { return false; } @@ -3683,7 +3685,7 @@ bool TinyGLTF::LoadFromString(Model *model, std::string *err, std::string *warn, if (size_t(image.bufferView) >= model->bufferViews.size()) { if (err) { std::stringstream ss; - ss << "bufferView \"" << image.bufferView + ss << "image[" << idx << "] bufferView \"" << image.bufferView << "\" not found in the scene." << std::endl; (*err) += ss.str(); } @@ -3700,7 +3702,7 @@ bool TinyGLTF::LoadFromString(Model *model, std::string *err, std::string *warn, } return false; } - bool ret = LoadImageData(&image, err, warn, image.width, image.height, + bool ret = LoadImageData(&image, idx, err, warn, image.width, image.height, &buffer.data[bufferView.byteOffset], static_cast(bufferView.byteLength), load_image_user_data_);