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

depthTexture support

parent 31c45f4b
No related branches found
No related tags found
No related merge requests found
...@@ -10,6 +10,7 @@ import { printTextureImage } from 'mol-gl/renderable/util'; ...@@ -10,6 +10,7 @@ import { printTextureImage } from 'mol-gl/renderable/util';
import { defaults, ValueCell } from 'mol-util'; import { defaults, ValueCell } from 'mol-util';
import { ValueSpec, AttributeSpec, UniformSpec, Values } from 'mol-gl/renderable/schema'; import { ValueSpec, AttributeSpec, UniformSpec, Values } from 'mol-gl/renderable/schema';
import { Vec2 } from 'mol-math/linear-algebra'; import { Vec2 } from 'mol-math/linear-algebra';
import { GLRenderingContext } from 'mol-gl/webgl/compat';
export const QuadPositions = new Float32Array([ export const QuadPositions = new Float32Array([
1.0, 1.0, -1.0, 1.0, -1.0, -1.0, // First triangle 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, // First triangle
...@@ -32,12 +33,21 @@ export const QuadValues: Values<typeof QuadSchema> = { ...@@ -32,12 +33,21 @@ export const QuadValues: Values<typeof QuadSchema> = {
// //
function getArrayForTexture(gl:GLRenderingContext, texture: Texture, size: number) {
switch (texture.type) {
case gl.UNSIGNED_BYTE: return new Uint8Array(size)
case gl.FLOAT: return new Float32Array(size)
}
throw new Error('unknown/unsupported texture type')
}
export function readTexture(ctx: WebGLContext, texture: Texture, width?: number, height?: number) { export function readTexture(ctx: WebGLContext, texture: Texture, width?: number, height?: number) {
const { gl, framebufferCache } = ctx const { gl, framebufferCache } = ctx
width = defaults(width, texture.width) width = defaults(width, texture.width)
height = defaults(height, texture.height) height = defaults(height, texture.height)
const size = width * height * 4
const framebuffer = framebufferCache.get('read-texture').value const framebuffer = framebufferCache.get('read-texture').value
const array = texture.type === gl.UNSIGNED_BYTE ? new Uint8Array(width * height * 4) : new Float32Array(width * height * 4) const array = getArrayForTexture(gl, texture, size)
framebuffer.bind() framebuffer.bind()
texture.attachFramebuffer(framebuffer, 0) texture.attachFramebuffer(framebuffer, 0)
ctx.readPixels(0, 0, width, height, array) ctx.readPixels(0, 0, width, height, array)
......
...@@ -47,6 +47,7 @@ export type KindValue = { ...@@ -47,6 +47,7 @@ export type KindValue = {
'image-uint8': TextureImage<Uint8Array> 'image-uint8': TextureImage<Uint8Array>
'image-float32': TextureImage<Float32Array> 'image-float32': TextureImage<Float32Array>
'image-depth': TextureImage<Uint8Array> // TODO should be Uint32Array
'volume-uint8': TextureVolume<Uint8Array> 'volume-uint8': TextureVolume<Uint8Array>
'volume-float32': TextureVolume<Float32Array> 'volume-float32': TextureVolume<Float32Array>
'texture': Texture 'texture': Texture
......
...@@ -220,4 +220,22 @@ export interface COMPAT_shader_texture_lod { ...@@ -220,4 +220,22 @@ export interface COMPAT_shader_texture_lod {
export function getShaderTextureLod(gl: GLRenderingContext): COMPAT_shader_texture_lod | null { export function getShaderTextureLod(gl: GLRenderingContext): COMPAT_shader_texture_lod | null {
return isWebGL2(gl) ? {} : gl.getExtension('EXT_shader_texture_lod') return isWebGL2(gl) ? {} : gl.getExtension('EXT_shader_texture_lod')
}
export interface COMPAT_depth_texture {
readonly UNSIGNED_INT_24_8: number;
}
export function getDepthTexture(gl: GLRenderingContext): COMPAT_depth_texture | null {
if(isWebGL2(gl)) {
return {
UNSIGNED_INT_24_8: gl.UNSIGNED_INT_24_8
}
} else {
const ext = gl.getExtension('WEBGL_depth_texture')
if (ext === null) return null
return {
UNSIGNED_INT_24_8: ext.UNSIGNED_INT_24_8_WEBGL
}
}
} }
\ No newline at end of file
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
import { createProgramCache, ProgramCache } from './program' import { createProgramCache, ProgramCache } from './program'
import { createShaderCache, ShaderCache } from './shader' import { createShaderCache, ShaderCache } from './shader'
import { GLRenderingContext, COMPAT_instanced_arrays, COMPAT_standard_derivatives, COMPAT_vertex_array_object, getInstancedArrays, getStandardDerivatives, getVertexArrayObject, isWebGL2, COMPAT_element_index_uint, getElementIndexUint, COMPAT_texture_float, getTextureFloat, COMPAT_texture_float_linear, getTextureFloatLinear, COMPAT_blend_minmax, getBlendMinMax, getFragDepth, COMPAT_frag_depth, COMPAT_color_buffer_float, getColorBufferFloat, COMPAT_draw_buffers, getDrawBuffers, getShaderTextureLod, COMPAT_shader_texture_lod } from './compat'; import { GLRenderingContext, COMPAT_instanced_arrays, COMPAT_standard_derivatives, COMPAT_vertex_array_object, getInstancedArrays, getStandardDerivatives, getVertexArrayObject, isWebGL2, COMPAT_element_index_uint, getElementIndexUint, COMPAT_texture_float, getTextureFloat, COMPAT_texture_float_linear, getTextureFloatLinear, COMPAT_blend_minmax, getBlendMinMax, getFragDepth, COMPAT_frag_depth, COMPAT_color_buffer_float, getColorBufferFloat, COMPAT_draw_buffers, getDrawBuffers, getShaderTextureLod, COMPAT_shader_texture_lod, getDepthTexture, COMPAT_depth_texture } from './compat';
import { createFramebufferCache, FramebufferCache, checkFramebufferStatus } from './framebuffer'; import { createFramebufferCache, FramebufferCache, checkFramebufferStatus } from './framebuffer';
import { Scheduler } from 'mol-task'; import { Scheduler } from 'mol-task';
import { isDebugMode } from 'mol-util/debug'; import { isDebugMode } from 'mol-util/debug';
...@@ -124,8 +124,10 @@ function readPixels(gl: GLRenderingContext, x: number, y: number, width: number, ...@@ -124,8 +124,10 @@ function readPixels(gl: GLRenderingContext, x: number, y: number, width: number,
if (isDebugMode) checkFramebufferStatus(gl) if (isDebugMode) checkFramebufferStatus(gl)
if (buffer instanceof Uint8Array) { if (buffer instanceof Uint8Array) {
gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buffer) gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buffer)
} else { } else if (buffer instanceof Float32Array) {
gl.readPixels(x, y, width, height, gl.RGBA, gl.FLOAT, buffer) gl.readPixels(x, y, width, height, gl.RGBA, gl.FLOAT, buffer)
} else {
throw new Error('unsupported readPixels buffer type')
} }
if (isDebugMode) checkError(gl) if (isDebugMode) checkError(gl)
} }
...@@ -153,7 +155,9 @@ export type WebGLExtensions = { ...@@ -153,7 +155,9 @@ export type WebGLExtensions = {
blendMinMax: COMPAT_blend_minmax blendMinMax: COMPAT_blend_minmax
textureFloat: COMPAT_texture_float textureFloat: COMPAT_texture_float
textureFloatLinear: COMPAT_texture_float_linear textureFloatLinear: COMPAT_texture_float_linear
elementIndexUint: COMPAT_element_index_uint | null elementIndexUint: COMPAT_element_index_uint
depthTexture: COMPAT_depth_texture
vertexArrayObject: COMPAT_vertex_array_object | null vertexArrayObject: COMPAT_vertex_array_object | null
fragDepth: COMPAT_frag_depth | null fragDepth: COMPAT_frag_depth | null
colorBufferFloat: COMPAT_color_buffer_float | null colorBufferFloat: COMPAT_color_buffer_float | null
...@@ -184,8 +188,13 @@ function createExtensions(gl: GLRenderingContext): WebGLExtensions { ...@@ -184,8 +188,13 @@ function createExtensions(gl: GLRenderingContext): WebGLExtensions {
} }
const elementIndexUint = getElementIndexUint(gl) const elementIndexUint = getElementIndexUint(gl)
if (elementIndexUint === null) { if (elementIndexUint === null) {
console.warn('Could not find support for "element_index_uint"') throw new Error('Could not find support for "element_index_uint"')
}
const depthTexture = getDepthTexture(gl)
if (depthTexture === null) {
throw new Error('Could not find support for "depth_texture"')
} }
const vertexArrayObject = getVertexArrayObject(gl) const vertexArrayObject = getVertexArrayObject(gl)
if (vertexArrayObject === null) { if (vertexArrayObject === null) {
console.log('Could not find support for "vertex_array_object"') console.log('Could not find support for "vertex_array_object"')
...@@ -207,7 +216,6 @@ function createExtensions(gl: GLRenderingContext): WebGLExtensions { ...@@ -207,7 +216,6 @@ function createExtensions(gl: GLRenderingContext): WebGLExtensions {
console.log('Could not find support for "shader_texture_lod"') console.log('Could not find support for "shader_texture_lod"')
} }
return { return {
instancedArrays, instancedArrays,
standardDerivatives, standardDerivatives,
...@@ -215,11 +223,13 @@ function createExtensions(gl: GLRenderingContext): WebGLExtensions { ...@@ -215,11 +223,13 @@ function createExtensions(gl: GLRenderingContext): WebGLExtensions {
textureFloat, textureFloat,
textureFloatLinear, textureFloatLinear,
elementIndexUint, elementIndexUint,
depthTexture,
vertexArrayObject, vertexArrayObject,
fragDepth, fragDepth,
colorBufferFloat, colorBufferFloat,
drawBuffers, drawBuffers,
shaderTextureLod shaderTextureLod,
} }
} }
......
/** /**
* Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
* *
* @author Alexander Rose <alexander.rose@weirdbyte.de> * @author Alexander Rose <alexander.rose@weirdbyte.de>
*/ */
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
import { WebGLContext, createImageData } from './context' import { WebGLContext, createImageData } from './context'
import { idFactory } from 'mol-util/id-factory'; import { idFactory } from 'mol-util/id-factory';
import { createTexture, Texture } from './texture'; import { createTexture, Texture } from './texture';
import { createFramebuffer } from './framebuffer'; import { createFramebuffer, Framebuffer } from './framebuffer';
import { createRenderbuffer } from './renderbuffer'; import { createRenderbuffer } from './renderbuffer';
import { TextureImage } from '../renderable/util'; import { TextureImage } from '../renderable/util';
import { Mutable } from 'mol-util/type-helpers'; import { Mutable } from 'mol-util/type-helpers';
...@@ -20,6 +20,7 @@ export interface RenderTarget { ...@@ -20,6 +20,7 @@ export interface RenderTarget {
readonly height: number readonly height: number
readonly image: TextureImage<any> readonly image: TextureImage<any>
readonly texture: Texture readonly texture: Texture
readonly framebuffer: Framebuffer
/** binds framebuffer and sets viewport to rendertarget's width and height */ /** binds framebuffer and sets viewport to rendertarget's width and height */
bind: () => void bind: () => void
...@@ -30,7 +31,7 @@ export interface RenderTarget { ...@@ -30,7 +31,7 @@ export interface RenderTarget {
destroy: () => void destroy: () => void
} }
export function createRenderTarget (ctx: WebGLContext, _width: number, _height: number): RenderTarget { export function createRenderTarget (ctx: WebGLContext, _width: number, _height: number, enableDepthTexture: boolean = false): RenderTarget {
const { gl, stats } = ctx const { gl, stats } = ctx
const image: Mutable<TextureImage<Uint8Array>> = { const image: Mutable<TextureImage<Uint8Array>> = {
...@@ -68,6 +69,7 @@ export function createRenderTarget (ctx: WebGLContext, _width: number, _height: ...@@ -68,6 +69,7 @@ export function createRenderTarget (ctx: WebGLContext, _width: number, _height:
get height () { return _height }, get height () { return _height },
image, image,
texture: targetTexture, texture: targetTexture,
framebuffer,
bind: () => { bind: () => {
framebuffer.bind() framebuffer.bind()
...@@ -80,7 +82,6 @@ export function createRenderTarget (ctx: WebGLContext, _width: number, _height: ...@@ -80,7 +82,6 @@ export function createRenderTarget (ctx: WebGLContext, _width: number, _height:
image.width = _width image.width = _width
image.height = _height image.height = _height
targetTexture.load(image) targetTexture.load(image)
depthRenderbuffer.setSize(_width, _height) depthRenderbuffer.setSize(_width, _height)
}, },
readBuffer, readBuffer,
......
...@@ -18,14 +18,15 @@ const getNextTextureId = idFactory() ...@@ -18,14 +18,15 @@ const getNextTextureId = idFactory()
export type TextureKindValue = { export type TextureKindValue = {
'image-uint8': TextureImage<Uint8Array> 'image-uint8': TextureImage<Uint8Array>
'image-float32': TextureImage<Float32Array> 'image-float32': TextureImage<Float32Array>
'image-depth': TextureImage<Uint8Array> // TODO should be Uint32Array
'volume-uint8': TextureVolume<Uint8Array> 'volume-uint8': TextureVolume<Uint8Array>
'volume-float32': TextureVolume<Float32Array> 'volume-float32': TextureVolume<Float32Array>
'texture': Texture 'texture': Texture
} }
export type TextureValueType = ValueOf<TextureKindValue> export type TextureValueType = ValueOf<TextureKindValue>
export type TextureKind = keyof TextureKindValue export type TextureKind = keyof TextureKindValue
export type TextureType = 'ubyte' | 'float' export type TextureType = 'ubyte' | 'ushort' | 'float'
export type TextureFormat = 'alpha' | 'rgb' | 'rgba' export type TextureFormat = 'alpha' | 'rgb' | 'rgba' | 'depth'
/** Numbers are shortcuts for color attachment */ /** Numbers are shortcuts for color attachment */
export type TextureAttachment = 'depth' | 'stencil' | 'color0' | 'color1' | 'color2' | 'color3' | 'color4' | 'color5' | 'color6' | 'color7' | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 export type TextureAttachment = 'depth' | 'stencil' | 'color0' | 'color1' | 'color2' | 'color3' | 'color4' | 'color5' | 'color6' | 'color7' | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
export type TextureFilter = 'nearest' | 'linear' export type TextureFilter = 'nearest' | 'linear'
...@@ -35,6 +36,7 @@ export function getTarget(ctx: WebGLContext, kind: TextureKind): number { ...@@ -35,6 +36,7 @@ export function getTarget(ctx: WebGLContext, kind: TextureKind): number {
switch (kind) { switch (kind) {
case 'image-uint8': return gl.TEXTURE_2D case 'image-uint8': return gl.TEXTURE_2D
case 'image-float32': return gl.TEXTURE_2D case 'image-float32': return gl.TEXTURE_2D
case 'image-depth': return gl.TEXTURE_2D
} }
if (isWebGL2(gl)) { if (isWebGL2(gl)) {
switch (kind) { switch (kind) {
...@@ -49,10 +51,11 @@ export function getFormat(ctx: WebGLContext, format: TextureFormat, type: Textur ...@@ -49,10 +51,11 @@ export function getFormat(ctx: WebGLContext, format: TextureFormat, type: Textur
const { gl } = ctx const { gl } = ctx
switch (format) { switch (format) {
case 'alpha': case 'alpha':
if (isWebGL2 && type === 'float') return (gl as WebGL2RenderingContext).RED if (isWebGL2(gl) && type === 'float') return gl.RED
else return gl.ALPHA else return gl.ALPHA
case 'rgb': return gl.RGB case 'rgb': return gl.RGB
case 'rgba': return gl.RGBA case 'rgba': return gl.RGBA
case 'depth': return gl.DEPTH_COMPONENT
} }
} }
...@@ -75,6 +78,8 @@ export function getInternalFormat(ctx: WebGLContext, format: TextureFormat, type ...@@ -75,6 +78,8 @@ export function getInternalFormat(ctx: WebGLContext, format: TextureFormat, type
case 'ubyte': return gl.RGBA case 'ubyte': return gl.RGBA
case 'float': return gl.RGBA32F case 'float': return gl.RGBA32F
} }
case 'depth':
return gl.DEPTH_COMPONENT16
} }
} }
return getFormat(ctx, format, type) return getFormat(ctx, format, type)
...@@ -84,6 +89,7 @@ export function getType(ctx: WebGLContext, type: TextureType): number { ...@@ -84,6 +89,7 @@ export function getType(ctx: WebGLContext, type: TextureType): number {
const { gl } = ctx const { gl } = ctx
switch (type) { switch (type) {
case 'ubyte': return gl.UNSIGNED_BYTE case 'ubyte': return gl.UNSIGNED_BYTE
case 'ushort': return gl.UNSIGNED_SHORT
case 'float': return gl.FLOAT case 'float': return gl.FLOAT
} }
} }
...@@ -152,7 +158,11 @@ export function createTexture(ctx: WebGLContext, kind: TextureKind, _format: Tex ...@@ -152,7 +158,11 @@ export function createTexture(ctx: WebGLContext, kind: TextureKind, _format: Tex
} }
// check texture kind and type compatability // check texture kind and type compatability
if ((kind.endsWith('float32') && _type !== 'float') || kind.endsWith('uint8') && _type !== 'ubyte') { if (
(kind.endsWith('float32') && _type !== 'float') ||
(kind.endsWith('uint8') && _type !== 'ubyte') ||
(kind.endsWith('depth') && _type !== 'ushort')
) {
throw new Error(`texture kind '${kind}' and type '${_type}' are incompatible`) throw new Error(`texture kind '${kind}' and type '${_type}' are incompatible`)
} }
...@@ -226,19 +236,23 @@ export function createTexture(ctx: WebGLContext, kind: TextureKind, _format: Tex ...@@ -226,19 +236,23 @@ export function createTexture(ctx: WebGLContext, kind: TextureKind, _format: Tex
}, },
attachFramebuffer: (framebuffer: Framebuffer, attachment: TextureAttachment, layer?: number) => { attachFramebuffer: (framebuffer: Framebuffer, attachment: TextureAttachment, layer?: number) => {
framebuffer.bind() framebuffer.bind()
if (target === (gl as WebGL2RenderingContext).TEXTURE_3D) { if (target === gl.TEXTURE_2D) {
if (layer === undefined) throw new Error('need `layer` to attach 3D texture');
(gl as WebGL2RenderingContext).framebufferTextureLayer(gl.FRAMEBUFFER, getAttachment(ctx, attachment), texture, 0, layer)
} else {
gl.framebufferTexture2D(gl.FRAMEBUFFER, getAttachment(ctx, attachment), gl.TEXTURE_2D, texture, 0) gl.framebufferTexture2D(gl.FRAMEBUFFER, getAttachment(ctx, attachment), gl.TEXTURE_2D, texture, 0)
} else if (isWebGL2(gl) && target === gl.TEXTURE_3D) {
if (layer === undefined) throw new Error('need `layer` to attach 3D texture')
gl.framebufferTextureLayer(gl.FRAMEBUFFER, getAttachment(ctx, attachment), texture, 0, layer)
} else {
throw new Error('unknown texture target')
} }
}, },
detachFramebuffer: (framebuffer: Framebuffer, attachment: TextureAttachment) => { detachFramebuffer: (framebuffer: Framebuffer, attachment: TextureAttachment) => {
framebuffer.bind() framebuffer.bind()
if (target === (gl as WebGL2RenderingContext).TEXTURE_3D) { if (target === gl.TEXTURE_2D) {
(gl as WebGL2RenderingContext).framebufferTextureLayer(gl.FRAMEBUFFER, getAttachment(ctx, attachment), null, 0, 0)
} else {
gl.framebufferTexture2D(gl.FRAMEBUFFER, getAttachment(ctx, attachment), gl.TEXTURE_2D, null, 0) gl.framebufferTexture2D(gl.FRAMEBUFFER, getAttachment(ctx, attachment), gl.TEXTURE_2D, null, 0)
} else if (isWebGL2(gl) && target === gl.TEXTURE_3D) {
gl.framebufferTextureLayer(gl.FRAMEBUFFER, getAttachment(ctx, attachment), null, 0, 0)
} else {
throw new Error('unknown texture target')
} }
}, },
destroy: () => { destroy: () => {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment