Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
c9f5b3f
core/DebugScene : change default arrow color
ManifoldFR Aug 12, 2025
6568b06
core/DebugScene : change default grid color
ManifoldFR Aug 12, 2025
2944d91
core/DebugScene : add getters for subsystems
ManifoldFR Aug 12, 2025
b1740af
multibody/Visualizer : set Wayland scaling hint
ManifoldFR Aug 12, 2025
353b0a5
core/Scene : add `update()` to the concept
ManifoldFR Aug 13, 2025
4cee255
multibody/Visualizer : wayland video scale hint works poorly on mixed…
ManifoldFR Aug 13, 2025
8c2ba89
[gui] Move all GUI functions into "gui" namespaces
ManifoldFR Aug 13, 2025
7c2a964
multibody : move robot debug GUI into `RobotDebugSystem`
ManifoldFR Aug 13, 2025
a5d7b55
multibody/RobotDebug : add external forces to debug elts GUI
ManifoldFR Aug 13, 2025
6ac6175
multibody/RobotScene : make PipelineType an enum class
ManifoldFR Aug 13, 2025
5686a5b
multibody/RobotScene : add wireframe pipeline
ManifoldFR Aug 13, 2025
1d7281d
multibody : integrate wireframe mode switch in Visualizer GUI
ManifoldFR Aug 13, 2025
dd0766e
core : add RAII class `GraphicsPipeline`
ManifoldFR Aug 14, 2025
dc85514
core/DepthAndShadowPass : use new RAII `GraphicsPipeline`
ManifoldFR Aug 14, 2025
ae27dc0
multibody/RobotScene : better graphics pipeline management
ManifoldFR Aug 14, 2025
001ad67
core/debug/DepthViz : use RAII `GraphicsPipeline`
ManifoldFR Aug 14, 2025
83a72e0
core : some RAII class fixes
ManifoldFR Aug 14, 2025
34511ed
core/DebugScene : use RAII `GraphicsPipeline`
ManifoldFR Aug 14, 2025
091b699
posteffects/SSAO : use RAII `GraphicsPipeline`
ManifoldFR Aug 14, 2025
5f3d297
multibody/RobotScene.h : remove commented-out code
ManifoldFR Aug 14, 2025
195220b
[core/debug | examples/LitMesh] : use RAII `GraphicsPipeline`
ManifoldFR Aug 14, 2025
c7b9c05
core : move contents on `Scene.h` into `Core.h` header
ManifoldFR Aug 14, 2025
9279a60
core/Texture.h : add `sampleCount()` getter
ManifoldFR Aug 14, 2025
24364a1
core/RenderContext : introduce intermediate color render target, star…
ManifoldFR Aug 14, 2025
31b9cdc
core/Window.h : small fix
ManifoldFR Aug 14, 2025
5631d20
bindings/python : expose more RenderContext and Window attributes
ManifoldFR Aug 14, 2025
d8dfa16
Update CHANGELOG
ManifoldFR Aug 14, 2025
ac5fd4b
Merge branch 'render-context-present' into next
ManifoldFR Aug 14, 2025
d312a57
render : Use resolved targets where needed
ManifoldFR Aug 14, 2025
cc27a75
core/RenderContext : implement `createMsaaTargets()`
ManifoldFR Aug 14, 2025
00f7d12
bindings/python : expose enableMSAA()
ManifoldFR Aug 14, 2025
260b610
core/GuiSystem : render to resolved
ManifoldFR Aug 14, 2025
d11359e
core/RenderContext : remove resolveMSAA()
ManifoldFR Aug 14, 2025
fbff0cf
core/Device.h : implement move assignment operator
ManifoldFR Aug 18, 2025
a0cdb43
core/RenderContext.h : implement move ctor and assignment op
ManifoldFR Aug 18, 2025
02d047b
multibody/Visualizer : rename a data member in Config
ManifoldFR Aug 18, 2025
92d02a7
utils/VideoRecorder : rename `writeTextureVideoToFrame` to `writeText…
ManifoldFR Aug 18, 2025
a317612
examples/MeshNormalsRgb.cpp : use the `GraphicsPipeline` class
ManifoldFR Aug 18, 2025
cc34d59
core/Texture.h : add comparison operator
ManifoldFR Aug 18, 2025
b3b747b
src : use `CANDLEWICK_ASSERT` more often
ManifoldFR Aug 18, 2025
1107fb3
core/GraphicsPipeline : store pipeline metadata
ManifoldFR Aug 18, 2025
86cd7e3
multibody/RobotScene : throw an actual error when setting config afte…
ManifoldFR Aug 18, 2025
bd8f5df
multibody/RobotScene.cpp : consistency
ManifoldFR Aug 18, 2025
a5a24e2
examples/Visualizer.cpp : set sample count
ManifoldFR Aug 18, 2025
8b89831
core/CommandBuffer : use CANDLEWICK_ASSERT(), make some function impl…
ManifoldFR Aug 18, 2025
bb18908
utils/WriteTextureToImage.h : add a warning
ManifoldFR Aug 18, 2025
cd95244
core/Texture.h : remove `hasValue()` and add getter for current devic…
ManifoldFR Aug 18, 2025
0d0c624
multibody/RobotScene.cpp : rename some stuff internally
ManifoldFR Aug 18, 2025
be4d5f0
core/RenderContext.cpp : use sizeInPixels()
ManifoldFR Aug 18, 2025
0635ad2
multibody/Visualizer : working high DPI support
ManifoldFR Aug 18, 2025
e3c3c79
multibody/Visualizer : add some notes + todo about collision geometries
ManifoldFR Aug 18, 2025
111c44a
examples/Visualizer.cpp : add floor in this example
ManifoldFR Aug 18, 2025
1a70711
multibody/LoadCoalGeometries.cpp : fix translation by 'd' in coal::Plane
ManifoldFR Aug 18, 2025
1db2506
Remove deprecated header LoadCoalPrimitives.h
ManifoldFR Aug 18, 2025
a247195
Reorganize CHANGELOG
ManifoldFR Aug 18, 2025
c13d2f4
core: move header `LoadCoalGeometries.h` and its functions to library…
ManifoldFR Aug 18, 2025
0069cf6
core/GraphicsPipeline : add getter fo no. of color targets
ManifoldFR Aug 19, 2025
5f7efbf
core/RenderContext.cpp : automatically recreate depth texture for MSAA
ManifoldFR Aug 19, 2025
ecedeef
core/DebugScene : add MSAA target support
ManifoldFR Aug 19, 2025
cef8956
RobotScene : remove unused config members
ManifoldFR Aug 19, 2025
605ee36
multibody/Visualizer : perform blit while swapchain is acquired
ManifoldFR Aug 19, 2025
38aaf71
Update pre-commit config
ManifoldFR Aug 19, 2025
eb949f7
src/fonts : add clang format ignore
ManifoldFR Aug 19, 2025
fe2667e
examples/Visualizer.cpp : pass sample count in CLI
ManifoldFR Aug 19, 2025
256ea8f
core/errors : fix terminate_with_message() automatic source code loca…
ManifoldFR Aug 19, 2025
850683f
multibody/RobotScene : *always* render to G-buffer normal map
ManifoldFR Aug 19, 2025
2872517
core/RenderContext : validate MSAA sample size
ManifoldFR Aug 19, 2025
600d8a1
shaders : use texelFetch() for WBOITComposite shader, recompile (with…
ManifoldFR Aug 19, 2025
415679f
examples/Visualizer.cpp : add transparent ball (to debug C++ Visualiz…
ManifoldFR Aug 19, 2025
b252098
multibody/Visualizer : leave acquiring swapchain to bit where we present
ManifoldFR Aug 19, 2025
1cf87d3
[multibody] Add MSAA support
ManifoldFR Aug 19, 2025
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
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ repos:
types: [text]
files: '\.(cpp|cxx|c|h|hpp|hxx|txx)$'
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
rev: v6.0.0
hooks:
- id: check-added-large-files
args: ['--maxkb=1800']
Expand All @@ -30,12 +30,12 @@ repos:
doc/doxygen-awesome.*
)$
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: 'v0.12.7'
rev: 'v0.12.9'
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
- id: ruff-format
- repo: https://github.com/BlankSpruce/gersemi
rev: 0.21.0
rev: 0.22.1
hooks:
- id: gersemi
29 changes: 29 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,35 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- core/DepthAndShadowPass : add support for multisampled depth/shadow passes
- multibody : add MSAA support in `RobotScene` and `Visualizer`
- core/RenderContext.h : implement move ctor and assignment op
- multibody/Visualizer : working high DPI support
- core/GraphicsPipeline : store pipeline metadata
- core/Texture.h : add comparison operator
- core/Texture.h : add `sampleCount()` getter
- core : add RAII class `GraphicsPipeline`
- multibody : add wireframe mode switch in Visualizer GUI
- multibody/RobotDebug : add external forces to debug elts GUI
- core/DebugScene : add getters for subsystems

### Changed

- multibody/RobotScene : always render to G-buffer normal map
- core: move header `LoadCoalGeometries.h` and its functions to library core
- multibody/Visualizer : rename a data member in Config
- core/Device.h : implement move assignment operator
- core/RenderContext : introduce intermediate color render target, start introducing MSAA texture buffers
- core : move contents on `Scene.h` into `Core.h` header
- multibody : better graphics pipeline management using RAII class
- gui : Move all GUI functions into "gui" namespaces

### Removed

- Remove deprecated header `candlewick/multibody/LoadCoalPrimitives.h`

## [0.9.0] - 2025-08-12

- utils/VideoRecorder : check filename extension (must be ".mp4")
Expand Down
22 changes: 21 additions & 1 deletion bindings/python/src/expose-renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,22 @@ void exposeRenderer() {
.def("driverName", &Device::driverName, ("self"_a))
.def("shaderFormats", &Device::shaderFormats, ("self"_a));

bp::class_<Window, boost::noncopyable>("Window", bp::no_init)
.def("pixelDensity", &Window::pixelDensity, ("self"_a))
.def("displayScale", &Window::displayScale, ("self"_a))
.def(
"title", +[](const Window &w) { return w.title().data(); },
("self"_a));

#define _c(name) value(#name, SDL_GPUSampleCount::name)
bp::enum_<SDL_GPUSampleCount>("SampleCount")
._c(SDL_GPU_SAMPLECOUNT_1)
._c(SDL_GPU_SAMPLECOUNT_2)
._c(SDL_GPU_SAMPLECOUNT_4)
._c(SDL_GPU_SAMPLECOUNT_8)
#undef _c
.export_values();

bp::def("get_num_gpu_drivers", SDL_GetNumGPUDrivers,
"Get number of available GPU drivers.");

Expand All @@ -36,5 +52,9 @@ void exposeRenderer() {
"Automatically detect the compatible set of shader formats."});

bp::class_<RenderContext, boost::noncopyable>("RenderContext", bp::no_init)
.def_readonly("device", &RenderContext::device);
.def_readonly("device", &RenderContext::device)
.def_readonly("window", &RenderContext::window)
.add_property("hasDepthTexture", &RenderContext::hasDepthTexture)
.def("enableMSAA", &RenderContext::enableMSAA, ("self"_a, "samples"))
.def("disableMSAA", &RenderContext::disableMSAA, ("self"_a));
}
15 changes: 8 additions & 7 deletions examples/ColoredCube.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ int main() {
Window{window}, // take ownership of existing SDL_Window handle
depth_stencil_format);
Device &device = ctx.device;
SDL_GPUTexture *depthTexture = ctx.depth_texture;

// Buffers

Expand Down Expand Up @@ -216,7 +215,6 @@ int main() {
SDL_GPURenderPass *render_pass;
SDL_GPUBufferBinding vertex_binding = mesh.getVertexBinding(0);
CommandBuffer cmdbuf{device};
SDL_GPUTexture *&swapchain = ctx.swapchain;
const Float3 center{0., 0., 0.};
Float3 eye{0., 0., 0.};
// start at phi -> eye.x = 2.5, eye.y = 0.5
Expand All @@ -227,18 +225,20 @@ int main() {
projViewMat = perp * view * modelMat;

if (ctx.waitAndAcquireSwapchain(cmdbuf)) {
SDL_GPUColorTargetInfo ctinfo{.texture = swapchain,
.clear_color = SDL_FColor{},
.load_op = SDL_GPU_LOADOP_CLEAR,
.store_op = SDL_GPU_STOREOP_STORE};
SDL_GPUColorTargetInfo ctinfo{
.texture = ctx.colorTarget(),
.clear_color = SDL_FColor{},
.load_op = SDL_GPU_LOADOP_CLEAR,
.store_op = SDL_GPU_STOREOP_STORE,
};
SDL_GPUDepthStencilTargetInfo depth_target;
SDL_zero(depth_target);
depth_target.clear_depth = 1.0f;
depth_target.load_op = SDL_GPU_LOADOP_CLEAR;
depth_target.store_op = SDL_GPU_STOREOP_DONT_CARE;
depth_target.stencil_load_op = SDL_GPU_LOADOP_DONT_CARE;
depth_target.stencil_store_op = SDL_GPU_STOREOP_DONT_CARE;
depth_target.texture = depthTexture;
depth_target.texture = ctx.depthTarget();
depth_target.cycle = true;
render_pass = SDL_BeginGPURenderPass(cmdbuf, &ctinfo, 1, &depth_target);
SDL_BindGPUGraphicsPipeline(render_pass, pipeline);
Expand All @@ -254,6 +254,7 @@ int main() {
SDL_Log("Failed to acquire swapchain: %s", SDL_GetError());
break;
}
ctx.presentToSwapchain(cmdbuf);
cmdbuf.submit();
}

Expand Down
49 changes: 26 additions & 23 deletions examples/LitMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "candlewick/core/RenderContext.h"
#include "candlewick/core/Mesh.h"
#include "candlewick/core/GraphicsPipeline.h"
#include "candlewick/core/Shader.h"
#include "candlewick/utils/MeshData.h"
#include "candlewick/utils/LoadMesh.h"
Expand Down Expand Up @@ -78,8 +79,7 @@ int main() {

/** CREATE PIPELINE **/
SDL_GPUDepthStencilTargetInfo depth_target_info;
SDL_GPUGraphicsPipeline *pipeline;
{
GraphicsPipeline pipeline = [&]() {
auto vertexShader = Shader::fromMetadata(device, "PbrBasic.vert");
auto fragmentShader = Shader::fromMetadata(device, "PbrBasic.frag");

Expand All @@ -94,7 +94,7 @@ int main() {
depth_target_info.store_op = SDL_GPU_STOREOP_DONT_CARE;
depth_target_info.stencil_load_op = SDL_GPU_LOADOP_DONT_CARE;
depth_target_info.stencil_store_op = SDL_GPU_STOREOP_DONT_CARE;
depth_target_info.texture = ctx.depth_texture;
depth_target_info.texture = ctx.depthTarget();
depth_target_info.cycle = true;

// create pipeline
Expand All @@ -103,24 +103,27 @@ int main() {
.fragment_shader = fragmentShader,
.vertex_input_state = meshes[0].layout(),
.primitive_type = meshDatas[0].primitiveType,
.rasterizer_state{.fill_mode = SDL_GPU_FILLMODE_FILL,
.cull_mode = SDL_GPU_CULLMODE_NONE,
.front_face = SDL_GPU_FRONTFACE_COUNTER_CLOCKWISE},
.depth_stencil_state{.compare_op = SDL_GPU_COMPAREOP_LESS_OR_EQUAL,
.enable_depth_test = true,
.enable_depth_write = true},
.target_info{.color_target_descriptions = &color_target_desc,
.num_color_targets = 1,
.depth_stencil_format = ctx.depthFormat(),
.has_depth_stencil_target = true},
.rasterizer_state{
.fill_mode = SDL_GPU_FILLMODE_FILL,
.cull_mode = SDL_GPU_CULLMODE_NONE,
.front_face = SDL_GPU_FRONTFACE_COUNTER_CLOCKWISE,
},
.multisample_state{},
.depth_stencil_state{
.compare_op = SDL_GPU_COMPAREOP_LESS_OR_EQUAL,
.enable_depth_test = true,
.enable_depth_write = true,
},
.target_info{
.color_target_descriptions = &color_target_desc,
.num_color_targets = 1,
.depth_stencil_format = ctx.depthFormat(),
.has_depth_stencil_target = true,
},
.props = 0,
};
pipeline = SDL_CreateGPUGraphicsPipeline(device, &pipeline_desc);
}
if (pipeline == NULL) {
SDL_Log("Failed to create pipeline: %s", SDL_GetError());
return 1;
}
return GraphicsPipeline(device, pipeline_desc, nullptr);
}();

Rad<float> fov = 55.0_degf;
CylindricalCamera camera{Camera{
Expand Down Expand Up @@ -197,15 +200,15 @@ int main() {
} else {

SDL_GPUColorTargetInfo ctinfo{
.texture = ctx.swapchain,
.texture = ctx.colorTarget(),
.clear_color = SDL_FColor{0., 0., 0., 0.},
.load_op = SDL_GPU_LOADOP_CLEAR,
.store_op = SDL_GPU_STOREOP_STORE,
.cycle = false,
};
render_pass = SDL_BeginGPURenderPass(command_buffer, &ctinfo, 1,
&depth_target_info);
SDL_BindGPUGraphicsPipeline(render_pass, pipeline);
pipeline.bind(render_pass);

TransformUniformData cameraUniform{
.modelView = modelView.matrix(),
Expand All @@ -231,15 +234,15 @@ int main() {
SDL_EndGPURenderPass(render_pass);
}

ctx.presentToSwapchain(command_buffer);
command_buffer.submit();
frameNo++;
}

for (auto &mesh : meshes) {
mesh.release();
}
SDL_ReleaseGPUGraphicsPipeline(device, pipeline);

pipeline.release();
ctx.destroy();
SDL_Quit();
return 0;
Expand Down
68 changes: 31 additions & 37 deletions examples/MeshNormalsRgb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "candlewick/core/RenderContext.h"
#include "candlewick/core/CommandBuffer.h"
#include "candlewick/core/GraphicsPipeline.h"
#include "candlewick/core/Mesh.h"
#include "candlewick/core/Shader.h"
#include "candlewick/utils/MeshData.h"
Expand Down Expand Up @@ -67,51 +68,47 @@ int main() {
Shader vertexShader{device, "VertexNormal.vert", {.uniform_buffers = 1}};
Shader fragmentShader{device, "VertexNormal.frag", {}};

SDL_GPUTexture *depthTexture = ctx.depth_texture;

SDL_GPUColorTargetDescription colorTarget;
SDL_zero(colorTarget);
colorTarget.format = SDL_GetGPUSwapchainTextureFormat(device, window);
colorTarget.format = ctx.colorFormat();
SDL_GPUDepthStencilTargetInfo depthTarget;
SDL_zero(depthTarget);
depthTarget.clear_depth = 1.0;
depthTarget.load_op = SDL_GPU_LOADOP_CLEAR;
depthTarget.store_op = SDL_GPU_STOREOP_DONT_CARE;
depthTarget.stencil_load_op = SDL_GPU_LOADOP_DONT_CARE;
depthTarget.stencil_store_op = SDL_GPU_STOREOP_DONT_CARE;
depthTarget.texture = depthTexture;
depthTarget.texture = ctx.depthTarget();
depthTarget.cycle = true;

// create pipeline
SDL_GPUGraphicsPipelineCreateInfo pipeline_desc{
.vertex_shader = vertexShader,
.fragment_shader = fragmentShader,
.vertex_input_state = meshes[0].layout(),
.primitive_type = meshDatas[0].primitiveType,
.rasterizer_state{
.fill_mode = SDL_GPU_FILLMODE_FILL,
.cull_mode = SDL_GPU_CULLMODE_NONE,
.front_face = SDL_GPU_FRONTFACE_COUNTER_CLOCKWISE,
},
.depth_stencil_state{
.compare_op = SDL_GPU_COMPAREOP_LESS_OR_EQUAL,
.enable_depth_test = true,
.enable_depth_write = true,
GraphicsPipeline pipeline{
device,
{
.vertex_shader = vertexShader,
.fragment_shader = fragmentShader,
.vertex_input_state = meshes[0].layout(),
.primitive_type = meshDatas[0].primitiveType,
.rasterizer_state{
.fill_mode = SDL_GPU_FILLMODE_FILL,
.cull_mode = SDL_GPU_CULLMODE_NONE,
.front_face = SDL_GPU_FRONTFACE_COUNTER_CLOCKWISE,
},
.depth_stencil_state{
.compare_op = SDL_GPU_COMPAREOP_LESS_OR_EQUAL,
.enable_depth_test = true,
.enable_depth_write = true,
},
.target_info{
.color_target_descriptions = &colorTarget,
.num_color_targets = 1,
.depth_stencil_format = ctx.depthFormat(),
.has_depth_stencil_target = true,
},
.props = 0,
},
.target_info{
.color_target_descriptions = &colorTarget,
.num_color_targets = 1,
.depth_stencil_format = ctx.depthFormat(),
.has_depth_stencil_target = true,
},
.props = 0,
"Main color pipeline",
};
SDL_GPUGraphicsPipeline *pipeline =
SDL_CreateGPUGraphicsPipeline(device, &pipeline_desc);
if (pipeline == NULL) {
SDL_Log("Failed to create pipeline: %s", SDL_GetError());
return 1;
}

vertexShader.release();
fragmentShader.release();
Expand Down Expand Up @@ -191,18 +188,16 @@ int main() {
SDL_Log("Failed to acquire swapchain: %s", SDL_GetError());
break;
} else {
auto *swapchain = ctx.swapchain;

SDL_GPUColorTargetInfo ctinfo{
.texture = swapchain,
.texture = ctx.colorTarget(),
.clear_color = SDL_FColor{0., 0., 0., 0.},
.load_op = SDL_GPU_LOADOP_CLEAR,
.store_op = SDL_GPU_STOREOP_STORE,
.cycle = false,
};
render_pass =
SDL_BeginGPURenderPass(command_buffer, &ctinfo, 1, &depthTarget);
SDL_BindGPUGraphicsPipeline(render_pass, pipeline);
pipeline.bind(render_pass);
TransformUniformData cameraUniform{
projViewMat,
normalMatrix,
Expand All @@ -224,8 +219,7 @@ int main() {
for (auto &mesh : meshes) {
mesh.release();
}
SDL_ReleaseGPUGraphicsPipeline(device, pipeline);

pipeline.release();
ctx.destroy();
SDL_Quit();
return 0;
Expand Down
Loading
Loading