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

wip, gl

parent 2f8bdd6f
Branches
Tags
No related merge requests found
Showing
with 312 additions and 245 deletions
...@@ -47,13 +47,16 @@ export default class State { ...@@ -47,13 +47,16 @@ export default class State {
const structures = await getStructuresFromPdbId(pdbId) const structures = await getStructuresFromPdbId(pdbId)
const struct = await Run(Symmetry.buildAssembly(structures[0], '1')) const struct = await Run(Symmetry.buildAssembly(structures[0], '1'))
// const structPointRepr = StructureRepresentation(Point) const structPointRepr = StructureRepresentation(Point)
// await Run(structPointRepr.create(struct)) await Run(structPointRepr.create(struct))
// structPointRepr.renderObjects.forEach(viewer.add) structPointRepr.renderObjects.forEach(viewer.add)
const structSpacefillRepr = StructureRepresentation(Spacefill) // const structSpacefillRepr = StructureRepresentation(Spacefill)
await Run(structSpacefillRepr.create(struct, { detail: 0 })) // await Run(structSpacefillRepr.create(struct, { detail: 0 }))
structSpacefillRepr.renderObjects.forEach(viewer.add) // structSpacefillRepr.renderObjects.forEach(viewer.add)
viewer.requestDraw()
console.log(viewer.stats)
this.loading.next(false) this.loading.next(false)
} }
......
...@@ -5,31 +5,10 @@ ...@@ -5,31 +5,10 @@
*/ */
import { ValueCell } from 'mol-util'; import { ValueCell } from 'mol-util';
import { ColorTexture, createColorTexture } from 'mol-gl/renderable/util';
import Color from './color'; import Color from './color';
import { Mesh } from '../shape/mesh'; import { Mesh } from '../shape/mesh';
function calculateTextureInfo (n: number, itemSize: number) {
const sqN = Math.sqrt(n * itemSize)
let width = Math.ceil(sqN)
width = width + (itemSize - (width % itemSize)) % itemSize
const height = width > 0 ? Math.ceil(n * itemSize / width) : 0
return { width, height, length: width * height * itemSize }
}
interface ColorTexture extends Uint8Array {
width: number,
height: number
}
function createColorTexture (n: number): ColorTexture {
const colorTexInfo = calculateTextureInfo(n, 3)
const colorTexture = new Uint8Array(colorTexInfo.length)
return Object.assign(colorTexture, {
width: colorTexInfo.width,
height: colorTexInfo.height
})
}
export type UniformColor = { type: 'uniform', value: number[] } export type UniformColor = { type: 'uniform', value: number[] }
export type AttributeColor = { type: 'attribute', value: ValueCell<Float32Array> } export type AttributeColor = { type: 'attribute', value: ValueCell<Float32Array> }
export type InstanceColor = { type: 'instance', value: ValueCell<ColorTexture> } export type InstanceColor = { type: 'instance', value: ValueCell<ColorTexture> }
......
...@@ -28,9 +28,10 @@ export namespace ColorScale { ...@@ -28,9 +28,10 @@ export namespace ColorScale {
const { domain, reverse, colors } = { ...DefaultColorScale, ...props } const { domain, reverse, colors } = { ...DefaultColorScale, ...props }
const [ min, max ] = reverse ? domain.slice().reverse() : domain const [ min, max ] = reverse ? domain.slice().reverse() : domain
const count1 = colors.length - 1 const count1 = colors.length - 1
const diff = (max - min) || 1
function color(value: number) { function color(value: number) {
const t = ((value - min) / (max - min)) * count1 const t = ((value - min) / diff) * count1
const tf = Math.floor(t) const tf = Math.floor(t)
const c1 = colors[tf] const c1 = colors[tf]
const c2 = colors[Math.ceil(t)] const c2 = colors[Math.ceil(t)]
......
...@@ -6,8 +6,7 @@ ...@@ -6,8 +6,7 @@
import { ValueCell } from 'mol-util/value-cell' import { ValueCell } from 'mol-util/value-cell'
import { createRenderObject, RenderObject } from 'mol-gl/scene' import { createPointRenderObject, RenderObject } from 'mol-gl/scene'
import { createColorTexture } from 'mol-gl/util';
import { Mat4 } from 'mol-math/linear-algebra' import { Mat4 } from 'mol-math/linear-algebra'
import { OrderedSet } from 'mol-data/int' import { OrderedSet } from 'mol-data/int'
import { ChunkedArray } from 'mol-data/util'; import { ChunkedArray } from 'mol-data/util';
...@@ -15,6 +14,9 @@ import { Unit, ElementGroup } from 'mol-model/structure'; ...@@ -15,6 +14,9 @@ import { Unit, ElementGroup } from 'mol-model/structure';
import { RepresentationProps, UnitsRepresentation } from './index'; import { RepresentationProps, UnitsRepresentation } from './index';
import { Task } from 'mol-task' import { Task } from 'mol-task'
import { VdwRadius } from 'mol-model/structure/model/properties/atomic'; import { VdwRadius } from 'mol-model/structure/model/properties/atomic';
import { createUniformColor, createInstanceColor } from '../../color/data';
import { fillSerial } from 'mol-gl/renderable/util';
import { ColorScale } from '../../color/scale';
export const DefaultPointProps = { export const DefaultPointProps = {
...@@ -39,29 +41,37 @@ export default function Point(): UnitsRepresentation<PointProps> { ...@@ -39,29 +41,37 @@ export default function Point(): UnitsRepresentation<PointProps> {
ChunkedArray.add3(vertices, x[e], y[e], z[e]) ChunkedArray.add3(vertices, x[e], y[e], z[e])
ChunkedArray.add(sizes, VdwRadius(type_symbol.value(e))) ChunkedArray.add(sizes, VdwRadius(type_symbol.value(e)))
if (i % 10 === 0 && ctx.shouldUpdate) { if (i % 10000 === 0 && ctx.shouldUpdate) {
await ctx.update({ message: 'Point', current: i, max: elementCount }); await ctx.update({ message: 'Point', current: i, max: elementCount });
} }
} }
const unitsCount = units.length const unitCount = units.length
const transformArray = new Float32Array(unitsCount * 16) const transformArray = new Float32Array(unitCount * 16)
for (let i = 0; i < unitsCount; i++) { for (let i = 0; i < unitCount; i++) {
Mat4.toArray(units[i].operator.matrix, transformArray, i * 16) Mat4.toArray(units[i].operator.matrix, transformArray, i * 16)
} }
const color = ValueCell.create(createColorTexture(unitsCount)) // const color = createUniformColor({ value: 0xFF4411 })
color.ref.value.set([ 0, 0, 255 ]) const scale = ColorScale.create({ domain: [ 0, unitCount - 1 ] })
const color = createInstanceColor({
colorFn: scale.color,
unitCount
})
const points = createPointRenderObject({
objectId: 0,
const points = createRenderObject('point', {
position: ValueCell.create(ChunkedArray.compact(vertices, true) as Float32Array), position: ValueCell.create(ChunkedArray.compact(vertices, true) as Float32Array),
id: ValueCell.create(fillSerial(new Float32Array(unitCount))),
size: ValueCell.create(ChunkedArray.compact(sizes, true) as Float32Array), size: ValueCell.create(ChunkedArray.compact(sizes, true) as Float32Array),
color, color,
transform: ValueCell.create(transformArray), transform: ValueCell.create(transformArray),
instanceCount: unitsCount, instanceCount: unitCount,
elementCount,
positionCount: vertices.elementCount positionCount: vertices.elementCount
}, {}) })
renderObjects.push(points) renderObjects.push(points)
}), }),
update: (props: RepresentationProps) => false update: (props: RepresentationProps) => false
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
import { ValueCell } from 'mol-util/value-cell' import { ValueCell } from 'mol-util/value-cell'
import { createRenderObject, RenderObject } from 'mol-gl/scene' import { RenderObject, createMeshRenderObject } from 'mol-gl/scene'
// import { createColorTexture } from 'mol-gl/util'; // import { createColorTexture } from 'mol-gl/util';
import { Vec3, Mat4 } from 'mol-math/linear-algebra' import { Vec3, Mat4 } from 'mol-math/linear-algebra'
import { OrderedSet } from 'mol-data/int' import { OrderedSet } from 'mol-data/int'
...@@ -53,7 +53,7 @@ export default function Spacefill(): UnitsRepresentation<SpacefillProps> { ...@@ -53,7 +53,7 @@ export default function Spacefill(): UnitsRepresentation<SpacefillProps> {
detail detail
}) })
if (i % 10 === 0 && ctx.shouldUpdate) { if (i % 10000 === 0 && ctx.shouldUpdate) {
await ctx.update({ message: 'Spacefill', current: i, max: elementCount }); await ctx.update({ message: 'Spacefill', current: i, max: elementCount });
} }
} }
...@@ -70,35 +70,31 @@ export default function Spacefill(): UnitsRepresentation<SpacefillProps> { ...@@ -70,35 +70,31 @@ export default function Spacefill(): UnitsRepresentation<SpacefillProps> {
// console.log({ unitCount, elementCount }) // console.log({ unitCount, elementCount })
let colorType = 'element-instance' // const color = createUniformColor({ value: 0xFF4411 })
let color: ColorData
// const color = elementSymbolColorData({ units, elementGroup, mesh })
if (colorType === 'uniform') {
color = createUniformColor({ value: 0xFF4411 }) const scale = ColorScale.create({ domain: [ 0, unitCount - 1 ] })
} else if (colorType === 'attribute') { const color = createInstanceColor({
color = elementSymbolColorData({ units, elementGroup, mesh }) colorFn: scale.color,
} else if (colorType === 'instance') { unitCount
const scale = ColorScale.create({ domain: [ 0, unitCount - 1 ] }) })
color = createInstanceColor({
colorFn: scale.color, // const scale = ColorScale.create({ domain: [ 0, unitCount * elementCount - 1 ] })
unitCount // const color = createElementInstanceColor({
}) // colorFn: (unitIdx, elementIdx) => scale.color(unitIdx * elementCount + elementIdx),
} else if (colorType === 'element-instance') { // unitCount,
const scale = ColorScale.create({ domain: [ 0, unitCount * elementCount - 1 ] }) // offsetCount: mesh.offsetCount,
color = createElementInstanceColor({ // offsets: mesh.offsetBuffer as any
colorFn: (unitIdx, elementIdx) => scale.color(unitIdx * elementCount + elementIdx), // })
unitCount,
offsetCount: mesh.offsetCount, const spheres = createMeshRenderObject({
offsets: mesh.offsetBuffer as any objectId: 0,
})
}
console.log(color!)
const spheres = createRenderObject('mesh', {
position: mesh.vertexBuffer, position: mesh.vertexBuffer,
normal: mesh.normalBuffer, normal: mesh.normalBuffer as ValueCell<Float32Array>,
color: color!, color: color as ColorData,
id: mesh.idBuffer, id: mesh.idBuffer as ValueCell<Float32Array>,
transform: ValueCell.create(transformArray), transform: ValueCell.create(transformArray),
index: mesh.indexBuffer, index: mesh.indexBuffer,
...@@ -106,7 +102,7 @@ export default function Spacefill(): UnitsRepresentation<SpacefillProps> { ...@@ -106,7 +102,7 @@ export default function Spacefill(): UnitsRepresentation<SpacefillProps> {
indexCount: mesh.triangleCount, indexCount: mesh.triangleCount,
elementCount: mesh.offsetCount - 1, elementCount: mesh.offsetCount - 1,
positionCount: mesh.vertexCount positionCount: mesh.vertexCount
}, {}) })
renderObjects.push(spheres) renderObjects.push(spheres)
}), }),
update: (props: RepresentationProps) => false update: (props: RepresentationProps) => false
......
...@@ -16,6 +16,7 @@ export type AttributesBuffers<T extends AttributesData> = { [K in keyof T]: REGL ...@@ -16,6 +16,7 @@ export type AttributesBuffers<T extends AttributesData> = { [K in keyof T]: REGL
export interface Renderable { export interface Renderable {
draw(): void draw(): void
dispose(): void
stats: REGL.CommandStats stats: REGL.CommandStats
name: string name: string
// isPicking: () => boolean // isPicking: () => boolean
......
...@@ -9,33 +9,20 @@ import { ValueCell } from 'mol-util/value-cell' ...@@ -9,33 +9,20 @@ import { ValueCell } from 'mol-util/value-cell'
import { ColorData } from 'mol-geo/color'; import { ColorData } from 'mol-geo/color';
import { Renderable } from '../renderable' import { Renderable } from '../renderable'
import { getBuffers, createTransformAttributes, fillSerial, createColorUniforms } from './util' import { createBaseDefines, createBaseUniforms, createBaseAttributes, destroyAttributes, destroyUniforms } from './util'
import Attribute from '../attribute'; import { MeshShaders, addDefines } from '../shaders'
import { MeshShaders, addDefines, ShaderDefines } from '../shaders'
type Mesh = 'mesh' type Mesh = 'mesh'
type Uniforms = { [k: string]: REGL.Uniform | REGL.Texture }
function getColorDefines(color: ColorData) {
const defines: ShaderDefines = {}
switch (color.type) {
case 'uniform': defines.UNIFORM_COLOR = ''; break;
case 'attribute': defines.ATTRIBUTE_COLOR = ''; break;
case 'element': defines.ELEMENT_COLOR = ''; break;
case 'instance': defines.INSTANCE_COLOR = ''; break;
case 'element-instance': defines.ELEMENT_INSTANCE_COLOR = ''; break;
}
return defines
}
namespace Mesh { namespace Mesh {
export type Data = { export type Data = {
objectId: number
position: ValueCell<Float32Array> position: ValueCell<Float32Array>
normal: ValueCell<Float32Array> normal?: ValueCell<Float32Array>
id: ValueCell<Float32Array> id: ValueCell<Float32Array>
readonly color: ColorData color: ColorData
transform: ValueCell<Float32Array> transform: ValueCell<Float32Array>
index: ValueCell<Uint32Array> index: ValueCell<Uint32Array>
...@@ -45,42 +32,23 @@ namespace Mesh { ...@@ -45,42 +32,23 @@ namespace Mesh {
positionCount: number positionCount: number
} }
export function create(regl: REGL.Regl, data: Data, _uniforms: Uniforms): Renderable { export function create(regl: REGL.Regl, props: Data): Renderable {
const defines = getColorDefines(data.color) const defines = createBaseDefines(regl, props)
const instanceId = ValueCell.create(fillSerial(new Float32Array(data.instanceCount))) const uniforms = createBaseUniforms(regl, props)
const uniforms = { const attributes = createBaseAttributes(regl, props)
objectId: _uniforms.objectId || 0, const elements = regl.elements({
instanceCount: data.instanceCount, data: props.index.ref.value,
elementCount: data.elementCount, primitive: 'triangles',
..._uniforms type: 'uint32',
} count: props.indexCount * 3
if (data.color.type === 'instance' || data.color.type === 'element' || data.color.type === 'element-instance') {
Object.assign(uniforms, createColorUniforms(regl, data.color.value))
} else if (data.color.type === 'uniform') {
Object.assign(uniforms, { color: data.color.value })
}
const attributes = getBuffers({
instanceId: Attribute.create(regl, instanceId, data.instanceCount, { size: 1, divisor: 1 }),
position: Attribute.create(regl, data.position, data.positionCount, { size: 3 }),
normal: Attribute.create(regl, data.normal, data.positionCount, { size: 3 }),
elementId: Attribute.create(regl, data.id, data.positionCount, { size: 1 }),
...createTransformAttributes(regl, data.transform, data.instanceCount)
}) })
if (data.color.type === 'attribute') {
attributes.color = Attribute.create(regl, data.color.value, data.positionCount, { size: 3 }).buffer
}
const command = regl({ const command = regl({
...addDefines(defines, MeshShaders), ...addDefines(defines, MeshShaders),
uniforms, uniforms,
attributes, attributes,
elements: regl.elements({ elements,
data: data.index.ref.value, instances: props.instanceCount,
primitive: 'triangles',
type: 'uint32',
count: data.indexCount * 3
}),
instances: data.instanceCount,
}) })
return { return {
draw: () => { draw: () => {
...@@ -89,7 +57,12 @@ namespace Mesh { ...@@ -89,7 +57,12 @@ namespace Mesh {
get stats() { get stats() {
return command.stats return command.stats
}, },
name: 'mesh' name: 'mesh',
dispose: () => {
destroyAttributes(attributes)
destroyUniforms(uniforms)
elements.destroy()
}
} }
} }
} }
......
...@@ -8,37 +8,39 @@ import REGL = require('regl'); ...@@ -8,37 +8,39 @@ import REGL = require('regl');
import { ValueCell } from 'mol-util/value-cell' import { ValueCell } from 'mol-util/value-cell'
import { Renderable } from '../renderable' import { Renderable } from '../renderable'
import { getBuffers, createTransformAttributes, fillSerial } from './util' import { createBaseDefines, createBaseUniforms, createBaseAttributes, destroyUniforms, destroyAttributes } from './util'
import Attribute from '../attribute'; import { PointShaders, addDefines } from '../shaders'
import { PointShaders } from '../shaders' import { ColorData } from 'mol-geo/color';
type Point = 'point' type Point = 'point'
namespace Point { namespace Point {
export type Data = { export type Data = {
objectId: number
position: ValueCell<Float32Array> position: ValueCell<Float32Array>
size?: ValueCell<Float32Array> size?: ValueCell<Float32Array>
id: ValueCell<Float32Array>
color: ColorData
transform: ValueCell<Float32Array> transform: ValueCell<Float32Array>
instanceCount: number instanceCount: number
elementCount: number
positionCount: number positionCount: number
} }
export function create(regl: REGL.Regl, data: Data): Renderable { export function create(regl: REGL.Regl, props: Data): Renderable {
const instanceId = ValueCell.create(fillSerial(new Float32Array(data.instanceCount))) const defines = createBaseDefines(regl, props)
const attributes = getBuffers({ const uniforms = createBaseUniforms(regl, props)
instanceId: Attribute.create(regl, instanceId, data.instanceCount, { size: 1, divisor: 1 }), const attributes = createBaseAttributes(regl, props)
position: Attribute.create(regl, data.position, data.positionCount, { size: 3 }),
...createTransformAttributes(regl, data.transform, data.positionCount)
})
if (data.size) {
attributes.size = Attribute.create(regl, data.size, data.positionCount, { size: 1 }).buffer
}
const command = regl({ const command = regl({
...PointShaders, ...addDefines(defines, PointShaders),
uniforms,
attributes, attributes,
count: data.positionCount, count: props.positionCount,
instances: data.instanceCount, instances: props.instanceCount,
primitive: 'points' primitive: 'points'
}) })
return { return {
...@@ -46,50 +48,13 @@ namespace Point { ...@@ -46,50 +48,13 @@ namespace Point {
get stats() { get stats() {
return command.stats return command.stats
}, },
name: 'point' name: 'point',
dispose: () => {
destroyAttributes(attributes)
destroyUniforms(uniforms)
}
} }
} }
} }
export default Point export default Point
\ No newline at end of file
// namespace Point {
// export type DataType = {
// position: { type: Float32Array, itemSize: 3 }
// }
// export type Data = { [K in keyof DataType]: DataType[K]['type'] }
// export type Attributes = { [K in keyof Data]: Attribute<Data[K]> }
// export function create(regl: REGL.Regl, dataOrCount: Data | number): Renderable<Data> {
// let count: number
// let data: Data
// if (typeof dataOrCount === 'number') {
// count = dataOrCount
// data = {
// position: new Float32Array(count * 3)
// }
// } else {
// count = dataOrCount.position.length / 3
// data = dataOrCount
// }
// const attributes = createAttributes(regl, data)
// const command = regl({
// vert: pointVert,
// frag: pointFrag,
// attributes: getBuffers(attributes),
// count,
// primitive: 'points'
// })
// return {
// draw: () => command(),
// setCount: (newCount: number) => {
// for (const k of Object.keys(data)) {
// attributes[k as keyof Data].setCount(newCount)
// }
// count = newCount
// },
// getCount: () => count,
// attributes
// }
// }
// }
\ No newline at end of file
...@@ -7,9 +7,35 @@ ...@@ -7,9 +7,35 @@
import REGL = require('regl'); import REGL = require('regl');
import { ValueCell } from 'mol-util/value-cell' import { ValueCell } from 'mol-util/value-cell'
import { ColorTexture } from '../util';
import { Attributes, AttributesData, AttributesBuffers } from '../renderable' import { Attributes, AttributesData, AttributesBuffers } from '../renderable'
import Attribute from '../attribute' import Attribute from '../attribute'
import { ColorData } from 'mol-geo/color';
import { ShaderDefines } from '../shaders';
export type ReglUniforms = { [k: string]: REGL.Uniform | REGL.Texture }
export type ReglAttributes = { [k: string]: REGL.AttributeConfig }
export function calculateTextureInfo (n: number, itemSize: number) {
const sqN = Math.sqrt(n * itemSize)
let width = Math.ceil(sqN)
width = width + (itemSize - (width % itemSize)) % itemSize
const height = width > 0 ? Math.ceil(n * itemSize / width) : 0
return { width, height, length: width * height * itemSize }
}
export interface ColorTexture extends Uint8Array {
width: number,
height: number
}
export function createColorTexture (n: number): ColorTexture {
const colorTexInfo = calculateTextureInfo(n, 3)
const colorTexture = new Uint8Array(colorTexInfo.length)
return Object.assign(colorTexture, {
width: colorTexInfo.width,
height: colorTexInfo.height
})
}
export function createTransformAttributes (regl: REGL.Regl, transform: ValueCell<Float32Array>, count: number) { export function createTransformAttributes (regl: REGL.Regl, transform: ValueCell<Float32Array>, count: number) {
const size = 4 const size = 4
...@@ -40,6 +66,18 @@ export function createColorUniforms (regl: REGL.Regl, color: ValueCell<ColorText ...@@ -40,6 +66,18 @@ export function createColorUniforms (regl: REGL.Regl, color: ValueCell<ColorText
} }
} }
export function getColorDefines(color: ColorData) {
const defines: ShaderDefines = {}
switch (color.type) {
case 'uniform': defines.UNIFORM_COLOR = ''; break;
case 'attribute': defines.ATTRIBUTE_COLOR = ''; break;
case 'element': defines.ELEMENT_COLOR = ''; break;
case 'instance': defines.INSTANCE_COLOR = ''; break;
case 'element-instance': defines.ELEMENT_INSTANCE_COLOR = ''; break;
}
return defines
}
export function getBuffers<T extends AttributesData>(attributes: Attributes<T>): AttributesBuffers<T> { export function getBuffers<T extends AttributesData>(attributes: Attributes<T>): AttributesBuffers<T> {
const buffers: AttributesBuffers<any> = {} const buffers: AttributesBuffers<any> = {}
for (const k of Object.keys(attributes)) { for (const k of Object.keys(attributes)) {
...@@ -52,4 +90,72 @@ export function fillSerial<T extends Helpers.NumberArray> (array: T) { ...@@ -52,4 +90,72 @@ export function fillSerial<T extends Helpers.NumberArray> (array: T) {
const n = array.length const n = array.length
for (let i = 0; i < n; ++i) array[ i ] = i for (let i = 0; i < n; ++i) array[ i ] = i
return array return array
}
interface BaseProps {
objectId: number,
instanceCount: number,
elementCount: number,
positionCount: number,
position: ValueCell<Float32Array>
normal?: ValueCell<Float32Array>
size?: ValueCell<Float32Array>
id: ValueCell<Float32Array>
transform: ValueCell<Float32Array>
color: ColorData
}
export function createBaseUniforms(regl: REGL.Regl, props: BaseProps): ReglUniforms {
const { objectId, instanceCount, elementCount, color } = props
const uniforms = { objectId, instanceCount, elementCount }
if (color.type === 'instance' || color.type === 'element' || color.type === 'element-instance') {
Object.assign(uniforms, createColorUniforms(regl, color.value))
} else if (color.type === 'uniform') {
Object.assign(uniforms, { color: color.value })
}
return uniforms
}
export function createBaseAttributes(regl: REGL.Regl, props: BaseProps): ReglAttributes {
const { instanceCount, positionCount, position, color, id, normal, size, transform } = props
const instanceId = ValueCell.create(fillSerial(new Float32Array(instanceCount)))
const attributes = getBuffers({
instanceId: Attribute.create(regl, instanceId, instanceCount, { size: 1, divisor: 1 }),
position: Attribute.create(regl, position, positionCount, { size: 3 }),
elementId: Attribute.create(regl, id, positionCount, { size: 1 }),
...createTransformAttributes(regl, transform, instanceCount)
})
if (color.type === 'attribute') {
attributes.color = Attribute.create(regl, color.value, positionCount, { size: 3 }).buffer
}
if (normal) {
attributes.normal = Attribute.create(regl, normal as any, positionCount, { size: 3 }).buffer
}
if (size) {
attributes.size = Attribute.create(regl, size, positionCount, { size: 1 }).buffer
}
return attributes
}
export function createBaseDefines(regl: REGL.Regl, props: BaseProps) {
return getColorDefines(props.color)
}
export function destroyAttributes(attributes: ReglAttributes) {
for (const k in attributes) {
const buffer = attributes[k].buffer
if (buffer) {
buffer.destroy()
}
}
}
export function destroyUniforms(uniforms: ReglUniforms) {
for (const k in uniforms) {
const uniform = uniforms[k]
if ((uniform as any).destroy) {
(uniform as any).destroy()
}
}
} }
\ No newline at end of file
...@@ -11,6 +11,14 @@ import { Camera } from 'mol-view/camera/base'; ...@@ -11,6 +11,14 @@ import { Camera } from 'mol-view/camera/base';
import * as glContext from './context' import * as glContext from './context'
import Scene, { RenderObject } from './scene'; import Scene, { RenderObject } from './scene';
export interface RendererStats {
elementsCount: number
bufferCount: number
textureCount: number
shaderCount: number
renderableCount: number
}
interface Renderer { interface Renderer {
add: (o: RenderObject) => void add: (o: RenderObject) => void
remove: (o: RenderObject) => void remove: (o: RenderObject) => void
...@@ -19,6 +27,7 @@ interface Renderer { ...@@ -19,6 +27,7 @@ interface Renderer {
setViewport: (viewport: Viewport) => void setViewport: (viewport: Viewport) => void
stats: RendererStats
dispose: () => void dispose: () => void
} }
...@@ -32,7 +41,7 @@ const optionalExtensions = [ ...@@ -32,7 +41,7 @@ const optionalExtensions = [
namespace Renderer { namespace Renderer {
export function create(canvas: HTMLCanvasElement, camera: Camera): Renderer { export function create(canvas: HTMLCanvasElement, camera: Camera): Renderer {
const regl = glContext.create({ canvas, extensions, optionalExtensions, profile: true }) const regl = glContext.create({ canvas, extensions, optionalExtensions, profile: false })
const scene = Scene.create(regl) const scene = Scene.create(regl)
const baseContext = regl({ const baseContext = regl({
...@@ -71,20 +80,26 @@ namespace Renderer { ...@@ -71,20 +80,26 @@ namespace Renderer {
return { return {
add: (o: RenderObject) => { add: (o: RenderObject) => {
scene.add(o) scene.add(o)
draw()
}, },
remove: (o: RenderObject) => { remove: (o: RenderObject) => {
scene.remove(o) scene.remove(o)
draw()
}, },
clear: () => { clear: () => {
scene.clear() scene.clear()
draw()
}, },
draw, draw,
setViewport: (viewport: Viewport) => { setViewport: (viewport: Viewport) => {
regl({ viewport }) regl({ viewport })
}, },
get stats() {
return {
elementsCount: regl.stats.elementsCount,
bufferCount: regl.stats.bufferCount,
textureCount: regl.stats.textureCount,
shaderCount: regl.stats.shaderCount,
renderableCount: scene.count
}
},
dispose: () => { dispose: () => {
regl.destroy() regl.destroy()
} }
......
...@@ -16,21 +16,21 @@ function getNextId() { ...@@ -16,21 +16,21 @@ function getNextId() {
export type RenderData = { [k: string]: ValueCell<Helpers.TypedArray> } export type RenderData = { [k: string]: ValueCell<Helpers.TypedArray> }
export interface RenderObject { export interface MeshRenderObject { id: number, type: 'mesh', props: MeshRenderable.Data }
id: number export interface PointRenderObject { id: number, type: 'point', props: PointRenderable.Data }
type: 'mesh' | 'point' export type RenderObject = MeshRenderObject | PointRenderObject
data: PointRenderable.Data | MeshRenderable.Data
uniforms: { [k: string]: REGL.Uniform }
}
export function createRenderObject(type: 'mesh' | 'point', data: PointRenderable.Data | MeshRenderable.Data, uniforms: { [k: string]: REGL.Uniform }) { export function createMeshRenderObject(props: MeshRenderable.Data): MeshRenderObject {
return { id: getNextId(), type, data, uniforms } return { id: getNextId(), type: 'mesh', props }
}
export function createPointRenderObject(props: PointRenderable.Data): PointRenderObject {
return { id: getNextId(), type: 'point', props }
} }
export function createRenderable(regl: REGL.Regl, o: RenderObject) { export function createRenderable(regl: REGL.Regl, o: RenderObject) {
switch (o.type) { switch (o.type) {
case 'mesh': return MeshRenderable.create(regl, o.data as MeshRenderable.Data, o.uniforms || {}) case 'mesh': return MeshRenderable.create(regl, o.props)
case 'point': return PointRenderable.create(regl, o.data as PointRenderable.Data) case 'point': return PointRenderable.create(regl, o.props)
} }
} }
...@@ -39,6 +39,7 @@ interface Scene { ...@@ -39,6 +39,7 @@ interface Scene {
remove: (o: RenderObject) => void remove: (o: RenderObject) => void
clear: () => void clear: () => void
forEach: (callbackFn: (value: Renderable) => void) => void forEach: (callbackFn: (value: Renderable) => void) => void
count: number
} }
namespace Scene { namespace Scene {
...@@ -54,21 +55,22 @@ namespace Scene { ...@@ -54,21 +55,22 @@ namespace Scene {
}, },
remove: (o: RenderObject) => { remove: (o: RenderObject) => {
if (o.id in objectIdRenderableMap) { if (o.id in objectIdRenderableMap) {
// TODO objectIdRenderableMap[o.id].dispose()
// objectIdRenderableMap[o.id].destroy()
delete objectIdRenderableMap[o.id] delete objectIdRenderableMap[o.id]
} }
}, },
clear: () => { clear: () => {
for (const id in objectIdRenderableMap) { for (const id in objectIdRenderableMap) {
// TODO objectIdRenderableMap[id].dispose()
// objectIdRenderableMap[id].destroy()
delete objectIdRenderableMap[id] delete objectIdRenderableMap[id]
} }
renderableList.length = 0 renderableList.length = 0
}, },
forEach: (callbackFn: (value: Renderable) => void) => { forEach: (callbackFn: (value: Renderable) => void) => {
renderableList.forEach(callbackFn) renderableList.forEach(callbackFn)
},
get count() {
return renderableList.length
} }
} }
} }
......
#if defined(UNIFORM_COLOR)
vec3 material = color;
#elif defined(ATTRIBUTE_COLOR) || defined(INSTANCE_COLOR) || defined(ELEMENT_COLOR) || defined(ELEMENT_INSTANCE_COLOR)
vec3 material = vColor;
#endif
\ No newline at end of file
#if defined(ATTRIBUTE_COLOR)
vColor = color;
#elif defined(INSTANCE_COLOR)
vColor = read_vec3(colorTex, instanceId, colorTexSize);
#elif defined(ELEMENT_COLOR)
vColor = read_vec3(colorTex, elementId, colorTexSize);
#elif defined(ELEMENT_INSTANCE_COLOR)
vColor = read_vec3(colorTex, instanceId * float(elementCount) + elementId, colorTexSize);
#endif
\ No newline at end of file
#if defined(UNIFORM_COLOR)
uniform vec3 color;
#elif defined(ATTRIBUTE_COLOR) || defined(INSTANCE_COLOR) || defined(ELEMENT_COLOR) || defined(ELEMENT_INSTANCE_COLOR)
varying vec3 vColor;
#endif
\ No newline at end of file
#if defined(UNIFORM_COLOR)
uniform vec3 color;
#elif defined(ATTRIBUTE_COLOR)
varying vec3 vColor;
attribute vec3 color;
#elif defined(INSTANCE_COLOR) || defined(ELEMENT_COLOR) || defined(ELEMENT_INSTANCE_COLOR)
varying vec3 vColor;
uniform vec2 colorTexSize;
uniform sampler2D colorTex;
#endif
#pragma glslify: read_vec3 = require(../utils/read-vec3.glsl)
\ No newline at end of file
...@@ -19,15 +19,11 @@ uniform mat4 view; ...@@ -19,15 +19,11 @@ uniform mat4 view;
varying vec3 vNormal, vViewPosition; varying vec3 vNormal, vViewPosition;
#if defined(UNIFORM_COLOR) #pragma glslify: import('./chunks/color-frag-params.glsl')
uniform vec3 color;
#elif defined(ATTRIBUTE_COLOR) || defined(INSTANCE_COLOR) || defined(ELEMENT_COLOR) || defined(ELEMENT_INSTANCE_COLOR)
varying vec3 vColor;
#endif
#pragma glslify: attenuation = require(./util/attenuation.glsl) #pragma glslify: attenuation = require(./utils/attenuation.glsl)
#pragma glslify: calculateSpecular = require(./util/phong-specular.glsl) #pragma glslify: calculateSpecular = require(./utils/phong-specular.glsl)
#pragma glslify: calculateDiffuse = require(./util/oren-nayar-diffuse.glsl) #pragma glslify: calculateDiffuse = require(./utils/oren-nayar-diffuse.glsl)
const float specularScale = 0.65; const float specularScale = 0.65;
const float shininess = 100.0; const float shininess = 100.0;
...@@ -36,11 +32,7 @@ const float albedo = 0.95; ...@@ -36,11 +32,7 @@ const float albedo = 0.95;
void main() { void main() {
// material color // material color
#if defined(UNIFORM_COLOR) #pragma glslify: import('./chunks/color-assign-material.glsl')
vec3 material = color;
#elif defined(ATTRIBUTE_COLOR) || defined(INSTANCE_COLOR) || defined(ELEMENT_COLOR) || defined(ELEMENT_INSTANCE_COLOR)
vec3 material = vColor;
#endif
// determine surface to light direction // determine surface to light direction
// vec4 lightPosition = view * vec4(light.position, 1.0); // vec4 lightPosition = view * vec4(light.position, 1.0);
......
...@@ -12,39 +12,23 @@ uniform int objectId; ...@@ -12,39 +12,23 @@ uniform int objectId;
uniform int instanceCount; uniform int instanceCount;
uniform int elementCount; uniform int elementCount;
#if defined(UNIFORM_COLOR) #pragma glslify: import('./chunks/color-vert-params.glsl')
uniform vec3 color;
#elif defined(ATTRIBUTE_COLOR)
attribute vec3 color;
#elif defined(INSTANCE_COLOR) || defined(ELEMENT_COLOR) || defined(ELEMENT_INSTANCE_COLOR)
uniform vec2 colorTexSize;
uniform sampler2D colorTex;
#endif
attribute vec3 position; attribute vec3 position;
attribute vec3 normal;
attribute vec4 transformColumn0, transformColumn1, transformColumn2, transformColumn3; attribute vec4 transformColumn0, transformColumn1, transformColumn2, transformColumn3;
attribute float instanceId; attribute float instanceId;
attribute float elementId; attribute float elementId;
varying vec3 vColor; attribute vec3 normal;
varying vec3 vNormal; varying vec3 vNormal;
varying vec3 vViewPosition; varying vec3 vViewPosition;
#pragma glslify: inverse = require(./util/inverse.glsl) #pragma glslify: inverse = require(./utils/inverse.glsl)
#pragma glslify: read_vec3 = require(./util/read-vec3.glsl) #pragma glslify: transpose = require(./utils/transpose.glsl)
#pragma glslify: transpose = require(./util/transpose.glsl)
void main(){ void main(){
#if defined(ATTRIBUTE_COLOR) #pragma glslify: import('./chunks/color-assign-varying.glsl')
vColor = color;
#elif defined(INSTANCE_COLOR)
vColor = read_vec3(colorTex, instanceId, colorTexSize);
#elif defined(ELEMENT_COLOR)
vColor = read_vec3(colorTex, elementId, colorTexSize);
#elif defined(ELEMENT_INSTANCE_COLOR)
vColor = read_vec3(colorTex, instanceId * float(elementCount) + elementId, colorTexSize);
#endif
mat4 transform = mat4(transformColumn0, transformColumn1, transformColumn2, transformColumn3); mat4 transform = mat4(transformColumn0, transformColumn1, transformColumn2, transformColumn3);
mat4 modelView = view * model * transform; mat4 modelView = view * model * transform;
......
...@@ -4,6 +4,11 @@ ...@@ -4,6 +4,11 @@
* @author Alexander Rose <alexander.rose@weirdbyte.de> * @author Alexander Rose <alexander.rose@weirdbyte.de>
*/ */
precision highp float;
#pragma glslify: import('./chunks/color-frag-params.glsl')
void main(){ void main(){
gl_FragColor = vec4(1, 0, 0, 1); #pragma glslify: import('./chunks/color-assign-material.glsl')
gl_FragColor = vec4(material, 1);
} }
\ No newline at end of file
...@@ -4,23 +4,27 @@ ...@@ -4,23 +4,27 @@
* @author Alexander Rose <alexander.rose@weirdbyte.de> * @author Alexander Rose <alexander.rose@weirdbyte.de>
*/ */
precision mediump float; precision highp float;
uniform mat4 projection, model, view; uniform mat4 projection, model, view;
attribute vec3 position; //, color; uniform int objectId;
attribute vec4 transformColumn0, transformColumn1, transformColumn2, transformColumn3; uniform int instanceCount;
// attribute int instanceId; uniform int elementCount;
// instanced #pragma glslify: import('./chunks/color-vert-params.glsl')
// attribute mat4 transform;
// uniform mat4 transform;
// varying vec3 vColor; attribute vec3 position;
attribute vec4 transformColumn0, transformColumn1, transformColumn2, transformColumn3;
attribute float instanceId;
attribute float elementId;
void main(){ void main(){
#pragma glslify: import('./chunks/color-assign-varying.glsl')
mat4 transform = mat4(transformColumn0, transformColumn1, transformColumn2, transformColumn3); mat4 transform = mat4(transformColumn0, transformColumn1, transformColumn2, transformColumn3);
// vColor = color; mat4 modelView = view * model * transform;
gl_PointSize = 1.0; gl_PointSize = 1.0;
gl_Position = projection * view * model * transform * vec4(position, 1.0); gl_Position = projection * modelView * vec4(position, 1.0);
} }
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment