Kaynağa Gözat

add support for WEBGL_clip_cull_distance

Alexander Rose 1 yıl önce
ebeveyn
işleme
cc1bf482f2

+ 1 - 0
CHANGELOG.md

@@ -11,6 +11,7 @@ Note that since we don't clearly distinguish between a public and private interf
 - ModelServer ligand queries: fix atom count reported by SDF/MOL/MOL2 export
 - CCD extension: Make visuals for aromatic bonds configurable
 - Add optional `file?: CifFile` to `MmcifFormat.data`
+- Add support for `WEBGL_clip_cull_distance`
 
 ## [v3.39.0] - 2023-09-02
 

+ 10 - 1
src/mol-gl/shader-code.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2023 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
@@ -20,6 +20,7 @@ export interface ShaderExtensions {
     readonly fragDepth?: ShaderExtensionsValue
     readonly drawBuffers?: ShaderExtensionsValue
     readonly shaderTextureLod?: ShaderExtensionsValue
+    readonly clipCullDistance?: ShaderExtensionsValue
 }
 
 type FragOutTypes = { [k in number]: 'vec4' | 'ivec4' }
@@ -313,6 +314,14 @@ function getGlsl300VertPrefix(extensions: WebGLExtensions, shaderExtensions: Sha
             prefix.push('#define requiredDrawBuffers');
         }
     }
+    if (shaderExtensions.clipCullDistance) {
+        if (extensions.clipCullDistance) {
+            prefix.push('#extension GL_ANGLE_clip_cull_distance : enable');
+            prefix.push('#define enabledClipCullDistance');
+        } else if (shaderExtensions.clipCullDistance === 'required') {
+            throw new Error(`required 'GL_ANGLE_clip_cull_distance' extension not available`);
+        }
+    }
     if (extensions.noNonInstancedActiveAttribs) {
         prefix.push('#define noNonInstancedActiveAttribs');
     }

+ 41 - 0
src/mol-gl/webgl/compat.ts

@@ -586,6 +586,47 @@ export function getProvokingVertex(gl: GLRenderingContext): COMPAT_provoking_ver
     return null;
 }
 
