mirror of
https://github.com/molstar/molstar.git
synced 2026-06-04 21:34:23 +08:00
Compare commits
1 Commits
master
...
batch-link
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
df26bde255 |
@@ -106,6 +106,7 @@ export class DrawPass {
|
||||
this.depthTextureOpaque.define(width, height);
|
||||
}
|
||||
|
||||
// TODO: link programs in parallel
|
||||
this.wboit = new WboitPass(webgl, width, height);
|
||||
this.dpoit = new DpoitPass(webgl, width, height);
|
||||
this.marking = new MarkingPass(webgl, width, height);
|
||||
|
||||
@@ -23,6 +23,12 @@ export class CommitQueue {
|
||||
return this.removeMap.size + this.addMap.size;
|
||||
}
|
||||
|
||||
forEachAdd(cb: (o: GraphicsRenderObject) => void) {
|
||||
for (let n = this.addList.first; n; n = n.next) {
|
||||
cb(n.value);
|
||||
}
|
||||
}
|
||||
|
||||
add(o: GraphicsRenderObject) {
|
||||
if (this.removeMap.has(o)) {
|
||||
const a = this.removeMap.get(o)!;
|
||||
|
||||
@@ -8,14 +8,14 @@ import { RenderableState, Renderable } from './renderable';
|
||||
import { idFactory } from '../mol-util/id-factory';
|
||||
import { WebGLContext } from './webgl/context';
|
||||
import { DirectVolumeValues, DirectVolumeRenderable } from './renderable/direct-volume';
|
||||
import { MeshValues, MeshRenderable } from './renderable/mesh';
|
||||
import { MeshValues, MeshRenderable, linkMeshRenderableShader } from './renderable/mesh';
|
||||
import { PointsValues, PointsRenderable } from './renderable/points';
|
||||
import { LinesValues, LinesRenderable } from './renderable/lines';
|
||||
import { SpheresValues, SpheresRenderable } from './renderable/spheres';
|
||||
import { SpheresValues, SpheresRenderable, linkSpheresRenderableShader } from './renderable/spheres';
|
||||
import { TextValues, TextRenderable } from './renderable/text';
|
||||
import { TextureMeshValues, TextureMeshRenderable } from './renderable/texture-mesh';
|
||||
import { ImageValues, ImageRenderable } from './renderable/image';
|
||||
import { CylindersRenderable, CylindersValues } from './renderable/cylinders';
|
||||
import { CylindersRenderable, CylindersValues, linkCylindersRenderableShader } from './renderable/cylinders';
|
||||
import { Transparency } from './webgl/render-item';
|
||||
|
||||
const getNextId = idFactory(0, 0x7FFFFFFF);
|
||||
@@ -63,3 +63,13 @@ export function createRenderable<T extends RenderObjectType>(ctx: WebGLContext,
|
||||
}
|
||||
throw new Error('unsupported type');
|
||||
}
|
||||
|
||||
export function linkRenderableShader<T extends RenderObjectType>(ctx: WebGLContext, o: GraphicsRenderObject<T>, transparency: Transparency) {
|
||||
switch (o.type) {
|
||||
case 'mesh': return linkMeshRenderableShader(ctx, o.id, o.values as MeshValues, o.state, o.materialId, transparency);
|
||||
case 'spheres': return linkSpheresRenderableShader(ctx, o.id, o.values as SpheresValues, o.state, o.materialId, transparency);
|
||||
case 'cylinders': return linkCylindersRenderableShader(ctx, o.id, o.values as CylindersValues, o.state, o.materialId, transparency);
|
||||
}
|
||||
console.log(o.type);
|
||||
// throw new Error('unsupported type');
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import { Renderable, RenderableState, createRenderable } from '../renderable';
|
||||
import { WebGLContext } from '../webgl/context';
|
||||
import { createGraphicsRenderItem, Transparency } from '../webgl/render-item';
|
||||
import { createGraphicsRenderItem, GraphicsRenderVariants, linkRenderItemProgram, Transparency } from '../webgl/render-item';
|
||||
import { GlobalUniformSchema, BaseSchema, AttributeSpec, Values, InternalSchema, SizeSchema, InternalValues, ElementsSpec, ValueSpec, DefineSpec, GlobalTextureSchema, UniformSpec } from './schema';
|
||||
import { CylindersShaderCode } from '../shader-code';
|
||||
import { ValueCell } from '../../mol-util';
|
||||
@@ -45,4 +45,13 @@ export function CylindersRenderable(ctx: WebGLContext, id: number, values: Cylin
|
||||
const shaderCode = CylindersShaderCode;
|
||||
const renderItem = createGraphicsRenderItem(ctx, 'triangles', shaderCode, schema, { ...values, ...internalValues }, materialId, transparency);
|
||||
return createRenderable(renderItem, values, state);
|
||||
}
|
||||
|
||||
export function linkCylindersRenderableShader(ctx: WebGLContext, id: number, values: CylindersValues, state: RenderableState, materialId: number, transparency: Transparency) {
|
||||
const schema = { ...GlobalUniformSchema, ...GlobalTextureSchema, ...InternalSchema, ...CylindersSchema };
|
||||
const internalValues: InternalValues = {
|
||||
uObjectId: ValueCell.create(id),
|
||||
};
|
||||
const shaderCode = CylindersShaderCode;
|
||||
linkRenderItemProgram(ctx, shaderCode, schema, { ...values, ...internalValues }, GraphicsRenderVariants, transparency);
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import { Renderable, RenderableState, createRenderable } from '../renderable';
|
||||
import { WebGLContext } from '../webgl/context';
|
||||
import { createGraphicsRenderItem, Transparency } from '../webgl/render-item';
|
||||
import { createGraphicsRenderItem, GraphicsRenderVariants, linkRenderItemProgram, Transparency } from '../webgl/render-item';
|
||||
import { GlobalUniformSchema, BaseSchema, AttributeSpec, ElementsSpec, DefineSpec, Values, InternalSchema, InternalValues, GlobalTextureSchema, ValueSpec, UniformSpec } from './schema';
|
||||
import { MeshShaderCode } from '../shader-code';
|
||||
import { ValueCell } from '../../mol-util';
|
||||
@@ -41,4 +41,13 @@ export function MeshRenderable(ctx: WebGLContext, id: number, values: MeshValues
|
||||
const renderItem = createGraphicsRenderItem(ctx, 'triangles', shaderCode, schema, { ...values, ...internalValues }, materialId, transparency);
|
||||
|
||||
return createRenderable(renderItem, values, state);
|
||||
}
|
||||
|
||||
export function linkMeshRenderableShader(ctx: WebGLContext, id: number, values: MeshValues, state: RenderableState, materialId: number, transparency: Transparency) {
|
||||
const schema = { ...GlobalUniformSchema, ...GlobalTextureSchema, ...InternalSchema, ...MeshSchema };
|
||||
const internalValues: InternalValues = {
|
||||
uObjectId: ValueCell.create(id),
|
||||
};
|
||||
const shaderCode = MeshShaderCode;
|
||||
linkRenderItemProgram(ctx, shaderCode, schema, { ...values, ...internalValues }, GraphicsRenderVariants, transparency);
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import { Renderable, RenderableState, createRenderable } from '../renderable';
|
||||
import { WebGLContext } from '../webgl/context';
|
||||
import { createGraphicsRenderItem, Transparency } from '../webgl/render-item';
|
||||
import { createGraphicsRenderItem, GraphicsRenderVariants, linkRenderItemProgram, Transparency } from '../webgl/render-item';
|
||||
import { GlobalUniformSchema, BaseSchema, Values, InternalSchema, SizeSchema, InternalValues, ValueSpec, DefineSpec, GlobalTextureSchema, UniformSpec, TextureSpec } from './schema';
|
||||
import { SpheresShaderCode } from '../shader-code';
|
||||
import { ValueCell } from '../../mol-util';
|
||||
@@ -46,4 +46,13 @@ export function SpheresRenderable(ctx: WebGLContext, id: number, values: Spheres
|
||||
const shaderCode = SpheresShaderCode;
|
||||
const renderItem = createGraphicsRenderItem(ctx, 'triangles', shaderCode, schema, { ...values, ...internalValues }, materialId, transparency);
|
||||
return createRenderable(renderItem, values, state);
|
||||
}
|
||||
|
||||
export function linkSpheresRenderableShader(ctx: WebGLContext, id: number, values: SpheresValues, state: RenderableState, materialId: number, transparency: Transparency) {
|
||||
const schema = { ...GlobalUniformSchema, ...GlobalTextureSchema, ...InternalSchema, ...SpheresSchema };
|
||||
const internalValues: InternalValues = {
|
||||
uObjectId: ValueCell.create(id),
|
||||
};
|
||||
const shaderCode = SpheresShaderCode;
|
||||
linkRenderItemProgram(ctx, shaderCode, schema, { ...values, ...internalValues }, GraphicsRenderVariants, transparency);
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
import { WebGLContext } from './webgl/context';
|
||||
import { GraphicsRenderObject, createRenderable } from './render-object';
|
||||
import { GraphicsRenderObject, createRenderable, linkRenderableShader as linkRenderableProgram } from './render-object';
|
||||
import { Object3D } from './object3d';
|
||||
import { Sphere3D } from '../mol-math/geometry/primitives/sphere3d';
|
||||
import { CommitQueue } from './commit-queue';
|
||||
@@ -130,7 +130,9 @@ namespace Scene {
|
||||
|
||||
function add(o: GraphicsRenderObject) {
|
||||
if (!renderableMap.has(o)) {
|
||||
console.time(`create renderable ${o.type}`);
|
||||
const renderable = createRenderable(ctx, o, transparency);
|
||||
console.timeEnd(`create renderable ${o.type}`);
|
||||
renderables.push(renderable);
|
||||
if (o.type === 'direct-volume') {
|
||||
volumes.push(renderable);
|
||||
@@ -164,6 +166,10 @@ namespace Scene {
|
||||
|
||||
let i = 0;
|
||||
|
||||
// TODO: have to destroy programs that were not added (=removed before added)
|
||||
commitQueue.forEachAdd(o => linkRenderableProgram(ctx, o, transparency));
|
||||
// there could also be a separate queue just for program linking that calls program.finalize()
|
||||
|
||||
while (true) {
|
||||
const o = commitQueue.tryGetRemove();
|
||||
if (!o) break;
|
||||
|
||||
@@ -22,6 +22,7 @@ export interface Program {
|
||||
readonly id: number
|
||||
|
||||
use: () => void
|
||||
finalize: () => void
|
||||
setUniforms: (uniformValues: UniformsList) => void
|
||||
uniform: (k: string, v: UniformType) => void
|
||||
bindAttributes: (attribueBuffers: AttributeBuffers) => void
|
||||
@@ -175,29 +176,38 @@ export function createProgram(gl: GLRenderingContext, state: WebGLState, extensi
|
||||
let locations: Locations;
|
||||
let uniformSetters: UniformSetters;
|
||||
|
||||
function init() {
|
||||
function link() {
|
||||
vertShader.attach(program);
|
||||
fragShader.attach(program);
|
||||
console.log('linking', programId)
|
||||
gl.linkProgram(program);
|
||||
if (isDebugMode) {
|
||||
checkProgram(gl, program);
|
||||
}
|
||||
|
||||
locations = getLocations(gl, program, schema);
|
||||
uniformSetters = getUniformSetters(schema);
|
||||
// if (isDebugMode) {
|
||||
// checkProgram(gl, program);
|
||||
// }
|
||||
|
||||
if (isDebugMode) {
|
||||
checkActiveAttributes(gl, program, schema);
|
||||
checkActiveUniforms(gl, program, schema);
|
||||
}
|
||||
// locations = getLocations(gl, program, schema);
|
||||
// uniformSetters = getUniformSetters(schema);
|
||||
|
||||
// if (isDebugMode) {
|
||||
// checkActiveAttributes(gl, program, schema);
|
||||
// checkActiveUniforms(gl, program, schema);
|
||||
// }
|
||||
}
|
||||
init();
|
||||
link();
|
||||
|
||||
let destroyed = false;
|
||||
|
||||
return {
|
||||
id: programId,
|
||||
|
||||
finalize: () => {
|
||||
if (locations) return;
|
||||
console.log('finalizing', programId)
|
||||
locations = getLocations(gl, program, schema);
|
||||
uniformSetters = getUniformSetters(schema);
|
||||
},
|
||||
|
||||
use: () => {
|
||||
// console.log('use', programId)
|
||||
state.currentProgramId = programId;
|
||||
@@ -245,7 +255,7 @@ export function createProgram(gl: GLRenderingContext, state: WebGLState, extensi
|
||||
|
||||
reset: () => {
|
||||
program = getProgram(gl);
|
||||
init();
|
||||
link();
|
||||
},
|
||||
destroy: () => {
|
||||
if (destroyed) return;
|
||||
|
||||
@@ -128,6 +128,26 @@ export function createComputeRenderItem(ctx: WebGLContext, drawMode: DrawMode, s
|
||||
return createRenderItem(ctx, drawMode, shaderCode, schema, values, materialId, ComputeRenderVariants, undefined);
|
||||
}
|
||||
|
||||
export function linkRenderItemProgram<T extends string>(ctx: WebGLContext, shaderCode: ShaderCode, schema: RenderableSchema, values: RenderableValues, renderVariants: T[], transparency: Transparency) {
|
||||
|
||||
// filter out unsupported variants
|
||||
renderVariants = renderVariants.filter(v => {
|
||||
if (v === 'tracing') return !!ctx.extensions.drawBuffers;
|
||||
return true;
|
||||
});
|
||||
|
||||
// TODO: optimize
|
||||
const { defineValues } = splitValues(schema, values);
|
||||
|
||||
for (const rv of renderVariants) {
|
||||
const defs = { ...defineValues, dRenderVariant: ValueCell.create(getRenderVariant(rv, transparency)) };
|
||||
if (schema.dRenderVariant === undefined) {
|
||||
Object.defineProperty(schema, 'dRenderVariant', { value: DefineSpec('string') });
|
||||
}
|
||||
ctx.resources.linkProgram(defs, shaderCode, schema);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a render item
|
||||
*
|
||||
|
||||
@@ -56,6 +56,7 @@ export interface WebGLResources {
|
||||
elements: (array: ElementsType, usageHint?: UsageHint) => ElementsBuffer
|
||||
pixelPack: (format: TextureFormat, type: TextureType) => PixelPackBuffer
|
||||
framebuffer: () => Framebuffer
|
||||
linkProgram: (defineValues: DefineValues, shaderCode: ShaderCode, schema: RenderableSchema) => Program
|
||||
program: (defineValues: DefineValues, shaderCode: ShaderCode, schema: RenderableSchema) => Program
|
||||
renderbuffer: (format: RenderbufferFormat, attachment: RenderbufferAttachment, width: number, height: number) => Renderbuffer
|
||||
shader: (type: ShaderType, source: string) => Shader
|
||||
@@ -137,9 +138,15 @@ export function createResources(gl: GLRenderingContext, state: WebGLState, stats
|
||||
framebuffer: () => {
|
||||
return wrap('framebuffer', createFramebuffer(gl));
|
||||
},
|
||||
program: (defineValues: DefineValues, shaderCode: ShaderCode, schema: RenderableSchema) => {
|
||||
linkProgram: (defineValues: DefineValues, shaderCode: ShaderCode, schema: RenderableSchema) => {
|
||||
return wrapCached(programCache.get({ defineValues, shaderCode, schema }));
|
||||
},
|
||||
program: (defineValues: DefineValues, shaderCode: ShaderCode, schema: RenderableSchema) => {
|
||||
// TODO: create function
|
||||
const linked = wrapCached(programCache.get({ defineValues, shaderCode, schema }));
|
||||
linked.finalize();
|
||||
return linked;
|
||||
},
|
||||
renderbuffer: (format: RenderbufferFormat, attachment: RenderbufferAttachment, width: number, height: number) => {
|
||||
return wrap('renderbuffer', createRenderbuffer(gl, format, attachment, width, height));
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user