Torch
Loading...
Searching...
No Matches
BaseBackend.h
1#pragma once
2
3#include <cstdint>
4#include <cstdio>
5#include <cstdlib>
6#include <memory>
7#include <string>
8#include <vector>
9
10#define IMGUI_DEFINE_MATH_OPERATORS
11#include "imgui.h"
12
13class ViewManager;
14
15// Renderer/windowing abstraction for the viewer. Implement BaseBackend and
16// expose a Create<Name>Backend() factory; only src/ui/backends may include a
17// backend's own headers.
18namespace UI {
19
20using TextureHandle = ImTextureID;
21constexpr TextureHandle kInvalidTexture = (TextureHandle)0;
22
23// A single point for DrawPointCloud (object-space position + RGBA color).
25 float position[3];
26 unsigned char color[4];
27};
28
29// One display list of an assembled model, with its object->world transform
30// (row-vector convention, translation in row 3) and SM64 drawing layer.
31// Billboarded parts store their transform relative to the billboard node plus
32// the node's world position; the backend rebuilds them facing the camera.
33// Texture bound to a model part; the backend emits the tile setup. Offsets
34// index into blob; fmt/siz are G_IM_FMT_*/G_IM_SIZ_* values, cm* are
35// G_TX_WRAP/MIRROR/CLAMP flags.
37 std::shared_ptr<std::vector<uint8_t>> blob;
38 uint32_t rasterOffset = 0;
39 uint32_t paletteOffset = 0; // CI formats only
40 uint16_t width = 0;
41 uint16_t height = 0;
42 uint8_t fmt = 0;
43 uint8_t siz = 0;
44 uint8_t cmS = 0;
45 uint8_t cmT = 0;
46 // Cycle-1 combine: 0 modulate, 1 blend, 2 decal (PM64 main-only subtypes).
47 uint8_t combine = 0;
48 // Second tile blended into cycle 1 (PM64 aux textures): 0 = none,
49 // 2 = shared raster (aux is the second half of the main raster),
50 // 3 = independent raster/palette.
51 uint8_t auxMode = 0;
52 uint32_t auxRasterOffset = 0;
53 uint32_t auxPaletteOffset = 0;
54 uint16_t auxWidth = 0;
55 uint16_t auxHeight = 0;
56 uint8_t auxFmt = 0;
57 uint8_t auxSiz = 0;
58 uint8_t auxCmS = 0;
59 uint8_t auxCmT = 0;
60};
61
62struct ModelPart {
63 std::string resource;
64 float mtx[4][4];
65 uint8_t layer = 1; // LAYER_OPAQUE
66 // Exact render mode pair (othermode L cycle words); 0 = layer default.
67 uint32_t renderMode1 = 0;
68 uint32_t renderMode2 = 0;
69 uint8_t cycleType = 1; // pipeline cycles the render mode pair expects (1 or 2)
70 bool billboard = false;
71 float anchor[3] = { 0.0f, 0.0f, 0.0f };
72 bool unlit = false; // vertex-colored geometry; preview lighting must not apply
73 bool fullAmbient = false; // light with white ambient (bright, for lit previews)
74 // Untextured combine for game DLs that load their own textures (SF64):
75 // 0 = shade only (vertex color), 1 = texture modulate (enables texturing so
76 // the DL's own texture shows), 2 = flat primitive color, 3 = auto (impose no
77 // combine/texture state; the display list renders as authored).
78 uint8_t gameShade = 0;
79 std::shared_ptr<PartTexture> texture;
80};
81
82// A display-list bundle parsed from a game blob: byte-swapped f3dex2 command
83// words whose pointer operands are file offsets. G_VTX operands are relative
84// to vtxBase within the blob; G_DL operands reference other dlists by their
85// blob offset; G_SETTIMG operands are blob offsets.
87 uint32_t offset = 0;
88 std::vector<uint32_t> words; // w0/w1 pairs
89};
90
91struct GfxBundle {
92 std::shared_ptr<std::vector<uint8_t>> blob;
93 uint32_t vtxBase = 0;
94 uint32_t vtxSize = 0;
95 std::vector<GfxBundleDList> dlists;
96};
97
98// Orbit camera: yaw/pitch in radians, zoom > 1 moves closer, pan in screen
99// pixels shifting the look-at target in the view plane.
100struct OrbitView {
101 float yaw = 0.6f;
102 float pitch = 0.3f;
103 float zoom = 1.0f;
104 float panX = 0.0f;
105 float panY = 0.0f;
106};
107
108// Shared preview point light. Position is in bounding radii from the model's
109// center; intensity falls off quadratically with distance. Parts that bind
110// their own material lights (how SM64 colors body parts) override it.
112 bool enabled = true; // G_LIGHTING on/off
113 float ambient[3] = { 0.25f, 0.25f, 0.25f };
114 float color[3] = { 1.0f, 1.0f, 1.0f };
115 float position[3] = { 1.5f, 2.0f, 1.5f };
116 float intensity = 1.0f;
117 float falloff = 0.3f;
118};
119
120inline PreviewLighting& GetPreviewLighting() {
121 static PreviewLighting lighting;
122 return lighting;
123}
124
125// Shared preview fog (N64 vertex fog: blender cycle-1 fog shade). Start/end
126// are gSPFogPosition units (0..1000 across the near..far range).
128 bool fogEnabled = false;
129 float fogColor[3] = { 0.45f, 0.50f, 0.65f };
130 int fogStart = 890;
131 int fogEnd = 1000;
132};
133
134inline PreviewAtmosphere& GetPreviewAtmosphere() {
135 static PreviewAtmosphere atmosphere = [] {
137 if (const char* f = std::getenv("TORCH_UI_FOG")) {
138 a.fogEnabled = true;
139 int s0 = 0, e0 = 0;
140 if (sscanf(f, "%d:%d", &s0, &e0) == 2 && e0 > s0) {
141 a.fogStart = s0;
142 a.fogEnd = e0;
143 }
144 }
145 return a;
146 }();
147 return atmosphere;
148}
149
151public:
152 virtual ~BaseBackend() = default;
153
154 // Owns the window and render loop: creates the window, applies the theme,
155 // draws `views` every frame until the user closes it.
156 virtual void RunViewer(const std::shared_ptr<ViewManager>& views) = 0;
157
158 // Uploads 8-bit RGBA pixels; kInvalidTexture on failure. The backend owns
159 // the GPU resource.
160 virtual TextureHandle UploadRGBA8(const uint8_t* pixels, int width, int height) = 0;
161
162 // Draws a colored point cloud at the given screen rect. `id` keys a
163 // reusable render target. Optional.
164 virtual void DrawPointCloud(uint64_t id, const std::vector<PreviewVertex>& points,
165 const ImVec2& topLeft, const ImVec2& size, const OrbitView& view) {}
166
167 // Previews a display-list resource as a shaded model at the given screen
168 // rect. Requires the resource's archive to be mounted. Optional.
169 virtual void DrawModel(const std::string& resourceName, const ImVec2& topLeft, const ImVec2& size,
170 const OrbitView& view) {}
171
172 // Previews a multi-part model (e.g. a flattened geo layout). `key`
173 // identifies the assembled model for render-target reuse. Optional.
174 virtual void DrawModelParts(const std::string& key, const std::vector<ModelPart>& parts,
175 const ImVec2& topLeft, const ImVec2& size, const OrbitView& view) {}
176
177 // Registers an entry display list from a parsed game blob under `name` so
178 // ModelPart::resource can reference it. Returns false if unsupported.
179 virtual bool RegisterGameDList(const std::string& name, const GfxBundle& bundle, uint32_t entryOffset) {
180 return false;
181 }
182
183 // Screen-space backdrop image (RGBA8, cover-fit) drawn behind the model
184 // keyed by DrawModelParts' `key`. nullptr clears it. Optional.
185 virtual void SetPreviewBackdrop(const std::string& key, const uint8_t* rgba, int width, int height) {}
186
187 // Renders a colored triangle soup (three PreviewVertex per triangle) with
188 // the same camera and render-target reuse as DrawModelParts. Optional.
189 virtual void DrawTriangles(const std::string& key, const std::vector<PreviewVertex>& tris,
190 const ImVec2& topLeft, const ImVec2& size, const OrbitView& view) {}
191
192 // Plays interleaved 16-bit PCM, replacing whatever is currently playing.
193 virtual bool PlaySamples(const int16_t* frames, size_t frameCount, int sampleRate, int channels) { return false; }
194 virtual void StopAudio() {}
195 // Playback position in [0,1]; negative when idle/finished.
196 virtual float AudioProgress() { return -1.0f; }
197 virtual void SeekAudio(float progress) {}
198 virtual void SetAudioVolume(float volume) {}
199 virtual float GetAudioVolume() { return 1.0f; }
200 // Playback-rate multiplier (1 = the sample's own rate).
201 virtual void SetAudioSpeed(float speed) {}
202 virtual float GetAudioSpeed() { return 1.0f; }
203};
204
205inline BaseBackend*& ActiveBackend() {
206 static BaseBackend* backend = nullptr;
207 return backend;
208}
209
210inline BaseBackend* GetBackend() {
211 return ActiveBackend();
212}
213
214inline void SetBackend(BaseBackend* backend) {
215 ActiveBackend() = backend;
216}
217
218} // namespace UI
Definition BaseBackend.h:150
Definition View.h:35
Definition BaseBackend.h:86
Definition BaseBackend.h:91
Definition BaseBackend.h:62
Definition BaseBackend.h:100
Definition BaseBackend.h:36
Definition BaseBackend.h:127
Definition BaseBackend.h:111
Definition BaseBackend.h:24