Files
pbio/README.md
T
2026-05-23 10:49:32 +02:00

111 lines
4.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# pbio: simple pixel buffer and I/O system
Pixelbuffer-basiertes Fenster mit Palette-Lookup-Renderer (winit + wgpu) und Maus/Tastatureingaben.
pbio nimmt einen Bytearray, interpretiert diesen als 8-Bit-Pixelbuffer und rendert ihn auf ein Fenster. Optional mit Letterbox für ein festes Seitenverhältnis.
## Integration
pbio ist nicht auf crates.io veröffentlicht. Das Crate kann direkt aus dem Git-Repository eingebunden werden:
```toml
[dependencies]
pbio = { git = "https://codeberg.org/irrlicht/rust-pbio.git" }
```
pbio braucht keine System-Libraries zum Bauen — winit lädt X11/Wayland zur Laufzeit per dlopen. Zur Laufzeit reichen aktuelle Grafiktreiber mit Vulkan-, Metal- oder DX12-Unterstützung für wgpu.
## Verwendung
```rust
use pbio::{Event, Key, Platform, PlatformConfig};
fn main() {
let mut p = Platform::new(PlatformConfig {
title: "Demo".into(),
window_size: (1024, 768),
framebuffer_size: (320, 240),
..Default::default()
});
while !p.should_close() {
p.poll_events(None);
while let Some(ev) = p.poll_event() {
if let Event::Key { key: Key::Escape, pressed: true, .. } = ev {
p.request_close();
}
}
let (w, _h) = p.framebuffer_size();
let fb = p.framebuffer_mut();
for (i, px) in fb.iter_mut().enumerate() {
*px = ((i as u32 % w) ^ (i as u32 / w)) as u8;
}
p.present();
}
}
```
## API-Überblick
- `PlatformConfig` Titel, Fenster-/Framebuffer-Größe, optionales
`aspect_ratio` (Letterbox), Palette, VSync, `mouse_visible`, `mouse_capture`.
Default = 800×600 Fenster, 320×240 Framebuffer, 4:3, `palette::RGB332`.
- `Platform::new(cfg)` Fenster + GPU-Pipeline aufsetzen.
- `poll_events(timeout)` winit-Events einlesen (`None` = blockierend).
- `poll_event() -> Option<Event>` ein Event aus der Queue holen. Gibt
`&mut self` nach jedem Call frei, sodass im Loop direkt auf die Platform
reagiert werden kann (`request_close`, `set_mouse_capture`, `palette_mut` …).
Empfohlen für die normale Event-Schleife.
- `drain_events()` Iterator über `Event` (`Key`, `Char`, `MouseMove`,
`MouseBtn`, `Resize`, `CloseRequested`). Borrowt `&mut self` bis der
Iterator fertig ist — Reaktionen auf die Platform müssen dann nach dem
Loop angewandt werden. Nützlich für reines Loggen/Filtern.
- `framebuffer_mut()` `&mut [u8]` der Länge `w*h`, je Pixel ein Paletten-Index.
- `palette_mut()` / `palette()` `&mut [[u8; 3]; 256]` bzw. `&[...]`; Schreibzugriff
markiert die Palette dirty, der nächste `present()` lädt sie hoch.
- `present()` Frame auf das Fenster bringen.
- `should_close()` / `request_close()`.
- `set_mouse_visible(bool)` Cursor anzeigen oder verstecken (freie Bewegung).
- `set_mouse_capture(bool)` Cursor einsperren + verstecken (winit
`CursorGrabMode::Locked`, Fallback `Confined`), liefert unbegrenzte
Bewegungsdeltas via `mouse_delta()`. Impliziert `mouse_visible = false`.
Im Capture-Mode ist `Event::MouseMove` nicht sinnvoll (eingefrorene oder
am Fensterrand klemmende Werte) — stattdessen `mouse_delta()` benutzen.
- `mouse_delta() -> (f32, f32)` akkumulierte Mausbewegung seit dem letzten Aufruf
in Framebuffer-Pixeln (gleiche Skala wie `MouseMove`), danach genullt. Nützlich
für FPS-Kamerasteuerung.
### Cursor-Modi
| `mouse_visible` | `mouse_capture` | winit-Modus | Einsatz |
|---|---|---|---|
| `true` | `false` | sichtbar, frei | Standard-UI |
| `false` | `false` | versteckt, frei | Eigener Cursor im Framebuffer |
| `*` | `true` | `Locked` / `Confined`, versteckt | FPS-Kamera, unbegrenzte Deltas |
```rust
// FPS-Kamera
p.set_mouse_capture(true);
let (dx, dy) = p.mouse_delta();
yaw += dx * sensitivity;
pitch += dy * sensitivity;
```
## Paletten
`palette::RGB332` ist als Default eingebaut. Eigene Paletten sind ein
`[[u8; 3]; 256]` (RGB pro Index) und werden über `PlatformConfig::palette`
übergeben.
Zur Laufzeit kann die Palette über `palette_mut()` modifiziert werden — einzelne
Einträge oder die komplette Tabelle. Der Upload passiert automatisch im nächsten
`present()`:
```rust
p.palette_mut()[42] = [255, 0, 0]; // Slot 42 → rot
p.present();
```