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';
import { defaults, ValueCell } from 'mol-util';
import { ValueSpec, AttributeSpec, UniformSpec, Values } from 'mol-gl/renderable/schema';
import { Vec2 } from 'mol-math/linear-algebra';
import { GLRenderingContext } from 'mol-gl/webgl/compat';
export const QuadPositions = new Float32Array([
1.0, 1.0, -1.0, 1.0, -1.0, -1.0, // First triangle
......@@ -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) {
const { gl, framebufferCache } = ctx
width = defaults(width, texture.width)
height = defaults(height, texture.height)
const size = width * height * 4
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()
texture.attachFramebuffer(framebuffer, 0)
ctx.readPixels(0, 0, width, height, array)
......
......@@ -47,6 +47,7 @@ export type KindValue = {
'image-uint8': TextureImage<Uint8Array>
'image-float32': TextureImage<Float32Array>
'image-depth': TextureImage<Uint8Array> // TODO should be Uint32Array
'volume-uint8': TextureVolume<Uint8Array>
'volume-float32': TextureVolume<Float32Array>
'texture': Texture
......
......@@ -220,4 +220,22 @@ export interface COMPAT_shader_texture_lod {
export function getShaderTextureLod(gl: GLRenderingContext): COMPAT_shader_texture_lod | null {
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 @@
import { createProgramCache, ProgramCache } from './program'
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 { Scheduler } from 'mol-task';
import { isDebugMode } from 'mol-util/debug';
......@@ -124,8 +124,10 @@ function readPixels(gl: GLRenderingContext, x: number, y: number, width: number,
if (isDebugMode) checkFramebufferStatus(gl)
if (buffer instanceof Uint8Array) {
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)
} else {
throw new Error('unsupported readPixels buffer type')
}
if (isDebugMode) checkError(gl)
}
......@@ -153,7 +155,9 @@ export type WebGLExtensions = {
blendMinMax: COMPAT_blend_minmax
textureFloat: COMPAT_texture_float
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
fragDepth: COMPAT_frag_depth | null
colorBufferFloat: COMPAT_color_buffer_float | null
......@@ -184,8 +188,13 @@ function createExtensions(gl: GLRenderingContext): WebGLExtensions {
}
const elementIndexUint = getElementIndexUint(gl)
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)
if (vertexArrayObject === null) {
console.log('Could not find support for "vertex_array_object"')
......@@ -207,7 +216,6 @@ function createExtensions(gl: GLRenderingContext): WebGLExtensions {
console.log('Could not find support for "shader_texture_lod"')
}
return {
instancedArrays,
standardDerivatives,
......@@ -215,11 +223,13 @@ function createExtensions(gl: GLRenderingContext): WebGLExtensions {
textureFloat,
textureFloatLinear,
elementIndexUint,
depthTexture,
vertexArrayObject,
fragDepth,
colorBufferFloat,
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>
*/
......@@ -7,7 +7,7 @@
import { WebGLContext, createImageData } from './context'
import { idFactory } from 'mol-util/id-factory';
import { createTexture, Texture } from './texture';
import { createFramebuffer } from './framebuffer';
import { createFramebuffer, Framebuffer } from './framebuffer';
import { createRenderbuffer } from './renderbuffer';
import { TextureImage } from '../renderable/util';
import { Mutable } from 'mol-util/type-helpers';
......@@ -20,6 +20,7 @@ export interface RenderTarget {
readonly height: number
readonly image: TextureImage<any>
readonly texture: Texture
readonly framebuffer: Framebuffer
/** binds framebuffer and sets viewport to rendertarget's width and height */
bind: () => void
......@@ -30,7 +31,7 @@ export interface RenderTarget {
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 image: Mutable<TextureImage<Uint8Array>> = {
......@@ -68,6 +69,7 @@ export function createRenderTarget (ctx: WebGLContext, _width: number, _height:
get height () { return _height },
image,
texture: targetTexture,
framebuffer,
bind: () => {
framebuffer.bind()
......@@ -80,7 +82,6 @@ export function createRenderTarget (ctx: WebGLContext, _width: number, _height:
image.width = _width
image.height = _height
targetTexture.load(image)
depthRenderbuffer.setSize(_width, _height)
},
readBuffer,
......
......@@ -18,14 +18,15 @@ const getNextTextureId = idFactory()
export type TextureKindValue = {
'image-uint8': TextureImage<Uint8Array>
'image-float32': TextureImage<Float32Array>
'image-depth': TextureImage<Uint8Array> // TODO should be Uint32Array
'volume-uint8': TextureVolume<Uint8Array>
'volume-float32': TextureVolume<Float32Array>
'texture': Texture
}
export type TextureValueType = ValueOf<TextureKindValue>
export type TextureKind = keyof TextureKindValue
export type TextureType = 'ubyte' | 'float'
export type TextureFormat = 'alpha' | 'rgb' | 'rgba'
export type TextureType = 'ubyte' | 'ushort' | 'float'
export type TextureFormat = 'alpha' | 'rgb' | 'rgba' | 'depth'
/** 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 TextureFilter = 'nearest' | 'linear'
......@@ -35,6 +36,7 @@ export function getTarget(ctx: WebGLContext, kind: TextureKind): number {
switch (kind) {
case 'image-uint8': return gl.TEXTURE_2D
case 'image-float32': return gl.TEXTURE_2D
case 'image-depth': return gl.TEXTURE_2D
}
if (isWebGL2(gl)) {
switch (kind) {
......@@ -49,10 +51,11 @@ export function getFormat(ctx: WebGLContext, format: TextureFormat, type: Textur
const { gl } = ctx
switch (format) {
case 'alpha':
if (isWebGL2 && type === 'float') return (gl as WebGL2RenderingContext).RED
if (isWebGL2(gl) && type === 'float') return gl.RED
else return gl.ALPHA
case 'rgb': return gl.RGB
case 'rgba': return gl.RGBA
case 'depth': return gl.DEPTH_COMPONENT
}
}
......@@ -75,6 +78,8 @@ export function getInternalFormat(ctx: WebGLContext, format: TextureFormat, type
case 'ubyte': return gl.RGBA
case 'float': return gl.RGBA32F
}
case 'depth':
return gl.DEPTH_COMPONENT16
}
}
return getFormat(ctx, format, type)
......@@ -84,6 +89,7 @@ export function getType(ctx: WebGLContext, type: TextureType): number {
const { gl } = ctx
switch (type) {
case 'ubyte': return gl.UNSIGNED_BYTE
case 'ushort': return gl.UNSIGNED_SHORT
case 'float': return gl.FLOAT
}
}
......@@ -152,7 +158,11 @@ export function createTexture(ctx: WebGLContext, kind: TextureKind, _format: Tex
}
// 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`)
}
......@@ -226,19 +236,23 @@ export function createTexture(ctx: WebGLContext, kind: TextureKind, _format: Tex
},
attachFramebuffer: (framebuffer: Framebuffer, attachment: TextureAttachment, layer?: number) => {
framebuffer.bind()
if (target === (gl as WebGL2RenderingContext).TEXTURE_3D) {
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 {
if (target === gl.TEXTURE_2D) {
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) => {
framebuffer.bind()
if (target === (gl as WebGL2RenderingContext).TEXTURE_3D) {
(gl as WebGL2RenderingContext).framebufferTextureLayer(gl.FRAMEBUFFER, getAttachment(ctx, attachment), null, 0, 0)
} else {
if (target === gl.TEXTURE_2D) {
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: () => {
......
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