make the brush box work under the new GPU renderer
the brush preview will need separate treatment, but it shouldn't be too difficult
This commit is contained in:
		
							parent
							
								
									63d5c04a0d
								
							
						
					
					
						commit
						2810fe248f
					
				
					 2 changed files with 86 additions and 11 deletions
				
			
		| 
						 | 
				
			
			@ -3,6 +3,7 @@ import { Haku } from "rkgk/haku.js";
 | 
			
		|||
import { randomId } from "rkgk/random.js";
 | 
			
		||||
import { SaveData } from "rkgk/framework.js";
 | 
			
		||||
import { ContextMenu, globalContextMenuSpace } from "rkgk/context-menu.js";
 | 
			
		||||
import { BrushRenderer } from "rkgk/brush-renderer.js";
 | 
			
		||||
 | 
			
		||||
export const builtInPresets = [
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -15,7 +16,7 @@ color: #000
 | 
			
		|||
thickness: 8
 | 
			
		||||
 | 
			
		||||
withDotter \\d ->
 | 
			
		||||
  stroke thickness color (line d.From d.To)
 | 
			
		||||
  stroke thickness color d.From d.To
 | 
			
		||||
        `.trim(),
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -27,7 +28,7 @@ color: #000
 | 
			
		|||
thickness: 48
 | 
			
		||||
 | 
			
		||||
withDotter \\d ->
 | 
			
		||||
  stroke thickness color (line d.From d.To)
 | 
			
		||||
  stroke thickness color d.From d.To
 | 
			
		||||
        `.trim(),
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -43,7 +44,7 @@ duty: 0.5
 | 
			
		|||
withDotter \\d ->
 | 
			
		||||
  visible? = d.Num |mod length < length * duty
 | 
			
		||||
  if (visible?)
 | 
			
		||||
    stroke thickness color (line d.From d.To)
 | 
			
		||||
    stroke thickness color d.From d.To
 | 
			
		||||
  else
 | 
			
		||||
    ()
 | 
			
		||||
        `.trim(),
 | 
			
		||||
| 
						 | 
				
			
			@ -57,7 +58,7 @@ color: #0003
 | 
			
		|||
thickness: 6
 | 
			
		||||
 | 
			
		||||
withDotter \\d ->
 | 
			
		||||
  stroke thickness color (line d.From d.To)
 | 
			
		||||
  stroke thickness color d.From d.To
 | 
			
		||||
        `.trim(),
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -75,7 +76,7 @@ withDotter \\d ->
 | 
			
		|||
  a = sin (d.Num * wavelength / pi) + 1 / 2
 | 
			
		||||
  range = maxThickness - minThickness
 | 
			
		||||
  thickness = a * range + minThickness
 | 
			
		||||
  stroke thickness color (line d.From d.To)
 | 
			
		||||
  stroke thickness color d.From d.To
 | 
			
		||||
        `.trim(),
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -104,7 +105,7 @@ withDotter \\d ->
 | 
			
		|||
  clockwise = norm (perpClockwise d.To-d.From) * vec a a
 | 
			
		||||
  from = d.From + clockwise
 | 
			
		||||
  to = d.To + clockwise
 | 
			
		||||
  stroke thickness color (line from to)
 | 
			
		||||
  stroke thickness color from to
 | 
			
		||||
        `.trim(),
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -125,7 +126,7 @@ withDotter \\d ->
 | 
			
		|||
  g = colorCurve (d.Num * l + pi/3)
 | 
			
		||||
  b = colorCurve (d.Num * l + 2*pi/3)
 | 
			
		||||
  color = rgba r g b 1
 | 
			
		||||
  stroke thickness color (line d.From d.To)
 | 
			
		||||
  stroke thickness color d.From d.To
 | 
			
		||||
        `.trim(),
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -134,7 +135,8 @@ withDotter \\d ->
 | 
			
		|||
 | 
			
		||||
function presetButton(info) {
 | 
			
		||||
    let button = document.createElement("button");
 | 
			
		||||
    let preview = button.appendChild(new BrushPreview(56, 56));
 | 
			
		||||
    let preview = button.appendChild(document.createElement("div"));
 | 
			
		||||
    preview.classList.add("preview");
 | 
			
		||||
    let label = button.appendChild(document.createElement("p"));
 | 
			
		||||
    label.classList.add("label");
 | 
			
		||||
    label.innerText = info.name;
 | 
			
		||||
| 
						 | 
				
			
			@ -172,6 +174,14 @@ export class BrushBox extends HTMLElement {
 | 
			
		|||
 | 
			
		||||
    initialize(wallLimits) {
 | 
			
		||||
        this.haku = new Haku(wallLimits);
 | 
			
		||||
 | 
			
		||||
        this.brushesCanvas = this.appendChild(document.createElement("canvas"));
 | 
			
		||||
        this.gl = this.brushesCanvas.getContext("webgl2");
 | 
			
		||||
        let canvasResizeObserver = new ResizeObserver(() => this.renderBrushes());
 | 
			
		||||
        canvasResizeObserver.observe(this);
 | 
			
		||||
 | 
			
		||||
        this.brushRenderer = new BrushRenderer(this.gl, this.canvasSource());
 | 
			
		||||
 | 
			
		||||
        this.renderBrushes();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -290,10 +300,61 @@ export class BrushBox extends HTMLElement {
 | 
			
		|||
        if (this.currentPresetId != null) this.setCurrentBrush(this.currentPresetId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    canvasSource() {
 | 
			
		||||
        let brushBox = this;
 | 
			
		||||
        return {
 | 
			
		||||
            useCanvas(gl, i) {
 | 
			
		||||
                let brush = brushBox.brushes[i];
 | 
			
		||||
 | 
			
		||||
                let canvasRect = brushBox.brushesCanvas.getBoundingClientRect();
 | 
			
		||||
                let previewRect = brush.presetButton.preview.getBoundingClientRect();
 | 
			
		||||
                let viewport = {
 | 
			
		||||
                    x: previewRect.x - canvasRect.x,
 | 
			
		||||
                    y: canvasRect.bottom - previewRect.bottom,
 | 
			
		||||
                    width: previewRect.width,
 | 
			
		||||
                    height: previewRect.height,
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                gl.enable(gl.SCISSOR_TEST);
 | 
			
		||||
                gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
 | 
			
		||||
                gl.scissor(viewport.x, viewport.y, viewport.width, viewport.height);
 | 
			
		||||
 | 
			
		||||
                return viewport;
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            resetCanvas(gl) {},
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async renderBrushes() {
 | 
			
		||||
        for (let brush of this.brushes) {
 | 
			
		||||
        let gl = this.gl;
 | 
			
		||||
 | 
			
		||||
        this.brushesCanvas.width = this.brushesCanvas.clientWidth;
 | 
			
		||||
        this.brushesCanvas.height = this.brushesContainer.scrollHeight;
 | 
			
		||||
 | 
			
		||||
        gl.clearColor(0, 0, 0, 0);
 | 
			
		||||
        gl.clear(gl.COLOR_BUFFER_BIT);
 | 
			
		||||
 | 
			
		||||
        for (let i = 0; i < this.brushes.length; ++i) {
 | 
			
		||||
            let brush = this.brushes[i];
 | 
			
		||||
            let previewRect = brush.presetButton.preview.getBoundingClientRect();
 | 
			
		||||
 | 
			
		||||
            this.haku.setBrush(brush.preset.code);
 | 
			
		||||
            await brush.presetButton.preview.renderBrush(this.haku);
 | 
			
		||||
            await this.haku.evalBrush({
 | 
			
		||||
                runDotter: async () => {
 | 
			
		||||
                    return {
 | 
			
		||||
                        fromX: previewRect.width / 2,
 | 
			
		||||
                        fromY: previewRect.height / 2,
 | 
			
		||||
                        toX: previewRect.width / 2,
 | 
			
		||||
                        toY: previewRect.height / 2,
 | 
			
		||||
                        num: 0,
 | 
			
		||||
                    };
 | 
			
		||||
                },
 | 
			
		||||
 | 
			
		||||
                runScribble: async (renderToCanvas) => {
 | 
			
		||||
                    renderToCanvas(this.brushRenderer, i, 0, 0);
 | 
			
		||||
                },
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -283,6 +283,8 @@ rkgk-reticle-cursor {
 | 
			
		|||
rkgk-brush-box {
 | 
			
		||||
    --button-size: 56px;
 | 
			
		||||
 | 
			
		||||
    position: relative;
 | 
			
		||||
 | 
			
		||||
    height: var(--height);
 | 
			
		||||
    padding: 12px;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -316,7 +318,7 @@ rkgk-brush-box {
 | 
			
		|||
                border-color: var(--color-brand-blue);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            & > rkgk-brush-preview {
 | 
			
		||||
            & > .preview {
 | 
			
		||||
                width: var(--button-size);
 | 
			
		||||
                aspect-ratio: 1 / 1;
 | 
			
		||||
                background: none;
 | 
			
		||||
| 
						 | 
				
			
			@ -352,6 +354,18 @@ rkgk-brush-box {
 | 
			
		|||
            display: flex;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    & > canvas {
 | 
			
		||||
        position: absolute;
 | 
			
		||||
        left: 0;
 | 
			
		||||
        top: 0;
 | 
			
		||||
        width: 100%;
 | 
			
		||||
        margin: 12px;
 | 
			
		||||
 | 
			
		||||
        pointer-events: none;
 | 
			
		||||
 | 
			
		||||
        image-rendering: pixelated;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Code editor */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue