Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@
[submodule "engine/native/thirdparty/bgfx"]
path = engine/native/thirdparty/bgfx
url = https://github.com/bkaradzic/bgfx
[submodule "engine/native/thirdparty/sdl"]
path = engine/native/thirdparty/sdl
url = https://github.com/libsdl-org/SDL
154 changes: 152 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,158 @@ endif()

project(DraconicEngine LANGUAGES C CXX)

add_compile_options(-mavx2 -mfma)

list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")

include(CTest)
# Subdirectories for engine libs
add_subdirectory(engine/native)

# Main Executable
add_executable(draconic engine/native/main/main.cpp)

enable_modules(draconic)

set_target_properties(draconic PROPERTIES CXX_SCAN_FOR_MODULES ON)

target_link_libraries(draconic
PRIVATE
core
io
memory
image_loader
platform
input
rhi
renderer
rendergraph
mesh
material
quad_renderer
scene
camera # Camera controller
transform
renderable
bgfx
bx
bimg
)

find_package(Threads REQUIRED)

if(UNIX AND NOT APPLE)
target_link_libraries(draconic PRIVATE SDL3::SDL3-static Threads::Threads dl)
target_link_options(draconic PRIVATE -Wl,--whole-archive $<TARGET_FILE:SDL3::SDL3-static> -Wl,--no-whole-archive)
elseif(APPLE)
target_link_libraries(draconic PRIVATE SDL3::SDL3-static)
target_link_options(draconic PRIVATE -Wl,-force_load,$<TARGET_FILE:SDL3::SDL3-static>)
else()
target_link_libraries(draconic PRIVATE SDL3::SDL3-static)
endif()

set(SHADER_DIR "${CMAKE_SOURCE_DIR}/engine/native/rendering/shaders")

set(BGFX_INCLUDE "${CMAKE_SOURCE_DIR}/engine/native/thirdparty/bgfx/src")

if(WIN32)

set(SHADERC
"${CMAKE_SOURCE_DIR}/engine/native/thirdparty/bgfx/.build/win64_vs2022/bin/shadercRelease.exe"
)

set(SHADER_PLATFORM windows)
set(SHADER_PROFILE spirv)

elseif(APPLE)

set(SHADERC
"${CMAKE_SOURCE_DIR}/engine/native/thirdparty/bgfx/.build/osx-arm64_clang/bin/shadercRelease"
)

set(SHADER_PLATFORM osx)
set(SHADER_PROFILE metal)

elseif(UNIX)

set(SHADERC
"${CMAKE_SOURCE_DIR}/engine/native/thirdparty/bgfx/.build/linux64_gcc/bin/shadercRelease"
)

set(SHADER_PLATFORM linux)
set(SHADER_PROFILE spirv)

endif()

# Shader source files
set(VERTEX_SHADER "${SHADER_DIR}/vs.sc")
set(FRAGMENT_SHADER "${SHADER_DIR}/fs.sc")
set(VARYING_DEF "${SHADER_DIR}/varying.def.sc")

# Output binaries
set(VERTEX_OUTPUT "${CMAKE_BINARY_DIR}/vs.bin")
set(FRAGMENT_OUTPUT "${CMAKE_BINARY_DIR}/fs.bin")

# Compile vertex shader
add_custom_command(
OUTPUT ${VERTEX_OUTPUT}

COMMAND ${SHADERC}
-f ${VERTEX_SHADER}
-o ${VERTEX_OUTPUT}
--type vertex
--platform ${SHADER_PLATFORM}
-p ${SHADER_PROFILE}
--varyingdef ${VARYING_DEF}
-i ${BGFX_INCLUDE}

DEPENDS
${VERTEX_SHADER}
${VARYING_DEF}

COMMENT "Compiling vertex shader..."
)

# Compile fragment shader
add_custom_command(
OUTPUT ${FRAGMENT_OUTPUT}

COMMAND ${SHADERC}
-f ${FRAGMENT_SHADER}
-o ${FRAGMENT_OUTPUT}
--type fragment
--platform ${SHADER_PLATFORM}
-p ${SHADER_PROFILE}
--varyingdef ${VARYING_DEF}
-i ${BGFX_INCLUDE}

DEPENDS
${FRAGMENT_SHADER}
${VARYING_DEF}

COMMENT "Compiling fragment shader..."
)

# Shader target
add_custom_target(shaders ALL
DEPENDS
${VERTEX_OUTPUT}
${FRAGMENT_OUTPUT}
)

# Make executable depend on shaders
add_dependencies(draconic shaders)

# Copy shader binaries to executable dir
add_custom_command(
TARGET draconic POST_BUILD

COMMAND ${CMAKE_COMMAND} -E copy_if_different
${VERTEX_OUTPUT}
$<TARGET_FILE_DIR:draconic>

COMMAND ${CMAKE_COMMAND} -E copy_if_different
${FRAGMENT_OUTPUT}
$<TARGET_FILE_DIR:draconic>

add_subdirectory(engine/native)
COMMENT "Copying compiled shaders..."
)
10 changes: 10 additions & 0 deletions cmake/Compiler.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,14 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
# TODO: Make SIMD level configurable or detect at runtime
add_compile_options(-mavx2 -mfma)
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 14.0)
message(FATAL_ERROR "GCC version must be at least 14 for C++23 support")
endif()
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 18.0)
message(FATAL_ERROR "Clang version must be at least 18 for C++23 support")
endif()
endif()
endif()
10 changes: 7 additions & 3 deletions engine/native/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
include(Compiler)
include(Modules)

