diff --git a/package-lock.json b/package-lock.json index e0ce8a7104c0c2831c0d2f0726b4aecad7820596..ba0d8e8601174f88ca60c365fe21061240abaab6 100644 Binary files a/package-lock.json and b/package-lock.json differ diff --git a/package.json b/package.json index 37d12c7353147f3050a9e9ec73f8272ccf8de6dd..b4ce18b111a4ddd77fe460be17c1669086e15042 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,8 @@ "js" ], "transform": { - "\\.ts$": "ts-jest" + "\\.ts$": "ts-jest", + "\\.(glsl|frag|vert)$": "jest-raw-loader" }, "moduleDirectories": [ "node_modules", @@ -67,6 +68,7 @@ "glslify-import": "^3.1.0", "glslify-loader": "^1.0.2", "jest": "^22.4.3", + "jest-raw-loader": "^1.0.1", "raw-loader": "^0.5.1", "regl": "git+https://github.com/regl-project/regl.git#45c6ec570232420fca21567499c9c5a2a054432e", "ts-jest": "^22.4.2", diff --git a/src/mol-gl/_spec/renderer.spec.ts b/src/mol-gl/_spec/renderer.spec.ts index c0c55ba4b384d8203a32c18275051c41b80b7a3e..155e8ed5cadc0b970332728f0afca49026acdf8b 100644 --- a/src/mol-gl/_spec/renderer.spec.ts +++ b/src/mol-gl/_spec/renderer.spec.ts @@ -4,11 +4,76 @@ * @author Alexander Rose <alexander.rose@weirdbyte.de> */ -// import createGl = require('gl'); +import createGl = require('gl'); -// import Renderer from '../renderer'; +import { PerspectiveCamera } from 'mol-view/camera/perspective'; +import { Vec3, Mat4 } from 'mol-math/linear-algebra'; +import { ValueCell } from 'mol-util'; -// describe('renderer', () => { -// const gl = createGl(256, 256) -// const renderer = Renderer.create(gl, {} as any) -// }) \ No newline at end of file +import Renderer from '../renderer'; +import { createPointRenderObject } from '../scene'; +import { fillSerial } from '../renderable/util'; +import { createUniformColor } from 'mol-geo/color/data'; +import { createUniformSize } from 'mol-geo/size/data'; + +function writeImage(gl: WebGLRenderingContext, width: number, height: number) { + const pixels = new Uint8Array(width * height * 4) + gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels) + process.stdout.write(['P3\n# gl.ppm\n', width, ' ', height, '\n255\n'].join('')) + for (let i = 0; i<pixels.length; i+=4) { + for (let j = 0; j<3; ++j) { + process.stdout.write(pixels[i+j] + ' ') + } + } +} + +function createRenderer(gl: WebGLRenderingContext) { + const camera = PerspectiveCamera.create({ + near: 0.01, + far: 10000, + position: Vec3.create(0, 0, 50) + }) + return Renderer.create(gl, camera) +} + +function createPoints() { + const position = ValueCell.create(new Float32Array([0, -1, 0, -1, 0, 0, 1, 1, 0])) + const id = ValueCell.create(fillSerial(new Float32Array(3))) + const color = createUniformColor({ value: 0xFF0000 }) + const size = createUniformSize({ value: 1 }) + + const transform = ValueCell.create(new Float32Array(16)) + const m4 = Mat4.identity() + Mat4.toArray(m4, transform.ref.value, 0) + + return createPointRenderObject({ + objectId: 0, + + position, + id, + color, + size, + transform, + + instanceCount: 1, + elementCount: 3, + positionCount: 3 + }) +} + +// TODO not working +// - headless-gl does not support 'OES_element_index_uint' +// - shaders not transformed via glslify +describe.skip('renderer', () => { + it('basic', () => { + const [ width, height ] = [ 32, 32 ] + const gl = createGl(width, height, { preserveDrawingBuffer: true }) + const renderer = createRenderer(gl) + const points = createPoints() + + renderer.add(points) + renderer.draw() + + writeImage(gl, width, height) + }) +}) \ No newline at end of file diff --git a/src/mol-gl/renderer.ts b/src/mol-gl/renderer.ts index 874f029d21b83b7109d2ec85f04ffc236aa1c456..2d2afd56f84808ad6b2534b4b42086b8027b4cec 100644 --- a/src/mol-gl/renderer.ts +++ b/src/mol-gl/renderer.ts @@ -44,8 +44,8 @@ function getPixelRatio() { } namespace Renderer { - export function create(canvas: HTMLCanvasElement, camera: Camera): Renderer { - const regl = glContext.create({ canvas, extensions, optionalExtensions, profile: false }) + export function create(gl: WebGLRenderingContext, camera: Camera): Renderer { + const regl = glContext.create({ gl, extensions, optionalExtensions, profile: false }) const scene = Scene.create(regl) const baseContext = regl({ diff --git a/src/mol-view/viewer.ts b/src/mol-view/viewer.ts index d7e59cd11623e95b6acb35ca9da32f1c88149ac0..667a0d0353bdb63da9c2b5a131d65f0dae95c5b6 100644 --- a/src/mol-view/viewer.ts +++ b/src/mol-view/viewer.ts @@ -29,6 +29,17 @@ interface Viewer { dispose: () => void } +function getWebGLContext(canvas: HTMLCanvasElement, contextAttributes?: WebGLContextAttributes) { + function getContext(contextId: 'webgl' | 'experimental-webgl') { + try { + return canvas.getContext(contextId, contextAttributes) + } catch (e) { + return null + } + } + return getContext('webgl') || getContext('experimental-webgl') +} + namespace Viewer { export function create(canvas: HTMLCanvasElement, container: Element): Viewer { const input = InputObserver.create(canvas) @@ -44,7 +55,10 @@ namespace Viewer { }) - const renderer = Renderer.create(canvas, camera) + const gl = getWebGLContext(canvas) + if (gl === null) throw new Error('Could not create a WebGL rendering context') + + const renderer = Renderer.create(gl, camera) let drawPending = false