Make desktop core dependencies portable
This commit is contained in:
+54
-16
@@ -4,11 +4,47 @@ project(vectorail-core VERSION 0.1.0 LANGUAGES CXX)
|
|||||||
|
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
include(CMakePackageConfigHelpers)
|
include(CMakePackageConfigHelpers)
|
||||||
|
include(FetchContent)
|
||||||
|
|
||||||
find_package(OpenGL REQUIRED)
|
find_package(OpenGL REQUIRED)
|
||||||
find_package(PNG REQUIRED)
|
|
||||||
find_package(SDL3 CONFIG REQUIRED)
|
set(VECTORAIL_CORE_FETCHED_DEPENDENCIES OFF)
|
||||||
find_package(glm CONFIG REQUIRED)
|
|
||||||
|
find_package(SDL3 CONFIG QUIET)
|
||||||
|
if(NOT TARGET SDL3::SDL3)
|
||||||
|
set(SDL_INSTALL OFF CACHE BOOL "" FORCE)
|
||||||
|
FetchContent_Declare(SDL3
|
||||||
|
GIT_REPOSITORY https://github.com/libsdl-org/SDL.git
|
||||||
|
GIT_TAG main
|
||||||
|
)
|
||||||
|
FetchContent_MakeAvailable(SDL3)
|
||||||
|
set(VECTORAIL_CORE_FETCHED_DEPENDENCIES ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
find_package(glm CONFIG QUIET)
|
||||||
|
if(NOT TARGET glm::glm)
|
||||||
|
FetchContent_Declare(glm
|
||||||
|
GIT_REPOSITORY https://github.com/g-truc/glm.git
|
||||||
|
GIT_TAG master
|
||||||
|
)
|
||||||
|
FetchContent_MakeAvailable(glm)
|
||||||
|
set(VECTORAIL_CORE_FETCHED_DEPENDENCIES ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
FetchContent_Declare(stb
|
||||||
|
GIT_REPOSITORY https://github.com/nothings/stb.git
|
||||||
|
GIT_TAG 2c980bb59875b0d32144a71867fbdebb2f77cd20
|
||||||
|
)
|
||||||
|
FetchContent_MakeAvailable(stb)
|
||||||
|
|
||||||
|
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR AND
|
||||||
|
NOT VECTORAIL_CORE_FETCHED_DEPENDENCIES)
|
||||||
|
set(VECTORAIL_CORE_INSTALL_DEFAULT ON)
|
||||||
|
else()
|
||||||
|
set(VECTORAIL_CORE_INSTALL_DEFAULT OFF)
|
||||||
|
endif()
|
||||||
|
option(VECTORAIL_CORE_INSTALL "Generate VectorailCore install rules"
|
||||||
|
${VECTORAIL_CORE_INSTALL_DEFAULT})
|
||||||
|
|
||||||
add_library(vectorail-core
|
add_library(vectorail-core
|
||||||
src/DdsTexture.cpp
|
src/DdsTexture.cpp
|
||||||
@@ -24,12 +60,13 @@ target_include_directories(vectorail-core
|
|||||||
PUBLIC
|
PUBLIC
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||||
|
PRIVATE
|
||||||
|
${stb_SOURCE_DIR}
|
||||||
)
|
)
|
||||||
target_link_libraries(vectorail-core
|
target_link_libraries(vectorail-core
|
||||||
PUBLIC
|
PUBLIC
|
||||||
SDL3::SDL3
|
SDL3::SDL3
|
||||||
OpenGL::GL
|
OpenGL::GL
|
||||||
PNG::PNG
|
|
||||||
glm::glm
|
glm::glm
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -39,33 +76,34 @@ set_target_properties(vectorail-core PROPERTIES
|
|||||||
SOVERSION ${PROJECT_VERSION_MAJOR}
|
SOVERSION ${PROJECT_VERSION_MAJOR}
|
||||||
)
|
)
|
||||||
|
|
||||||
install(TARGETS vectorail-core
|
if(VECTORAIL_CORE_INSTALL)
|
||||||
|
install(TARGETS vectorail-core
|
||||||
EXPORT VectorailCoreTargets
|
EXPORT VectorailCoreTargets
|
||||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||||
)
|
)
|
||||||
install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||||
install(EXPORT VectorailCoreTargets
|
install(EXPORT VectorailCoreTargets
|
||||||
FILE VectorailCoreTargets.cmake
|
FILE VectorailCoreTargets.cmake
|
||||||
NAMESPACE Vectorail::
|
NAMESPACE Vectorail::
|
||||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/VectorailCore
|
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/VectorailCore
|
||||||
)
|
)
|
||||||
|
|
||||||
configure_package_config_file(
|
configure_package_config_file(
|
||||||
cmake/VectorailCoreConfig.cmake.in
|
cmake/VectorailCoreConfig.cmake.in
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/VectorailCoreConfig.cmake
|
${CMAKE_CURRENT_BINARY_DIR}/VectorailCoreConfig.cmake
|
||||||
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/VectorailCore
|
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/VectorailCore
|
||||||
)
|
)
|
||||||
write_basic_package_version_file(
|
write_basic_package_version_file(
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/VectorailCoreConfigVersion.cmake
|
${CMAKE_CURRENT_BINARY_DIR}/VectorailCoreConfigVersion.cmake
|
||||||
VERSION ${PROJECT_VERSION}
|
VERSION ${PROJECT_VERSION}
|
||||||
COMPATIBILITY SameMajorVersion
|
COMPATIBILITY SameMajorVersion
|
||||||
)
|
)
|
||||||
install(FILES
|
install(FILES
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/VectorailCoreConfig.cmake
|
${CMAKE_CURRENT_BINARY_DIR}/VectorailCoreConfig.cmake
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/VectorailCoreConfigVersion.cmake
|
${CMAKE_CURRENT_BINARY_DIR}/VectorailCoreConfigVersion.cmake
|
||||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/VectorailCore
|
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/VectorailCore
|
||||||
)
|
)
|
||||||
|
endif()
|
||||||
|
|||||||
@@ -2,9 +2,7 @@
|
|||||||
|
|
||||||
include(CMakeFindDependencyMacro)
|
include(CMakeFindDependencyMacro)
|
||||||
find_dependency(OpenGL)
|
find_dependency(OpenGL)
|
||||||
find_dependency(PNG)
|
|
||||||
find_dependency(SDL3 CONFIG)
|
find_dependency(SDL3 CONFIG)
|
||||||
find_dependency(glm CONFIG)
|
find_dependency(glm CONFIG)
|
||||||
|
|
||||||
include("${CMAKE_CURRENT_LIST_DIR}/VectorailCoreTargets.cmake")
|
include("${CMAKE_CURRENT_LIST_DIR}/VectorailCoreTargets.cmake")
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,9 @@
|
|||||||
#ifndef WIN32_LEAN_AND_MEAN
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef NOMINMAX
|
||||||
|
#define NOMINMAX
|
||||||
|
#endif
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
+30
-49
@@ -2,11 +2,13 @@
|
|||||||
|
|
||||||
#include "vectorail/core/gl_loader.hpp"
|
#include "vectorail/core/gl_loader.hpp"
|
||||||
|
|
||||||
#include <png.h>
|
#define STBI_ONLY_PNG
|
||||||
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
|
#include <stb_image.h>
|
||||||
|
|
||||||
#include <cstdio>
|
#include <algorithm>
|
||||||
#include <cstring>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <limits>
|
||||||
#include <span>
|
#include <span>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -35,56 +37,34 @@ bool readFile(const std::string& path, std::vector<uint8_t>& bytes) {
|
|||||||
return static_cast<bool>(file) || file.eof();
|
return static_cast<bool>(file) || file.eof();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PngMemoryReader {
|
|
||||||
std::span<const uint8_t> bytes;
|
|
||||||
size_t offset = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
void readPngMemory(png_structp png, png_bytep destination, png_size_t length) {
|
|
||||||
auto* reader = static_cast<PngMemoryReader*>(png_get_io_ptr(png));
|
|
||||||
if (!reader || length > reader->bytes.size() - reader->offset) {
|
|
||||||
png_error(png, "truncated PNG stream");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::memcpy(destination, reader->bytes.data() + reader->offset, length);
|
|
||||||
reader->offset += length;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool decodePng(std::span<const uint8_t> bytes, DdsTexture& out, std::string* error) {
|
bool decodePng(std::span<const uint8_t> bytes, DdsTexture& out, std::string* error) {
|
||||||
out = {};
|
out = {};
|
||||||
if (bytes.size() < 8 || png_sig_cmp(bytes.data(), 0, 8) != 0) {
|
constexpr uint8_t signature[] = {0x89, 'P', 'N', 'G', 0x0d, 0x0a, 0x1a, 0x0a};
|
||||||
|
if (bytes.size() < sizeof(signature) ||
|
||||||
|
!std::equal(std::begin(signature), std::end(signature), bytes.begin())) {
|
||||||
if (error) *error = "not a PNG stream";
|
if (error) *error = "not a PNG stream";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (bytes.size() > static_cast<size_t>(std::numeric_limits<int>::max())) {
|
||||||
png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
|
if (error) *error = "PNG stream is too large";
|
||||||
png_infop info = png ? png_create_info_struct(png) : nullptr;
|
|
||||||
if (!png || !info || setjmp(png_jmpbuf(png))) {
|
|
||||||
if (error) *error = "could not decode PNG";
|
|
||||||
if (png) png_destroy_read_struct(&png, info ? &info : nullptr, nullptr);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
PngMemoryReader reader{bytes};
|
int width = 0;
|
||||||
png_set_read_fn(png, &reader, readPngMemory);
|
int height = 0;
|
||||||
png_read_info(png, info);
|
int sourceChannels = 0;
|
||||||
const png_uint_32 width = png_get_image_width(png, info);
|
stbi_uc* rgba = stbi_load_from_memory(
|
||||||
const png_uint_32 height = png_get_image_height(png, info);
|
bytes.data(), static_cast<int>(bytes.size()),
|
||||||
const int colorType = png_get_color_type(png, info);
|
&width, &height, &sourceChannels, STBI_rgb_alpha);
|
||||||
const int bitDepth = png_get_bit_depth(png, info);
|
if (!rgba || width <= 0 || height <= 0) {
|
||||||
if (bitDepth == 16) png_set_strip_16(png);
|
if (error) {
|
||||||
if (colorType == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png);
|
const char* reason = stbi_failure_reason();
|
||||||
if (colorType == PNG_COLOR_TYPE_GRAY && bitDepth < 8) png_set_expand_gray_1_2_4_to_8(png);
|
*error = reason ? std::string("could not decode PNG: ") + reason
|
||||||
if (png_get_valid(png, info, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png);
|
: "could not decode PNG";
|
||||||
if (colorType == PNG_COLOR_TYPE_GRAY || colorType == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png);
|
}
|
||||||
if ((colorType & PNG_COLOR_MASK_ALPHA) == 0) png_set_add_alpha(png, 0xff, PNG_FILLER_AFTER);
|
stbi_image_free(rgba);
|
||||||
png_read_update_info(png, info);
|
return false;
|
||||||
|
}
|
||||||
std::vector<uint8_t> rgba(static_cast<size_t>(width) * height * 4);
|
|
||||||
std::vector<png_bytep> rows(height);
|
|
||||||
for (png_uint_32 y = 0; y < height; ++y) rows[y] = rgba.data() + static_cast<size_t>(y) * width * 4;
|
|
||||||
png_read_image(png, rows.data());
|
|
||||||
png_destroy_read_struct(&png, &info, nullptr);
|
|
||||||
|
|
||||||
glGenTextures(1, &out.id);
|
glGenTextures(1, &out.id);
|
||||||
glBindTexture(GL_TEXTURE_2D, out.id);
|
glBindTexture(GL_TEXTURE_2D, out.id);
|
||||||
@@ -92,11 +72,12 @@ bool decodePng(std::span<const uint8_t> bytes, DdsTexture& out, std::string* err
|
|||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, static_cast<GLsizei>(width), static_cast<GLsizei>(height),
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height,
|
||||||
0, GL_RGBA, GL_UNSIGNED_BYTE, rgba.data());
|
0, GL_RGBA, GL_UNSIGNED_BYTE, rgba);
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
out.width = static_cast<int>(width);
|
stbi_image_free(rgba);
|
||||||
out.height = static_cast<int>(height);
|
out.width = width;
|
||||||
|
out.height = height;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user