检测WebGL支持的正确方法?

时间:2012-08-08 18:44:16

标签: javascript jquery firefox cross-browser webgl

我试图检测跨多个浏览器的WebGL支持,我遇到了以下情况。即使访问者的视频卡被黑名单和/或WebGL被禁用,当前版本的Firefox似乎也会使用以下检查报告正面支持:

if (window.WebGLRenderingContext) {
    // This is true in Firefox under certain circumstances,
    // even when WebGL is disabled...
}

我已尝试使用以下步骤指示我的用户启用WebGL。这在某些情况下有效,但并非总是如此。显然,这不是我可以向公众要求的东西:

  1. 在Firefox的地址栏中输入 about:config
  2. 要启用WebGL,请将 webgl.force-enabled 设置为true
  3. 这使我创建了自己的检测支持方法,它使用jQuery注入canvas元素来检测支持。这引出了我在各种WebGL库和插件中发现的许多技术。麻烦的是,测试非常困难(对以下链接是否适合您的任何评论都非常感谢!)。为了使这成为一个客观的问题,我想知道是否有一种普遍接受的方法来检测所有浏览器的WebGL支持

    测试网址:

    http://jsfiddle.net/Jn49q/5/

7 个答案:

答案 0 :(得分:34)

[ 2014年10月] 我已更新了modernizrs示例以匹配他们的current implementation,这是http://get.webgl.org/下面的清理版本。

Modernizr确实,

var canvas;
var ctx;
var exts;

try {
  canvas = createElement('canvas');
  ctx = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
  exts = ctx.getSupportedExtensions();
}
catch (e) {
  return;
}

if (ctx !== undefined) {
  Modernizr.webglextensions = new Boolean(true);
}

for (var i = -1, len = exts.length; ++i < len; ){
  Modernizr.webglextensions[exts[i]] = true;
}

canvas = undefined;

Chromium指向http://get.webgl.org/规范支持实施,

try { gl = canvas.getContext("webgl"); }
catch (x) { gl = null; }

if (gl == null) {
    try { gl = canvas.getContext("experimental-webgl"); experimental = true; }
    catch (x) { gl = null; }
}

答案 1 :(得分:32)

优秀的三库实际上是一种检测以下内容的机制:

  1. WebGL支持
  2. 文件API支持
  3. 工人支持
  4. 对于WebGL,特别是以下是使用的代码:

    function webgl_support () { 
       try {
        var canvas = document.createElement('canvas'); 
        return !!window.WebGLRenderingContext &&
          (canvas.getContext('webgl') || canvas.getContext('experimental-webgl'));
       } catch(e) {
         return false;
       }
     };
    

    该代码段是Detector类的一部分,它还可能向用户显示相应的错误消息。

答案 2 :(得分:18)

http://www.browserleaks.com/webgl#howto-detect-webgl

所示
  

这是一个正确的javascript函数,用于检测WebGL支持,包含所有类型的实验性WebGL上下文名称,并检查特殊情况,例如通过NoScript或TorBrowser阻止WebGL函数。

     

它将报告三种WebGL功能状态之一:

     
      
  • 启用WebGL - 返回TRUE,或返回
  •   
  • WebGL对象,如果传递了第一个参数
  •   
  • WebGL已停用 - 返回FALSE,如果需要,可以更改   
  • WebGL没有得到重视 - 返回FALSE
  •   
function webgl_detect(return_context)
{
    if (!!window.WebGLRenderingContext) {
        var canvas = document.createElement("canvas"),
             names = ["webgl2", "webgl", "experimental-webgl", "moz-webgl", "webkit-3d"],
           context = false;

        for(var i=0;i< names.length;i++) {
            try {
                context = canvas.getContext(names[i]);
                if (context && typeof context.getParameter == "function") {
                    // WebGL is enabled
                    if (return_context) {
                        // return WebGL object if the function's argument is present
                        return {name:names[i], gl:context};
                    }
                    // else, return just true
                    return true;
                }
            } catch(e) {}
        }

        // WebGL is supported, but disabled
        return false;
    }

    // WebGL not supported
    return false;
}

