> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Replace the JavaFX `SubScene`/`MeshView` 3D view in `CityDoctorGUI` with an OpenGL-rendered viewport (openglfx-jogl, GL 3.3 core) that orbits/zooms/pans smoothly on whole-city models.
**Architecture:** A single global static VBO holds all triangle vertices (`position`, baked-shade `color`, `polygonId`); one `glDrawElements` per frame draws an index set rebuilt on filter/LOD changes. GPU color-picking (off-screen FBO + readback) resolves clicks to polygons/vertices/edges. Selection is a shader `selectedId` tint; vertex/edge highlight markers live in a small dynamic overlay buffer. The pure math/data core is unit-tested (TDD); the GL/openglfx glue is verified by running the app.
Expected: `openglfx-jogl`, `jogl-all` (or `jogl-all-main`), and `gluegen-rt` appear. If `jogl-all` natives
for win/linux are absent, add to `pom.xml` dependencies:
```xml
<dependency>
<groupId>org.jogamp.jogl</groupId>
<artifactId>jogl-all-main</artifactId>
</dependency>
<dependency>
<groupId>org.jogamp.gluegen</groupId>
<artifactId>gluegen-rt-main</artifactId>
</dependency>
```
(Version is managed by the parent `pom.xml``dependencyManagement` — see `CityDoctorParent/pom.xml:169,179`.)
- [ ] **Step 2: Minimal canvas smoke test**
Temporarily add a `main` to a scratch class (or a JUnit test guarded by `Assume.assumeFalse(GraphicsEnvironment.isHeadless())`) that constructs `new GLCanvas(new JOGLExecutor(), GLProfile.CORE)` inside a JavaFX `Application.start`, adds it to a `Scene`, and logs from an `addOnInitEvent` handler.
The GUI renders 3D CityGML geometry with JavaFX, tesselating **each polygon into its own
`TriangleMesh` + `MeshView` + `PhongMaterial`** (see `TriangulatedGeometry`). At city scale this
produces thousands of scene-graph nodes, each with its own material — the JavaFX node overhead, not
just the lack of shader access, makes orbit/zoom stutter or freeze.
**Goal:** Replace the JavaFX `SubScene` 3D view with an OpenGL-rendered viewport that orbits, zooms,
and pans smoothly on whole-city models (millions of triangles), while preserving every existing view
feature (picking, highlights, filters, wireframe, culling, north arrow, screenshot).
## 2. Decisions (settled during brainstorming)
| Topic | Decision |
|-------|----------|
| Scale target | Whole cities, millions of triangles; smooth (30–60 fps) interaction. |
| Integration | Embed an OpenGL canvas via the already-present `openglfx-jogl` (huskerdev) dependency, in the `meshView``Pane` where the `SubScene` lives today. |
| Platforms | **Windows + Linux** are hard targets. macOS bundle still builds but the GL view may degrade — accepted. |
| JavaFX 3D path | **Fully removed** (no fallback). |
| Buffer strategy | **Single global static VBO**; one `glDrawElements` per frame; filter/LOD changes rebuild the draw **index set** (EBO), not the VBO. |
| Picking | **GPU color-picking**: off-screen FBO encodes `polygonId` per fragment; `glReadPixels` on click. |
| Shading | **Keep existing fake shading** (`normal·AXIS` → brightness), **baked into per-vertex color on the CPU** at build time. No lighting in the shader. Normal attribute dropped from the VBO. |