Texture based approach WIP

This commit is contained in:
Jamie Wong
2018-01-25 21:15:35 -08:00
parent f103f3ad7a
commit 82ad36f55a
4 changed files with 97 additions and 43 deletions
-26
View File
@@ -176,32 +176,6 @@ export class GLCanvas extends ReloadableComponent<GLCanvasProps, void> {
}
}
function rectangleBatchForFlamechart(canvasContext: CanvasContext, flamechart: Flamechart) {
console.time('rectangle batch generation')
const batch = canvasContext.createRectangleBatch()
const layers = flamechart.getLayers()
for (let i = 0; i < layers.length; i++) {
const layer = layers[i]
for (let flamechartFrame of layer) {
const configSpaceBounds = new Rect(
new Vec2(flamechartFrame.start, i + 1),
new Vec2(flamechartFrame.end - flamechartFrame.start, 1)
)
const color = flamechart.getColorForFrame(flamechartFrame.node.frame)
batch.addRect(configSpaceBounds, color)
}
}
// GPU upload
batch.uploadToGPU()
console.timeEnd('rectangle batch generation')
return batch
}
export class Application extends ReloadableComponent<{}, ApplicationState> {
constructor() {
super()
+12 -2
View File
@@ -1,7 +1,7 @@
import * as regl from 'regl'
import { RectangleBatchRenderer, RectangleBatch, RectangleBatchRendererProps } from './rectangle-batch-renderer';
import { ViewportRectangleRenderer, ViewportRectangleRendererProps } from './overlay-rectangle-renderer';
import { TextureCachedRenderer, TextureRenderer } from './texture-catched-renderer'
import { TextureCachedRenderer, TextureRenderer, TextureRendererProps } from './texture-catched-renderer'
import { Vec2, Rect } from './math';
@@ -12,7 +12,7 @@ interface SetViewportScopeProps {
}
export class CanvasContext {
private gl: regl.Instance
public gl: regl.Instance
private rectangleBatchRenderer: RectangleBatchRenderer
private viewportRectangleRenderer: ViewportRectangleRenderer
private textureRenderer: TextureRenderer
@@ -120,6 +120,12 @@ export class CanvasContext {
this.rectangleBatchRenderer.render(props)
}
drawTexture(props: TextureRendererProps) {
this.gl({})((context: regl.Context) => {
this.textureRenderer.render(context, props)
})
}
createRectangleBatch(): RectangleBatch {
return new RectangleBatch(this.gl)
}
@@ -146,4 +152,8 @@ export class CanvasContext {
)
this.setViewportScope({ physicalBounds }, cb)
}
getMaxTextureSize() {
return this.gl.limits.maxTextureSize
}
}
+52 -2
View File
@@ -1,3 +1,4 @@
import * as regl from 'regl'
import { Flamechart } from './flamechart'
import { RectangleBatch } from './rectangle-batch-renderer'
import { CanvasContext } from './canvas-context';
@@ -129,16 +130,65 @@ class BoundedLayer {
export class FlamechartRenderer {
private layers: BoundedLayer[] = []
private texture: regl.Texture | null = null
constructor(canvasContext: CanvasContext, flamechart: Flamechart) {
for (let i = 0; i < flamechart.getLayers().length; i++) {
constructor(private canvasContext: CanvasContext, flamechart: Flamechart) {
const nLayers = flamechart.getLayers().length
const maxTextureSize = canvasContext.getMaxTextureSize()
if (nLayers > maxTextureSize) {
throw new Error(`This profile has more than ${maxTextureSize} layers!`)
}
this.texture = canvasContext.gl.texture({
width: canvasContext.getMaxTextureSize(),
height: nLayers,
})
const fbo = canvasContext.gl.framebuffer({ color: [this.texture] })
for (let i = 0; i < nLayers; i++) {
this.layers.push(new BoundedLayer(canvasContext, flamechart, i))
}
const configSpaceToNDC = AffineTransform.withScale(new Vec2(1, -1)).times(
AffineTransform.betweenRects(
new Rect(new Vec2(0, 0), new Vec2(flamechart.getTotalWeight(), nLayers)),
new Rect(new Vec2(-1, -1), new Vec2(2, 2))
)
)
canvasContext.gl({
viewport: (context, props) => {
return {
x: 0,
y: 0,
width: canvasContext.getMaxTextureSize(),
height: nLayers
}
},
framebuffer: fbo
})((context: regl.Context) => {
const physicalSize = new Vec2(context.drawingBufferWidth, context.drawingBufferHeight)
for (let layer of this.layers) {
layer.render({ physicalSize, configSpaceToNDC })
}
})
fbo.destroy()
}
render(props: FlamechartRendererProps) {
if (!this.texture) return
this.canvasContext.drawTexture({
texture: this.texture,
ndcRect: new Rect(new Vec2(-1, -1), new Vec2(2, 2)),
uvRect: new Rect(new Vec2(0, 0), new Vec2(1, 1))
})
/*
for (let layer of this.layers) {
layer.render(props)
}
*/
}
}
+33 -13
View File
@@ -1,7 +1,10 @@
import * as regl from 'regl'
import { Vec2, Rect } from './math'
export class TextureRendererProps {
texture: regl.Texture
ndcRect: Rect
uvRect: Rect
}
export class TextureRenderer {
@@ -28,6 +31,11 @@ export class TextureRenderer {
gl_FragColor = texture2D(texture, vUv);
}
`,
depth: {
enable: false
},
attributes: {
// Cover full canvas with a rectangle
// with 2 triangles using a triangle
@@ -37,18 +45,26 @@ export class TextureRenderer {
// | /|
// |/ |
// 2 +--+ 3
position: [
[-1, 1],
[1, 1],
[-1, -1],
[1, -1]
],
uv: [
[0, 1],
[1, 1],
[0, 0],
[1, 0]
]
position: (context, props) => {
const rect = props.ndcRect
return [
rect.topLeft().flatten(),
rect.topRight().flatten(),
rect.bottomLeft().flatten(),
rect.bottomRight().flatten()
]
},
uv: (context, props) => {
const rect = props.uvRect
return [
rect.topLeft().flatten(),
rect.topRight().flatten(),
rect.bottomLeft().flatten(),
rect.bottomRight().flatten()
]
}
},
uniforms: {
@@ -132,7 +148,11 @@ export class TextureCachedRenderer<T> {
}
// Render from texture
this.textureRenderer.render(context, {texture: this.texture})
this.textureRenderer.render(context, {
texture: this.texture,
ndcRect: new Rect(new Vec2(-1, -1), new Vec2(2, 2)),
uvRect: new Rect(new Vec2(0, 0), new Vec2(1, 1))
})
this.lastRenderProps = props
this.dirty = false
}