Browse Source

wip, uniform blocks

Alexander Rose 6 years ago
parent
commit
28ad4f4229

+ 6 - 0
src/mol-gl/shader/chunks/common-vert-params.glsl

@@ -1,6 +1,12 @@
 uniform mat4 uProjection, uModel, uView;
 uniform vec3 uCameraPosition;
 
+uniform Common {
+    mat4 uProjection;
+    int uObjectId;
+    int uInstanceCount;
+} uboCommon;
+
 uniform int uObjectId;
 uniform int uInstanceCount;
 uniform int uGroupCount;

+ 31 - 1
src/mol-gl/webgl/buffer.ts

@@ -76,6 +76,7 @@ export function getBufferType(ctx: WebGLContext, bufferType: BufferType) {
     switch (bufferType) {
         case 'attribute': return gl.ARRAY_BUFFER
         case 'elements': return gl.ELEMENT_ARRAY_BUFFER
+        case 'uniform': return (gl as WebGL2RenderingContext).UNIFORM_BUFFER
     }
 }
 
@@ -214,4 +215,33 @@ export function createElementsBuffer(ctx: WebGLContext, array: ElementsType, usa
             gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, _buffer);
         }
     }
-}
+}
+
+//
+
+export type UniformType = Float32Array
+export type UniformKind = 'float32'
+
+// export type AttributeDefs = {
+//     [k: string]: { kind: ArrayKind, itemSize: BufferItemSize, divisor: number }
+// }
+// export type AttributeValues = { [k: string]: ValueCell<ArrayType> }
+export type UniformBuffers = { [k: string]: UniformBuffer }
+
+export interface UniformBuffer extends Buffer {
+    bind: (location: number) => void
+}
+
+export function createUniformBuffer(ctx: WebGLContext, array: UniformType, usageHint: UsageHint = 'dynamic'): UniformBuffer {
+    const gl = ctx.gl as WebGL2RenderingContext
+    const buffer = createBuffer(ctx, array, usageHint, 'uniform')
+    const { _buffer } = buffer
+
+    return {
+        ...buffer,
+        bind: (location: number) => {
+            gl.bindBuffer(gl.UNIFORM_BUFFER, _buffer)
+            gl.bindBufferBase(gl.UNIFORM_BUFFER, location, _buffer)
+        }
+    }
+}

+ 46 - 1
src/mol-gl/webgl/program.ts

@@ -7,7 +7,7 @@
 import { ShaderCode, DefineValues, addShaderDefines } from '../shader-code'
 import { WebGLContext } from './context';
 import { UniformValues, getUniformSetters } from './uniform';
-import { AttributeBuffers } from './buffer';
+import { AttributeBuffers, UniformBuffers, createUniformBuffer } from './buffer';
 import { Textures, TextureId } from './texture';
 import { createReferenceCache, ReferenceCache } from 'mol-util/reference-cache';
 import { idFactory } from 'mol-util/id-factory';