add_subdirectory(thirdparty SYSTEM)

add_modules_library(core SHARED)
target_link_libraries(core PUBLIC definitions math)
target_link_libraries(core PUBLIC definitions math io memory)
Comment thread
coderabbitai[bot] marked this conversation as resolved.

add_subdirectory(thirdparty SYSTEM)
add_subdirectory(platform)
add_subdirectory(input)
add_subdirectory(rendering)
add_subdirectory(scene)
24 changes: 23 additions & 1 deletion engine/native/core/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
add_modules_library(definitions PIC)
add_modules_library(math)
target_link_libraries(math PUBLIC definitions)
target_link_libraries(math PUBLIC definitions)

add_modules_library(io)
target_link_libraries(io PUBLIC definitions stb_image)

add_modules_library(memory)
target_link_libraries(memory PUBLIC definitions)

add_library(image_loader)

target_sources(image_loader
PUBLIC
FILE_SET CXX_MODULES FILES io/image_loader.cppm
PRIVATE
io/image_loader.cpp
)

target_link_libraries(image_loader
PRIVATE
stb_image
io
definitions
)
44 changes: 44 additions & 0 deletions engine/native/core/io/filesystem.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
module;

#include <vector>
#include <string>
#include <fstream>
#include <cstdint>
#include <print>

module core.io.filesystem;

namespace draco::core::io::filesystem
{
std::vector<std::uint8_t> load_binary(const std::string& path)
{
// Open at the end (ate) to get size and in binary mode
std::ifstream file(path, std::ios::binary | std::ios::ate);

if (!file.is_open()) {
std::println("Error: Could not open file at: {}", path);
// Return an empty vector
return {};
}

std::streamsize size = file.tellg();
if (size < 0) {
std::println("Error: File is empty or unreadable: {}", path);
return {};
}

if (size == 0) {
return {};
}

file.seekg(0, std::ios::beg);

std::vector<std::uint8_t> buffer(static_cast<std::size_t>(size));
if (file.read(reinterpret_cast<char*>(buffer.data()), size)) {
return buffer;
}

std::println("Error: Failed to read file contents: {}", path);
return {};
Comment thread
AR-DEV-1 marked this conversation as resolved.
}
}
14 changes: 14 additions & 0 deletions engine/native/core/io/filesystem.cppm
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module;

#include <vector>
#include <string>
#include <fstream>
#include <cstdint>

export module core.io.filesystem;

export namespace draco::core::io::filesystem
{
// Returns a buffer of the file data
std::vector<uint8_t> load_binary(const std::string& path);
}
61 changes: 61 additions & 0 deletions engine/native/core/io/image_loader.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
module;

#include <vector>
#include <cstdint>
#include <filesystem>
#include <print>

#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>

module core.io.image_loader;

// TODO: I'm too lazy to write code so we need somethin' better

namespace draco::core::io::image_loader
{
ImageData load_image(const std::filesystem::path& path)
{
ImageData result;

std::error_code ec;
if (!std::filesystem::exists(path, ec) || ec) {
std::println("Error: Image path does not exist: {}", path.string());
return result;
}

int width, height, channels;
// STBI_rgb_alpha forces the output to be 4 bytes per pixel (RGBA)
unsigned char* data = stbi_load(path.string().c_str(), &width, &height, &channels, STBI_rgb_alpha);

if (!data) {
std::println("Error: Failed to decode image: {}", path.string());
return result;
}

if (width <= 0 || height <= 0) {
stbi_image_free(data);
return result;
}

const size_t w = static_cast<size_t>(width);
const size_t h = static_cast<size_t>(height);
if (w > (std::numeric_limits<size_t>::max() / 4) / h) {
stbi_image_free(data);
return result;
}

size_t size = w * h * 4;

result.pixels.assign(data, data + size);
result.width = static_cast<uint16_t>(width);
result.height = static_cast<uint16_t>(height);
result.channels = 4;
result.is_valid = true;

// Free the memory allocated by stb
stbi_image_free(data);

return result;
}
}
22 changes: 22 additions & 0 deletions engine/native/core/io/image_loader.cppm
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module;

#include <vector>
#include <cstdint>
#include <filesystem>

export module core.io.image_loader;

export namespace draco::core::io::image_loader
{
struct ImageData
{
std::vector<uint8_t> pixels;
uint32_t width = 0;
uint32_t height = 0;
uint8_t channels = 0;
bool is_valid = false;
};

// Load an image file (PNG, JPG, etc) & decode it to raw RGBA8
ImageData load_image(const std::filesystem::path& path);
}
4 changes: 4 additions & 0 deletions engine/native/core/io/io.cppm
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export module core.io;

export import core.io.filesystem;
export import core.io.image_loader;
Loading