Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
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
42 changes: 41 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,53 @@ endif()

project(DraconicEngine LANGUAGES C CXX)

# Ensure that everyone is on the same page hardware wise or else we get errors
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
add_compile_options(-mavx2 -mfma)
endif()

# Only have safe global rules here
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_MODULE_STD ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON) # bgfx & deps give error if this isn't set, this is a temp workaround
# Force all to use Clang or else a mismatch occurs
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++ -lc++abi")

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

include(CTest)

add_subdirectory(engine/native)
add_subdirectory(engine/native)

find_package(PkgConfig REQUIRED)
pkg_check_modules(X11_LIBS REQUIRED IMPORTED_TARGET x11 xext xcursor xrandr xrender xi xfixes)

add_executable(draconic engine/native/main/main.cpp)
enable_modules(draconic)
target_link_libraries(draconic
PRIVATE
rhi
core
bgfx
bx
bimg
-Wl,--whole-archive SDL3::SDL3-static -Wl,--no-whole-archive
c++
c++abi
PkgConfig::X11_LIBS
dl
pthread
m
)

# Shader copying
set(ENGINE_SHADER_DIR "${CMAKE_SOURCE_DIR}/engine/native/rendering/shaders")
add_custom_command(
TARGET draconic POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${ENGINE_SHADER_DIR}"
"$<TARGET_FILE_DIR:draconic>"
COMMENT "Copying shaders to build directory..."
)
1 change: 0 additions & 1 deletion CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
"CMAKE_CXX_STANDARD": "23",
"CMAKE_CXX_STANDARD_REQUIRED": "ON",
"CMAKE_CXX_EXTENSIONS": "OFF",
"CMAKE_CXX_MODULE_STD": "1",
"CMAKE_CXX_FLAGS_INIT": "-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0"
}
},
Expand Down
6 changes: 0 additions & 6 deletions cmake/Compiler.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,6 @@ else()
add_compile_definitions(DEBUG)
endif()

# Force Clang to use libc++
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-stdlib=libc++)
add_link_options(-stdlib=libc++)
endif()

if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
if (CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64")
# TODO: Make SIMD level configurable or detect at runtime
Expand Down
4 changes: 3 additions & 1 deletion engine/native/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ include(Modules)
add_subdirectory(thirdparty)

add_modules_library(core SHARED)
target_link_libraries(core PUBLIC definitions math)
target_link_libraries(core PUBLIC definitions math filesystem)

add_subdirectory(rendering)
4 changes: 3 additions & 1 deletion engine/native/core/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
add_modules_library(definitions)
add_modules_library(math)
target_link_libraries(math PUBLIC definitions)
add_modules_library(filesystem)
target_link_libraries(math PUBLIC definitions)
target_link_libraries(filesystem PUBLIC definitions)
36 changes: 36 additions & 0 deletions engine/native/core/filesystem/filesystem.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
module;

import std;

module core.filesystem;

namespace draco::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 {};
}

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 {};
}
}
9 changes: 9 additions & 0 deletions engine/native/core/filesystem/filesystem.cppm
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export module core.filesystem;

import std;

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

#include <SDL3/SDL.h>
#include <bgfx/bgfx.h>
#include <bx/math.h>
Comment thread
coderabbitai[bot] marked this conversation as resolved.

import core.filesystem;

import rendering.rhi;
import rendering.rhi.vertex;

int main(int argc, char* argv[])
{
if (!SDL_Init(SDL_INIT_VIDEO)) {
std::println("SDL init failed: {}", SDL_GetError());
return -1;
}

SDL_Window* window = SDL_CreateWindow(
"Draconic Engine",
1280, 720,
SDL_WINDOW_RESIZABLE
);

if (!window) {
std::println("Failed to create window: {}", SDL_GetError());
return -1;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}

const char* driver = SDL_GetCurrentVideoDriver();
std::println("Driver: {}", driver ? driver : "Unknown");

void* nwh = nullptr; // Native window handle
void* ndt = nullptr; // Native display type

#if defined(__linux__)

SDL_PropertiesID props = SDL_GetWindowProperties(window);

if (driver && std::string_view(driver) == "x11")
{
ndt = SDL_GetPointerProperty(props, SDL_PROP_WINDOW_X11_DISPLAY_POINTER, nullptr); // Get the X11 display pointer
nwh = (void*)(uintptr_t)SDL_GetNumberProperty(props, SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0); // Get the X11 window number and cast it to a pointer
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

#endif

if (!nwh) {
std::println("Failed to get native window handle");
return -1;
}

if(!ndt) {
std::println("Failed to get native display type");
return -1;
}

// Init the RHI with the native window handle and initial size
if (!draco::rhi::init(ndt, nwh, 1280, 720)) {
std::println("Failed to initialize RHI");
SDL_DestroyWindow(window);
SDL_Quit();
return -1;
}

// Geometry data for a triangle to test rendering
// It includes both positions & colors
draco::rhi::PosColorVertex triangle[] = {
{ 0.0f, 0.5f, 0.0f, 0xff0000ff },
{ 0.5f, -0.5f, 0.0f, 0xff00ff00 },
{ -0.5f, -0.5f, 0.0f, 0xffff0000}
};

auto vbh = draco::rhi::create_vertex_buffer(triangle, sizeof(triangle));

// Load the vertex & fragment shaders
auto vs_data = draco::filesystem::load_binary("vs_triangle.bin");
auto fs_data = draco::filesystem::load_binary("fs_triangle.bin");

// If the path is empty, return an error
if (vs_data.empty() || fs_data.empty()) {
std::println("Failed to load shaders");
std::println("Workin' dir: {}", std::filesystem::current_path().string());
return -1;
}
Comment thread
AR-DEV-1 marked this conversation as resolved.
Outdated

auto vsh = draco::rhi::create_shader(vs_data.data(), (uint32_t)vs_data.size());
auto fsh = draco::rhi::create_shader(fs_data.data(), (uint32_t)fs_data.size());


// TODO: Expose our own macros for the state flags instead of using bgfx's directly, tis is just for testin'
auto pipeline = draco::rhi::create_pipeline({vsh, fsh, (0
| BGFX_STATE_WRITE_RGB
| BGFX_STATE_WRITE_A
| BGFX_STATE_MSAA
| BGFX_STATE_PT_TRISTRIP)});

bool running = true;

while (running)
{
SDL_Event event;
while (SDL_PollEvent(&event))
{
if (event.type == SDL_EVENT_QUIT)
running = false;
}

int w, h;
SDL_GetWindowSize(window, &w, &h);

draco::rhi::resize(uint16_t(w), uint16_t(h));

draco::rhi::begin_frame();

draco::rhi::RenderPacket packet{};
packet.vertex_buffer = vbh;
packet.pipeline = pipeline;
bx::mtxIdentity(packet.model);

draco::rhi::submit(packet, 0);
Comment thread
AR-DEV-1 marked this conversation as resolved.
Outdated

draco::rhi::end_frame();
}

draco::rhi::shutdown();

SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}

// Fun fact: AR literally went mad & tis is the result
Comment thread
AR-DEV-1 marked this conversation as resolved.
Outdated
3 changes: 3 additions & 0 deletions engine/native/rendering/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
add_modules_library(rhi SHARED)
target_sources(rhi PRIVATE rhi/rhi_bgfx.cpp rhi/vertex.cppm)
target_link_libraries(rhi PUBLIC core bgfx bx)
Comment thread
AR-DEV-1 marked this conversation as resolved.
Outdated
46 changes: 46 additions & 0 deletions engine/native/rendering/rhi/rhi.cppm
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
export module rendering.rhi;

#include <cstdint>

export namespace draco::rhi
{
using BufferHandle = uint16_t;
using PipelineHandle = uint16_t;
using ShaderHandle = uint16_t;
using ViewID = uint16_t;

struct RenderPacket
{
uint64_t sort_key;

BufferHandle vertex_buffer;
BufferHandle index_buffer;
PipelineHandle pipeline;

float model[16];
uint32_t draw_tags;
};

struct PipelineDesc
{
ShaderHandle vs;
ShaderHandle fs;
uint64_t state;
};

bool init(void* display_type, void* window_handle, uint16_t width, uint16_t height);
void shutdown();

void resize(uint16_t width, uint16_t height);

ShaderHandle create_shader(const void* data, uint32_t size);
PipelineHandle create_pipeline(const PipelineDesc&);

BufferHandle create_vertex_buffer(const void* data, uint32_t size);
BufferHandle create_index_buffer(const void* data, uint32_t size);

void submit(const RenderPacket&, ViewID);

void begin_frame();
void end_frame();
}
Loading