From 88c187829ed86a8b82378ae5144174963422c405 Mon Sep 17 00:00:00 2001 From: Ken Martin Date: Wed, 5 Jan 2022 12:55:38 -0500 Subject: [PATCH] refactor(WebGL): remove support for WebGL1 Now that safari supports webgl2 move to that as the webg1 code and conditionals added a lot of complexity and limited what we could do. Now that WebGL2 is fairly universal this change should not break anything other than iOS devices still running iOS 14 or earlier. There is a second step (not in this MR) which is to update vtk.js to assume that we have depth textures. This will remove the need for the opaque depth pass code and some other sections of code but to keep this MR reasonably small it is being left out. --- Sources/Rendering/OpenGL/Framebuffer/index.js | 66 +-- .../Rendering/OpenGL/Glyph3DMapper/index.js | 222 +++----- .../Rendering/OpenGL/RenderWindow/index.js | 74 +-- .../OpenGL/ReplacementShaderMapper/index.js | 42 +- Sources/Rendering/OpenGL/ShaderCache/index.js | 67 +-- .../Rendering/OpenGL/SphereMapper/index.js | 4 +- Sources/Rendering/OpenGL/StickMapper/index.js | 4 +- .../SurfaceLIC/SurfaceLICMapper/index.js | 6 - Sources/Rendering/OpenGL/Texture/index.js | 497 +++--------------- .../OpenGL/VertexArrayObject/index.js | 181 +------ .../Rendering/OpenGL/VolumeMapper/index.js | 43 +- .../Rendering/OpenGL/glsl/vtkVolumeFS.glsl | 82 --- 12 files changed, 264 insertions(+), 1024 deletions(-) diff --git a/Sources/Rendering/OpenGL/Framebuffer/index.js b/Sources/Rendering/OpenGL/Framebuffer/index.js index 203f970c650..9c8ed3ff012 100644 --- a/Sources/Rendering/OpenGL/Framebuffer/index.js +++ b/Sources/Rendering/OpenGL/Framebuffer/index.js @@ -31,7 +31,7 @@ function vtkFramebuffer(publicAPI, model) { }; publicAPI.saveCurrentBuffers = (modeIn) => { - // noop on webgl 1 + // noop on webgl }; publicAPI.restorePreviousBindingsAndBuffers = (modeIn) => { @@ -50,7 +50,7 @@ function vtkFramebuffer(publicAPI, model) { }; publicAPI.restorePreviousBuffers = (modeIn) => { - // currently a noop on webgl1 + // currently a noop }; publicAPI.bind = () => { @@ -75,14 +75,7 @@ function vtkFramebuffer(publicAPI, model) { let glAttachment = gl.COLOR_ATTACHMENT0; if (attachment > 0) { - if (model.openGLRenderWindow.getWebgl2()) { - glAttachment += attachment; - } else { - macro.vtkErrorMacro( - 'Using multiple framebuffer attachments requires WebGL 2' - ); - return; - } + glAttachment += attachment; } model.colorTexture = texture; gl.framebufferTexture2D( @@ -99,14 +92,7 @@ function vtkFramebuffer(publicAPI, model) { let glAttachment = gl.COLOR_ATTACHMENT0; if (attachment > 0) { - if (model.openGLRenderWindow.getWebgl2()) { - glAttachment += attachment; - } else { - macro.vtkErrorMacro( - 'Using multiple framebuffer attachments requires WebGL 2' - ); - return; - } + glAttachment += attachment; } gl.framebufferTexture2D( @@ -119,37 +105,25 @@ function vtkFramebuffer(publicAPI, model) { }; publicAPI.setDepthBuffer = (texture) => { - if (model.openGLRenderWindow.getWebgl2()) { - const gl = model.context; - gl.framebufferTexture2D( - gl.FRAMEBUFFER, - gl.DEPTH_ATTACHMENT, - gl.TEXTURE_2D, - texture.getHandle(), - 0 - ); - } else { - macro.vtkErrorMacro( - 'Attaching depth buffer textures to fbo requires WebGL 2' - ); - } + const gl = model.context; + gl.framebufferTexture2D( + gl.FRAMEBUFFER, + gl.DEPTH_ATTACHMENT, + gl.TEXTURE_2D, + texture.getHandle(), + 0 + ); }; publicAPI.removeDepthBuffer = () => { - if (model.openGLRenderWindow.getWebgl2()) { - const gl = model.context; - gl.framebufferTexture2D( - gl.FRAMEBUFFER, - gl.DEPTH_ATTACHMENT, - gl.TEXTURE_2D, - null, - 0 - ); - } else { - macro.vtkErrorMacro( - 'Attaching depth buffer textures to framebuffers requires WebGL 2' - ); - } + const gl = model.context; + gl.framebufferTexture2D( + gl.FRAMEBUFFER, + gl.DEPTH_ATTACHMENT, + gl.TEXTURE_2D, + null, + 0 + ); }; publicAPI.getGLFramebuffer = () => model.glFramebuffer; diff --git a/Sources/Rendering/OpenGL/Glyph3DMapper/index.js b/Sources/Rendering/OpenGL/Glyph3DMapper/index.js index 25960db40f7..e9e677d4abb 100644 --- a/Sources/Rendering/OpenGL/Glyph3DMapper/index.js +++ b/Sources/Rendering/OpenGL/Glyph3DMapper/index.js @@ -3,7 +3,6 @@ import { mat3, mat4 } from 'gl-matrix'; import * as macro from 'vtk.js/Sources/macros'; import vtkBufferObject from 'vtk.js/Sources/Rendering/OpenGL/BufferObject'; -import vtkHardwareSelector from 'vtk.js/Sources/Rendering/OpenGL/HardwareSelector'; import vtkProperty from 'vtk.js/Sources/Rendering/Core/Property'; import vtkOpenGLPolyDataMapper from 'vtk.js/Sources/Rendering/OpenGL/PolyDataMapper'; import vtkShaderProgram from 'vtk.js/Sources/Rendering/OpenGL/ShaderProgram'; @@ -13,7 +12,6 @@ import { registerOverride } from 'vtk.js/Sources/Rendering/OpenGL/ViewNodeFactor const { vtkErrorMacro } = macro; const { Representation } = vtkProperty; const { ObjectType } = vtkBufferObject; -const { PassTypes } = vtkHardwareSelector; const StartEvent = { type: 'StartEvent' }; const EndEvent = { type: 'EndEvent' }; @@ -52,16 +50,7 @@ function vtkOpenGLGlyph3DMapper(publicAPI, model) { // apply faceCulling const gl = model.context; - if (model.openGLRenderWindow.getWebgl2()) { - model.hardwareSupport = true; - model.extension = null; - } else if (!model.extension) { - model.extension = model.context.getExtension('ANGLE_instanced_arrays'); - model.hardwareSupport = !!model.extension; - } - // to test without extension support uncomment the next two lines - // model.extension = null; - // model.hardwareSupport = !!model.extension; + model.hardwareSupport = true; const backfaceCulling = actor.getProperty().getBackfaceCulling(); const frontfaceCulling = actor.getProperty().getFrontfaceCulling(); @@ -137,39 +126,33 @@ function vtkOpenGLGlyph3DMapper(publicAPI, model) { }; publicAPI.replaceShaderNormal = (shaders, ren, actor) => { - if (model.hardwareSupport) { - const lastLightComplexity = model.lastBoundBO.getReferenceByName( - 'lastLightComplexity' - ); + const lastLightComplexity = model.lastBoundBO.getReferenceByName( + 'lastLightComplexity' + ); - if (lastLightComplexity > 0) { - let VSSource = shaders.Vertex; - - if (model.lastBoundBO.getCABO().getNormalOffset()) { - VSSource = vtkShaderProgram.substitute( - VSSource, - '//VTK::Normal::Dec', - [ - 'attribute vec3 normalMC;', - 'attribute mat3 gNormal;', - 'uniform mat3 normalMatrix;', - 'varying vec3 normalVCVSOutput;', - ] - ).result; - VSSource = vtkShaderProgram.substitute( - VSSource, - '//VTK::Normal::Impl', - ['normalVCVSOutput = normalMatrix * gNormal * normalMC;'] - ).result; - } - shaders.Vertex = VSSource; + if (lastLightComplexity > 0) { + let VSSource = shaders.Vertex; + + if (model.lastBoundBO.getCABO().getNormalOffset()) { + VSSource = vtkShaderProgram.substitute(VSSource, '//VTK::Normal::Dec', [ + 'attribute vec3 normalMC;', + 'attribute mat3 gNormal;', + 'uniform mat3 normalMatrix;', + 'varying vec3 normalVCVSOutput;', + ]).result; + VSSource = vtkShaderProgram.substitute( + VSSource, + '//VTK::Normal::Impl', + ['normalVCVSOutput = normalMatrix * gNormal * normalMC;'] + ).result; } + shaders.Vertex = VSSource; } superClass.replaceShaderNormal(shaders, ren, actor); }; publicAPI.replaceShaderColor = (shaders, ren, actor) => { - if (model.hardwareSupport && model.renderable.getColorArray()) { + if (model.renderable.getColorArray()) { let VSSource = shaders.Vertex; let GSSource = shaders.Geometry; let FSSource = shaders.Fragment; @@ -260,74 +243,68 @@ function vtkOpenGLGlyph3DMapper(publicAPI, model) { }; publicAPI.replaceShaderPositionVC = (shaders, ren, actor) => { - if (model.hardwareSupport) { - let VSSource = shaders.Vertex; - - // do we need the vertex in the shader in View Coordinates - const lastLightComplexity = model.lastBoundBO.getReferenceByName( - 'lastLightComplexity' - ); - if (lastLightComplexity > 0) { - VSSource = vtkShaderProgram.substitute( - VSSource, - '//VTK::PositionVC::Impl', - [ - 'vec4 gVertexMC = gMatrix * vertexMC;', - 'vertexVCVSOutput = MCVCMatrix * gVertexMC;', - ' gl_Position = MCPCMatrix * gVertexMC;', - ] - ).result; - VSSource = vtkShaderProgram.substitute(VSSource, '//VTK::Camera::Dec', [ - 'attribute mat4 gMatrix;', - 'uniform mat4 MCPCMatrix;', - 'uniform mat4 MCVCMatrix;', - ]).result; - } else { - VSSource = vtkShaderProgram.substitute(VSSource, '//VTK::Camera::Dec', [ - 'attribute mat4 gMatrix;', - 'uniform mat4 MCPCMatrix;', - ]).result; - VSSource = vtkShaderProgram.substitute( - VSSource, - '//VTK::PositionVC::Impl', - [ - 'vec4 gVertexMC = gMatrix * vertexMC;', - ' gl_Position = MCPCMatrix * gVertexMC;', - ] - ).result; - } - shaders.Vertex = VSSource; - } - superClass.replaceShaderPositionVC(shaders, ren, actor); - }; + let VSSource = shaders.Vertex; - publicAPI.replaceShaderPicking = (shaders, ren, actor) => { - if (model.hardwareSupport) { - let FSSource = shaders.Fragment; - let VSSource = shaders.Vertex; - VSSource = vtkShaderProgram.substitute(VSSource, '//VTK::Picking::Dec', [ - 'attribute vec3 mapperIndexVS;', - 'varying vec3 mapperIndexVSOutput;', - ]).result; + // do we need the vertex in the shader in View Coordinates + const lastLightComplexity = model.lastBoundBO.getReferenceByName( + 'lastLightComplexity' + ); + if (lastLightComplexity > 0) { VSSource = vtkShaderProgram.substitute( VSSource, - '//VTK::Picking::Impl', - ' mapperIndexVSOutput = mapperIndexVS;' + '//VTK::PositionVC::Impl', + [ + 'vec4 gVertexMC = gMatrix * vertexMC;', + 'vertexVCVSOutput = MCVCMatrix * gVertexMC;', + ' gl_Position = MCPCMatrix * gVertexMC;', + ] ).result; - shaders.Vertex = VSSource; - FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::Picking::Dec', [ - 'varying vec3 mapperIndexVSOutput;', - 'uniform vec3 mapperIndex;', - 'uniform int picking;', - ]).result; - FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::Picking::Impl', [ - ' vec4 pickColor = picking == 2 ? vec4(mapperIndexVSOutput,1.0) : vec4(mapperIndex,1.0);', - ' gl_FragData[0] = picking != 0 ? pickColor : gl_FragData[0];', + VSSource = vtkShaderProgram.substitute(VSSource, '//VTK::Camera::Dec', [ + 'attribute mat4 gMatrix;', + 'uniform mat4 MCPCMatrix;', + 'uniform mat4 MCVCMatrix;', ]).result; - shaders.Fragment = FSSource; } else { - superClass.replaceShaderPicking(shaders, ren, actor); + VSSource = vtkShaderProgram.substitute(VSSource, '//VTK::Camera::Dec', [ + 'attribute mat4 gMatrix;', + 'uniform mat4 MCPCMatrix;', + ]).result; + VSSource = vtkShaderProgram.substitute( + VSSource, + '//VTK::PositionVC::Impl', + [ + 'vec4 gVertexMC = gMatrix * vertexMC;', + ' gl_Position = MCPCMatrix * gVertexMC;', + ] + ).result; } + shaders.Vertex = VSSource; + superClass.replaceShaderPositionVC(shaders, ren, actor); + }; + + publicAPI.replaceShaderPicking = (shaders, ren, actor) => { + let FSSource = shaders.Fragment; + let VSSource = shaders.Vertex; + VSSource = vtkShaderProgram.substitute(VSSource, '//VTK::Picking::Dec', [ + 'attribute vec3 mapperIndexVS;', + 'varying vec3 mapperIndexVSOutput;', + ]).result; + VSSource = vtkShaderProgram.substitute( + VSSource, + '//VTK::Picking::Impl', + ' mapperIndexVSOutput = mapperIndexVS;' + ).result; + shaders.Vertex = VSSource; + FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::Picking::Dec', [ + 'varying vec3 mapperIndexVSOutput;', + 'uniform vec3 mapperIndex;', + 'uniform int picking;', + ]).result; + FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::Picking::Impl', [ + ' vec4 pickColor = picking == 2 ? vec4(mapperIndexVSOutput,1.0) : vec4(mapperIndex,1.0);', + ' gl_FragData[0] = picking != 0 ? pickColor : gl_FragData[0];', + ]).result; + shaders.Fragment = FSSource; }; publicAPI.updateGlyphShaderParameters = ( @@ -438,20 +415,8 @@ function vtkOpenGLGlyph3DMapper(publicAPI, model) { mat4.multiply(model.mcvcMatrix, keyMats.wcvc, actMats.mcwc); const garray = model.renderable.getMatrixArray(); - const narray = model.renderable.getNormalArray(); - const carray = model.renderable.getColorArray(); const numPts = garray.length / 16; - let compositePass = false; - if (model.openGLRenderer.getSelector()) { - if ( - model.openGLRenderer.getSelector().getCurrentPass() === - PassTypes.COMPOSITE_INDEX_PASS - ) { - compositePass = true; - } - } - // for every primitive type for (let i = model.primTypes.Start; i < model.primTypes.End; i++) { // if there are entries @@ -463,42 +428,9 @@ function vtkOpenGLGlyph3DMapper(publicAPI, model) { (i === model.primTypes.TrisEdges || i === model.primTypes.TriStripsEdges); publicAPI.updateShaders(model.primitives[i], ren, actor); - const program = model.primitives[i].getProgram(); const mode = publicAPI.getOpenGLMode(representation, i); - const normalMatrixUsed = program.isUniformUsed('normalMatrix'); - const mcvcMatrixUsed = program.isUniformUsed('MCVCMatrix'); - - if (model.hardwareSupport) { - if (model.extension) { - model.extension.drawArraysInstancedANGLE( - mode, - 0, - cabo.getElementCount(), - numPts - ); - } else { - gl.drawArraysInstanced(mode, 0, cabo.getElementCount(), numPts); - } - } else { - // draw the array multiple times with different cam matrix - for (let p = 0; p < numPts; ++p) { - if (compositePass) { - model.openGLRenderer.getSelector().renderCompositeIndex(p); - } - publicAPI.updateGlyphShaderParameters( - normalMatrixUsed, - mcvcMatrixUsed, - model.primitives[i], - carray, - garray, - narray, - p, - compositePass ? model.openGLRenderer.getSelector() : null - ); - gl.drawArrays(mode, 0, cabo.getElementCount()); - } - } + gl.drawArraysInstanced(mode, 0, cabo.getElementCount(), numPts); } } }; diff --git a/Sources/Rendering/OpenGL/RenderWindow/index.js b/Sources/Rendering/OpenGL/RenderWindow/index.js index b6534a345cb..f9b12c438cd 100644 --- a/Sources/Rendering/OpenGL/RenderWindow/index.js +++ b/Sources/Rendering/OpenGL/RenderWindow/index.js @@ -237,7 +237,7 @@ function vtkOpenGLRenderWindow(publicAPI, model) { const webgl2Supported = typeof WebGL2RenderingContext !== 'undefined'; model.webgl2 = false; - if (model.defaultToWebgl2 && webgl2Supported) { + if (webgl2Supported) { result = model.canvas.getContext('webgl2', options); if (result) { model.webgl2 = true; @@ -245,10 +245,7 @@ function vtkOpenGLRenderWindow(publicAPI, model) { } } if (!result) { - vtkDebugMacro('using webgl1'); - result = - model.canvas.getContext('webgl', options) || - model.canvas.getContext('experimental-webgl', options); + vtkErrorMacro('required webgl2 support is missing'); } // prevent default context lost handler @@ -461,47 +458,32 @@ function vtkOpenGLRenderWindow(publicAPI, model) { }; publicAPI.getDefaultTextureInternalFormat = (vtktype, numComps, useFloat) => { - if (model.webgl2) { - switch (vtktype) { - case VtkDataTypes.UNSIGNED_CHAR: - switch (numComps) { - case 1: - return model.context.R8; - case 2: - return model.context.RG8; - case 3: - return model.context.RGB8; - case 4: - default: - return model.context.RGBA8; - } - default: - case VtkDataTypes.FLOAT: - switch (numComps) { - case 1: - return model.context.R16F; - case 2: - return model.context.RG16F; - case 3: - return model.context.RGB16F; - case 4: - default: - return model.context.RGBA16F; - } - } - } - - // webgl1 only supports four types - switch (numComps) { - case 1: - return model.context.LUMINANCE; - case 2: - return model.context.LUMINANCE_ALPHA; - case 3: - return model.context.RGB; - case 4: + switch (vtktype) { + case VtkDataTypes.UNSIGNED_CHAR: + switch (numComps) { + case 1: + return model.context.R8; + case 2: + return model.context.RG8; + case 3: + return model.context.RGB8; + case 4: + default: + return model.context.RGBA8; + } default: - return model.context.RGBA; + case VtkDataTypes.FLOAT: + switch (numComps) { + case 1: + return model.context.R16F; + case 2: + return model.context.RG16F; + case 3: + return model.context.RGB16F; + case 4: + default: + return model.context.RGBA16F; + } } }; @@ -1056,7 +1038,7 @@ function vtkOpenGLRenderWindow(publicAPI, model) { glDebugRendererInfo && gl.getParameter(glDebugRendererInfo.UNMASKED_VENDOR_WEBGL), ], - ['WebGL Version', 'WEBGL_VERSION', model.webgl2 ? 2 : 1], + ['WebGL Version', 'WEBGL_VERSION', 2], ]; const result = {}; diff --git a/Sources/Rendering/OpenGL/ReplacementShaderMapper/index.js b/Sources/Rendering/OpenGL/ReplacementShaderMapper/index.js index d9c8f9b47f9..25678f712fb 100644 --- a/Sources/Rendering/OpenGL/ReplacementShaderMapper/index.js +++ b/Sources/Rendering/OpenGL/ReplacementShaderMapper/index.js @@ -46,29 +46,27 @@ function implementReplaceShaderCoincidentOffset( ).result; } } - if (model.openGLRenderWindow.getWebgl2()) { - if (cp.factor !== 0.0) { - FSSource = vtkShaderProgram.substitute( - FSSource, + if (cp.factor !== 0.0) { + FSSource = vtkShaderProgram.substitute( + FSSource, + '//VTK::UniformFlow::Impl', + [ + 'float cscale = length(vec2(dFdx(gl_FragCoord.z),dFdy(gl_FragCoord.z)));', '//VTK::UniformFlow::Impl', - [ - 'float cscale = length(vec2(dFdx(gl_FragCoord.z),dFdy(gl_FragCoord.z)));', - '//VTK::UniformFlow::Impl', - ], - false - ).result; - FSSource = vtkShaderProgram.substitute( - FSSource, - '//VTK::Depth::Impl', - 'gl_FragDepth = gl_FragCoord.z + cfactor*cscale + 0.000016*coffset;' - ).result; - } else { - FSSource = vtkShaderProgram.substitute( - FSSource, - '//VTK::Depth::Impl', - 'gl_FragDepth = gl_FragCoord.z + 0.000016*coffset;' - ).result; - } + ], + false + ).result; + FSSource = vtkShaderProgram.substitute( + FSSource, + '//VTK::Depth::Impl', + 'gl_FragDepth = gl_FragCoord.z + cfactor*cscale + 0.000016*coffset;' + ).result; + } else { + FSSource = vtkShaderProgram.substitute( + FSSource, + '//VTK::Depth::Impl', + 'gl_FragDepth = gl_FragCoord.z + 0.000016*coffset;' + ).result; } shaders.Fragment = FSSource; } diff --git a/Sources/Rendering/OpenGL/ShaderCache/index.js b/Sources/Rendering/OpenGL/ShaderCache/index.js index 7e3748ff80d..dd54bd14424 100644 --- a/Sources/Rendering/OpenGL/ShaderCache/index.js +++ b/Sources/Rendering/OpenGL/ShaderCache/index.js @@ -31,36 +31,17 @@ function vtkShaderCache(publicAPI, model) { ).result; } - const gl2 = model.openGLRenderWindow.getWebgl2(); - - let fragDepthString = '\n'; - let version = '#version 100\n'; - if (gl2) { - version = - '#version 300 es\n' + - '#define attribute in\n' + - '#define textureCube texture\n' + - '#define texture2D texture\n' + - '#define textureCubeLod textureLod\n' + - '#define texture2DLod textureLod\n'; - } else { - model.context.getExtension('OES_standard_derivatives'); - if (model.context.getExtension('EXT_frag_depth')) { - fragDepthString = '#extension GL_EXT_frag_depth : enable\n'; - } - if (model.context.getExtension('EXT_shader_texture_lod')) { - fragDepthString += - '#extension GL_EXT_shader_texture_lod : enable\n' + - '#define textureCubeLod textureCubeLodEXT\n' + - '#define texture2DLod texture2DLodEXT'; - } - } + version = + '#version 300 es\n' + + '#define attribute in\n' + + '#define textureCube texture\n' + + '#define texture2D texture\n' + + '#define textureCubeLod textureLod\n' + + '#define texture2DLod textureLod\n'; nFSSource = vtkShaderProgram.substitute(nFSSource, '//VTK::System::Dec', [ `${version}\n`, - gl2 ? '' : '#extension GL_OES_standard_derivatives : enable\n', - fragDepthString, '#ifdef GL_FRAGMENT_PRECISION_HIGH', 'precision highp float;', 'precision highp int;', @@ -85,28 +66,18 @@ function vtkShaderCache(publicAPI, model) { ] ).result; - if (gl2) { - nVSSource = vtkShaderProgram.substitute( - nVSSource, - 'varying', - 'out' - ).result; - nFSSource = vtkShaderProgram.substitute( - nFSSource, - 'varying', - 'in' - ).result; - nFSSource = vtkShaderProgram.substitute( - nFSSource, - 'gl_FragData\\[0\\]', - 'fragOutput0' - ).result; - nFSSource = vtkShaderProgram.substitute( - nFSSource, - '//VTK::Output::Dec', - 'layout(location = 0) out vec4 fragOutput0;' - ).result; - } + nVSSource = vtkShaderProgram.substitute(nVSSource, 'varying', 'out').result; + nFSSource = vtkShaderProgram.substitute(nFSSource, 'varying', 'in').result; + nFSSource = vtkShaderProgram.substitute( + nFSSource, + 'gl_FragData\\[0\\]', + 'fragOutput0' + ).result; + nFSSource = vtkShaderProgram.substitute( + nFSSource, + '//VTK::Output::Dec', + 'layout(location = 0) out vec4 fragOutput0;' + ).result; // nFSSource = ShaderProgram.substitute(nFSSource, 'gl_FragData\\[0\\]', // 'gl_FragColor').result; diff --git a/Sources/Rendering/OpenGL/SphereMapper/index.js b/Sources/Rendering/OpenGL/SphereMapper/index.js index ae7a6e971e6..ba4ff5203ee 100644 --- a/Sources/Rendering/OpenGL/SphereMapper/index.js +++ b/Sources/Rendering/OpenGL/SphereMapper/index.js @@ -73,9 +73,7 @@ function vtkOpenGLSphereMapper(publicAPI, model) { if (model.context.getExtension('EXT_frag_depth')) { fragString = 'gl_FragDepthEXT = (pos.z / pos.w + 1.0) / 2.0;\n'; } - if (model.openGLRenderWindow.getWebgl2()) { - fragString = 'gl_FragDepth = (pos.z / pos.w + 1.0) / 2.0;\n'; - } + fragString = 'gl_FragDepth = (pos.z / pos.w + 1.0) / 2.0;\n'; FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::Depth::Impl', [ // compute the eye position and unit direction ' vec3 EyePos;\n', diff --git a/Sources/Rendering/OpenGL/StickMapper/index.js b/Sources/Rendering/OpenGL/StickMapper/index.js index cdddb983425..8a8ae9ba137 100644 --- a/Sources/Rendering/OpenGL/StickMapper/index.js +++ b/Sources/Rendering/OpenGL/StickMapper/index.js @@ -74,9 +74,7 @@ function vtkOpenGLStickMapper(publicAPI, model) { if (model.context.getExtension('EXT_frag_depth')) { fragString = ' gl_FragDepthEXT = (pos.z / pos.w + 1.0) / 2.0;\n'; } - if (model.openGLRenderWindow.getWebgl2()) { - fragString = 'gl_FragDepth = (pos.z / pos.w + 1.0) / 2.0;\n'; - } + fragString = 'gl_FragDepth = (pos.z / pos.w + 1.0) / 2.0;\n'; // see https://www.cl.cam.ac.uk/teaching/1999/AGraphHCI/SMAG/node2.html FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::Depth::Impl', [ // compute the eye position and unit direction diff --git a/Sources/Rendering/OpenGL/SurfaceLIC/SurfaceLICMapper/index.js b/Sources/Rendering/OpenGL/SurfaceLIC/SurfaceLICMapper/index.js index 75f093e3fd0..1cae53938d6 100644 --- a/Sources/Rendering/OpenGL/SurfaceLIC/SurfaceLICMapper/index.js +++ b/Sources/Rendering/OpenGL/SurfaceLIC/SurfaceLICMapper/index.js @@ -139,12 +139,6 @@ function vtkOpenGLSurfaceLICMapper(publicAPI, model) { publicAPI.renderPiece = (ren, actor) => { let canDrawLIC = true; - // Check for gl compatibility - const gl2 = model.openGLRenderWindow.getWebgl2(); - if (!gl2) { - vtkErrorMacro('SurfaceLICMapper Requires WebGL 2'); - canDrawLIC = false; - } // Check for required extensions if ( diff --git a/Sources/Rendering/OpenGL/Texture/index.js b/Sources/Rendering/OpenGL/Texture/index.js index f57b866bf5f..788968e5859 100644 --- a/Sources/Rendering/OpenGL/Texture/index.js +++ b/Sources/Rendering/OpenGL/Texture/index.js @@ -170,13 +170,11 @@ function vtkOpenGLTexture(publicAPI, model) { model.context.TEXTURE_WRAP_T, publicAPI.getOpenGLWrapMode(model.wrapT) ); - if (model.openGLRenderWindow.getWebgl2()) { - model.context.texParameteri( - model.target, - model.context.TEXTURE_WRAP_R, - publicAPI.getOpenGLWrapMode(model.wrapR) - ); - } + model.context.texParameteri( + model.target, + model.context.TEXTURE_WRAP_R, + publicAPI.getOpenGLWrapMode(model.wrapR) + ); model.context.bindTexture(model.target, null); } @@ -270,13 +268,11 @@ function vtkOpenGLTexture(publicAPI, model) { model.context.TEXTURE_WRAP_T, publicAPI.getOpenGLWrapMode(model.wrapT) ); - if (model.openGLRenderWindow.getWebgl2()) { - model.context.texParameteri( - model.target, - model.context.TEXTURE_WRAP_R, - publicAPI.getOpenGLWrapMode(model.wrapR) - ); - } + model.context.texParameteri( + model.target, + model.context.TEXTURE_WRAP_R, + publicAPI.getOpenGLWrapMode(model.wrapR) + ); model.context.texParameteri( model.target, @@ -290,19 +286,17 @@ function vtkOpenGLTexture(publicAPI, model) { publicAPI.getOpenGLFilterMode(model.magnificationFilter) ); - if (model.openGLRenderWindow.getWebgl2()) { - model.context.texParameteri( - model.target, - model.context.TEXTURE_BASE_LEVEL, - model.baseLevel - ); + model.context.texParameteri( + model.target, + model.context.TEXTURE_BASE_LEVEL, + model.baseLevel + ); - model.context.texParameteri( - model.target, - model.context.TEXTURE_MAX_LEVEL, - model.maxLevel - ); - } + model.context.texParameteri( + model.target, + model.context.TEXTURE_MAX_LEVEL, + model.maxLevel + ); // model.context.texParameterf(model.target, model.context.TEXTURE_MIN_LOD, model.minLOD); // model.context.texParameterf(model.target, model.context.TEXTURE_MAX_LOD, model.maxLOD); @@ -375,33 +369,17 @@ function vtkOpenGLTexture(publicAPI, model) { //---------------------------------------------------------------------------- publicAPI.getDefaultFormat = (vtktype, numComps) => { - if (model.openGLRenderWindow.getWebgl2()) { - switch (numComps) { - case 1: - return model.context.RED; - case 2: - return model.context.RG; - case 3: - return model.context.RGB; - case 4: - return model.context.RGBA; - default: - return model.context.RGB; - } - } else { - // webgl1 - switch (numComps) { - case 1: - return model.context.LUMINANCE; - case 2: - return model.context.LUMINANCE_ALPHA; - case 3: - return model.context.RGB; - case 4: - return model.context.RGBA; - default: - return model.context.RGB; - } + switch (numComps) { + case 1: + return model.context.RED; + case 2: + return model.context.RG; + case 3: + return model.context.RGB; + case 4: + return model.context.RGBA; + default: + return model.context.RGB; } }; @@ -415,36 +393,15 @@ function vtkOpenGLTexture(publicAPI, model) { //---------------------------------------------------------------------------- publicAPI.getDefaultDataType = (vtkScalarType, useHalfFloatType = false) => { // DON'T DEAL with VTK_CHAR as this is platform dependent. - if (model.openGLRenderWindow.getWebgl2()) { - switch (vtkScalarType) { - // case VtkDataTypes.SIGNED_CHAR: - // return model.context.BYTE; - case VtkDataTypes.UNSIGNED_CHAR: - return model.context.UNSIGNED_BYTE; - case useHalfFloatType && VtkDataTypes.SHORT: - return model.context.HALF_FLOAT; - case useHalfFloatType && VtkDataTypes.UNSIGNED_SHORT: - return model.context.HALF_FLOAT; - // case VtkDataTypes.INT: - // return model.context.INT; - // case VtkDataTypes.UNSIGNED_INT: - // return model.context.UNSIGNED_INT; - case VtkDataTypes.FLOAT: - case VtkDataTypes.VOID: // used for depth component textures. - default: - return model.context.FLOAT; - } - } - switch (vtkScalarType) { // case VtkDataTypes.SIGNED_CHAR: // return model.context.BYTE; case VtkDataTypes.UNSIGNED_CHAR: return model.context.UNSIGNED_BYTE; - // case VtkDataTypes.SHORT: - // return model.context.SHORT; - // case VtkDataTypes.UNSIGNED_SHORT: - // return model.context.UNSIGNED_SHORT; + case useHalfFloatType && VtkDataTypes.SHORT: + return model.context.HALF_FLOAT; + case useHalfFloatType && VtkDataTypes.UNSIGNED_SHORT: + return model.context.HALF_FLOAT; // case VtkDataTypes.INT: // return model.context.INT; // case VtkDataTypes.UNSIGNED_INT: @@ -452,24 +409,7 @@ function vtkOpenGLTexture(publicAPI, model) { case VtkDataTypes.FLOAT: case VtkDataTypes.VOID: // used for depth component textures. default: - if ( - model.context.getExtension('OES_texture_float') && - model.context.getExtension('OES_texture_float_linear') - ) { - return model.context.FLOAT; - } - { - const halfFloat = model.context.getExtension( - 'OES_texture_half_float' - ); - if ( - halfFloat && - model.context.getExtension('OES_texture_half_float_linear') - ) { - return halfFloat.HALF_FLOAT_OES; - } - } - return model.context.UNSIGNED_BYTE; + return model.context.FLOAT; } }; @@ -594,10 +534,7 @@ function vtkOpenGLTexture(publicAPI, model) { // if the opengl data type is half float // then the data array must be u16 - const halfFloatExt = model.context.getExtension('OES_texture_half_float'); - const halfFloat = model.openGLRenderWindow.getWebgl2() - ? model.openGLDataType === model.context.HALF_FLOAT - : halfFloatExt && model.openGLDataType === halfFloatExt.HALF_FLOAT_OES; + const halfFloat = model.openGLDataType === model.context.HALF_FLOAT; if (halfFloat) { for (let idx = 0; idx < data.length; idx++) { @@ -619,108 +556,6 @@ function vtkOpenGLTexture(publicAPI, model) { return pixData; } - //---------------------------------------------------------------------------- - function scaleTextureToHighestPowerOfTwo(data) { - if (model.openGLRenderWindow.getWebgl2()) { - // No need if webGL2 - return data; - } - const pixData = []; - const width = model.width; - const height = model.height; - const numComps = model.components; - if ( - data && - (!vtkMath.isPowerOfTwo(width) || !vtkMath.isPowerOfTwo(height)) - ) { - // Scale up the texture to the next highest power of two dimensions. - const halfFloat = model.context.getExtension('OES_texture_half_float'); - const newWidth = vtkMath.nearestPowerOfTwo(width); - const newHeight = vtkMath.nearestPowerOfTwo(height); - const pixCount = newWidth * newHeight * model.components; - for (let idx = 0; idx < data.length; idx++) { - if (data[idx] !== null) { - let newArray = null; - const jFactor = height / newHeight; - const iFactor = width / newWidth; - let usingHalf = false; - if (model.openGLDataType === model.context.FLOAT) { - newArray = new Float32Array(pixCount); - } else if ( - halfFloat && - model.openGLDataType === halfFloat.HALF_FLOAT_OES - ) { - newArray = new Uint16Array(pixCount); - usingHalf = true; - } else { - newArray = new Uint8Array(pixCount); - } - for (let j = 0; j < newHeight; j++) { - const joff = j * newWidth * numComps; - const jidx = j * jFactor; - let jlow = Math.floor(jidx); - let jhi = Math.ceil(jidx); - if (jhi >= height) { - jhi = height - 1; - } - const jmix = jidx - jlow; - const jmix1 = 1.0 - jmix; - jlow = jlow * width * numComps; - jhi = jhi * width * numComps; - for (let i = 0; i < newWidth; i++) { - const ioff = i * numComps; - const iidx = i * iFactor; - let ilow = Math.floor(iidx); - let ihi = Math.ceil(iidx); - if (ihi >= width) { - ihi = width - 1; - } - const imix = iidx - ilow; - ilow *= numComps; - ihi *= numComps; - for (let c = 0; c < numComps; c++) { - if (usingHalf) { - newArray[joff + ioff + c] = HalfFloat.toHalf( - HalfFloat.fromHalf(data[idx][jlow + ilow + c]) * - jmix1 * - (1.0 - imix) + - HalfFloat.fromHalf(data[idx][jlow + ihi + c]) * - jmix1 * - imix + - HalfFloat.fromHalf(data[idx][jhi + ilow + c]) * - jmix * - (1.0 - imix) + - HalfFloat.fromHalf(data[idx][jhi + ihi + c]) * jmix * imix - ); - } else { - newArray[joff + ioff + c] = - data[idx][jlow + ilow + c] * jmix1 * (1.0 - imix) + - data[idx][jlow + ihi + c] * jmix1 * imix + - data[idx][jhi + ilow + c] * jmix * (1.0 - imix) + - data[idx][jhi + ihi + c] * jmix * imix; - } - } - } - } - pixData.push(newArray); - model.width = newWidth; - model.height = newHeight; - } else { - pixData.push(null); - } - } - } - - // The output has to be filled - if (pixData.length === 0) { - for (let i = 0; i < data.length; i++) { - pixData.push(data[i]); - } - } - - return pixData; - } - //---------------------------------------------------------------------------- publicAPI.create2DFromRaw = (width, height, numComps, dataType, data) => { // Now determine the texture parameters using the arguments. @@ -746,7 +581,6 @@ function vtkOpenGLTexture(publicAPI, model) { // Create an array of texture with one texture const dataArray = [data]; const pixData = updateArrayDataType(dataType, dataArray); - const scaledData = scaleTextureToHighestPowerOfTwo(pixData); // Source texture data from the PBO. // model.context.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); @@ -761,7 +595,7 @@ function vtkOpenGLTexture(publicAPI, model) { 0, model.format, model.openGLDataType, - scaledData[0] + pixData[0] ); if (model.generateMipmap) { @@ -796,7 +630,6 @@ function vtkOpenGLTexture(publicAPI, model) { publicAPI.bind(); const pixData = updateArrayDataType(dataType, data); - const scaledData = scaleTextureToHighestPowerOfTwo(pixData); // invert the data because opengl is messed up with cube maps // and uses the old renderman standard with Y going down @@ -804,7 +637,7 @@ function vtkOpenGLTexture(publicAPI, model) { const invertedData = []; let widthLevel = model.width; let heightLevel = model.height; - for (let i = 0; i < scaledData.length; i++) { + for (let i = 0; i < pixData.length; i++) { if (i % 6 === 0 && i !== 0) { widthLevel /= 2; heightLevel /= 2; @@ -817,7 +650,7 @@ function vtkOpenGLTexture(publicAPI, model) { const row1 = y * widthLevel * model.components; const row2 = (heightLevel - y - 1) * widthLevel * model.components; invertedData[i].set( - scaledData[i].slice(row2, row2 + widthLevel * model.components), + pixData[i].slice(row2, row2 + widthLevel * model.components), row1 ); } @@ -869,14 +702,10 @@ function vtkOpenGLTexture(publicAPI, model) { // Now determine the texture parameters using the arguments. publicAPI.getOpenGLDataType(dataType); model.format = model.context.DEPTH_COMPONENT; - if (model.openGLRenderWindow.getWebgl2()) { - if (dataType === VtkDataTypes.FLOAT) { - model.internalFormat = model.context.DEPTH_COMPONENT32F; - } else { - model.internalFormat = model.context.DEPTH_COMPONENT16; - } + if (dataType === VtkDataTypes.FLOAT) { + model.internalFormat = model.context.DEPTH_COMPONENT32F; } else { - model.internalFormat = model.context.DEPTH_COMPONENT; + model.internalFormat = model.context.DEPTH_COMPONENT16; } if (!model.internalFormat || !model.format || !model.openGLDataType) { @@ -1044,10 +873,7 @@ function vtkOpenGLTexture(publicAPI, model) { const useHalfFloatType = true; publicAPI.getOpenGLDataType(dataType, useHalfFloatType); - const halfFloatExt = model.context.getExtension('OES_texture_half_float'); - const useHalfFloat = model.openGLRenderWindow.getWebgl2() - ? model.openGLDataType === model.context.HALF_FLOAT - : halfFloatExt && model.openGLDataType === halfFloatExt.HALF_FLOAT_OES; + const useHalfFloat = model.openGLDataType === model.context.HALF_FLOAT; if (!useHalfFloat) { return false; @@ -1097,7 +923,6 @@ function vtkOpenGLTexture(publicAPI, model) { const dataArray = [data]; const is3DArray = true; const pixData = updateArrayDataType(dataType, dataArray, is3DArray); - const scaledData = scaleTextureToHighestPowerOfTwo(pixData); // Source texture data from the PBO. // model.context.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); @@ -1113,7 +938,7 @@ function vtkOpenGLTexture(publicAPI, model) { 0, model.format, model.openGLDataType, - scaledData[0] + pixData[0] ); if (model.generateMipmap) { @@ -1125,7 +950,7 @@ function vtkOpenGLTexture(publicAPI, model) { }; //---------------------------------------------------------------------------- - // This method simulates a 3D texture using 2D + // This method creates a 3d filterable texture suitable for the data type publicAPI.create3DFilterableFromRaw = ( width, height, @@ -1167,217 +992,55 @@ function vtkOpenGLTexture(publicAPI, model) { ); // WebGL2 path, we have 3d textures etc - if (model.openGLRenderWindow.getWebgl2()) { - if ( - dataType === VtkDataTypes.FLOAT || - (useHalfFloat && - (dataType === VtkDataTypes.SHORT || - dataType === VtkDataTypes.UNSIGNED_SHORT)) - ) { - return publicAPI.create3DFromRaw( - width, - height, - depth, - numComps, - dataType, - data - ); - } - if (dataType === VtkDataTypes.UNSIGNED_CHAR) { - for (let c = 0; c < numComps; ++c) { - model.volumeInfo.scale[c] = 255.0; - } - return publicAPI.create3DFromRaw( - width, - height, - depth, - numComps, - dataType, - data - ); - } - // otherwise convert to float - const newArray = new Float32Array(numPixelsIn * numComps); - // compute min and max values - model.volumeInfo.offset = computedOffset; - model.volumeInfo.scale = computedScale; - let count = 0; - const scaleInverse = computedScale.map((s) => 1 / s); - for (let i = 0; i < numPixelsIn; i++) { - for (let nc = 0; nc < numComps; nc++) { - newArray[count] = - (data[count] - computedOffset[nc]) * scaleInverse[nc]; - count++; - } - } + if ( + dataType === VtkDataTypes.FLOAT || + (useHalfFloat && + (dataType === VtkDataTypes.SHORT || + dataType === VtkDataTypes.UNSIGNED_SHORT)) + ) { return publicAPI.create3DFromRaw( width, height, depth, numComps, - VtkDataTypes.FLOAT, - newArray + dataType, + data ); } - - // not webgl2, deal with webgl1, no 3d textures - // and maybe no float textures - - // compute min and max values - const res = computeScaleOffsets(numComps, numPixelsIn, data); - - let volCopyData = (outArray, outIdx, inValue, smin, smax) => { - outArray[outIdx] = inValue; - }; - let dataTypeToUse = VtkDataTypes.UNSIGNED_CHAR; - // unsigned char gets used as is if (dataType === VtkDataTypes.UNSIGNED_CHAR) { for (let c = 0; c < numComps; ++c) { - res.offset[c] = 0.0; - res.scale[c] = 255.0; + model.volumeInfo.scale[c] = 255.0; } - } else if ( - model.context.getExtension('OES_texture_float') && - model.context.getExtension('OES_texture_float_linear') - ) { - // use float textures scaled to 0.0 to 1.0 - dataTypeToUse = VtkDataTypes.FLOAT; - volCopyData = (outArray, outIdx, inValue, soffset, sscale) => { - outArray[outIdx] = (inValue - soffset) / sscale; - }; - } else { - // worst case, scale data to uchar - dataTypeToUse = VtkDataTypes.UNSIGNED_CHAR; - volCopyData = (outArray, outIdx, inValue, soffset, sscale) => { - outArray[outIdx] = (255.0 * (inValue - soffset)) / sscale; - }; - } - - // Now determine the texture parameters using the arguments. - publicAPI.getOpenGLDataType(dataTypeToUse); - publicAPI.getInternalFormat(dataTypeToUse, numComps); - publicAPI.getFormat(dataTypeToUse, numComps); - - if (!model.internalFormat || !model.format || !model.openGLDataType) { - vtkErrorMacro('Failed to determine texture parameters.'); - return false; - } - - // have to pack this 3D texture into pot 2D texture - model.target = model.context.TEXTURE_2D; - model.components = numComps; - model.depth = 1; - model.numberOfDimensions = 2; - - // MAX_TEXTURE_SIZE gives the max dimensions that can be supported by the GPU, - // but it doesn't mean it will fit in memory. If we have to use a float data type - // or 4 components, there are good chances that the texture size will blow up - // and could not fit in the GPU memory. Use a smaller texture size in that case, - // which will force a downsampling of the dataset. - // That problem does not occur when using webGL2 since we can pack the data in - // denser textures based on our data type. - // TODO: try to fit in the biggest supported texture, catch the gl error if it - // does not fix (OUT_OF_MEMORY), then attempt with smaller texture - let maxTexDim = model.context.getParameter(model.context.MAX_TEXTURE_SIZE); - if ( - maxTexDim > 4096 && - (dataTypeToUse === VtkDataTypes.FLOAT || numComps >= 3) - ) { - maxTexDim = 4096; - } - - // compute estimate for XY subsample - let xstride = 1; - let ystride = 1; - if (numPixelsIn > maxTexDim * maxTexDim) { - xstride = Math.ceil(Math.sqrt(numPixelsIn / (maxTexDim * maxTexDim))); - ystride = xstride; - } - let targetWidth = Math.sqrt(numPixelsIn) / xstride; - targetWidth = vtkMath.nearestPowerOfTwo(targetWidth); - // determine X reps - const xreps = Math.floor((targetWidth * xstride) / width); - const yreps = Math.ceil(depth / xreps); - const targetHeight = vtkMath.nearestPowerOfTwo((height * yreps) / ystride); - - model.width = targetWidth; - model.height = targetHeight; - model.openGLRenderWindow.activateTexture(publicAPI); - publicAPI.createTexture(); - publicAPI.bind(); - - // store the information, we will need it later - model.volumeInfo.xreps = xreps; - model.volumeInfo.yreps = yreps; - model.volumeInfo.xstride = xstride; - model.volumeInfo.ystride = ystride; - model.volumeInfo.offset = res.offset; - model.volumeInfo.scale = res.scale; - - // OK stuff the data into the 2d TEXTURE - - // first allocate the new texture - let newArray; - const pixCount = targetWidth * targetHeight * numComps; - if (dataTypeToUse === VtkDataTypes.FLOAT) { - newArray = new Float32Array(pixCount); - } else { - newArray = new Uint8Array(pixCount); + return publicAPI.create3DFromRaw( + width, + height, + depth, + numComps, + dataType, + data + ); } - - // then stuff the data into it, nothing fancy right now - // for stride - let outIdx = 0; - - const tileWidth = Math.floor(width / xstride); - const tileHeight = Math.floor(height / ystride); - - for (let yRep = 0; yRep < yreps; yRep++) { - const xrepsThisRow = Math.min(xreps, depth - yRep * xreps); - const outXContIncr = - numComps * (model.width - xrepsThisRow * Math.floor(width / xstride)); - for (let tileY = 0; tileY < tileHeight; tileY++) { - for (let xRep = 0; xRep < xrepsThisRow; xRep++) { - const inOffset = - numComps * - ((yRep * xreps + xRep) * width * height + ystride * tileY * width); - - for (let tileX = 0; tileX < tileWidth; tileX++) { - // copy value - for (let nc = 0; nc < numComps; nc++) { - volCopyData( - newArray, - outIdx, - data[inOffset + xstride * tileX * numComps + nc], - res.offset[nc], - res.scale[nc] - ); - outIdx++; - } - } - } - outIdx += outXContIncr; + // otherwise convert to float + const newArray = new Float32Array(numPixelsIn * numComps); + // compute min and max values + model.volumeInfo.offset = computedOffset; + model.volumeInfo.scale = computedScale; + let count = 0; + const scaleInverse = computedScale.map((s) => 1 / s); + for (let i = 0; i < numPixelsIn; i++) { + for (let nc = 0; nc < numComps; nc++) { + newArray[count] = (data[count] - computedOffset[nc]) * scaleInverse[nc]; + count++; } } - - // Source texture data from the PBO. - // model.context.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); - model.context.pixelStorei(model.context.UNPACK_ALIGNMENT, 1); - - model.context.texImage2D( - model.target, - 0, - model.internalFormat, - model.width, - model.height, - 0, - model.format, - model.openGLDataType, + return publicAPI.create3DFromRaw( + width, + height, + depth, + numComps, + VtkDataTypes.FLOAT, newArray ); - - publicAPI.deactivate(); - return true; }; publicAPI.setOpenGLRenderWindow = (rw) => { diff --git a/Sources/Rendering/OpenGL/VertexArrayObject/index.js b/Sources/Rendering/OpenGL/VertexArrayObject/index.js index 7ed59f05960..16cffbbe472 100644 --- a/Sources/Rendering/OpenGL/VertexArrayObject/index.js +++ b/Sources/Rendering/OpenGL/VertexArrayObject/index.js @@ -15,133 +15,32 @@ function vtkOpenGLVertexArrayObject(publicAPI, model) { }; publicAPI.initialize = () => { - model.instancingExtension = null; - if (!model.openGLRenderWindow.getWebgl2()) { - model.instancingExtension = model.context.getExtension( - 'ANGLE_instanced_arrays' - ); - } - if ( - !model.forceEmulation && - model.openGLRenderWindow && - model.openGLRenderWindow.getWebgl2() - ) { - model.extension = null; - model.supported = true; - model.handleVAO = model.context.createVertexArray(); - } else { - model.extension = model.context.getExtension('OES_vertex_array_object'); - // Start setting up VAO - if (!model.forceEmulation && model.extension) { - model.supported = true; - model.handleVAO = model.extension.createVertexArrayOES(); - } else { - model.supported = false; - } - } + model.handleVAO = model.context.createVertexArray(); }; - publicAPI.isReady = () => - // We either probed and allocated a VAO, or are falling back as the current - // hardware does not support VAOs. - model.handleVAO !== 0 || model.supported === false; + publicAPI.isReady = () => model.handleVAO !== 0; publicAPI.bind = () => { // Either simply bind the VAO, or emulate behavior by binding all attributes. if (!publicAPI.isReady()) { publicAPI.initialize(); } - if (publicAPI.isReady() && model.supported) { - if (model.extension) { - model.extension.bindVertexArrayOES(model.handleVAO); - } else { - model.context.bindVertexArray(model.handleVAO); - } - } else if (publicAPI.isReady()) { - const gl = model.context; - for (let ibuff = 0; ibuff < model.buffers.length; ++ibuff) { - const buff = model.buffers[ibuff]; - model.context.bindBuffer(gl.ARRAY_BUFFER, buff.buffer); - for (let iatt = 0; iatt < buff.attributes.length; ++iatt) { - const attrIt = buff.attributes[iatt]; - const matrixCount = attrIt.isMatrix ? attrIt.size : 1; - for (let i = 0; i < matrixCount; ++i) { - gl.enableVertexAttribArray(attrIt.index + i); - gl.vertexAttribPointer( - attrIt.index + i, - attrIt.size, - attrIt.type, - attrIt.normalize, - attrIt.stride, - attrIt.offset + (attrIt.stride * i) / attrIt.size - ); - if (attrIt.divisor > 0) { - if (model.instancingExtension) { - model.instancingExtension.vertexAttribDivisorANGLE( - attrIt.index + i, - 1 - ); - } else { - gl.vertexAttribDivisor(attrIt.index + i, 1); - } - } - } - } - } + if (publicAPI.isReady()) { + model.context.bindVertexArray(model.handleVAO); } }; publicAPI.release = () => { // Either simply release the VAO, or emulate behavior by releasing all attributes. - if (publicAPI.isReady() && model.supported) { - if (model.extension) { - model.extension.bindVertexArrayOES(null); - } else { - model.context.bindVertexArray(null); - } - } else if (publicAPI.isReady()) { - const gl = model.context; - for (let ibuff = 0; ibuff < model.buffers.length; ++ibuff) { - const buff = model.buffers[ibuff]; - model.context.bindBuffer(gl.ARRAY_BUFFER, buff.buffer); - for (let iatt = 0; iatt < buff.attributes.length; ++iatt) { - const attrIt = buff.attributes[iatt]; - const matrixCount = attrIt.isMatrix ? attrIt.size : 1; - for (let i = 0; i < matrixCount; ++i) { - gl.enableVertexAttribArray(attrIt.index + i); - gl.vertexAttribPointer( - attrIt.index + i, - attrIt.size, - attrIt.type, - attrIt.normalize, - attrIt.stride, - attrIt.offset + (attrIt.stride * i) / attrIt.size - ); - if (attrIt.divisor > 0) { - if (model.instancingExtension) { - model.instancingExtension.vertexAttribDivisorANGLE( - attrIt.index + i, - 0 - ); - } else { - gl.vertexAttribDivisor(attrIt.index + i, 0); - } - } - gl.disableVertexAttribArray(attrIt.index + i); - } - } - } + if (publicAPI.isReady()) { + model.context.bindVertexArray(null); } }; publicAPI.shaderProgramChanged = () => { publicAPI.release(); if (model.handleVAO) { - if (model.extension) { - model.extension.deleteVertexArrayOES(model.handleVAO); - } else { - model.context.deleteVertexArray(model.handleVAO); - } + model.context.deleteVertexArray(model.handleVAO); } model.handleVAO = 0; model.handleProgram = 0; @@ -150,14 +49,9 @@ function vtkOpenGLVertexArrayObject(publicAPI, model) { publicAPI.releaseGraphicsResources = () => { publicAPI.shaderProgramChanged(); if (model.handleVAO) { - if (model.extension) { - model.extension.deleteVertexArrayOES(model.handleVAO); - } else { - model.context.deleteVertexArray(model.handleVAO); - } + model.context.deleteVertexArray(model.handleVAO); } model.handleVAO = 0; - model.supported = true; model.handleProgram = 0; }; @@ -251,40 +145,11 @@ function vtkOpenGLVertexArrayObject(publicAPI, model) { ); if (divisor > 0) { - if (model.instancingExtension) { - model.instancingExtension.vertexAttribDivisorANGLE(attribs.index, 1); - } else { - gl.vertexAttribDivisor(attribs.index, 1); - } + gl.vertexAttribDivisor(attribs.index, 1); } attribs.buffer = buffer.getHandle(); - // If vertex array objects are not supported then build up our list. - if (!model.supported) { - // find the buffer - let buffFound = false; - for (let ibuff = 0; ibuff < model.buffers.length; ++ibuff) { - const buff = model.buffers[ibuff]; - if (buff.buffer === attribs.buffer) { - buffFound = true; - let found = false; - for (let iatt = 0; iatt < buff.attributes.length; ++iatt) { - const attrIt = buff.attributes[iatt]; - if (attrIt.name === name) { - found = true; - buff.attributes[iatt] = attribs; - } - } - if (!found) { - buff.attributes.push(attribs); - } - } - } - if (!buffFound) { - model.buffers.push({ buffer: attribs.buffer, attributes: [attribs] }); - } - } return true; }; @@ -332,11 +197,7 @@ function vtkOpenGLVertexArrayObject(publicAPI, model) { offset + (stride * i) / elementTupleSize ); if (divisor > 0) { - if (model.instancingExtension) { - model.instancingExtension.vertexAttribDivisorANGLE(index + i, 1); - } else { - gl.vertexAttribDivisor(index + i, 1); - } + gl.vertexAttribDivisor(index + i, 1); } } @@ -347,24 +208,6 @@ function vtkOpenGLVertexArrayObject(publicAPI, model) { if (!publicAPI.isReady() || model.handleProgram === 0) { return false; } - - // If we don't have real VAOs find the entry and remove it too. - if (!model.supported) { - for (let ibuff = 0; ibuff < model.buffers.length; ++ibuff) { - const buff = model.buffers[ibuff]; - for (let iatt = 0; iatt < buff.attributes.length; ++iatt) { - const attrIt = buff.attributes[iatt]; - if (attrIt.name === name) { - buff.attributes.splice(iatt, 1); - if (!buff.attributes.length) { - model.buffers.splice(ibuff, 1); - } - return true; - } - } - } - } - return true; }; @@ -389,7 +232,6 @@ const DEFAULT_VALUES = { forceEmulation: false, handleVAO: 0, handleProgram: 0, - supported: true, buffers: null, context: null, openGLRenderWindow: null, @@ -406,9 +248,6 @@ export function extend(publicAPI, model, initialValues = {}) { // Object methods macro.obj(publicAPI, model); - // Create get-only macros - macro.get(publicAPI, model, ['supported']); - // Create get-set macros macro.setGet(publicAPI, model, ['forceEmulation']); diff --git a/Sources/Rendering/OpenGL/VolumeMapper/index.js b/Sources/Rendering/OpenGL/VolumeMapper/index.js index 4cb6c26af43..d55d3bd637a 100644 --- a/Sources/Rendering/OpenGL/VolumeMapper/index.js +++ b/Sources/Rendering/OpenGL/VolumeMapper/index.js @@ -687,15 +687,6 @@ function vtkOpenGLVolumeMapper(publicAPI, model) { program.setUniform3f('vVCToIJK', vctoijk[0], vctoijk[1], vctoijk[2]); program.setUniform3i('volumeDimensions', dims[0], dims[1], dims[2]); - if (!model.openGLRenderWindow.getWebgl2()) { - const volInfo = model.scalarTexture.getVolumeInfo(); - program.setUniformf('texWidth', model.scalarTexture.getWidth()); - program.setUniformf('texHeight', model.scalarTexture.getHeight()); - program.setUniformi('xreps', volInfo.xreps); - program.setUniformi('xstride', volInfo.xstride); - program.setUniformi('ystride', volInfo.ystride); - } - // map normals through normal matrix // then use a point on the plane to compute the distance const normal = new Float64Array(3); @@ -1309,35 +1300,17 @@ function vtkOpenGLVolumeMapper(publicAPI, model) { model.opacityTexture.setMinificationFilter(Filter.LINEAR); model.opacityTexture.setMagnificationFilter(Filter.LINEAR); - // use float texture where possible because we really need the resolution + // use float texture because we really need the resolution // for this table. Errors in low values of opacity accumulate to // visible artifacts. High values of opacity quickly terminate without // artifacts. - if ( - model.openGLRenderWindow.getWebgl2() || - (model.context.getExtension('OES_texture_float') && - model.context.getExtension('OES_texture_float_linear')) - ) { - model.opacityTexture.create2DFromRaw( - oWidth, - 2 * numIComps, - 1, - VtkDataTypes.FLOAT, - ofTable - ); - } else { - const oTable = new Uint8Array(oSize); - for (let i = 0; i < oSize; ++i) { - oTable[i] = 255.0 * ofTable[i]; - } - model.opacityTexture.create2DFromRaw( - oWidth, - 2 * numIComps, - 1, - VtkDataTypes.UNSIGNED_CHAR, - oTable - ); - } + model.opacityTexture.create2DFromRaw( + oWidth, + 2 * numIComps, + 1, + VtkDataTypes.FLOAT, + ofTable + ); model.opacityTextureString = toString; } diff --git a/Sources/Rendering/OpenGL/glsl/vtkVolumeFS.glsl b/Sources/Rendering/OpenGL/glsl/vtkVolumeFS.glsl index dfe57e052c9..78ba7f8a8ed 100644 --- a/Sources/Rendering/OpenGL/glsl/vtkVolumeFS.glsl +++ b/Sources/Rendering/OpenGL/glsl/vtkVolumeFS.glsl @@ -87,10 +87,6 @@ uniform float gomax3; #endif #endif -// if you want to see the raw tiled -// data in webgl1 uncomment the following line -// #define debugtile - // camera values uniform float camThick; uniform float camNear; @@ -191,10 +187,6 @@ uniform vec4 ipScalarRangeMax; // Lighting values //VTK::Light::Dec -//======================================================================= -// Webgl2 specific version of functions -#if __VERSION__ == 300 - uniform highp sampler3D texture1; vec4 getTextureValue(vec3 pos) @@ -212,80 +204,6 @@ vec4 getTextureValue(vec3 pos) return tmp; } -//======================================================================= -// WebGL1 specific version of functions -#else - -uniform sampler2D texture1; - -uniform float texWidth; -uniform float texHeight; -uniform int xreps; -uniform int xstride; -uniform int ystride; - -// if computing trilinear values from multiple z slices -#ifdef vtkTrilinearOn -vec4 getTextureValue(vec3 ijk) -{ - float zoff = 1.0/float(volumeDimensions.z); - vec4 val1 = getOneTextureValue(ijk); - vec4 val2 = getOneTextureValue(vec3(ijk.xy, ijk.z + zoff)); - - float indexZ = float(volumeDimensions)*ijk.z; - float zmix = indexZ - floor(indexZ); - - return mix(val1, val2, zmix); -} - -vec4 getOneTextureValue(vec3 ijk) -#else // nearest or fast linear -vec4 getTextureValue(vec3 ijk) -#endif -{ - vec3 tdims = vec3(volumeDimensions); - -#ifdef debugtile - vec2 tpos = vec2(ijk.x, ijk.y); - vec4 tmp = texture2D(texture1, tpos); - tmp.a = 1.0; - -#else - int z = int(ijk.z * tdims.z); - int yz = z / xreps; - int xz = z - yz*xreps; - - int tileWidth = volumeDimensions.x/xstride; - int tileHeight = volumeDimensions.y/ystride; - - xz *= tileWidth; - yz *= tileHeight; - - float ni = float(xz) + (ijk.x*float(tileWidth)); - float nj = float(yz) + (ijk.y*float(tileHeight)); - - vec2 tpos = vec2(ni/texWidth, nj/texHeight); - - vec4 tmp = texture2D(texture1, tpos); - -#if vtkNumComponents == 1 - tmp.a = tmp.r; -#endif -#if vtkNumComponents == 2 - tmp.g = tmp.a; -#endif -#if vtkNumComponents == 3 - tmp.a = length(tmp.rgb); -#endif -#endif - - return tmp; -} - -// End of Webgl1 specific code -//======================================================================= -#endif - //======================================================================= // compute the normal and gradient magnitude for a position vec4 computeNormal(vec3 pos, float scalar, vec3 tstep)