Skip to content
Open
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
59 changes: 59 additions & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
FROM ubuntu:24.04

ARG VulkanSDKVersion=1.4.335.0
ARG SDL3TagOrCommit=release-3.4.0

WORKDIR /app

# Install basic build tools
RUN apt-get update && apt-get install -y \
curl \
xz-utils \
cmake \
ninja-build \
gdb

# Install other dependencies
RUN apt-get install -y \
# CMake dependencies
git pkg-config \
# SDL3 dependencies (https://wiki.libsdl.org/SDL3/README-linux#build-dependencies)
cmake ninja-build gnome-desktop-testing libasound2-dev libpulse-dev \
libaudio-dev libfribidi-dev libjack-dev libsndio-dev libx11-dev libxext-dev \
libxrandr-dev libxcursor-dev libxfixes-dev libxi-dev libxss-dev libxtst-dev \
libxkbcommon-dev libdrm-dev libgbm-dev libgl1-mesa-dev libgles2-mesa-dev \
libegl1-mesa-dev libdbus-1-dev libibus-1.0-dev libudev-dev \
libpipewire-0.3-dev libwayland-dev libdecor-0-dev liburing-dev \
# SDL3 dependencies not mentioned in the README
libusb-1.0-0-dev \
# SDL3_mixer dependencies
libogg-dev libopus-dev libopusfile-dev libgme-dev libxmp-dev libfluidsynth-dev fluidsynth libwavpack-dev \
# Other VVE dependencies
libglm-dev \
# Documentation tools
doxygen graphviz

# During configuration, CMake can't find libunwind - don't know why. It works without it.
RUN apt-get install -y \
build-essential \
clang-20 libc++-20-dev libc++abi-20-dev

ENV XDG_RUNTIME_DIR=/run/user

# Download, build and install SDL3 - needed for VECS Console on Linux
RUN git clone -b ${SDL3TagOrCommit} --depth 1 https://github.com/libsdl-org/SDL.git /tmp/SDL3
WORKDIR /tmp/SDL3
RUN cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -G Ninja && \
cmake --build build && cmake --install build --prefix /usr/local
WORKDIR /app
RUN rm -rf /tmp/SDL3

# Download Vulkan SDK
RUN curl -o /tmp/vulkansdk.tar.gz https://sdk.lunarg.com/sdk/download/${VulkanSDKVersion}/linux/vulkansdk-linux-x86_64-${VulkanSDKVersion}.tar.xz
RUN mkdir /opt/VulkanSDK && tar -xf /tmp/vulkansdk.tar.gz -C /opt/VulkanSDK && rm /tmp/vulkansdk.tar.gz
RUN echo "source /opt/VulkanSDK/${VulkanSDKVersion}/setup-env.sh" >> ~/.bashrc
ENV VULKAN_SDK=/opt/VulkanSDK/${VulkanSDKVersion}/x86_64
RUN echo "VULKAN_SDK=${VULKAN_SDK}"

