Skip to content
Merged
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
12 changes: 6 additions & 6 deletions crates/processing_glfw/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ pub struct GlfwContext {
window: PWindow,
events: GlfwReceiver<(f64, WindowEvent)>,
surface: Option<Entity>,
scale_factor: f32,
}

impl GlfwContext {
Expand All @@ -31,14 +30,11 @@ impl GlfwContext {
window.set_all_polling(true);
window.show();

let (scale_factor, _) = window.get_content_scale();

Ok(Self {
glfw,
window,
events,
surface: None,
scale_factor,
})
}

Expand Down Expand Up @@ -127,8 +123,7 @@ impl GlfwContext {
return false;
}
WindowEvent::CursorPos(x, y) => {
let s = self.scale_factor;
input_set_mouse_move(surface, x as f32 / s, y as f32 / s).unwrap();
input_set_mouse_move(surface, x as f32, y as f32).unwrap();
}
WindowEvent::MouseButton(button, action, _mods) => {
if let Some(btn) = glfw_button_to_bevy(button) {
Expand Down Expand Up @@ -182,6 +177,11 @@ impl GlfwContext {
true
}

pub fn content_scale(&self) -> f32 {
let (s, _) = self.window.get_content_scale();
s
}

fn sync_cursor(&mut self, surface: Entity) {
use bevy::window::CursorGrabMode;

Expand Down
13 changes: 13 additions & 0 deletions crates/processing_pyo3/src/graphics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,19 @@ impl Surface {
None => true, // no-op, offscreen surfaces never close
}
}

#[getter]
pub fn display_density(&self) -> PyResult<f32> {
match &self.glfw_ctx {
Some(ctx) => Ok(ctx.content_scale()),
None => Ok(1.0),
}
}

pub fn set_pixel_density(&self, density: f32) -> PyResult<()> {
surface_set_pixel_density(self.entity, density)
.map_err(|e| PyRuntimeError::new_err(format!("{e}")))
}
}

impl Drop for Surface {
Expand Down
14 changes: 14 additions & 0 deletions crates/processing_pyo3/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1432,4 +1432,18 @@ mod mewnala {
fn key_just_pressed(key_code: u32) -> PyResult<bool> {
input::key_just_pressed(key_code)
}

#[pyfunction]
#[pyo3(pass_module)]
fn pixel_density(module: &Bound<'_, PyModule>, density: f32) -> PyResult<()> {
graphics!(module).surface.set_pixel_density(density)
}

#[pyfunction]
#[pyo3(pass_module)]
fn display_density(module: &Bound<'_, PyModule>) -> PyResult<f32> {
let graphics =
get_graphics(module)?.ok_or_else(|| PyRuntimeError::new_err("call size() first"))?;
graphics.surface.display_density()
}
}
64 changes: 55 additions & 9 deletions crates/processing_render/src/graphics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ pub struct GraphicsPlugin;

impl Plugin for GraphicsPlugin {
fn build(&self, app: &mut App) {
app.init_resource::<RenderLayersManager>();
app.init_resource::<RenderLayersManager>()
.add_systems(PostUpdate, sync_to_surface);
}
}

Expand Down Expand Up @@ -149,14 +150,26 @@ pub fn create(
mut commands: Commands,
mut layer_manager: ResMut<RenderLayersManager>,
p_images: Query<&Image, With<Surface>>,
windows: Query<&Window, With<Surface>>,
render_device: Res<RenderDevice>,
) -> Result<Entity> {
// find the surface entity, if it is an image, we will render to that image
// otherwise we will render to the window
let target = match p_images.get(surface_entity) {
Ok(p_image) => RenderTarget::Image(ImageRenderTarget::from(p_image.handle.clone())),
let (target, physical_width, physical_height) = match p_images.get(surface_entity) {
Ok(p_image) => (
RenderTarget::Image(ImageRenderTarget::from(p_image.handle.clone())),
p_image.size.width,
p_image.size.height,
),
Err(QueryEntityError::QueryDoesNotMatch(..)) => {
RenderTarget::Window(WindowRef::Entity(surface_entity))
let window = windows
.get(surface_entity)
.map_err(|_| ProcessingError::SurfaceNotFound)?;
(
RenderTarget::Window(WindowRef::Entity(surface_entity)),
window.resolution.physical_width(),
window.resolution.physical_height(),
)
}
Err(_) => return Err(ProcessingError::SurfaceNotFound),
};
Expand All @@ -165,14 +178,14 @@ pub fn create(
let render_layer = layer_manager.allocate();

let size = Extent3d {
width,
height,
width: physical_width,
height: physical_height,
depth_or_array_layers: 1,
};
let readback_buffer = create_readback_buffer(
&render_device,
width,
height,
physical_width,
physical_height,
texture_format,
"Graphics Readback Buffer",
)
Expand Down Expand Up @@ -241,6 +254,39 @@ pub fn resize(
}
}

pub fn sync_to_surface(
mut graphics_query: Query<(&mut Graphics, &RenderTarget)>,
windows: Query<&Window, (With<Surface>, Changed<Window>)>,
render_device: Res<RenderDevice>,
) {
for (mut graphics, target) in graphics_query.iter_mut() {
let RenderTarget::Window(WindowRef::Entity(surface_entity)) = *target else {
continue;
};
let Ok(window) = windows.get(surface_entity) else {
continue;
};
let physical_w = window.resolution.physical_width();
let physical_h = window.resolution.physical_height();
if graphics.size.width == physical_w && graphics.size.height == physical_h {
continue;
}
graphics.size = Extent3d {
width: physical_w,
height: physical_h,
depth_or_array_layers: 1,
};
graphics.readback_buffer = create_readback_buffer(
&render_device,
physical_w,
physical_h,
graphics.texture_format,
"Graphics Readback Buffer",
)
.expect("Failed to reallocate readback buffer");
}
}

pub fn mode_3d(
In(entity): In<Entity>,
mut projections: Query<&mut Projection>,
Expand Down Expand Up @@ -396,7 +442,7 @@ pub fn begin_draw(In(entity): In<Entity>, mut state_query: Query<&mut RenderStat
let mut state = state_query
.get_mut(entity)
.map_err(|_| ProcessingError::GraphicsNotFound)?;
state.reset();
state.begin_frame();
Ok(())
}

Expand Down
8 changes: 8 additions & 0 deletions crates/processing_render/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,14 @@ pub fn surface_resize(graphics_entity: Entity, width: u32, height: u32) -> error
})
}

pub fn surface_set_pixel_density(entity: Entity, density: f32) -> error::Result<()> {
app_mut(|app| {
app.world_mut()
.run_system_cached_with(surface::set_pixel_density, (entity, density))
.unwrap()
})
}

/// Create a new graphics surface for rendering.
pub fn graphics_create(
surface_entity: Entity,
Expand Down
2 changes: 1 addition & 1 deletion crates/processing_render/src/render/mesh_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl<'a> MeshBuilder<'a> {
if let Some(VertexAttributeValues::Float32x4(colors)) =
self.mesh.attribute_mut(Mesh::ATTRIBUTE_COLOR)
{
colors.push(self.color.to_srgba().to_f32_array());
colors.push(self.color.to_linear().to_f32_array());
}

if let Some(VertexAttributeValues::Float32x3(normals)) =
Expand Down
5 changes: 5 additions & 0 deletions crates/processing_render/src/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ impl RenderState {
self.shape_builder = None;
}

pub fn begin_frame(&mut self) {
self.transform = TransformStack::new();
self.shape_builder = None;
}

pub fn fill_is_transparent(&self) -> bool {
self.fill_color.map(|c| c.alpha() < 1.0).unwrap_or(false)
}
Expand Down
2 changes: 1 addition & 1 deletion crates/processing_render/src/render/primitive/quad.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ fn simple_quad(
if let Some(VertexAttributeValues::Float32x4(colors)) =
mesh.attribute_mut(Mesh::ATTRIBUTE_COLOR)
{
let color_array = color.to_srgba().to_f32_array();
let color_array = color.to_linear().to_f32_array();
for _ in 0..4 {
colors.push(color_array);
}
Expand Down
2 changes: 1 addition & 1 deletion crates/processing_render/src/render/primitive/rect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ fn simple_rect(mesh: &mut Mesh, x: f32, y: f32, w: f32, h: f32, color: Color) {
if let Some(VertexAttributeValues::Float32x4(colors)) =
mesh.attribute_mut(Mesh::ATTRIBUTE_COLOR)
{
let color_array = color.to_srgba().to_f32_array();
let color_array = color.to_linear().to_f32_array();
for _ in 0..4 {
colors.push(color_array);
}
Expand Down
4 changes: 2 additions & 2 deletions crates/processing_render/src/render/primitive/shape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ fn push_triangle(
positions.push([x3, y3, 0.0]);
}

let color_array = color.to_srgba().to_f32_array();
let color_array = color.to_linear().to_f32_array();
if let Some(VertexAttributeValues::Float32x4(colors)) =
mesh.attribute_mut(Mesh::ATTRIBUTE_COLOR)
{
Expand Down Expand Up @@ -556,7 +556,7 @@ fn push_quad(
positions.push([x4, y4, 0.0]);
}

let color_array = color.to_srgba().to_f32_array();
let color_array = color.to_linear().to_f32_array();
if let Some(VertexAttributeValues::Float32x4(colors)) =
mesh.attribute_mut(Mesh::ATTRIBUTE_COLOR)
{
Expand Down
2 changes: 1 addition & 1 deletion crates/processing_render/src/render/primitive/triangle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ fn simple_triangle(
if let Some(VertexAttributeValues::Float32x4(colors)) =
mesh.attribute_mut(Mesh::ATTRIBUTE_COLOR)
{
let color_array = color.to_srgba().to_f32_array();
let color_array = color.to_linear().to_f32_array();
for _ in 0..3 {
colors.push(color_array);
}
Expand Down
27 changes: 25 additions & 2 deletions crates/processing_render/src/surface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,13 @@ fn spawn_surface(
let window_wrapper = WindowWrapper::new(glfw_window);
let handle_wrapper = RawHandleWrapper::new(&window_wrapper)?;

let physical_width = (width as f32 * scale_factor) as u32;
let physical_height = (height as f32 * scale_factor) as u32;

Ok(commands
.spawn((
Window {
resolution: WindowResolution::new(width, height)
resolution: WindowResolution::new(physical_width, physical_height)
.with_scale_factor_override(scale_factor),
..default()
},
Expand Down Expand Up @@ -362,8 +365,28 @@ pub fn resize(
mut windows: Query<&mut Window>,
) -> Result<()> {
if let Ok(mut window) = windows.get_mut(window_entity) {
window.resolution.set_physical_resolution(width, height);
let scale = window.resolution.scale_factor();
let physical_w = (width as f32 * scale) as u32;
let physical_h = (height as f32 * scale) as u32;
window.resolution.set_physical_resolution(physical_w, physical_h);
Ok(())
} else {
Err(error::ProcessingError::SurfaceNotFound)
}
}

pub fn set_pixel_density(
In((window_entity, density)): In<(Entity, f32)>,
mut windows: Query<&mut Window>,
) -> Result<()> {
if let Ok(mut window) = windows.get_mut(window_entity) {
let logical_w = window.resolution.width();
let logical_h = window.resolution.height();
window.resolution.set_scale_factor_override(Some(density));
window.resolution.set_physical_resolution(
(logical_w * density) as u32,
(logical_h * density) as u32,
);
Ok(())
} else {
Err(error::ProcessingError::SurfaceNotFound)
Expand Down
Loading