@@ -21,6 +21,8 @@ export interface Program {
 
     use: () => void
     setUniforms: (uniformValues: UniformValues) => void
+    setUniformBuffers: (uniformBuffers: UniformBuffers, uniformValues: UniformValues) => void
+    bindUniformBuffers: (/* uniformBuffers: UniformBuffers */) => void
     bindAttributes: (attribueBuffers: AttributeBuffers) => void
     bindTextures: (textures: Textures) => void
 
@@ -77,6 +79,32 @@ export function createProgram(ctx: WebGLContext, props: ProgramProps): Program {
     const locations = getLocations(ctx, program, schema)
     const uniformSetters = getUniformSetters(schema)
 
+    interface UniformBufferInfo {
+        blockIndex: number,
+        blockSize: number,
+        uniformIndices: number[],
+        uniformOffsets: number[]
+    }
+    function getUniformBufferInfo(gl: WebGL2RenderingContext, program: WebGLProgram, name: string, uniformNames: string[]): UniformBufferInfo {
+        const blockIndex = gl.getUniformBlockIndex(program, name)
+        const blockSize = gl.getActiveUniformBlockParameter(program, blockIndex, gl.UNIFORM_BLOCK_DATA_SIZE)
+        const uniformIndices = gl.getUniformIndices(program, uniformNames)
+        if (uniformIndices === null) throw new Error(`Could not get uniform indices`)
+        const uniformOffsets = gl.getActiveUniforms(program, uniformIndices, gl.UNIFORM_OFFSET)
+        return { blockIndex, blockSize, uniformIndices, uniformOffsets }
+    }
+
+    const uniformBufferInfos: { [k: string]: UniformBufferInfo } = {
+        'Common': getUniformBufferInfo(gl as WebGL2RenderingContext, program, 'Common', [
+            'Common.uProjection', 'Common.uObjectId', 'Common.uInstanceCount'
+        ])
+    }
+    console.log(uniformBufferInfos)
+
+    const uniformBuffers: UniformBuffers = {
+        'Common': createUniformBuffer(ctx, new Float32Array(uniformBufferInfos['Common'].blockSize))
+    }
+
     let destroyed = false
 
     return {
@@ -96,6 +124,23 @@ export function createProgram(ctx: WebGLContext, props: ProgramProps): Program {
                 if (v) uniformSetters[k](gl, l, v.ref.value)
             }
         },
+        setUniformBuffers: (uniformBuffers: UniformBuffers, uniformValues: UniformValues) => {
+            const uniformBufferKeys = Object.keys(uniformBuffers)
+            for (let i = 0, il = uniformBufferKeys.length; i < il; ++i) {
+                // const k = uniformBufferKeys[i]
+                // const info = uniformBufferInfos[k]
+                // uniformBuffers[k].updateData()
+            }
+        },
+        bindUniformBuffers: (/* uniformBuffers: UniformBuffers */) => {
+            const uniformBufferKeys = Object.keys(uniformBuffers)
+            for (let i = 0, il = uniformBufferKeys.length; i < il; ++i) {
+                const k = uniformBufferKeys[i]
+                const info = uniformBufferInfos[k]
+                uniformBuffers[k].bind(i)
+                ;(gl as WebGL2RenderingContext).uniformBlockBinding(program, info.blockIndex, i)
+            }
+        },
         bindAttributes: (attribueBuffers: AttributeBuffers) => {
             const attributeKeys = Object.keys(attribueBuffers)
             for (let i = 0, il = attributeKeys.length; i < il; ++i) {

+ 1 - 0
src/mol-gl/webgl/render-item.ts

@@ -139,6 +139,7 @@ export function createRenderItem(ctx: WebGLContext, drawMode: DrawMode, shaderCo
             const program = programs[variant].value
             const vertexArray = vertexArrays[variant]
             program.setUniforms(uniformValues)
+            program.bindUniformBuffers()
             if (vertexArrayObject && vertexArray) {
                 vertexArrayObject.bindVertexArray(vertexArray)
                 // need to bind elements buffer explicitly since it is not always recorded in the VAO

+ 15 - 0
src/mol-gl/webgl/uniform.ts

@@ -8,6 +8,7 @@ import { Mat3, Mat4, Vec2, Vec3, Vec4 } from 'mol-math/linear-algebra'
 import { ValueCell } from 'mol-util';
 import { GLRenderingContext } from './compat';
 import { RenderableSchema } from 'mol-gl/renderable/schema';
+import { WebGLContext } from './context';
 
 export type UniformKindValue = {
     'f': number
@@ -72,4 +73,18 @@ export function getUniformSetters(schema: RenderableSchema) {
         }
     })
     return setters
+}
+
+//
+
+export interface UniformBlock {
+    update(): void
+    bind(): void
+}
+
+export function createUniformBlock(ctx: WebGLContext, ) {
+
+    return {
+        
+    }
 }