merge branch diplomat into master

This commit is contained in:
numzero 2026-10-29 14:23:29 +03:00
commit 80be92faaa
15 changed files with 280 additions and 344 deletions

View File

@ -9,6 +9,9 @@ find_package(Qt6 REQUIRED COMPONENTS Gui Widgets)
find_program(CARGO cargo REQUIRED) find_program(CARGO cargo REQUIRED)
set(CARGO_TARGET_DIR "${CMAKE_SOURCE_DIR}/target" CACHE PATH "Path to the Cargo target directory") set(CARGO_TARGET_DIR "${CMAKE_SOURCE_DIR}/target" CACHE PATH "Path to the Cargo target directory")
include(diplomat.cmake)
qt_standard_project_setup() qt_standard_project_setup()
add_subdirectory(src)
add_subdirectory(ui) add_subdirectory(ui)

91
Cargo.lock generated
View File

@ -165,9 +165,9 @@ checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510"
[[package]] [[package]]
name = "bytemuck" name = "bytemuck"
version = "1.24.0" version = "1.25.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" checksum = "95832e849adfb21180ccb6826a99da14e5d266ae5c2e668e1602cf234f153797"
dependencies = [ dependencies = [
"bytemuck_derive", "bytemuck_derive",
] ]
@ -180,7 +180,7 @@ checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.114",
] ]
[[package]] [[package]]
@ -354,6 +354,38 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f"
[[package]]
name = "diplomat"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61a80510e6103d35c5cd031c0e3f21165b32742c301ee3dafdbb5904c6dca46a"
dependencies = [
"diplomat_core",
"proc-macro2",
"quote",
"syn 3.0.9",
]
[[package]]
name = "diplomat-runtime"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9d981121ba76150987fda68185b37853c0b928a55dfdc28897348cd068440be"
[[package]]
name = "diplomat_core"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa5c594efd1d097105255fc325c430a517c97b7b7c69f8727f653593e1ce726"
dependencies = [
"proc-macro2",
"quote",
"serde",
"smallvec",
"strck",
"syn 3.0.9",
]
[[package]] [[package]]
name = "dispatch" name = "dispatch"
version = "0.2.0" version = "0.2.0"
@ -442,7 +474,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.114",
] ]
[[package]] [[package]]
@ -892,7 +924,7 @@ dependencies = [
"proc-macro-crate", "proc-macro-crate",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.114",
] ]
[[package]] [[package]]
@ -1182,6 +1214,8 @@ version = "0.1.0"
dependencies = [ dependencies = [
"approx", "approx",
"bytemuck", "bytemuck",
"diplomat",
"diplomat-runtime",
"glam", "glam",
"pollster", "pollster",
"rand", "rand",
@ -1191,17 +1225,6 @@ dependencies = [
"winit", "winit",
] ]
[[package]]
name = "photon-light-impl"
version = "0.1.0"
dependencies = [
"glam",
"photon-light",
"pollster",
"raw-window-handle",
"wgpu",
]
[[package]] [[package]]
name = "pin-project" name = "pin-project"
version = "1.1.10" version = "1.1.10"
@ -1219,7 +1242,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.114",
] ]
[[package]] [[package]]
@ -1530,7 +1553,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.114",
] ]
[[package]] [[package]]
@ -1609,6 +1632,15 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "strck"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42316e70da376f3d113a68d138a60d8a9883c604fe97942721ec2068dab13a9f"
dependencies = [
"unicode-ident",
]
[[package]] [[package]]
name = "strict-num" name = "strict-num"
version = "0.1.1" version = "0.1.1"
@ -1626,6 +1658,17 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "syn"
version = "3.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d78c8dee4c7bf0e14673097256fed6142ce9d3b85a408189d07482442145823b"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]] [[package]]
name = "termcolor" name = "termcolor"
version = "1.4.1" version = "1.4.1"
@ -1661,7 +1704,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.114",
] ]
[[package]] [[package]]
@ -1672,7 +1715,7 @@ checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.114",
] ]
[[package]] [[package]]
@ -1841,7 +1884,7 @@ dependencies = [
"bumpalo", "bumpalo",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.114",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -2174,7 +2217,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.114",
] ]
[[package]] [[package]]
@ -2185,7 +2228,7 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.114",
] ]
[[package]] [[package]]
@ -2517,5 +2560,5 @@ checksum = "2c7962b26b0a8685668b671ee4b54d007a67d4eaf05fda79ac0ecf41e32270f1"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.114",
] ]

