检测 WebGL 支持的正确方法
Proper way to detect WebGL support?
我正在尝试在多个浏览器中检测WebGL支持,并且遇到了以下情况。当前版本的 Firefox 似乎使用以下检查报告了积极的支持,即使访问者的视频卡被列入黑名单和/或 WebGL 被禁用:
if (window.WebGLRenderingContext) {
// This is true in Firefox under certain circumstances,
// even when WebGL is disabled...
}
我尝试使用以下步骤指示我的用户启用 WebGL。这在某些情况下有效,但并非总是如此。显然,这不是我可以向公众提出的要求:
- 类型 about:config in Firefox 的地址栏
- 要启用 WebGL,请将 webgl.force-enabled 设置为 true
这促使我创建了自己的方法来检测支持,该方法使用 jQuery 注入 canvas 元素来检测支持。这拉动了我在各种WebGL库和插件中找到的许多技术。问题是,测试起来非常困难(非常感谢对以下链接是否适合您的任何评论!为了使这个问题成为一个客观的问题,我想知道是否有一种普遍接受的方法来检测所有浏览器的WebGL支持。
测试网址:
http://jsfiddle.net/Jn49q/5/
事实上,优秀的 Three 库具有检测以下内容的机制:
- WebGL支持
- 文件接口支持
- 工人支持
特别是对于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 类的一部分,该类也可能向用户显示相应的错误消息。
[2014 年 10 月] 我已经更新了现代化示例以匹配其当前的实现,这是下面 http://get.webgl.org/进一步的清理版本。
现代化确实如此,
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; }
}
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;
}
除了@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 选项)。
但省略较旧的浏览器可能不支持它(在 WebGL 中需要检测为支持,而实际上它不是为了排除 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;
},
// 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);
* 重新"可能超过上下文或 MEM 限制"参见https://bugs.chromium.org/p/chromium/issues/detail?id=226868
来自 MDN:
// 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);
body {
text-align : center;
}
button {
display : block;
font-size : inherit;
margin : auto;
padding : 0.6em;
}
<p>[ Here would go the result of WebGL feature detection ]</p>
<button>Press here to detect WebGLRenderingContext</button>
- electronic BrowserWindow的最小高度和宽度在hide()show()方法之后不起作用
- 有没有任何方法可以将控制器从文件加载到ui路由器$stateProvider中
- 数组在递归方法中设置为null
- 打破承诺链的好方法是什么
- 在使用Polymer'加载所有json文件后执行方法;s的核心ajax
- 使用“;这个“;JavaScript原型方法中的关键字
- 序列化数据属性中对象的最可靠方法
- 使用Objective-C的JavaScript注入方法
- 有没有一种方法可以添加相同的项目val=“0”;4〃;到JavaScript中数组的每个对象
- 有没有一种方法可以防止img get请求使用css或js发生
- Javascript,有没有一种方法可以将数组写成没有逗号或空格的单个文本字符串
- 如何检测用于WebGL的专用或集成显卡
- toBoolean方法类似于toString
- 如何在单击复选框后调用控制器方法
- 检测 WebGL 支持的正确方法
- 在WebGL中进行全屏手绘的正确方法是什么
- 推荐在WebGL中制作2D HUD的方法
- Pixi.js / WebGL方法,用于将数据模型坐标转换为画布像素坐标
- Three.js/WebGL一次加载大量纹理数据,操作方法
- WebGL中批处理调用的最快方法