From 515ebbe5c2e78910502178251b9f8e29afab9ade Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 24 Jun 2020 20:14:57 -0400 Subject: [PATCH] feat: simplify framebuffer attachment creation --- .../10_renderToTexture/index.ts | 20 ++---- .../gettingstarted/11_depthTexture/index.ts | 30 ++------- .../renderers/webgl/extensions/Extensions.ts | 28 ++++---- .../webgl/extensions/OptionalExtensions.ts | 14 ---- .../webgl/framebuffers/Attachment.ts | 65 +++++++++++++++++++ .../webgl/framebuffers/Framebuffer.ts | 5 +- .../webgl/framebuffers/VirtualFramebuffer.ts | 8 +-- .../renderers/webgl/textures/TexImage2D.ts | 47 -------------- 8 files changed, 97 insertions(+), 120 deletions(-) create mode 100644 src/lib/renderers/webgl/framebuffers/Attachment.ts diff --git a/src/examples/gettingstarted/10_renderToTexture/index.ts b/src/examples/gettingstarted/10_renderToTexture/index.ts index 9c9ccf3d..282ea307 100644 --- a/src/examples/gettingstarted/10_renderToTexture/index.ts +++ b/src/examples/gettingstarted/10_renderToTexture/index.ts @@ -12,17 +12,12 @@ import { Vector3 } from "../../../lib/math/Vector3"; import { makeBufferGeometryFromGeometry } from "../../../lib/renderers/webgl/buffers/BufferGeometry"; import { ClearState } from "../../../lib/renderers/webgl/ClearState"; import { DepthTestFunc, DepthTestState } from "../../../lib/renderers/webgl/DepthTestState"; +import { makeColorAttachment } from "../../../lib/renderers/webgl/framebuffers/Attachment"; import { AttachmentBits } from "../../../lib/renderers/webgl/framebuffers/AttachmentBits"; -import { AttachmentPoint } from "../../../lib/renderers/webgl/framebuffers/AttachmentPoint"; import { Framebuffer } from "../../../lib/renderers/webgl/framebuffers/Framebuffer"; -import { FramebufferAttachment } from "../../../lib/renderers/webgl/framebuffers/VirtualFramebuffer"; import { makeProgramFromShaderMaterial } from "../../../lib/renderers/webgl/programs/Program"; import { RenderingContext } from "../../../lib/renderers/webgl/RenderingContext"; -import { DataType } from "../../../lib/renderers/webgl/textures/DataType"; -import { - makeFramebufferAttachmentTexImage2D, - makeTexImage2DFromTexture, -} from "../../../lib/renderers/webgl/textures/TexImage2D"; +import { makeTexImage2DFromTexture } from "../../../lib/renderers/webgl/textures/TexImage2D"; import { fetchImage } from "../../../lib/textures/loaders/Image"; import { Texture } from "../../../lib/textures/Texture"; import fragmentSourceCode from "./fragment.glsl"; @@ -40,13 +35,8 @@ async function init(): Promise { document.body.appendChild(canvas); } - const colorRenderTexture = makeFramebufferAttachmentTexImage2D( - context, - new Vector2(1024, 1024), - AttachmentPoint.Color0, - DataType.UnsignedByte, - ); - const framebuffer = new Framebuffer(context, [new FramebufferAttachment(AttachmentPoint.Color0, colorRenderTexture)]); + const colorAttachment = makeColorAttachment(context, new Vector2(1024, 1024), 0); + const framebuffer = new Framebuffer(context, [colorAttachment]); const program = makeProgramFromShaderMaterial(context, material); const uvTestTexture = makeTexImage2DFromTexture(context, texture); @@ -74,7 +64,7 @@ async function init(): Promise { framebuffer.clear(AttachmentBits.All, whiteClearState); framebuffer.renderBufferGeometry(program, uniforms, bufferGeometry, depthTestState); - uniforms.map = colorRenderTexture; + uniforms.map = colorAttachment.texImage2D; canvasFramebuffer.clear(AttachmentBits.All, whiteClearState); canvasFramebuffer.renderBufferGeometry(program, uniforms, bufferGeometry, depthTestState); } diff --git a/src/examples/gettingstarted/11_depthTexture/index.ts b/src/examples/gettingstarted/11_depthTexture/index.ts index 1a57078d..df51058c 100644 --- a/src/examples/gettingstarted/11_depthTexture/index.ts +++ b/src/examples/gettingstarted/11_depthTexture/index.ts @@ -12,17 +12,12 @@ import { Vector3 } from "../../../lib/math/Vector3"; import { makeBufferGeometryFromGeometry } from "../../../lib/renderers/webgl/buffers/BufferGeometry"; import { ClearState } from "../../../lib/renderers/webgl/ClearState"; import { DepthTestFunc, DepthTestState } from "../../../lib/renderers/webgl/DepthTestState"; +import { makeColorAttachment, makeDepthAttachment } from "../../../lib/renderers/webgl/framebuffers/Attachment"; import { AttachmentBits } from "../../../lib/renderers/webgl/framebuffers/AttachmentBits"; -import { AttachmentPoint } from "../../../lib/renderers/webgl/framebuffers/AttachmentPoint"; import { Framebuffer } from "../../../lib/renderers/webgl/framebuffers/Framebuffer"; -import { FramebufferAttachment } from "../../../lib/renderers/webgl/framebuffers/VirtualFramebuffer"; import { makeProgramFromShaderMaterial } from "../../../lib/renderers/webgl/programs/Program"; import { RenderingContext } from "../../../lib/renderers/webgl/RenderingContext"; -import { DataType } from "../../../lib/renderers/webgl/textures/DataType"; -import { - makeFramebufferAttachmentTexImage2D, - makeTexImage2DFromTexture, -} from "../../../lib/renderers/webgl/textures/TexImage2D"; +import { makeTexImage2DFromTexture } from "../../../lib/renderers/webgl/textures/TexImage2D"; import { fetchImage } from "../../../lib/textures/loaders/Image"; import { Texture } from "../../../lib/textures/Texture"; import fragmentSourceCode from "./fragment.glsl"; @@ -40,21 +35,10 @@ async function init(): Promise { document.body.appendChild(canvas); } - const colorRenderTexture = makeFramebufferAttachmentTexImage2D( - context, - new Vector2(1024, 1024), - AttachmentPoint.Color0, - DataType.UnsignedByte, - ); - const depthRenderTexture = makeFramebufferAttachmentTexImage2D( - context, - new Vector2(1024, 1024), - AttachmentPoint.Depth, - ); - const framebuffer = new Framebuffer(context, [ - new FramebufferAttachment(AttachmentPoint.Color0, colorRenderTexture), - new FramebufferAttachment(AttachmentPoint.Depth, depthRenderTexture), - ]); + const framebufferSize = new Vector2(1024, 1024); + const colorAttachment = makeColorAttachment(context, framebufferSize, 0); + const depthAttachment = makeDepthAttachment(context, framebufferSize); + const framebuffer = new Framebuffer(context, [colorAttachment, depthAttachment]); const program = makeProgramFromShaderMaterial(context, material); const uvTestTexture = makeTexImage2DFromTexture(context, texture); @@ -82,7 +66,7 @@ async function init(): Promise { framebuffer.clear(AttachmentBits.All, whiteClearState); framebuffer.renderBufferGeometry(program, uniforms, bufferGeometry, depthTestState); - uniforms.map = depthRenderTexture; + uniforms.map = depthAttachment.texImage2D; canvasFramebuffer.clear(AttachmentBits.All, whiteClearState); canvasFramebuffer.renderBufferGeometry(program, uniforms, bufferGeometry, depthTestState); } diff --git a/src/lib/renderers/webgl/extensions/Extensions.ts b/src/lib/renderers/webgl/extensions/Extensions.ts index 82b54f00..c92a715c 100644 --- a/src/lib/renderers/webgl/extensions/Extensions.ts +++ b/src/lib/renderers/webgl/extensions/Extensions.ts @@ -1,43 +1,45 @@ +// TODO: uncomment the extensions once support is added for them in core. + /* eslint-disable @typescript-eslint/naming-convention */ export class Extensions { - ANGLE_instance_array: ANGLE_instanced_arrays; - EXT_blend_minmax: EXT_blend_minmax; + // ANGLE_instance_array: ANGLE_instanced_arrays; + // EXT_blend_minmax: EXT_blend_minmax; OES_element_index_uint: OES_element_index_uint; OES_standard_derivatives: OES_standard_derivatives; - WEBGL_depth_texture: WEBGL_depth_texture; - WEBGL_lose_context: WEBGL_lose_context; OES_vertex_array_object: OES_vertex_array_object; + // WEBGL_lose_context: WEBGL_lose_context; + WEBGL_depth_texture: WEBGL_depth_texture; EXT_shader_texture_lod: EXT_shader_texture_lod; constructor(gl: WebGLRenderingContext) { - const ia = gl.getExtension("ANGLE_instanced_arrays"); // 98% support - const bm = gl.getExtension("EXT_blend_minmax"); // 98% support + // const ia = gl.getExtension("ANGLE_instanced_arrays"); // 98% support + // const bm = gl.getExtension("EXT_blend_minmax"); // 98% support const eiu = gl.getExtension("OES_element_index_uint"); // 98% support const sd = gl.getExtension("OES_standard_derivatives"); // 100% support const vao = gl.getExtension("OES_vertex_array_object"); // 98% support - const lc = gl.getExtension("WEBGL_lose_context"); // 98% support + // const lc = gl.getExtension("WEBGL_lose_context"); // 98% support const dt = gl.getExtension("WEBGL_depth_texture"); // 91% support const stl = gl.getExtension("EXT_shader_texture_lod"); // <80% support if ( - ia === null || - bm === null || + // ia === null || + // bm === null || eiu === null || sd === null || vao === null || - lc === null || + // lc === null || dt === null || stl === null ) { throw new Error("required extension(s) not supported"); } - this.ANGLE_instance_array = ia; - this.EXT_blend_minmax = bm; + // this.ANGLE_instance_array = ia; + // this.EXT_blend_minmax = bm; this.OES_element_index_uint = eiu; this.OES_standard_derivatives = sd; this.OES_vertex_array_object = vao; - this.WEBGL_lose_context = lc; + // this.WEBGL_lose_context = lc; this.WEBGL_depth_texture = dt; this.EXT_shader_texture_lod = stl; // TODO: maybe make this one optional at some point? } diff --git a/src/lib/renderers/webgl/extensions/OptionalExtensions.ts b/src/lib/renderers/webgl/extensions/OptionalExtensions.ts index 723b00d2..08951da4 100644 --- a/src/lib/renderers/webgl/extensions/OptionalExtensions.ts +++ b/src/lib/renderers/webgl/extensions/OptionalExtensions.ts @@ -2,33 +2,19 @@ /* eslint-disable @typescript-eslint/naming-convention */ export class OptionalExtensions { - // https://developer.mozilla.org/en-US/docs/Web/API/EXT_frag_depth // EXT_frag_depth: EXT_frag_depth | null; - // https://developer.mozilla.org/en-US/docs/Web/API/EXT_sRGB // EXT_sRGB: EXT_sRGB | null; - // https://developer.mozilla.org/en-US/docs/Web/API/EXT_texture_filter_anisotropic EXT_texture_filter_anisotropic: EXT_texture_filter_anisotropic | null; - // https://developer.mozilla.org/en-US/docs/Web/API/OES_texture_float // OES_texture_float: OES_texture_float | null; - // https://developer.mozilla.org/en-US/docs/Web/API/OES_texture_float_linear // OES_texture_float_linear: OES_texture_float_linear | null; - // https://developer.mozilla.org/en-US/docs/Web/API/OES_texture_half_float // OES_texture_half_float: OES_texture_half_float | null; - // https://developer.mozilla.org/en-US/docs/Web/API/OES_texture_half_float_linear // OES_texture_half_float_linear: OES_texture_half_float_linear | null; - // https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_color_buffer_float // WEBGL_color_buffer_float: WEBGL_color_buffer_float | null; - // https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_debug_renderer_info WEBGL_debug_renderer_info: WEBGL_debug_renderer_info | null; - // https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_debug_shaders WEBGL_debug_shaders: WEBGL_debug_shaders | null; - // https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_draw_buffers // WEBGL_draw_buffers: WEBGL_draw_buffers | null; - // https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_compressed_texture_astc // WEBGL_compressed_texture_astc: WEBGL_compressed_texture_astc | null; - // https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_compressed_texture_s3tc // WEBGL_compressed_texture_s3tc: WEBGL_compressed_texture_s3tc | null; - // https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_compressed_texture_s3tc_srgb // WEBGL_compressed_texture_s3tc_srgb: WEBGL_compressed_texture_s3tc_srgb | null; constructor(gl: WebGLRenderingContext) { diff --git a/src/lib/renderers/webgl/framebuffers/Attachment.ts b/src/lib/renderers/webgl/framebuffers/Attachment.ts new file mode 100644 index 00000000..f6a47724 --- /dev/null +++ b/src/lib/renderers/webgl/framebuffers/Attachment.ts @@ -0,0 +1,65 @@ +import { Vector2 } from "../../../math/Vector2"; +import { RenderingContext } from "../RenderingContext"; +import { DataType } from "../textures/DataType"; +import { PixelFormat } from "../textures/PixelFormat"; +import { TexImage2D } from "../textures/TexImage2D"; +import { TexParameters } from "../textures/TexParameters"; +import { TextureFilter } from "../textures/TextureFilter"; +import { TextureTarget } from "../textures/TextureTarget"; +import { AttachmentPoint } from "./AttachmentPoint"; + +export class Attachment { + constructor(public attachmentPoint: number, public texImage2D: TexImage2D) {} +} + +export function makeColorAttachment( + context: RenderingContext, + size: Vector2, + attachmentOffset: number, + dataType: DataType | undefined = undefined, +): Attachment { + const texParams = new TexParameters(); + texParams.generateMipmaps = false; + texParams.magFilter = TextureFilter.Linear; + texParams.minFilter = TextureFilter.Linear; + return new Attachment( + AttachmentPoint.Color0 + attachmentOffset, + new TexImage2D( + context, + [], + size, + 0, + PixelFormat.RGBA, + dataType ?? DataType.UnsignedByte, + PixelFormat.RGBA, + TextureTarget.Texture2D, + texParams, + ), + ); +} + +export function makeDepthAttachment(context: RenderingContext, size: Vector2): Attachment { + const texParams = new TexParameters(); + texParams.generateMipmaps = false; + texParams.magFilter = TextureFilter.Nearest; + texParams.minFilter = TextureFilter.Nearest; + + // TODO: figure out which are supported and choose one of those. + // context.glx.WEBGL_depth_texture.UNSIGNED_INT_24_8_WEBGL as DataType, + const dataType = DataType.UnsignedShort; + + return new Attachment( + AttachmentPoint.Depth, + new TexImage2D( + context, + [], + size, + 0, + PixelFormat.DepthComponent, + dataType, + PixelFormat.DepthComponent, + TextureTarget.Texture2D, + texParams, + ), + ); +} diff --git a/src/lib/renderers/webgl/framebuffers/Framebuffer.ts b/src/lib/renderers/webgl/framebuffers/Framebuffer.ts index 17493e8b..2d90ad07 100644 --- a/src/lib/renderers/webgl/framebuffers/Framebuffer.ts +++ b/src/lib/renderers/webgl/framebuffers/Framebuffer.ts @@ -8,13 +8,14 @@ import { Vector2 } from "../../../math/Vector2"; import { GL } from "../GL"; import { RenderingContext } from "../RenderingContext"; -import { FramebufferAttachment, VirtualFramebuffer } from "./VirtualFramebuffer"; +import { Attachment } from "./Attachment"; +import { VirtualFramebuffer } from "./VirtualFramebuffer"; export class Framebuffer extends VirtualFramebuffer { readonly glFramebuffer: WebGLFramebuffer; readonly #size: Vector2 = new Vector2(); - constructor(context: RenderingContext, attachments: Array = []) { + constructor(context: RenderingContext, attachments: Array = []) { super(context, attachments); const gl = this.context.gl; diff --git a/src/lib/renderers/webgl/framebuffers/VirtualFramebuffer.ts b/src/lib/renderers/webgl/framebuffers/VirtualFramebuffer.ts index 94e9837f..11a283e6 100644 --- a/src/lib/renderers/webgl/framebuffers/VirtualFramebuffer.ts +++ b/src/lib/renderers/webgl/framebuffers/VirtualFramebuffer.ts @@ -20,17 +20,13 @@ import { UniformValueMap } from "../programs/ProgramUniform"; import { RenderingContext } from "../RenderingContext"; import { sizeOfDataType } from "../textures/DataType"; import { numPixelFormatComponents, PixelFormat } from "../textures/PixelFormat"; -import { TexImage2D } from "../textures/TexImage2D"; import { VertexArrayObject } from "../VertexArrayObject"; +import { Attachment } from "./Attachment"; import { AttachmentBits } from "./AttachmentBits"; import { AttachmentPoint } from "./AttachmentPoint"; const GL = WebGLRenderingContext; -export class FramebufferAttachment { - constructor(public attachmentPoint: number, public texImage2D: TexImage2D) {} -} - export abstract class VirtualFramebuffer implements IDisposable { disposed = false; public clearState: ClearState | undefined = undefined; @@ -39,7 +35,7 @@ export abstract class VirtualFramebuffer implements IDisposable { public maskState: MaskState | undefined = undefined; public viewport: Box2 | undefined = undefined; - constructor(public context: RenderingContext, public attachments: Array = []) {} + constructor(public context: RenderingContext, public attachments: Array = []) {} abstract get size(): Vector2; diff --git a/src/lib/renderers/webgl/textures/TexImage2D.ts b/src/lib/renderers/webgl/textures/TexImage2D.ts index 759b9876..69084cb0 100644 --- a/src/lib/renderers/webgl/textures/TexImage2D.ts +++ b/src/lib/renderers/webgl/textures/TexImage2D.ts @@ -12,13 +12,11 @@ import { ArrayBufferImage } from "../../../textures/ArrayBufferImage"; import { CubeTexture } from "../../../textures/CubeTexture"; import { Texture, TextureImage } from "../../../textures/Texture"; import { Pool } from "../../Pool"; -import { AttachmentPoint } from "../framebuffers/AttachmentPoint"; import { GL } from "../GL"; import { RenderingContext } from "../RenderingContext"; import { DataType } from "./DataType"; import { PixelFormat } from "./PixelFormat"; import { TexParameters } from "./TexParameters"; -import { TextureFilter } from "./TextureFilter"; import { TextureTarget } from "./TextureTarget"; export class TexImage2D implements IDisposable { @@ -186,48 +184,3 @@ export class TexImage2DPool extends Pool { }); } } - -export function makeFramebufferAttachmentTexImage2D( - context: RenderingContext, - size: Vector2, - attachmentPoint: AttachmentPoint, - dataType: DataType | undefined = undefined, -): TexImage2D { - if (attachmentPoint === AttachmentPoint.Color0) { - const texParams = new TexParameters(); - texParams.generateMipmaps = false; - texParams.magFilter = TextureFilter.Linear; - texParams.minFilter = TextureFilter.Linear; - return new TexImage2D( - context, - [], - size, - 0, - PixelFormat.RGBA, - dataType ?? DataType.UnsignedByte, - PixelFormat.RGBA, - TextureTarget.Texture2D, - texParams, - ); - } - if (attachmentPoint === AttachmentPoint.Depth) { - const texParams = new TexParameters(); - texParams.generateMipmaps = false; - texParams.magFilter = TextureFilter.Nearest; - texParams.minFilter = TextureFilter.Nearest; - return new TexImage2D( - context, - [], - size, - 0, - PixelFormat.DepthComponent, - DataType.UnsignedShort, // context.glx.WEBGL_depth_texture.UNSIGNED_INT_24_8_WEBGL as DataType, - PixelFormat.DepthComponent, - TextureTarget.Texture2D, - texParams, - ); - - // gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT, 512, 512, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_SHORT, null); - } - throw new Error("unsupported attachment point"); -}