View File

@ -1,11 +1,11 @@
[workspace]
members = ["ui"]
[package] [package]
name = "photon-light" name = "photon-light"
version = "0.1.0" version = "0.1.0"
edition = "2024" edition = "2024"
[lib]
crate-type = ["lib", "staticlib"]
[profile.dev] [profile.dev]
panic = 'abort' panic = 'abort'
@ -18,7 +18,7 @@ debug = false
opt-level = 3 opt-level = 3
[dependencies] [dependencies]
bytemuck = "1.24.0" bytemuck = "1.25.2"
glam = { version = "0.30.9", features = ["bytemuck", "approx"] } glam = { version = "0.30.9", features = ["bytemuck", "approx"] }
pollster = "0.4.0" pollster = "0.4.0"
rand = "0.9.2" rand = "0.9.2"
@ -26,6 +26,8 @@ rand_distr = "0.5.1"
rand_pcg = "0.9.0" rand_pcg = "0.9.0"
wgpu = "27.0.1" wgpu = "27.0.1"
winit = "0.30.12" winit = "0.30.12"
diplomat = "0.17.0"
diplomat-runtime = "0.16.1"
[dev-dependencies] [dev-dependencies]
approx = "0.5.1" approx = "0.5.1"

8
diplomat.cmake Normal file
View File

@ -0,0 +1,8 @@
set(crates "${CMAKE_BINARY_DIR}/crates")
set(diplomat "${crates}/bin/diplomat-tool")
if(NOT IS_EXECUTABLE "${diplomat}")
message(CONFIGURE_LOG "Downloading Diplomat...")
file(MAKE_DIRECTORY "${crates}")
execute_process(COMMAND ${CARGO} install --root "${crates}" diplomat-tool@0.17.0)
endif()

63
src/CMakeLists.txt Normal file
View File

@ -0,0 +1,63 @@
# build the Rust side as a static library
set(impl_basename "${CARGO_TARGET_DIR}/release/libphoton_light")
set(cargo_cmake_args)
set(diplomat_cmake_args)
if("${CMAKE_VERSION}" VERSION_GREATER_EQUAL "3.27")
list(APPEND cargo_cmake_args DEPENDS_EXPLICIT_ONLY)
list(APPEND diplomat_cmake_args DEPENDS_EXPLICIT_ONLY)
endif()
if("${CMAKE_VERSION}" VERSION_GREATER_EQUAL "3.28")
list(APPEND cargo_cmake_args JOB_SERVER_AWARE TRUE)
endif()
if("${CMAKE_VERSION}" VERSION_GREATER_EQUAL "3.31")
list(APPEND diplomat_cmake_args CODEGEN)
endif()
add_custom_command(
OUTPUT "${impl_basename}.a"
COMMAND env "CARGO_TARGET_DIR=${CARGO_TARGET_DIR}" ${CARGO} build --release --package photon-light
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
DEPFILE "${impl_basename}.d"
USES_TERMINAL
VERBATIM
${cargo_cmake_args}
)
# HACK ensure CMake *actually adds* the command above
add_custom_target(build_impl
DEPENDS "${impl_basename}.a"
)
add_library(photon_light_impl STATIC IMPORTED GLOBAL)
set_target_properties(photon_light_impl PROPERTIES
IMPORTED_LOCATION "${impl_basename}.a"
)
# generate the bindings
set(bindings_dir "${CMAKE_CURRENT_BINARY_DIR}/include")
file(MAKE_DIRECTORY "${bindings_dir}")
set(bindings
"${bindings_dir}/Core.hpp"
)
add_custom_command(
OUTPUT ${bindings}
COMMAND ${diplomat} cpp "${bindings_dir}"
MAIN_DEPENDENCY "lib.rs"
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
VERBATIM
${diplomat_cmake_args}
)
# HACK ensure CMake *actually adds* the command above
add_custom_target(codegen_impl
DEPENDS ${bindings}
)
target_sources(photon_light_impl INTERFACE ${bindings})
target_include_directories(photon_light_impl INTERFACE "${bindings_dir}")