答案 3 :(得分:8)

除了@Andrew的回答,还有可以支持的实验模式。我写了以下代码片段:

var canvasID = 'webgl',
    canvas = document.getElementById(canvasID),
    gl,
    glExperimental = false;

function hasWebGL() {

    try { gl = canvas.getContext("webgl"); }
    catch (x) { gl = null; }

    if (gl === null) {
        try { gl = canvas.getContext("experimental-webgl"); glExperimental = true; }
        catch (x) { gl = null; }
    }

    if(gl) { return true; }
    else if ("WebGLRenderingContext" in window) { return true; } // not a best way, as you're not 100% sure, so you can change it to false
    else { return false; }
}

根据您的ID更改canvasID变量。

在Chrome,Safari,Firefox,Opera和IE(8到10)上测试过。如果Safari记得它可用,但您需要显式启用WebGL(启用开发人员菜单并在之后启用Web GL选项)。

答案 4 :(得分:2)

为了检测支持WebGL的浏览器,但是遗漏旧浏览器可能不能很好地支持它(根据WebGL detected as supported when it is actually not的需要排除Android 4.4.2设备),我添加的更紧,但不相关检查:

function hasWebGL() {
    var supported;

    try {
        var canvas = document.createElement('canvas');
        supported = !! window.WebGLRenderingContext && (canvas.getContext('webgl') || canvas.getContext('experimental-webgl'));
    } catch(e) { supported = false; }

    try {
        // let is by no means required, but will help us rule out some old browsers/devices with potentially buggy implementations: http://caniuse.com/#feat=let
        eval('let foo = 123;');
    } catch (e) { supported = false; }

    if (supported === false) {
        console.log("WebGL is not supported");
    }

    canvas = undefined;

    return supported;
},

答案 5 :(得分:1)

// this code will detect WebGL version until WebGL Version maxVersionTest 
var
maxVersionTest = 5,
canvas = document.createElement('canvas'),
webglVersion = (canvas.getContext('webgl') || canvas.getContext('experimental-webgl')) ? 1 : null,
canvas = null; // free context

// range: if maxVersionTest = 5 makes [5, 4, 3, 2]
Array.apply(null, Array(maxVersionTest - 1))
.map(function (_, idx) {return idx + 2;})
.reverse()
.some(function(version){
    // cant reuse canvas, potential to exceed contexts or mem limit *
    if (document.createElement('canvas').getContext('webgl'+version))
        return !!(webglVersion = version);
});

console.log(webglVersion);

*重新&#34;可能超出上下文或内存限制&#34;看到 https://bugs.chromium.org/p/chromium/issues/detail?id=226868

答案 6 :(得分:0)

来自MDN

&#13;
&#13;
// Run everything inside window load event handler, to make sure
// DOM is fully loaded and styled before trying to manipulate it.
window.addEventListener("load", function() {
  var paragraph = document.querySelector("p"),
    button = document.querySelector("button");
  // Adding click event handler to button.
  button.addEventListener("click", detectWebGLContext, false);
  function detectWebGLContext () {
    // Create canvas element. The canvas is not added to the
    // document itself, so it is never displayed in the
    // browser window.
    var canvas = document.createElement("canvas");
    // Get WebGLRenderingContext from canvas element.
    var gl = canvas.getContext("webgl")
      || canvas.getContext("experimental-webgl");
    // Report the result.
    if (gl && gl instanceof WebGLRenderingContext) {
      paragraph.innerHTML =
        "Congratulations! Your browser supports WebGL.";
    } else {
      paragraph.innerHTML = "Failed to get WebGL context. "
        + "Your browser or device may not support WebGL.";
    }
  }
}, false);
&#13;
body {
  text-align : center;
}
button {
  display : block;
  font-size : inherit;
  margin : auto;
  padding : 0.6em;
}
&#13;
<p>[ Here would go the result of WebGL feature detection ]</p>
<button>Press here to detect WebGLRenderingContext</button>
&#13;
&#13;
&#13;