Skip to content

Boreal 3D Framework

A 3D rendering framework. Not quite an "engine" since it lacks tooling for editing assets, as well as any for mof proprietary data formatting or other requirements. Its little more than abstractions atop low level and platform dependent programming, although in reality, this is quite a lot.

Sponza, remastered by Intel, from an early iteration of the renderer.
A later WIP shot of the renderer.

Github repo is currently unavailable since it is private for now, as the project is still being refactored constantly and core parts of the renderer are still being worked on. Currently, the two "modules" built from scratch are the renderer and the input system.

Build System

CMake is the industry standard and for good reason, but I went with Premake. I hate CMake so much, and a lot of its built-in convenience functions create some extremely messy intermediate outputs and other artifacts which are hard to follow, and imo can create debt down the line. That being said, I still have to interact with it whenever I want to move a third party dependency over to Premake.

Third Party Dependencies

A major goal is to have third party dependencies always compiled from source, and to stay out of their directories. This way no forks have to be maintained, and they can be properly registered as git submodules. This lets the project/dev "sync" with their latest revisions very easily, and prevents labyrinthine modifications.

This is what the third party dependencies directory looks like.

Build Scripts

I want total control over the project, beholden to no caching of files or metadata, nothing. I can build the project, rebuild the entire project, clear the build directory, even completely reinitialize git from scratch, with no consequences.

Here is my current build script. Its focused around Windows + Visual Studio but should work just fine with other platforms and systems. Its platform agnostic assuming Git for Windows is installed, which comes with bash. There's some extra candy in here in the exit handling code. I'm lazy about cleaning up terminal windows, but I want to read logs ocassionally. So, in the event of an exit code 0, the script enters a 5 second timeout where the dev can either press a key to keep the window open, or it'll close itself.

build.sh
#!/bin/bash

CONFIG="${1:-Release}"
PLATFORM="${2:-x64}"

# Validate configuration
if [[ "$CONFIG" != "Debug" && "$CONFIG" != "Release" ]]; then
    echo "Error: Invalid configuration '$CONFIG'. Use 'Debug' or 'Release'."
    exit 1
fi

BUILD_RESULT=1

# Find a build tool
build_with_msbuild() {
    local VSWHERE="/c/Program Files (x86)/Microsoft Visual Studio/Installer/vswhere.exe"
    [[ ! -f "$VSWHERE" ]] && return 1

    local VS_PATH
    VS_PATH=$("$VSWHERE" -latest -requires Microsoft.Component.MSBuild -property installationPath)
    [[ -z "$VS_PATH" ]] && return 1

    local MSBUILD="$VS_PATH/MSBuild/Current/Bin/MSBuild.exe"
    [[ ! -f "$MSBUILD" ]] && return 1

    echo "Building with MSBuild [$CONFIG|$PLATFORM]"
    "$MSBUILD" boreal.slnx -p:Configuration="$CONFIG" -p:Platform="$PLATFORM" -m -verbosity:minimal -clp:ForceNoAlign
    BUILD_RESULT=$?
    return 0
}

build_with_make() {
    command -v make &>/dev/null || return 1
    [[ -f Makefile || -d build ]] || return 1

    local cfg
    cfg=$(echo "${CONFIG}_${PLATFORM}" | tr '[:upper:]' '[:lower:]')

    echo "Building with Make [$cfg]"
    if [[ -f build/Makefile ]]; then
        make -C build config="$cfg" -j"$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4)"
    else
        make config="$cfg" -j"$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4)"
    fi
    BUILD_RESULT=$?
    return 0
}

build_with_xcodebuild() {
    command -v xcodebuild &>/dev/null || return 1
    ls *.xcworkspace &>/dev/null || return 1

    echo "Building with xcodebuild [$CONFIG]"
    xcodebuild -workspace boreal.xcworkspace -scheme boreal -configuration "$CONFIG"
    BUILD_RESULT=$?
    return 0
}

# Try build tools in order of preference
if [[ -f boreal.slnx ]] && build_with_msbuild; then
    :
elif build_with_make; then
    :
elif build_with_xcodebuild; then
    :
else
    echo "Error: No supported build tool found."
    echo "Supported: MSBuild (Windows), Make (any), xcodebuild (macOS)"
    exit 1
fi

if [[ $BUILD_RESULT -eq 0 ]]; then
    echo "Build complete."
else
    echo "Build failed with code $BUILD_RESULT"
fi

function pause(){
   read -p "$*"
}

read -t 5 -n 1 -p "Press any key in 5 seconds to keep window open.." key
if [[ $? -gt 128 ]] ; then
    echo -e "\nWindow exiting.."
else
    echo ""
    pause 'Key pressed. Keeping window open. Press [Enter] to close..'
fi

# return exit code 0 here as alternative to enabling force-close on terminal
exit $BUILD_RESULT