22
src/iter.rs Normal file
View File

@ -0,0 +1,22 @@
use std::convert::identity;
pub(crate) fn loop_list<T: Clone>(iter: impl IntoIterator<Item = T>) -> impl Iterator<Item = T> {
loop_list_ex(iter, identity, identity)
}
pub(crate) fn loop_list_ex<T: Clone, U>(
iter: impl IntoIterator<Item = T>,
mut fa: impl FnMut(T) -> U,
mut fb: impl FnMut(T) -> U,
) -> impl Iterator<Item = U> {
gen move {
let mut iter = iter.into_iter();
let Some(first) = iter.next() else { return };
yield fa(first.clone());
for item in iter {
yield fb(item.clone());
yield fa(item);
}
yield fb(first);
}
}

View File

@ -1,12 +1,14 @@
#![feature(gen_blocks)] #![feature(gen_blocks)]
use std::{convert::identity, error::Error, f32::consts::PI}; use std::{error::Error, f32::consts::PI};
use glam::{Mat4, UVec2, Vec2, Vec3, vec3}; use glam::{Mat4, UVec2, Vec2, Vec3, vec3};
use rand_distr::Distribution as _; use rand_distr::Distribution as _;
use wgpu::rwh::{RawDisplayHandle, RawWindowHandle};
use crate::{ use crate::{
camera::OrbitalCamera, camera::OrbitalCamera,
iter::loop_list,
ray::Ray, ray::Ray,
render::{ render::{
DEPTH_FORMAT, OUTPUT_FORMAT, DEPTH_FORMAT, OUTPUT_FORMAT,
@ -15,30 +17,37 @@ use crate::{
trace::{Hit, Lambertian, Reflector, Scene, Source, Sphere}, trace::{Hit, Lambertian, Reflector, Scene, Source, Sphere},
}; };
pub use crate::ffi::{RedrawArgs, SphericalPosition, UseNormal};
mod camera; mod camera;
mod iter;
mod ray; mod ray;
mod render; mod render;
mod shape; mod shape;
mod trace; mod trace;
#[derive(Debug, Clone, Copy, PartialEq)] #[diplomat::bridge]
#[repr(C)] mod ffi {
pub struct SphericalPosition { use std::{f32::consts::PI, num::NonZero, ptr::NonNull};
use glam::uvec2;
use wgpu::rwh::{XcbDisplayHandle, XcbWindowHandle};
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct SphericalPosition {
pub yaw: f32, pub yaw: f32,
pub pitch: f32, pub pitch: f32,
pub distance: f32, pub distance: f32,
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug)]
#[repr(u8)] pub enum UseNormal {
pub enum UseNormal {
Light, Light,
Camera, Camera,
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
#[repr(C)] pub struct RedrawArgs {
pub struct RedrawArgs {
pub camera_position: SphericalPosition, pub camera_position: SphericalPosition,
pub light_position: SphericalPosition, pub light_position: SphericalPosition,
pub light_radius: f32, pub light_radius: f32,
@ -54,9 +63,9 @@ pub struct RedrawArgs {
pub show_direct_hit: bool, pub show_direct_hit: bool,
pub show_indirect_hit: bool, pub show_indirect_hit: bool,
pub show_light: bool, pub show_light: bool,
} }
impl Default for RedrawArgs { impl Default for RedrawArgs {
fn default() -> Self { fn default() -> Self {
Self { Self {
camera_position: SphericalPosition { camera_position: SphericalPosition {
@ -84,6 +93,29 @@ impl Default for RedrawArgs {
show_light: true, show_light: true,
} }
} }
}
#[diplomat::opaque_mut]
pub struct Core(crate::Core);
impl Core {
pub fn from_xcb(connection: usize, window: u32, width: u32, height: u32) -> Box<Core> {
let display =
XcbDisplayHandle::new(Some(NonNull::new(connection as *mut _).unwrap()), 0);
let window = XcbWindowHandle::new(NonZero::new(window).unwrap());
let gpu = unsafe { crate::Gpu::new_raw(display, window) };
let size = uvec2(width, height);
Box::new(Self(crate::Core::new(gpu, size)))
}
pub fn configure(&mut self, width: u32, height: u32) {
self.0.configure(uvec2(width, height));
}
pub fn redraw(&mut self, args: &RedrawArgs) {
self.0.redraw(args);
}
}
} }
pub struct Gpu { pub struct Gpu {
@ -92,6 +124,23 @@ pub struct Gpu {
surface: wgpu::Surface<'static>, surface: wgpu::Surface<'static>,
} }
impl Gpu {
unsafe fn new_raw(
display: impl Into<RawDisplayHandle>,
window: impl Into<RawWindowHandle>,
) -> Self {
let target = wgpu::SurfaceTargetUnsafe::RawHandle {
raw_display_handle: display.into(),
raw_window_handle: window.into(),
};
let gpu = pollster::block_on(init_gpu_inner(|instance| unsafe {
instance.create_surface_unsafe(target)
}))
.unwrap();
gpu
}
}
pub struct Core { pub struct Core {
device: wgpu::Device, device: wgpu::Device,
queue: wgpu::Queue, queue: wgpu::Queue,
@ -118,27 +167,6 @@ pub fn new_tripod(device: &wgpu::Device) -> Mesh {
) )
} }
fn loop_list<T: Clone>(iter: impl IntoIterator<Item = T>) -> impl Iterator<Item = T> {
loop_list_ex(iter, identity, identity)
}
fn loop_list_ex<T: Clone, U>(
iter: impl IntoIterator<Item = T>,
mut fa: impl FnMut(T) -> U,
mut fb: impl FnMut(T) -> U,
) -> impl Iterator<Item = U> {
gen move {
let mut iter = iter.into_iter();
let Some(first) = iter.next() else { return };
yield fa(first.clone());
for item in iter {
yield fb(item.clone());
yield fa(item);
}
yield fb(first);
}
}
impl OrbitalCamera { impl OrbitalCamera {
fn make_ray(&self, rng: &mut impl rand::Rng) -> Ray { fn make_ray(&self, rng: &mut impl rand::Rng) -> Ray {
let off: f32 = rand_distr::StandardUniform.sample(rng); let off: f32 = rand_distr::StandardUniform.sample(rng);

View File

@ -1,7 +1,4 @@
include(impl.cmake)
qt_add_executable(photon-light qt_add_executable(photon-light
src/api.cxx
src/main.cxx src/main.cxx
src/main_window.cxx src/main_window.cxx
src/main_window.ui src/main_window.ui

View File

@ -1,15 +0,0 @@
[package]
name = "photon-light-impl"
version = "0.1.0"
edition = "2024"
[lib]
crate-type = ["staticlib"]
[dependencies]
photon-light = {path = "../"}
glam = { version = "0.30" }
pollster = "0.4.0"
raw-window-handle = "0.6.2"
wgpu = "27.0.1"

View File

@ -1,33 +0,0 @@
# build the Rust side as a static library
set(impl_basename "${CARGO_TARGET_DIR}/release/libphoton_light_impl")
set(cargo_cmake_args)
if("${CMAKE_VERSION}" VERSION_GREATER_EQUAL "3.27")
list(APPEND cargo_cmake_args DEPENDS_EXPLICIT_ONLY)
endif()
if("${CMAKE_VERSION}" VERSION_GREATER_EQUAL "3.28")
list(APPEND cargo_cmake_args JOB_SERVER_AWARE TRUE)
endif()
add_custom_command(
OUTPUT "${impl_basename}.a"
COMMAND env "CARGO_TARGET_DIR=${CARGO_TARGET_DIR}" ${CARGO} build --release --package photon-light-impl
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
DEPFILE "${impl_basename}.d"
USES_TERMINAL
VERBATIM
${cargo_cmake_args}
)
# HACK ensure CMake *actually adds* the command above
add_custom_target(build_impl
DEPENDS "${impl_basename}.a"
)
add_library(photon_light_impl STATIC IMPORTED)
set_target_properties(photon_light_impl PROPERTIES
IMPORTED_LOCATION "${impl_basename}.a"
)

View File

@ -1,57 +0,0 @@
#include "api.hxx"
#include <stdexcept>
#include <utility>
namespace ffi {
extern "C" Core* rt4_viewport_create(xcb_connection_t* connection, std::uint32_t window, std::uint32_t width, std::uint32_t height);
extern "C" void rt4_viewport_destroy(Core* viewport);
extern "C" void rt4_viewport_configure(Core* viewport, std::uint32_t width, std::uint32_t height);
extern "C" void rt4_viewport_redraw(Core* viewport, const RedrawArgs* args);
} // namespace ffi
BoxCore::BoxCore(BoxCore&& b)
: ptr(std::exchange(b.ptr, {})) {
}
BoxCore::~BoxCore() {
reset();
}
BoxCore& BoxCore::operator=(BoxCore&& b) {
if (&b == this)
return *this;
std::swap(ptr, b.ptr);
b.reset();
return *this;
}
BoxCore BoxCore::from_xcb(xcb_connection_t* connection, std::uint32_t window, std::uint32_t width, std::uint32_t height) {
if (!connection)
throw std::logic_error("attempt to use a null connection");
if (!window)
throw std::logic_error("attempt to use a null window");
BoxCore out;
out.ptr.ptr = ffi::rt4_viewport_create(connection, window, width, height);
return out;
}
void BoxCore::reset() {
auto viewport = std::exchange(ptr, {});
if (viewport)
ffi::rt4_viewport_destroy(viewport.use());
}
ffi::Core* MutCore::use() const {
if (!ptr)
throw std::logic_error("attempt to use a null Core");
return ptr;
}
void MutCore::configure(std::uint32_t width, std::uint32_t height) const {
rt4_viewport_configure(use(), width, height);
}
void MutCore::redraw(const RedrawArgs& args) const {
rt4_viewport_redraw(use(), &args);
}

View File

@ -1,76 +0,0 @@
#pragma once
#include <cstdint>
struct xcb_connection_t;
namespace ffi {
struct Core;
struct SphericalPosition {
float yaw = 0.;
float pitch = 0.;
float distance = 1.;
};
enum class UseNormal: std::uint8_t {
Light,
Camera,
};
struct RedrawArgs {
SphericalPosition camera_position;
SphericalPosition light_position;
float light_radius = 1.;
float light_spread = 0.;
float accum_sigma = 1.;
float accum_scale = 1.;
std::uint8_t reflections = 0;
UseNormal use_normal = UseNormal::Light;
bool show_axes = true;
bool show_shapes = true;
bool show_hit_emission = true;
bool show_miss_emission = true;
bool show_direct_hit = true;
bool show_indirect_hit = true;
bool show_light = true;
};
} // namespace ffi
using ffi::UseNormal;
using ffi::RedrawArgs;
using ffi::SphericalPosition;
class MutCore {
friend class BoxCore;
public:
explicit operator bool() const { return ptr; }
void configure(std::uint32_t width, std::uint32_t height) const;
void redraw(const RedrawArgs& args) const;
private:
ffi::Core* ptr = nullptr;
ffi::Core* use() const;
};
class BoxCore {
public:
BoxCore() = default;
BoxCore(const BoxCore&) = delete;
BoxCore(BoxCore&&);
BoxCore& operator=(const BoxCore&) = delete;
BoxCore& operator=(BoxCore&&);
~BoxCore();
explicit operator bool() const { return !!ptr; }
const MutCore* operator->() const { return &ptr; }
void reset();
static BoxCore from_xcb(xcb_connection_t* connection, std::uint32_t window, std::uint32_t width, std::uint32_t height);
private:
MutCore ptr;
};

View File

@ -1,49 +0,0 @@
use std::{ffi::c_void, num::NonZero, ptr::NonNull};
use glam::{UVec2, uvec2};
use raw_window_handle::{RawDisplayHandle, RawWindowHandle, XcbDisplayHandle, XcbWindowHandle};
use photon_light::{Core, RedrawArgs, init_gpu_inner};
unsafe fn create_viewport(
display: impl Into<RawDisplayHandle>,
window: impl Into<RawWindowHandle>,
size: UVec2,
) -> Box<Core> {
let target = wgpu::SurfaceTargetUnsafe::RawHandle {
raw_display_handle: display.into(),
raw_window_handle: window.into(),
};
let gpu = pollster::block_on(init_gpu_inner(|instance| unsafe {
instance.create_surface_unsafe(target)
}))
.unwrap();
Box::new(Core::new(gpu, size))
}
#[unsafe(no_mangle)]
unsafe extern "C" fn rt4_viewport_create(
connection: NonNull<c_void>,
window: NonZero<u32>,
width: u32,
height: u32,
) -> Box<Core> {
let display = XcbDisplayHandle::new(Some(connection), 0);
let window = XcbWindowHandle::new(window);
unsafe { create_viewport(display, window, uvec2(width, height)) }
}
#[unsafe(no_mangle)]
unsafe extern "C" fn rt4_viewport_destroy(viewport: Box<Core>) {
drop(viewport);
}
#[unsafe(no_mangle)]
unsafe extern "C" fn rt4_viewport_configure(viewport: &mut Core, width: u32, height: u32) {
viewport.configure(uvec2(width, height));
}
#[unsafe(no_mangle)]
unsafe extern "C" fn rt4_viewport_redraw(viewport: &mut Core, args: &RedrawArgs) {
viewport.redraw(args);
}

View File

@ -63,7 +63,7 @@ void Viewport::recreate() try {
const QSize device_size = size() * devicePixelRatio(); const QSize device_size = size() * devicePixelRatio();
core.reset(); core.reset();
core = BoxCore::from_xcb(xcb_connection, x11_window, device_size.width(), device_size.height()); core = Core::from_xcb((std::uintptr_t)xcb_connection, x11_window, device_size.width(), device_size.height());
} catch (const std::exception& e) { } catch (const std::exception& e) {
fprintf(stderr, "failed to recreate the viewport: %s", e.what()); fprintf(stderr, "failed to recreate the viewport: %s", e.what());
} }

View File

@ -2,7 +2,7 @@
#include <QWidget> #include <QWidget>
#include "api.hxx" #include "Core.hpp"
class Viewport : public QWidget { class Viewport : public QWidget {
Q_OBJECT Q_OBJECT
@ -20,7 +20,7 @@ protected:
void resizeEvent(QResizeEvent* event) override; void resizeEvent(QResizeEvent* event) override;
private: private:
BoxCore core; std::unique_ptr<Core> core;
RedrawArgs args = {}; RedrawArgs args = {};
void recreate(); void recreate();