Skip to content
Snippets Groups Projects
Commit 54476ad8 authored by Alexander Rose's avatar Alexander Rose
Browse files

improve print texture debug helpers

parent 6dd87623
No related branches found
No related tags found
No related merge requests found
...@@ -6,11 +6,12 @@ ...@@ -6,11 +6,12 @@
import { WebGLContext } from '../../mol-gl/webgl/context'; import { WebGLContext } from '../../mol-gl/webgl/context';
import { Texture } from '../../mol-gl/webgl/texture'; import { Texture } from '../../mol-gl/webgl/texture';
import { printTextureImage } from '../../mol-gl/renderable/util'; import { PrintImageOptions, printTextureImage } from '../../mol-gl/renderable/util';
import { defaults, ValueCell } from '../../mol-util'; import { defaults, ValueCell } from '../../mol-util';
import { ValueSpec, AttributeSpec, UniformSpec, Values } from '../../mol-gl/renderable/schema'; import { ValueSpec, AttributeSpec, UniformSpec, Values } from '../../mol-gl/renderable/schema';
import { Vec2 } from '../../mol-math/linear-algebra'; import { Vec2 } from '../../mol-math/linear-algebra';
import { GLRenderingContext } from '../../mol-gl/webgl/compat'; import { GLRenderingContext } from '../../mol-gl/webgl/compat';
import { PixelData } from '../../mol-util/image';
export const QuadPositions = new Float32Array([ export const QuadPositions = new Float32Array([
1.0, 1.0, -1.0, 1.0, -1.0, -1.0, // First triangle 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, // First triangle
...@@ -41,7 +42,7 @@ function getArrayForTexture(gl: GLRenderingContext, texture: Texture, size: numb ...@@ -41,7 +42,7 @@ function getArrayForTexture(gl: GLRenderingContext, texture: Texture, size: numb
throw new Error('unknown/unsupported texture type'); throw new Error('unknown/unsupported texture type');
} }
export function readTexture(ctx: WebGLContext, texture: Texture, width?: number, height?: number) { export function readTexture(ctx: WebGLContext, texture: Texture, width?: number, height?: number): PixelData {
const { gl, resources } = ctx; const { gl, resources } = ctx;
width = defaults(width, texture.getWidth()); width = defaults(width, texture.getWidth());
height = defaults(height, texture.getHeight()); height = defaults(height, texture.getHeight());
...@@ -55,6 +56,8 @@ export function readTexture(ctx: WebGLContext, texture: Texture, width?: number, ...@@ -55,6 +56,8 @@ export function readTexture(ctx: WebGLContext, texture: Texture, width?: number,
return { array, width, height }; return { array, width, height };
} }
export function printTexture(ctx: WebGLContext, texture: Texture, scale: number) { export function printTexture(ctx: WebGLContext, texture: Texture, options: Partial<PrintImageOptions> = {}) {
printTextureImage(readTexture(ctx, texture), scale); const pixelData = readTexture(ctx, texture);
PixelData.flipY(pixelData);
printTextureImage(pixelData, options);
} }
\ No newline at end of file
...@@ -39,7 +39,15 @@ export function createTextureImage<T extends Uint8Array | Float32Array>(n: numbe ...@@ -39,7 +39,15 @@ export function createTextureImage<T extends Uint8Array | Float32Array>(n: numbe
return { array, width, height }; return { array, width, height };
} }
export function printTextureImage(textureImage: TextureImage<any>, scale = 1) { const DefaultPrintImageOptions = {
scale: 1,
pixelated: false,
id: 'molstar.debug.image'
};
export type PrintImageOptions = typeof DefaultPrintImageOptions
export function printTextureImage(textureImage: TextureImage<any>, options: Partial<PrintImageOptions> = {}) {
const { array, width, height } = textureImage; const { array, width, height } = textureImage;
const itemSize = array.length / (width * height); const itemSize = array.length / (width * height);
const data = new Uint8ClampedArray(width * height * 4); const data = new Uint8ClampedArray(width * height * 4);
...@@ -54,32 +62,50 @@ export function printTextureImage(textureImage: TextureImage<any>, scale = 1) { ...@@ -54,32 +62,50 @@ export function printTextureImage(textureImage: TextureImage<any>, scale = 1) {
} else { } else {
console.warn(`itemSize '${itemSize}' not supported`); console.warn(`itemSize '${itemSize}' not supported`);
} }
return printImageData(new ImageData(data, width, height), scale); return printImageData(new ImageData(data, width, height), options);
} }
export function printImageData(imageData: ImageData, scale = 1, pixelated = false) { let tmpCanvas: HTMLCanvasElement;
const canvas = document.createElement('canvas'); let tmpCanvasCtx: CanvasRenderingContext2D;
let tmpContainer: HTMLDivElement;
export function printImageData(imageData: ImageData, options: Partial<PrintImageOptions> = {}) {
const o = { ...DefaultPrintImageOptions, ...options };
const canvas = tmpCanvas || document.createElement('canvas');
tmpCanvas = canvas;
canvas.width = imageData.width; canvas.width = imageData.width;
canvas.height = imageData.height; canvas.height = imageData.height;
const ctx = canvas.getContext('2d'); const ctx = tmpCanvasCtx || canvas.getContext('2d');
tmpCanvasCtx = ctx;
if (!ctx) throw new Error('Could not create canvas 2d context'); if (!ctx) throw new Error('Could not create canvas 2d context');
ctx.putImageData(imageData, 0, 0); ctx.putImageData(imageData, 0, 0);
if (!tmpContainer) {
tmpContainer = document.createElement('div');
tmpContainer.style.position = 'absolute';
tmpContainer.style.bottom = '0px';
tmpContainer.style.right = '0px';
tmpContainer.style.border = 'solid orange';
tmpContainer.style.pointerEvents = 'none';
document.body.appendChild(tmpContainer);
}
canvas.toBlob(imgBlob => { canvas.toBlob(imgBlob => {
const objectURL = window.URL.createObjectURL(imgBlob); const objectURL = URL.createObjectURL(imgBlob);
const img = document.createElement('img'); const existingImg = document.getElementById(o.id) as HTMLImageElement;
const img = existingImg || document.createElement('img');
img.id = o.id;
img.src = objectURL; img.src = objectURL;
img.style.width = imageData.width * scale + 'px'; img.style.width = imageData.width * o.scale + 'px';
img.style.height = imageData.height * scale + 'px'; img.style.height = imageData.height * o.scale + 'px';
if (pixelated) { if (o.pixelated) {
// not supported in Firefox and IE // not supported in Firefox and IE
img.style.imageRendering = 'pixelated'; img.style.imageRendering = 'pixelated';
} }
img.style.position = 'relative'; img.style.position = 'relative';
img.style.top = '0px';
img.style.left = '0px';
img.style.border = 'solid grey'; img.style.border = 'solid grey';
img.style.pointerEvents = 'none'; img.style.pointerEvents = 'none';
document.body.appendChild(img); if (!existingImg) tmpContainer.appendChild(img);
}, 'image/png'); }, 'image/png');
} }
......
...@@ -7,13 +7,13 @@ ...@@ -7,13 +7,13 @@
export { PixelData }; export { PixelData };
interface PixelData { interface PixelData {
readonly array: Uint8Array readonly array: Uint8Array | Float32Array
readonly width: number readonly width: number
readonly height: number readonly height: number
} }
namespace PixelData { namespace PixelData {
export function create(array: Uint8Array, width: number, height: number): PixelData { export function create(array: Uint8Array | Float32Array, width: number, height: number): PixelData {
return { array, width, height }; return { array, width, height };
} }
...@@ -36,8 +36,9 @@ namespace PixelData { ...@@ -36,8 +36,9 @@ namespace PixelData {
/** to undo pre-multiplied alpha */ /** to undo pre-multiplied alpha */
export function divideByAlpha(pixelData: PixelData): PixelData { export function divideByAlpha(pixelData: PixelData): PixelData {
const { array } = pixelData; const { array } = pixelData;
const factor = (array instanceof Uint8Array) ? 255 : 1;
for (let i = 0, il = array.length; i < il; i += 4) { for (let i = 0, il = array.length; i < il; i += 4) {
const a = array[i + 3] / 255; const a = array[i + 3] / factor;
array[i] /= a; array[i] /= a;
array[i + 1] /= a; array[i + 1] /= a;
array[i + 2] /= a; array[i + 2] /= a;
......
...@@ -33,7 +33,7 @@ function test() { ...@@ -33,7 +33,7 @@ function test() {
fontAtlas.get(String.fromCharCode(0x212B)); fontAtlas.get(String.fromCharCode(0x212B));
console.timeEnd('Angstrom Sign'); console.timeEnd('Angstrom Sign');
printTextureImage(fontAtlas.texture, 0.5); printTextureImage(fontAtlas.texture, { scale: 0.5 });
console.log(`${Object.keys(fontAtlas.mapped).length} chars prepared`); console.log(`${Object.keys(fontAtlas.mapped).length} chars prepared`);
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment