What Graphics API Does ArmorPaint Use? A Deep Dive into Kinc's WebGPU Abstraction
ArmorPaint does not use a single graphics API; instead, it leverages the Kinc engine's WebGPU abstraction layer to dynamically target Vulkan, Metal, Direct3D 12, OpenGL, or WebGPU depending on the platform.
ArmorPaint, the open-source 3D texture painting software, relies on a sophisticated hardware abstraction layer rather than locking itself to one specific rendering backend. According to the armory3d/armorpaint source code, the application utilizes the Kinc engine's WebGPU implementation to automatically select the optimal graphics API for each target platform. This architecture ensures maximum performance across Windows, macOS, Linux, Android, and Web browsers without requiring separate codebases for each graphics backend.
ArmorPaint's Multi-Backend Graphics Architecture
Unlike applications hardcoded to OpenGL or DirectX, ArmorPaint employs a WebGPU abstraction that decouples the rendering logic from the underlying native API. The core header file base/sources/backends/webgpu.h defines the WGPUBackendType enum, which enumerates every supported graphics backend the engine can initialize at runtime.
The supported backends include:
- Vulkan – Default for Windows and Linux desktops, providing high-performance GPU access
- Metal – Native backend for macOS, iOS, and iPadOS devices
- Direct3D 12 – Fallback option on Windows when Vulkan is unavailable
- OpenGL / OpenGL ES – Legacy fallbacks for older Windows/Linux systems and Android devices
- WebGPU – Browser-native implementation for WebAssembly builds
- Null / CPU – Headless or software rendering for server environments
How the WebGPU Abstraction Works
The abstraction layer centers on the WGPUBackendType enum defined in base/sources/backends/webgpu.h (lines 114-124). This enum maps logical backend types to their native implementations:
typedef enum WGPUBackendType {
WGPUBackendType_Undefined = 0,
WGPUBackendType_Null = 1,
WGPUBackendType_WebGPU = 2,
WGPUBackendType_D3D12 = 4,
WGPUBackendType_Metal = 5,
WGPUBackendType_Vulkan = 6,
WGPUBackendType_OpenGL = 7,
WGPUBackendType_OpenGLES = 8,
} WGPUBackendType;
The global GPU state structure g_gpu, declared in base/sources/iron_gpu.h, stores the currently active backend type in its backendType member. This allows the engine to query which graphics API is driving the rendering pipeline at any point during execution.
Platform-Specific Backend Selection
ArmorPaint's build system automatically selects the appropriate backend source files based on the compilation target. The Node.js build script base/project.js (lines 52-78) conditionally adds Vulkan, Metal, Direct3D 12, OpenGL, or WebGPU implementation files to the project depending on the target platform variables.
For example, when targeting Windows desktop, the build system prioritizes Vulkan sources but includes Direct3D 12 and OpenGL fallbacks. When targeting Apple platforms, it exclusively pulls the Metal backend sources. This selection happens at compile time, ensuring the binary only contains the necessary native graphics code for that specific platform.
Working with Graphics Backends in Code
Developers interacting with ArmorPaint's source can manipulate the graphics backend through the WebGPU C API exposed in base/sources/backends/webgpu.h.
Explicitly Selecting a Backend
To force a specific graphics API for debugging or testing purposes, initialize the WGPUContext structure with your desired backend before calling wgpu_init:
#include "backends/webgpu.h"
void force_vulkan_backend(void) {
WGPUContext ctx = {0};
// Force Vulkan instead of letting Kinc auto-select
ctx.backendType = WGPUBackendType_Vulkan;
if (!wgpu_init(&ctx)) {
// Handle initialization failure
fprintf(stderr, "Failed to initialize Vulkan backend\n");
}
}
Querying the Active Backend at Runtime
You can determine which graphics API is currently driving the renderer by accessing the global g_gpu structure:
#include "backends/webgpu.h"
#include "iron_gpu.h"
#include <stdio.h>
void print_graphics_api(void) {
const char *backend_names[] = {
"Undefined", "Null", "WebGPU", "D3D11", "D3D12",
"Metal", "Vulkan", "OpenGL", "OpenGLES"
};
printf("Active graphics API: %s\n",
backend_names[g_gpu.backendType]);
}
WebGPU in WebAssembly Builds
When ArmorPaint compiles to WebAssembly for browser deployment, the same webgpu.h abstraction maps to the browser's native WebGPU JavaScript API:
// Accessed through Kinc's WASM glue code
const canvas = document.getElementById('canvas');
const context = canvas.getContext('webgpu');
const device = await wgpu.requestDevice();
const swapChain = context.configureSwapChain({
device: device,
format: "bgra8unorm"
});
Key Source Files for Graphics Implementation
Understanding the graphics API layer requires examining these critical files in the armory3d/armorpaint repository:
base/sources/backends/webgpu.h– Defines theWGPUBackendTypeenum andWGPUContextstructure used for all graphics initializationbase/sources/iron_gpu.h– Contains the globalg_gpustate structure that tracks the active backendbase/project.js– Build script that injects platform-specific backend sources (Vulkan, Metal, D3D12, etc.) during compilationbase/sources/backends/webgpu_gpu.c– Implementation file containing the platform-specific translation logic between WebGPU calls and native API commands
Summary
- ArmorPaint uses Kinc's WebGPU abstraction layer rather than a single hardcoded graphics API
- The engine supports Vulkan, Metal, Direct3D 12, OpenGL, OpenGL ES, and WebGPU through the
WGPUBackendTypeenum inbase/sources/backends/webgpu.h - Platform selection is automatic, handled by the build system in
base/project.jsand runtime initialization inwgpu_init() - Developers can query or force specific backends using the
g_gpuglobal state andWGPUContextconfiguration - The same codebase compiles to desktop (Windows/Linux/macOS), mobile (iOS/Android), and web targets without changing rendering logic
Frequently Asked Questions
Does ArmorPaint use Metal on macOS?
Yes. When compiled for macOS, iOS, or iPadOS, ArmorPaint automatically selects the Metal backend via WGPUBackendType_Metal as defined in base/sources/backends/webgpu.h. The build system excludes Vulkan and DirectX sources when targeting Apple platforms, ensuring native Metal performance on Apple silicon and Intel Macs.
Can I force ArmorPaint to use OpenGL instead of Vulkan on Windows?
Yes, you can force a specific graphics API by modifying the WGPUContext initialization before wgpu_init() is called. Set ctx.backendType = WGPUBackendType_OpenGL to override the default Vulkan selection. However, this requires rebuilding from source, as the backend selection is compile-time optimized in base/project.js.
What graphics API does the web version of ArmorPaint use?
The WebAssembly build uses the WebGPU backend (WGPUBackendType_WebGPU), which maps to the browser's native WebGPU implementation. This is distinct from WebGL; ArmorPaint requires a browser with native WebGPU support (such as Chrome or Edge) to run in web mode, as it does not fall back to WebGL for web deployment.
Is Vulkan the default graphics API on all desktop platforms?
Vulkan is the default on Windows and Linux, but not on macOS, where Metal is the only supported backend. On Windows, if Vulkan drivers are unavailable, ArmorPaint can fall back to Direct3D 12 or OpenGL, though this requires the appropriate backend sources to be included during the build process defined in base/project.js.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →