From 5dbdf9351a065a821938c9cc123988a236fd417b Mon Sep 17 00:00:00 2001 From: Marcus Ramse Date: Mon, 20 May 2024 01:14:12 +0200 Subject: [PATCH] sim: fix colors (flipping all over) --- simulator/src/compositor.ts | 18 +++++++++++++++--- simulator/src/framebuffer.ts | 14 +++++++------- simulator/src/ui/utils.ts | 6 ++++-- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/simulator/src/compositor.ts b/simulator/src/compositor.ts index aa157bf..ddf86e8 100644 --- a/simulator/src/compositor.ts +++ b/simulator/src/compositor.ts @@ -3,6 +3,8 @@ import * as GL from "./webgl-constants"; import type { Framebuffer } from "./framebuffer"; export class WebGLCompositor { + flipped = new Uint16Array(WIDTH * HEIGHT); + constructor (public gl: WebGLRenderingContext) { const canvas = gl.canvas; canvas.addEventListener("webglcontextlost", event => { @@ -63,7 +65,7 @@ export class WebGLCompositor { varying vec2 framebufferCoord; void main () { - gl_FragColor = texture2D(framebuffer, vec2(framebufferCoord.y, framebufferCoord.x)); + gl_FragColor = texture2D(framebuffer, framebufferCoord); } `); @@ -88,7 +90,7 @@ export class WebGLCompositor { // Create framebuffer texture createTexture(GL.TEXTURE0); - gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGB565, HEIGHT, WIDTH, 0, GL.RGB, GL.UNSIGNED_SHORT_5_6_5, null); + gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGB565, WIDTH, HEIGHT, 0, GL.RGB, GL.UNSIGNED_SHORT_5_6_5, null); // Setup static geometry const positionAttrib = gl.getAttribLocation(program, "pos"); @@ -107,8 +109,18 @@ export class WebGLCompositor { const gl = this.gl; const bytes = framebuffer.bytes; + // Rotate and swap byte order flip bytes + // Would not be required if WebGL supported `UNSIGNED_SHORT_5_6_5_REV` + for (let x = 0; x < WIDTH; x++) { + for (let y = 0; y < HEIGHT; y++) { + const fi = x + y * WIDTH; + const bi = x * HEIGHT + y; + this.flipped[fi] = ((bytes[bi] & 0xff) << 8) | (bytes[bi] >> 8); + } + } + // Upload framebuffer - gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGB565, HEIGHT, WIDTH, 0, GL.RGB, GL.UNSIGNED_SHORT_5_6_5, bytes); + gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGB565, WIDTH, HEIGHT, 0, GL.RGB, GL.UNSIGNED_SHORT_5_6_5, this.flipped); // Draw the fullscreen quad gl.drawArrays(GL.TRIANGLES, 0, 6); diff --git a/simulator/src/framebuffer.ts b/simulator/src/framebuffer.ts index 9dd04f7..27c0164 100644 --- a/simulator/src/framebuffer.ts +++ b/simulator/src/framebuffer.ts @@ -28,7 +28,7 @@ export class Framebuffer { } drawHLine(color: number, x: number, y: number, len: number) { - if (y + len <= 0 || x < 0 || x >= WIDTH) { + if (x + len <= 0 || y < 0 || y >= HEIGHT) { return; } @@ -36,7 +36,7 @@ export class Framebuffer { const endX = Math.min(WIDTH, x + len); for (let xx = startX; xx < endX; xx++) { - this.drawPoint(color, xx, y); + this.drawPointUnclipped(color, xx, y); } } @@ -67,7 +67,7 @@ export class Framebuffer { if (fillColor !== OPTIONAL_COLOR_NONE) { for (let yy = startY; yy < endY; ++yy) { - this.drawHLine(fillColor, startX, yy, endX); + this.drawHLine(fillColor, startX, yy, endX - startX); } } @@ -88,12 +88,12 @@ export class Framebuffer { // Top edge if (y >= 0 && y < HEIGHT) { - this.drawHLine(strokeColor, startX, y, endX); + this.drawHLine(strokeColor, startX, y, endX - startX); } // Bottom edge if (endYUnclamped > 0 && endYUnclamped <= HEIGHT) { - this.drawHLine(strokeColor, startX, endYUnclamped - 1, endX); + this.drawHLine(strokeColor, startX, endYUnclamped - 1, endX - startX); } } } @@ -151,8 +151,8 @@ export class Framebuffer { const len = east - start; if (fillColor !== OPTIONAL_COLOR_NONE && len > 0) { // Only draw fill if the length from west to east is not 0 - this.drawHLine(fillColor, start, north, east); /* I and III. Quadrant */ - this.drawHLine(fillColor, start, south, east); /* II and IV. Quadrant */ + this.drawHLine(fillColor, start, north, east - start); /* I and III. Quadrant */ + this.drawHLine(fillColor, start, south, east - start); /* II and IV. Quadrant */ } const err2 = 2 * err; diff --git a/simulator/src/ui/utils.ts b/simulator/src/ui/utils.ts index 1b4f888..618aae3 100644 --- a/simulator/src/ui/utils.ts +++ b/simulator/src/ui/utils.ts @@ -44,11 +44,13 @@ export function requestFullscreen () { * @returns RGB565 representation */ export function pack565(red: number, green: number, blue: number): number { - return blue | (green << 5) | (red << 11); + const rev = blue | (green << 5) | (red << 11); + return ((rev & 0xff) << 8) | (rev >> 8); } export function unpack565(bgr565: number): [number, number, number] { - return [bgr565 >> 11, bgr565 >> 5 & 0b111111, bgr565 & 0b11111]; + const flipped = ((bgr565 & 0xff) << 8) | (bgr565 >> 8); + return [flipped >> 11, flipped >> 5 & 0b111111, flipped & 0b11111]; } export function unpack888(bgr888: number): [number, number, number] {