Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
6458806
Start workin' on RHI
AR-DEV-1 Apr 7, 2026
b58cba3
Idk how I missed these, they coulda been major security vulnerabilities
AR-DEV-1 Apr 10, 2026
7b92c6b
Do what CodeRabbit said & add Wayland support (still doesn't work)
AR-DEV-1 Apr 13, 2026
64c0d2f
Fix includes
AR-DEV-1 Apr 13, 2026
c955c7d
Add uniform management
AR-DEV-1 Apr 13, 2026
eebea86
Add texture loadin' support
AR-DEV-1 Apr 15, 2026
b433315
Add framebuffer handles, render targets & dynamic/transient buffers s…
AR-DEV-1 Apr 20, 2026
436c405
Add depth & stencil testing, Alpha blending modes, dedicated sampler …
AR-DEV-1 Apr 26, 2026
d1694ef
Draco is 3D!
AR-DEV-1 May 5, 2026
64615cd
Add camera controller & remove all std imports (replaced by the tradi…
AR-DEV-1 May 6, 2026
27f83bc
Apply suggestions
AR-DEV-1 May 6, 2026
80af026
Fix issues
AR-DEV-1 May 6, 2026
43141d2
Minor improvements & fixes
AR-DEV-1 May 7, 2026
b448c46
Add mesh abstraction + compilation of shaders when building
AR-DEV-1 May 8, 2026
97d97ee
Add transform system
AR-DEV-1 May 8, 2026
c2c80b5
Upgrade render pipeline architecture (material + RenderGraph refactor)
AR-DEV-1 May 10, 2026
2f2f08c
Start working on Quad/Sprite renderer
AR-DEV-1 May 12, 2026
e43bcea
Merge branch 'master' of https://github.com/Redot-Engine/DraconicEngi…
AR-DEV-1 May 12, 2026
b117660
Work on QuadRenderer
AR-DEV-1 May 12, 2026
463ab5e
QuadRenderer finally works!
AR-DEV-1 May 17, 2026
e148291
Merge branch 'Redot-Engine:master' into rendering-hardware-abstraction
AR-DEV-1 May 17, 2026
6dcdc0f
Small stuff
AR-DEV-1 May 17, 2026
1046f1d
Apply some suggestions
AR-DEV-1 May 17, 2026
833d9a8
Forgot these
AR-DEV-1 May 17, 2026
d28e09f
Minor fixes
AR-DEV-1 May 17, 2026
62db8b7
Minor fixes
AR-DEV-1 May 17, 2026
7183e07
Fix incorrect declaration
AR-DEV-1 May 17, 2026
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);
}
137 changes: 137 additions & 0 deletions engine/native/main/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
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());
draco::rhi::shutdown();
SDL_DestroyWindow(window);
SDL_Quit();
return -1;
}

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.index_buffer = UINT16_MAX; // No index buffer
packet.pipeline = pipeline;
bx::mtxIdentity(packet.model);

draco::rhi::submit(packet, 0);

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