# Clean up download related packages
RUN apt-get remove -y curl xz-utils
72 changes: 72 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// For format details, see https://aka.ms/devcontainer.json.
{
"name": "C++",
"build": {
"dockerfile": "Dockerfile"
},
// "dockerComposeFile": "compose.yml",
// "service": "cpp-dev",
"runArgs": [
"--device=/dev/dri",
"--group-add=video",
"--ipc=host"
],

"containerEnv": {
"DISPLAY": "${localEnv:DISPLAY}",
"XAUTHORITY": "/tmp/.docker.xauth",
// PulseAudio / PipeWire configuration
"PULSE_SERVER": "unix:/run/user/host/pulse/native",
"PULSE_COOKIE": "/tmp/pulseaudio.cookie",
"PIPEWIRE_RUNTIME_DIR": "/run/user/host"
},

"mounts": [
{
"type": "bind",
"source": "/tmp/.X11-unix",
"target": "/tmp/.X11-unix"
},
{
"type": "bind",
"source": "${localEnv:HOME}/.Xauthority",
"target": "/tmp/.docker.xauth"
},
// Mount XDG_RUNTIME_DIR for shared sockets (PulseAudio, PipeWire)
{
"type": "bind",
"source": "${localEnv:XDG_RUNTIME_DIR}",
"target": "/run/user/host"
},
// Mount PulseAudio cookie if it exists
{
"type": "bind",
"source": "${localEnv:HOME}/.config/pulse/cookie",
"target": "/tmp/pulseaudio.cookie"
}
],


// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},

// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],

// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "gcc -v",

// Configure tool-specific properties.
"customizations": {
"vscode": {
"extensions": [
"ms-vscode.cpptools-extension-pack",
"Gruntfuggly.todo-tree"
]
}
},

// Connect as root so the container can read the mounted Xauthority (which is typically 0600 on host)
// More info: https://aka.ms/dev-containers-non-root
"remoteUser": "root"
}
2 changes: 1 addition & 1 deletion .vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
],
"windowsSdkVersion": "10.0.22000.0",
"cppStandard": "c++20",
"intelliSenseMode": "windows-msvc-x64",
"intelliSenseMode": "${default}",
"configurationProvider": "ms-vscode.cmake-tools"
}
],
Expand Down
25 changes: 19 additions & 6 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@
"environment": [],
"externalConsole": false,
"MIMode": "lldb",
"MIDebuggerPath": "/usr/bin/lldb"
"miDebuggerPath": "/usr/bin/lldb"
},
{
"name": "AppleClang Helper",
Expand All @@ -161,7 +161,7 @@
"environment": [],
"externalConsole": false,
"MIMode": "lldb",
"MIDebuggerPath": "/usr/bin/lldb"
"miDebuggerPath": "/usr/bin/lldb"
},
{
"name": "AppleClang Game",
Expand All @@ -174,7 +174,7 @@
"environment": [],
"externalConsole": false,
"MIMode": "lldb",
"MIDebuggerPath": "/usr/bin/lldb"
"miDebuggerPath": "/usr/bin/lldb"
},
{
"name": "Linux Clang Test",
Expand All @@ -187,7 +187,7 @@
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"MIDebuggerPath": "/usr/bin/gdb"
"miDebuggerPath": "/usr/bin/gdb"
},
{
"name": "Linux Clang Helper",
Expand All @@ -200,7 +200,7 @@
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"MIDebuggerPath": "/usr/bin/gdb"
"miDebuggerPath": "/usr/bin/gdb"
},
{
"name": "Linux Clang Game",
Expand All @@ -213,7 +213,20 @@
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"MIDebuggerPath": "/usr/bin/gdb"
"miDebuggerPath": "/usr/bin/gdb"
},
{
"name": "Linux Clang Physics",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/examples/physics/physics",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "/usr/bin/gdb"
}
]

Expand Down
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,6 @@
"source_location": "cpp",
"future": "cpp"
},
"C_Cpp.errorSquiggles": "enabled"
"C_Cpp.errorSquiggles": "enabled",
"C_Cpp.default.cppStandard": "c++20"
}
42 changes: 42 additions & 0 deletions README_Linux.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# The Vienna Vulkan Engine (VVE) - Linux
This README describes how to set up the dev enviroment on Linux via VSCode and Docker.

> [!NOTE]
> Only tested with an AMD GPU and X11 on Linux Mint/Ubuntu. Also works with an Intel iGPU but fullscreening may be broken.
>
> With an NVIDIA GPU you might need the [nvidia-container-toolkit](<https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html>) locally installed and need to edit `.devcontainer/devcontainer.json` and replace `--device=/dev/dri` with `--gpus all`.
>
> For native Wayland you may ask an AI of your choice to assist you.
>
> Also audio may or may not work depending on your setup - it worked fine for me with PipewWire as audio server.

