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)