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

allow canvas3d creation from gl and input

parent b8ddccfe
No related branches found
No related tags found
No related merge requests found
...@@ -14,7 +14,7 @@ import { GraphicsRenderObject } from 'mol-gl/render-object' ...@@ -14,7 +14,7 @@ import { GraphicsRenderObject } from 'mol-gl/render-object'
import { TrackballControls, TrackballControlsParams } from './controls/trackball' import { TrackballControls, TrackballControlsParams } from './controls/trackball'
import { Viewport } from './camera/util' import { Viewport } from './camera/util'
import { createContext, getGLContext, WebGLContext } from 'mol-gl/webgl/context'; import { createContext, WebGLContext, getGLContext } from 'mol-gl/webgl/context';
import { Representation } from 'mol-repr/representation'; import { Representation } from 'mol-repr/representation';
import { createRenderTarget } from 'mol-gl/webgl/render-target'; import { createRenderTarget } from 'mol-gl/webgl/render-target';
import Scene from 'mol-gl/scene'; import Scene from 'mol-gl/scene';
...@@ -32,6 +32,7 @@ import { createTexture } from 'mol-gl/webgl/texture'; ...@@ -32,6 +32,7 @@ import { createTexture } from 'mol-gl/webgl/texture';
import { ValueCell } from 'mol-util'; import { ValueCell } from 'mol-util';
import { getPostprocessingRenderable, PostprocessingParams, setPostprocessingProps } from './helper/postprocessing'; import { getPostprocessingRenderable, PostprocessingParams, setPostprocessingProps } from './helper/postprocessing';
import { JitterVectors, getComposeRenderable } from './helper/multi-sample'; import { JitterVectors, getComposeRenderable } from './helper/multi-sample';
import { GLRenderingContext } from 'mol-gl/webgl/compat';
export const Canvas3DParams = { export const Canvas3DParams = {
// TODO: FPS cap? // TODO: FPS cap?
...@@ -92,7 +93,19 @@ namespace Canvas3D { ...@@ -92,7 +93,19 @@ namespace Canvas3D {
export interface HighlightEvent { current: Representation.Loci, prev: Representation.Loci, modifiers?: ModifiersKeys } export interface HighlightEvent { current: Representation.Loci, prev: Representation.Loci, modifiers?: ModifiersKeys }
export interface ClickEvent { current: Representation.Loci, buttons: ButtonsType, modifiers: ModifiersKeys } export interface ClickEvent { current: Representation.Loci, buttons: ButtonsType, modifiers: ModifiersKeys }
export function create(canvas: HTMLCanvasElement, props: Partial<Canvas3DProps> = {}): Canvas3D { export function fromCanvas(canvas: HTMLCanvasElement, props: Partial<Canvas3DProps> = {}) {
const gl = getGLContext(canvas, {
alpha: false,
antialias: true,
depth: true,
preserveDrawingBuffer: true
})
if (gl === null) throw new Error('Could not create a WebGL rendering context')
const input = InputObserver.create(canvas)
return Canvas3D.create(gl, input)
}
export function create(gl: GLRenderingContext, input: InputObserver, props: Partial<Canvas3DProps> = {}): Canvas3D {
const p = { ...PD.getDefaultValues(Canvas3DParams), ...props } const p = { ...PD.getDefaultValues(Canvas3DParams), ...props }
const reprRenderObjects = new Map<Representation.Any, Set<GraphicsRenderObject>>() const reprRenderObjects = new Map<Representation.Any, Set<GraphicsRenderObject>>()
...@@ -101,7 +114,6 @@ namespace Canvas3D { ...@@ -101,7 +114,6 @@ namespace Canvas3D {
const startTime = now() const startTime = now()
const didDraw = new BehaviorSubject<now.Timestamp>(0 as now.Timestamp) const didDraw = new BehaviorSubject<now.Timestamp>(0 as now.Timestamp)
const input = InputObserver.create(canvas)
const camera = new Camera({ const camera = new Camera({
near: 0.1, near: 0.1,
...@@ -110,38 +122,32 @@ namespace Canvas3D { ...@@ -110,38 +122,32 @@ namespace Canvas3D {
mode: p.cameraMode mode: p.cameraMode
}) })
const _gl = getGLContext(canvas, { const webgl = createContext(gl)
alpha: false, const { state } = webgl
antialias: true,
depth: true, let width = gl.drawingBufferWidth
preserveDrawingBuffer: true let height = gl.drawingBufferHeight
})
if (_gl === null) {
throw new Error('Could not create a WebGL rendering context')
}
const webgl = createContext(_gl)
const { state, gl } = webgl
const scene = Scene.create(webgl) const scene = Scene.create(webgl)
const controls = TrackballControls.create(input, camera, p.trackball) const controls = TrackballControls.create(input, camera, p.trackball)
const renderer = Renderer.create(webgl, camera, p.renderer) const renderer = Renderer.create(webgl, camera, p.renderer)
const drawTarget = createRenderTarget(webgl, canvas.width, canvas.height) const drawTarget = createRenderTarget(webgl, width, height)
const depthTexture = createTexture(webgl, 'image-depth', 'depth', 'ushort', 'nearest') const depthTexture = createTexture(webgl, 'image-depth', 'depth', 'ushort', 'nearest')
depthTexture.define(canvas.width, canvas.height) depthTexture.define(width, height)
depthTexture.attachFramebuffer(drawTarget.framebuffer, 'depth') depthTexture.attachFramebuffer(drawTarget.framebuffer, 'depth')
const postprocessingTarget = createRenderTarget(webgl, canvas.width, canvas.height) const postprocessingTarget = createRenderTarget(webgl, width, height)
const postprocessing = getPostprocessingRenderable(webgl, drawTarget.texture, depthTexture, p.postprocessing) const postprocessing = getPostprocessingRenderable(webgl, drawTarget.texture, depthTexture, p.postprocessing)
const composeTarget = createRenderTarget(webgl, canvas.width, canvas.height) const composeTarget = createRenderTarget(webgl, width, height)
const holdTarget = createRenderTarget(webgl, canvas.width, canvas.height) const holdTarget = createRenderTarget(webgl, width, height)
const compose = getComposeRenderable(webgl, drawTarget.texture) const compose = getComposeRenderable(webgl, drawTarget.texture)
const pickBaseScale = 0.25 const pickBaseScale = 0.5
let pickScale = pickBaseScale / webgl.pixelRatio let pickScale = pickBaseScale / webgl.pixelRatio
let pickWidth = Math.round(canvas.width * pickScale) let pickWidth = Math.round(width * pickScale)
let pickHeight = Math.round(canvas.height * pickScale) let pickHeight = Math.round(height * pickScale)
const objectPickTarget = createRenderTarget(webgl, pickWidth, pickHeight) const objectPickTarget = createRenderTarget(webgl, pickWidth, pickHeight)
const instancePickTarget = createRenderTarget(webgl, pickWidth, pickHeight) const instancePickTarget = createRenderTarget(webgl, pickWidth, pickHeight)
const groupPickTarget = createRenderTarget(webgl, pickWidth, pickHeight) const groupPickTarget = createRenderTarget(webgl, pickWidth, pickHeight)
...@@ -220,7 +226,7 @@ namespace Canvas3D { ...@@ -220,7 +226,7 @@ namespace Canvas3D {
} }
function renderDraw() { function renderDraw() {
renderer.setViewport(0, 0, canvas.width, canvas.height) renderer.setViewport(0, 0, width, height)
renderer.render(scene, 'draw') renderer.render(scene, 'draw')
if (debugHelper.isEnabled) { if (debugHelper.isEnabled) {
debugHelper.syncVisibility() debugHelper.syncVisibility()
...@@ -229,7 +235,7 @@ namespace Canvas3D { ...@@ -229,7 +235,7 @@ namespace Canvas3D {
} }
function renderPostprocessing() { function renderPostprocessing() {
gl.viewport(0, 0, canvas.width, canvas.height) gl.viewport(0, 0, width, height)
state.disable(gl.SCISSOR_TEST) state.disable(gl.SCISSOR_TEST)
state.disable(gl.BLEND) state.disable(gl.BLEND)
state.disable(gl.DEPTH_TEST) state.disable(gl.DEPTH_TEST)
...@@ -318,7 +324,7 @@ namespace Canvas3D { ...@@ -318,7 +324,7 @@ namespace Canvas3D {
ValueCell.update(compose.values.tColor, composeTarget.texture) ValueCell.update(compose.values.tColor, composeTarget.texture)
compose.update() compose.update()
webgl.unbindFramebuffer() webgl.unbindFramebuffer()
gl.viewport(0, 0, canvas.width, canvas.height) gl.viewport(0, 0, width, height)
state.disable(gl.BLEND) state.disable(gl.BLEND)
compose.render() compose.render()
} }
...@@ -327,7 +333,7 @@ namespace Canvas3D { ...@@ -327,7 +333,7 @@ namespace Canvas3D {
ValueCell.update(compose.values.tColor, holdTarget.texture) ValueCell.update(compose.values.tColor, holdTarget.texture)
compose.update() compose.update()
webgl.unbindFramebuffer() webgl.unbindFramebuffer()
gl.viewport(0, 0, canvas.width, canvas.height) gl.viewport(0, 0, width, height)
if (accumulationWeight === 0) state.disable(gl.BLEND) if (accumulationWeight === 0) state.disable(gl.BLEND)
else state.enable(gl.BLEND) else state.enable(gl.BLEND)
compose.render() compose.render()
...@@ -379,7 +385,7 @@ namespace Canvas3D { ...@@ -379,7 +385,7 @@ namespace Canvas3D {
// compose rendered scene with compose target // compose rendered scene with compose target
composeTarget.bind() composeTarget.bind()
gl.viewport(0, 0, canvas.width, canvas.height) gl.viewport(0, 0, width, height)
state.enable(gl.BLEND) state.enable(gl.BLEND)
state.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD) state.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD)
state.blendFuncSeparate(gl.ONE, gl.ONE, gl.ONE, gl.ONE) state.blendFuncSeparate(gl.ONE, gl.ONE, gl.ONE, gl.ONE)
...@@ -398,7 +404,7 @@ namespace Canvas3D { ...@@ -398,7 +404,7 @@ namespace Canvas3D {
compose.update() compose.update()
webgl.unbindFramebuffer() webgl.unbindFramebuffer()
gl.viewport(0, 0, canvas.width, canvas.height) gl.viewport(0, 0, width, height)
state.disable(gl.BLEND) state.disable(gl.BLEND)
compose.render() compose.render()
...@@ -441,7 +447,7 @@ namespace Canvas3D { ...@@ -441,7 +447,7 @@ namespace Canvas3D {
renderer.render(scene, 'pickGroup'); renderer.render(scene, 'pickGroup');
break; break;
case 'draw': case 'draw':
renderer.setViewport(0, 0, canvas.width, canvas.height); renderer.setViewport(0, 0, width, height);
if (multiSample) { if (multiSample) {
if (p.multiSample === 'temporal') { if (p.multiSample === 'temporal') {
renderTemporalMultiSample(postprocessingEnabled) renderTemporalMultiSample(postprocessingEnabled)
...@@ -508,7 +514,7 @@ namespace Canvas3D { ...@@ -508,7 +514,7 @@ namespace Canvas3D {
x *= webgl.pixelRatio x *= webgl.pixelRatio
y *= webgl.pixelRatio y *= webgl.pixelRatio
y = canvas.height - y // flip y y = height - y // flip y
const xp = Math.round(x * pickScale) const xp = Math.round(x * pickScale)
const yp = Math.round(y * pickScale) const yp = Math.round(y * pickScale)
...@@ -681,21 +687,24 @@ namespace Canvas3D { ...@@ -681,21 +687,24 @@ namespace Canvas3D {
} }
function handleResize() { function handleResize() {
renderer.setViewport(0, 0, canvas.width, canvas.height) width = gl.drawingBufferWidth
Viewport.set(camera.viewport, 0, 0, canvas.width, canvas.height) height = gl.drawingBufferHeight
Viewport.set(controls.viewport, 0, 0, canvas.width, canvas.height)
renderer.setViewport(0, 0, width, height)
drawTarget.setSize(canvas.width, canvas.height) Viewport.set(camera.viewport, 0, 0, width, height)
postprocessingTarget.setSize(canvas.width, canvas.height) Viewport.set(controls.viewport, 0, 0, width, height)
composeTarget.setSize(canvas.width, canvas.height)
holdTarget.setSize(canvas.width, canvas.height) drawTarget.setSize(width, height)
depthTexture.define(canvas.width, canvas.height) postprocessingTarget.setSize(width, height)
ValueCell.update(postprocessing.values.uTexSize, Vec2.set(postprocessing.values.uTexSize.ref.value, canvas.width, canvas.height)) composeTarget.setSize(width, height)
ValueCell.update(compose.values.uTexSize, Vec2.set(compose.values.uTexSize.ref.value, canvas.width, canvas.height)) holdTarget.setSize(width, height)
depthTexture.define(width, height)
ValueCell.update(postprocessing.values.uTexSize, Vec2.set(postprocessing.values.uTexSize.ref.value, width, height))
ValueCell.update(compose.values.uTexSize, Vec2.set(compose.values.uTexSize.ref.value, width, height))
pickScale = pickBaseScale / webgl.pixelRatio pickScale = pickBaseScale / webgl.pixelRatio
pickWidth = Math.round(canvas.width * pickScale) pickWidth = Math.round(width * pickScale)
pickHeight = Math.round(canvas.height * pickScale) pickHeight = Math.round(height * pickScale)
objectPickTarget.setSize(pickWidth, pickHeight) objectPickTarget.setSize(pickWidth, pickHeight)
instancePickTarget.setSize(pickWidth, pickHeight) instancePickTarget.setSize(pickWidth, pickHeight)
groupPickTarget.setSize(pickWidth, pickHeight) groupPickTarget.setSize(pickWidth, pickHeight)
......
...@@ -113,7 +113,7 @@ export class PluginContext { ...@@ -113,7 +113,7 @@ export class PluginContext {
try { try {
this.layout.setRoot(container); this.layout.setRoot(container);
if (this.spec.layout && this.spec.layout.initial) this.layout.setProps(this.spec.layout.initial); if (this.spec.layout && this.spec.layout.initial) this.layout.setProps(this.spec.layout.initial);
(this.canvas3d as Canvas3D) = Canvas3D.create(canvas); (this.canvas3d as Canvas3D) = Canvas3D.fromCanvas(canvas);
const renderer = this.canvas3d.props.renderer; const renderer = this.canvas3d.props.renderer;
PluginCommands.Canvas3D.SetSettings.dispatch(this, { settings: { renderer: { ...renderer, backgroundColor: Color(0xFCFBF9) } } }); PluginCommands.Canvas3D.SetSettings.dispatch(this, { settings: { renderer: { ...renderer, backgroundColor: Color(0xFCFBF9) } } });
this.canvas3d.animate(); this.canvas3d.animate();
......
...@@ -32,7 +32,7 @@ canvas.style.width = '100%' ...@@ -32,7 +32,7 @@ canvas.style.width = '100%'
canvas.style.height = '100%' canvas.style.height = '100%'
parent.appendChild(canvas) parent.appendChild(canvas)
const canvas3d = Canvas3D.create(canvas, { const canvas3d = Canvas3D.fromCanvas(canvas, {
renderer: { ...PD.getDefaultValues(RendererParams), backgroundColor: ColorNames.white }, renderer: { ...PD.getDefaultValues(RendererParams), backgroundColor: ColorNames.white },
cameraMode: 'orthographic' cameraMode: 'orthographic'
}) })
......
...@@ -28,7 +28,7 @@ canvas.style.width = '100%' ...@@ -28,7 +28,7 @@ canvas.style.width = '100%'
canvas.style.height = '100%' canvas.style.height = '100%'
parent.appendChild(canvas) parent.appendChild(canvas)
const canvas3d = Canvas3D.create(canvas) const canvas3d = Canvas3D.fromCanvas(canvas)
canvas3d.animate() canvas3d.animate()
......
...@@ -23,7 +23,7 @@ canvas.style.width = '100%' ...@@ -23,7 +23,7 @@ canvas.style.width = '100%'
canvas.style.height = '100%' canvas.style.height = '100%'
parent.appendChild(canvas) parent.appendChild(canvas)
const canvas3d = Canvas3D.create(canvas) const canvas3d = Canvas3D.fromCanvas(canvas)
canvas3d.animate() canvas3d.animate()
function linesRepr() { function linesRepr() {
......
...@@ -24,7 +24,7 @@ canvas.style.width = '100%' ...@@ -24,7 +24,7 @@ canvas.style.width = '100%'
canvas.style.height = '100%' canvas.style.height = '100%'
parent.appendChild(canvas) parent.appendChild(canvas)
const canvas3d = Canvas3D.create(canvas) const canvas3d = Canvas3D.fromCanvas(canvas)
canvas3d.animate() canvas3d.animate()
function meshRepr() { function meshRepr() {
......
...@@ -38,7 +38,7 @@ info.style.color = 'white' ...@@ -38,7 +38,7 @@ info.style.color = 'white'
parent.appendChild(info) parent.appendChild(info)
let prevReprLoci = Representation.Loci.Empty let prevReprLoci = Representation.Loci.Empty
const canvas3d = Canvas3D.create(canvas) const canvas3d = Canvas3D.fromCanvas(canvas)
canvas3d.animate() canvas3d.animate()
canvas3d.input.move.subscribe(({x, y}) => { canvas3d.input.move.subscribe(({x, y}) => {
const pickingId = canvas3d.identify(x, y) const pickingId = canvas3d.identify(x, y)
......
...@@ -21,7 +21,7 @@ canvas.style.width = '100%' ...@@ -21,7 +21,7 @@ canvas.style.width = '100%'
canvas.style.height = '100%' canvas.style.height = '100%'
parent.appendChild(canvas) parent.appendChild(canvas)
const canvas3d = Canvas3D.create(canvas) const canvas3d = Canvas3D.fromCanvas(canvas)
canvas3d.animate() canvas3d.animate()
function spheresRepr() { function spheresRepr() {
......
...@@ -26,7 +26,7 @@ canvas.style.width = '100%' ...@@ -26,7 +26,7 @@ canvas.style.width = '100%'
canvas.style.height = '100%' canvas.style.height = '100%'
parent.appendChild(canvas) parent.appendChild(canvas)
const canvas3d = Canvas3D.create(canvas) const canvas3d = Canvas3D.fromCanvas(canvas)
canvas3d.animate() canvas3d.animate()
......
...@@ -24,7 +24,7 @@ canvas.style.width = '100%' ...@@ -24,7 +24,7 @@ canvas.style.width = '100%'
canvas.style.height = '100%' canvas.style.height = '100%'
parent.appendChild(canvas) parent.appendChild(canvas)
const canvas3d = Canvas3D.create(canvas) const canvas3d = Canvas3D.fromCanvas(canvas)
canvas3d.animate() canvas3d.animate()
function textRepr() { function textRepr() {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment