glPlan: runde Linien-Caps/Joins + Schraffurbreite bildschirm-konstant
- Runde Enden und Ecken statt Butt-Caps/Miter: jedes Segment als eigenes Quad, an Innenecken ein Dreiecks-Fächer über den Aussenwinkel (addRoundJoin), an offenen Enden ein Halbkreis-Fächer (addRoundCap). Gilt für Wandumrisse, Linien, Bögen und Schraffurläufe — Look wie das Vektor-PDF. Keine Shader- Änderung nötig (Radius weiterhin zur Render-Zeit aus strokePx*strokeScale). - Schraffur-Dicke-Bug behoben: glPlan schickte die Schraffur-mm durch die Papier-mm-Pipeline (strokeMm*mmToDevicePx); im Display-Modus ist der darin steckende paperScaleN ein zoom-abgeleiteter, nicht auf 0.13/mm kalibrierter Wert → Breite explodierte. Jetzt hatchStrokeVb = max(0.6, hatchMm/0.13) als screenPx-Batch (skaliert nur mit meet/Zoom) — byte-genau wie SVG-<pattern> und der PDF-Export (widthScreen). Wandumrisse unverändert (echte mm).
This commit is contained in:
@@ -160,7 +160,7 @@ export class PlanGpuRenderer {
|
||||
const mmToDevicePx = (paperScaleN / 1000) * PX_PER_M * meet;
|
||||
|
||||
this.drawFills(geometry);
|
||||
this.drawLines(geometry, viewport, mmToDevicePx);
|
||||
this.drawLines(geometry, viewport, mmToDevicePx, meet);
|
||||
}
|
||||
|
||||
/** Gefüllte Polygone (Poché). */
|
||||
@@ -191,11 +191,21 @@ export class PlanGpuRenderer {
|
||||
if (pos !== undefined && pos >= 0) gl.disableVertexAttribArray(pos);
|
||||
}
|
||||
|
||||
/** Striche mit echter Papier-mm-Breite (massstabs- + zoomrichtig). */
|
||||
/**
|
||||
* Striche. Zwei Skalierungs-Regime pro Batch (siehe `LineBatch.screenPx`):
|
||||
* • Papier-mm (Standard) — Wand-/Objekt-Umrisse: massstabs- + zoomrichtig
|
||||
* über `mmToDevicePx`.
|
||||
* • Bildschirm-px (`screenPx`) — Schraffur-Musterlinien: NUR mit `meet`
|
||||
* (Zoom) skaliert, unabhängig vom Papier-Massstab N — exakt wie der SVG-
|
||||
* `hatchStrokePx`-Pfad (`patternUnits="userSpaceOnUse"`, keine
|
||||
* `printStrokeVb`-Umrechnung) und der PDF-Export (`toRenderScene.ts`,
|
||||
* `widthScreen: true`).
|
||||
*/
|
||||
private drawLines(
|
||||
geometry: GpuGeometry,
|
||||
viewport: { width: number; height: number },
|
||||
mmToDevicePx: number,
|
||||
meet: number,
|
||||
): void {
|
||||
const gl = this.gl;
|
||||
const { vertexBuffer, indexBuffer, batches } = geometry.line;
|
||||
@@ -210,10 +220,6 @@ export class PlanGpuRenderer {
|
||||
if (prog.uniforms.viewportPx) {
|
||||
gl.uniform2f(prog.uniforms.viewportPx, viewport.width, viewport.height);
|
||||
}
|
||||
// strokeScale = mm → Geräte-px; die Basis-Breite (strokePx) trägt die mm.
|
||||
if (prog.uniforms.strokeScale) {
|
||||
gl.uniform1f(prog.uniforms.strokeScale, mmToDevicePx);
|
||||
}
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
|
||||
const stride = 6 * 4; // [x,y, nx,ny, side, miter]
|
||||
@@ -239,13 +245,17 @@ export class PlanGpuRenderer {
|
||||
}
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
|
||||
|
||||
// strokePx-Uniform trägt die ECHTE Papier-mm-Breite; der Shader multipliziert
|
||||
// mit strokeScale (= mm→Geräte-px) und klemmt bei ~0.6 px (Haarlinie sichtbar,
|
||||
// MSAA via antialias:true), damit sehr feine Gewichte beim Rauszoomen nicht
|
||||
// verschwinden.
|
||||
// strokePx-Uniform trägt die Breite (Papier-mm ODER Bildschirm-px, je nach
|
||||
// `screenPx`); strokeScale wählt PRO BATCH den passenden Massstabsfaktor.
|
||||
// Der Shader multipliziert beides und klemmt bei ~0.6 px (Haarlinie
|
||||
// sichtbar, MSAA via antialias:true), damit sehr feine Gewichte beim
|
||||
// Rauszoomen nicht verschwinden.
|
||||
for (const b of batches) {
|
||||
if (prog.uniforms.color) gl.uniform4fv(prog.uniforms.color, b.color);
|
||||
if (prog.uniforms.strokePx) gl.uniform1f(prog.uniforms.strokePx, b.strokeMm);
|
||||
if (prog.uniforms.strokeScale) {
|
||||
gl.uniform1f(prog.uniforms.strokeScale, b.screenPx ? meet : mmToDevicePx);
|
||||
}
|
||||
gl.drawElements(gl.TRIANGLES, b.indexCount, gl.UNSIGNED_INT, b.startIndex * 4);
|
||||
}
|
||||
if (pos !== undefined && pos >= 0) gl.disableVertexAttribArray(pos);
|
||||
|
||||
Reference in New Issue
Block a user