+/**
+ * See https://registry.khronos.org/webgl/extensions/WEBGL_clip_cull_distance/
+ */
+export interface COMPAT_clip_cull_distance {
+    readonly MAX_CLIP_DISTANCES: number;
+    readonly MAX_CULL_DISTANCES: number;
+    readonly MAX_COMBINED_CLIP_AND_CULL_DISTANCES: number;
+
+    readonly CLIP_DISTANCE0: number;
+    readonly CLIP_DISTANCE1: number;
+    readonly CLIP_DISTANCE2: number;
+    readonly CLIP_DISTANCE3: number;
+    readonly CLIP_DISTANCE4: number;
+    readonly CLIP_DISTANCE5: number;
+    readonly CLIP_DISTANCE6: number;
+    readonly CLIP_DISTANCE7: number;
+}
+
+export function getClipCullDistance(gl: GLRenderingContext): COMPAT_clip_cull_distance | null {
+    if (isWebGL2(gl)) {
+        const ext = gl.getExtension('WEBGL_clip_cull_distance');
+        if (ext) {
+            return {
+                MAX_CLIP_DISTANCES: ext.MAX_CLIP_DISTANCES_WEBGL,
+                MAX_CULL_DISTANCES: ext.MAX_CULL_DISTANCES_WEBGL,
+                MAX_COMBINED_CLIP_AND_CULL_DISTANCES: ext.MAX_COMBINED_CLIP_AND_CULL_DISTANCES_WEBGL,
+
+                CLIP_DISTANCE0: ext.CLIP_DISTANCE0_WEBGL,
+                CLIP_DISTANCE1: ext.CLIP_DISTANCE1_WEBGL,
+                CLIP_DISTANCE2: ext.CLIP_DISTANCE2_WEBGL,
+                CLIP_DISTANCE3: ext.CLIP_DISTANCE3_WEBGL,
+                CLIP_DISTANCE4: ext.CLIP_DISTANCE4_WEBGL,
+                CLIP_DISTANCE5: ext.CLIP_DISTANCE5_WEBGL,
+                CLIP_DISTANCE6: ext.CLIP_DISTANCE6_WEBGL,
+                CLIP_DISTANCE7: ext.CLIP_DISTANCE7_WEBGL
+            };
+        }
+    }
+    return null;
+}
+
 export function getNoNonInstancedActiveAttribs(gl: GLRenderingContext): boolean {
     if (!isWebGL2(gl)) return false;
 

+ 7 - 1
src/mol-gl/webgl/extensions.ts

@@ -4,7 +4,7 @@
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
-import { GLRenderingContext, COMPAT_instanced_arrays, COMPAT_standard_derivatives, COMPAT_vertex_array_object, getInstancedArrays, getStandardDerivatives, 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, COMPAT_sRGB, getSRGB, getTextureHalfFloat, getTextureHalfFloatLinear, COMPAT_texture_half_float, COMPAT_texture_half_float_linear, COMPAT_color_buffer_half_float, getColorBufferHalfFloat, getVertexArrayObject, getDisjointTimerQuery, COMPAT_disjoint_timer_query, getNoNonInstancedActiveAttribs, getDrawBuffersIndexed, COMPAT_draw_buffers_indexed, getParallelShaderCompile, COMPAT_parallel_shader_compile, getFboRenderMipmap, COMPAT_fboRenderMipmap, COMPAT_provoking_vertex, getProvokingVertex } from './compat';
+import { GLRenderingContext, COMPAT_instanced_arrays, COMPAT_standard_derivatives, COMPAT_vertex_array_object, getInstancedArrays, getStandardDerivatives, 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, COMPAT_sRGB, getSRGB, getTextureHalfFloat, getTextureHalfFloatLinear, COMPAT_texture_half_float, COMPAT_texture_half_float_linear, COMPAT_color_buffer_half_float, getColorBufferHalfFloat, getVertexArrayObject, getDisjointTimerQuery, COMPAT_disjoint_timer_query, getNoNonInstancedActiveAttribs, getDrawBuffersIndexed, COMPAT_draw_buffers_indexed, getParallelShaderCompile, COMPAT_parallel_shader_compile, getFboRenderMipmap, COMPAT_fboRenderMipmap, COMPAT_provoking_vertex, getProvokingVertex, COMPAT_clip_cull_distance, getClipCullDistance } from './compat';
 import { isDebugMode } from '../../mol-util/debug';
 
 export type WebGLExtensions = {
@@ -30,6 +30,7 @@ export type WebGLExtensions = {
     parallelShaderCompile: COMPAT_parallel_shader_compile | null
     fboRenderMipmap: COMPAT_fboRenderMipmap | null
     provokingVertex: COMPAT_provoking_vertex | null
+    clipCullDistance: COMPAT_clip_cull_distance | null
 
     noNonInstancedActiveAttribs: boolean
 }
@@ -126,6 +127,10 @@ export function createExtensions(gl: GLRenderingContext): WebGLExtensions {
     if (isDebugMode && provokingVertex === null) {
         console.log('Could not find support for "provoking_vertex"');
     }
+    const clipCullDistance = getClipCullDistance(gl);
+    if (isDebugMode && clipCullDistance === null) {
+        console.log('Could not find support for "clip_cull_distance"');
+    }
 
     const noNonInstancedActiveAttribs = getNoNonInstancedActiveAttribs(gl);
 
@@ -152,6 +157,7 @@ export function createExtensions(gl: GLRenderingContext): WebGLExtensions {
         parallelShaderCompile,
         fboRenderMipmap,
         provokingVertex,
+        clipCullDistance,
 
         noNonInstancedActiveAttribs,
     };

+ 3 - 1
src/mol-gl/webgl/state.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2023 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
@@ -22,6 +22,7 @@ export type WebGLState = {
      * - `gl.SAMPLE_COVERAGE`: ANDing the fragment's coverage with the temporary coverage value
      * - `gl.SCISSOR_TEST`: scissor test that discards fragments that are outside of the scissor rectangle
      * - `gl.STENCIL_TEST`: stencil testing and updates to the stencil buffer
+     * - `ext.CLIP_DISTANCE[0-7]`: clip distance 0 to 7 (with `ext` being `WEBGL_clip_cull_distance`)
      */
     enable: (cap: number) => void
     /**
@@ -35,6 +36,7 @@ export type WebGLState = {
      * - `gl.SAMPLE_COVERAGE`: ANDing the fragment's coverage with the temporary coverage value
      * - `gl.SCISSOR_TEST`: scissor test that discards fragments that are outside of the scissor rectangle
      * - `gl.STENCIL_TEST`: stencil testing and updates to the stencil buffer
+     * - `ext.CLIP_DISTANCE[0-7]`: clip distance 0 to 7 (with `ext` being `WEBGL_clip_cull_distance`)
      */
     disable: (cap: number) => void