|
@@ -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: () => {
|