Files
pbio/README.md
T
irrlicht c5a4d0026b 16-Bit-Truecolor (RGB565) statt 8-Bit-Palette
Framebuffer ist jetzt &mut [u16], jeder Wert ein RGB565-Pixel. Der
Shader dekodiert die Bitfelder direkt aus einer R16Uint-Textur; die
Palette (Textur, API, Presets, Tooling) entfaellt. Neu: pbio::rgb565()
zum Packen von 8-Bit-Kanaelen.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 15:04:05 +02:00

109 lines
4.3 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 — 16-Bit-Truecolor-Variante
Pixelbuffer-basiertes Fenster mit RGB565-Truecolor-Renderer (winit + wgpu) und Maus/Tastatureingaben.
pbio nimmt ein `u16`-Array, interpretiert jeden Wert als RGB565-Pixel (Bits `RRRRRGGGGGGBBBBB`) und rendert ihn auf ein Fenster. Optional mit Letterbox für ein festes Seitenverhältnis.
Dies ist der Branch `truecolor16`. Auf `master` liegt die 8-Bit-Variante mit Palette-Lookup — beide sind unabhängig voneinander nutzbar.
## 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", branch = "truecolor16" }
```
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() {
let v = ((i as u32 % w) ^ (i as u32 / w)) as u8;
*px = pbio::rgb565(v, v, v);
}
p.present();
}
}
```
## API-Überblick
- `PlatformConfig` Titel, Fenster-/Framebuffer-Größe, optionales
`aspect_ratio` (Letterbox), VSync, `mouse_visible`, `mouse_capture`.
Default = 800×600 Fenster, 320×240 Framebuffer, 4:3.
- `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` …).
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 [u16]` der Länge `w*h`, je Pixel ein RGB565-Wert.
- `rgb565(r, g, b) -> u16` packt 8-Bit-RGB in einen RGB565-Pixelwert (const fn).
- `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;
```
## Pixelformat
RGB565: 5 Bit Rot, 6 Bit Grün, 5 Bit Blau in einem `u16` (Bits
`RRRRRGGGGGGBBBBB`). Der Shader dekodiert die Bitfelder direkt — es gibt
keine Palette. Zum Packen von 8-Bit-Kanälen dient `pbio::rgb565`:
```rust
let orange = pbio::rgb565(255, 160, 0);
p.framebuffer_mut()[0] = orange;
```