## Prerequesites
* [VSCode](<https://code.visualstudio.com/>)
* [Docker Engine](<https://docs.docker.com/engine/install/>) - NOT Docker Desktop!!
* Be in the `docker` group to use docker commands without root
* [Dev Container Extension](<https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers>)

## Setup
After cloning and opening the project in VSCode open the Command Pallete (`F1`) and use the `>Dev Containers: Rebuild and Reopen in Container` command to build the development container and open the project inside it.

Once you are in the container you can check if the GPU is detected by executing
```bash
vulkaninfo | head -n 60
```
> [!NOTE]
> If you get an output like this: `Authorization required, but no authorization protocol specified`
>
> Then grant permission to the root user to use your X11 session - RUN ON LOCAL USER, NOT IN THE CONTAINER!:
> ```bash
> xhost +si:localuser:root
> ```
> You can remove the permissions again with
> ```bash
> xhost -si:localuser:root
> ```

You can now select the right compiler with `>CMake: Select a Kit` - I use *Clang \[...\]* (the one without *-cl*). If the list is empty select the *\[Scan for Kits\]* option and invoke the command again.

And use `>CMake: Configure` and `>CMake: Build`. To change the build type use `>CMake: Select Variant` (e.g. *Debug* or *Release*).

To debug/run an example use the *Run and Debug* (`CTRL+SHIFT+D`) option in the sidebar and select the appropriate option or create your own by modifying `.vscode/launch.json`.
28 changes: 14 additions & 14 deletions examples/physics/VPE.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,12 +228,12 @@ namespace vpe {

inline static glmmat3 CTrans = glm::transpose(C);

static constexpr glmvec3 toPhysics(glmvec3 vec) { return C * vec; }
static constexpr glmmat3 toPhysics(glmmat3 mat) { return CTrans * mat * C; }
static constexpr glmmat4 toPhysics(glmmat4 mat) { return glmmat4{CTrans} * mat * glmmat4{C}; }
static constexpr glmvec3 fromPhysics(glmvec3 vec) { return CTrans * vec; }
static constexpr glmmat3 fromPhysics(glmmat3 mat) { return C * mat * CTrans; }
static constexpr glmmat4 fromPhysics(glmmat4 mat) { return glmmat4{C} * mat * glmmat4{CTrans};}
static const glmvec3 toPhysics(glmvec3 vec) { return C * vec; }
static const glmmat3 toPhysics(glmmat3 mat) { return CTrans * mat * C; }
static const glmmat4 toPhysics(glmmat4 mat) { return glmmat4{CTrans} * mat * glmmat4{C}; }
static const glmvec3 fromPhysics(glmvec3 vec) { return CTrans * vec; }
static const glmmat3 fromPhysics(glmmat3 mat) { return C * mat * CTrans; }
static const glmmat4 fromPhysics(glmmat4 mat) { return glmmat4{C} * mat * glmmat4{CTrans};}

/// <summary>
/// This class implements a simple rigid body physics engine.
Expand All @@ -248,12 +248,12 @@ namespace vpe {

inline static glmmat3 CTrans = glm::transpose(C);

static constexpr glmvec3 toPhysics(glmvec3 vec) { return C * vec; }
static constexpr glmmat3 toPhysics(glmmat3 mat) { return CTrans * mat * C; }
static constexpr glmmat4 toPhysics(glmmat4 mat) { return glmmat4{CTrans} * mat * glmmat4{C}; }
static constexpr glmvec3 fromPhysics(glmvec3 vec) { return CTrans * vec; }
static constexpr glmmat3 fromPhysics(glmmat3 mat) { return C * mat * CTrans; }
static constexpr glmmat4 fromPhysics(glmmat4 mat) { return glmmat4{C} * mat * glmmat4{CTrans};}
static const glmvec3 toPhysics(glmvec3 vec) { return C * vec; }
static const glmmat3 toPhysics(glmmat3 mat) { return CTrans * mat * C; }
static const glmmat4 toPhysics(glmmat4 mat) { return glmmat4{CTrans} * mat * glmmat4{C}; }
static const glmvec3 fromPhysics(glmvec3 vec) { return CTrans * vec; }
static const glmmat3 fromPhysics(glmmat3 mat) { return C * mat * CTrans; }
static const glmmat4 fromPhysics(glmmat4 mat) { return glmmat4{C} * mat * glmmat4{CTrans};}

public:

Expand Down Expand Up @@ -1669,8 +1669,8 @@ namespace vpe {
/// <param name="contact">Contact between the two bodies.</param>
/// <param name="eq">Result of edge query.</param>
void createEdgeContact(Contact& contact, EdgeQuery& eq) {
Face* ref_face = maxFaceAlignment(eq.m_normalL, eq.m_edge_ref->m_edge_face_ptrs, fabs); //face of A best aligned with the contact normal
Face* inc_face = maxFaceAlignment(-RTOIN(eq.m_normalL), eq.m_edge_inc->m_edge_face_ptrs, fabs); //face of B best aligned with the contact normal
Face* ref_face = maxFaceAlignment(eq.m_normalL, eq.m_edge_ref->m_edge_face_ptrs, [](real x) { return static_cast<real>(fabs(x)); }); //face of A best aligned with the contact normal
Face* inc_face = maxFaceAlignment(-RTOIN(eq.m_normalL), eq.m_edge_inc->m_edge_face_ptrs, [](real x) { return static_cast<real>(fabs(x)); }); //face of B best aligned with the contact normal

real dp_ref = fabs(glm::dot(eq.m_normalL, ref_face->m_normalL)); //Use the better aligned face as reference face.
real dp_inc = fabs(glm::dot(eq.m_normalL, inc_face->m_normalL));
Expand Down