it-swarm.com.de

Richtige Methode zum Erkennen von WebGL-Unterstützung?

Ich versuche, die WebGL-Unterstützung in mehreren Browsern zu erkennen, und bin auf das folgende Szenario gestoßen. Die aktuelle Firefox-Version scheint mit der folgenden Überprüfung positive Unterstützung zu melden, auch wenn die Grafikkarte des Besuchers auf der schwarzen Liste steht und/oder WebGL deaktiviert ist:

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

Ich habe versucht, meine Benutzer anzuweisen, WebGL mithilfe der folgenden Schritte zu aktivieren. Dies hat in einigen Fällen funktioniert, aber nicht immer. Dies kann ich natürlich nicht von der breiten Öffentlichkeit fordern:

  1. Geben Sie in die Adressleiste von Firefox about: config ein
  2. Um WebGL zu aktivieren, setzen Sie webgl.force-enabled auf true

Dies hat mich dazu veranlasst, eine eigene Methode zum Erkennen von Support zu erstellen, die jQuery verwendet, um ein Canvas-Element zum Erkennen von Support einzufügen. Dies basiert auf einer Reihe von Techniken, die ich in verschiedenen WebGL-Bibliotheken und Plugins gefunden habe. Das Problem ist, es ist extrem schwierig zu testen (Kommentare dazu, ob der unten stehende Link für Sie funktioniert, werden sehr geschätzt!). Um dies zu einer objektiven Frage zu machen, würde ich gerne wissen, ob es eine allgemein akzeptierte Möglichkeit gibt, die Unterstützung von WebGL in allen Browsern zu erkennen .

TEST URL:

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

49
Derek Hunziker

[Oct 2014] Ich habe das modernizrs-Beispiel aktualisiert, damit es mit aktuelle Implementierung übereinstimmt. Dies ist eine bereinigte Version von http://get.webgl.org/ unten.

Modernizr tut,

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 verweist auf http://get.webgl.org/ für die kanonische Support-Implementierung. 

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

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

Die exzellente Three-Bibliothek verfügt über einen Mechanismus zum Erkennen von Folgendem: 

  1. WebGL-Unterstützung
  2. Datei-API-Unterstützung
  3. Arbeiter unterstützen

Insbesondere für WebGL ist hier der Code, der verwendet wird:

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

Dieses Code-Snippet ist Teil einer Detector - Klasse, die dem Benutzer auch die entsprechenden Fehlermeldungen anzeigen kann.

32
oabarca

Wie in http://www.browserleaks.com/webgl#howto-detect-webgl zu sehen ist.

Dies ist eine richtige JavaScript-Funktion zum Erkennen der WebGL-Unterstützung mit allen Arten von experimentellen WebGL-Kontextnamen und zum Überprüfen von Sonderfällen, wie beispielsweise das Blockieren von WebGL-Funktionen durch NoScript oder TorBrowser.

Es wird einer der drei WebGL-Funktionszustände gemeldet:

  • WebGL ist aktiviert - Rückgabe TRUE oder Rückgabe 
  • WebGL-Objekt, wenn das erste Argument übergeben wurde
  • WebGL ist deaktiviert. Geben Sie FALSE zurück. Sie können es bei Bedarf ändern
  • WebGL ist nicht implizit - geben Sie FALSE zurück
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;
}
18
Juan Arias

Neben der Antwort von @Andrew gibt es auch einen experimentellen Modus, der unterstützt werden kann. Ich habe folgenden Code-Ausschnitt geschrieben:

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; }
}

Ändern Sie die Variable canvasID entsprechend Ihrer ID.

Getestet auf Chrome, Safari, Firefox, Opera und IEs (8 bis 10). Bei Safari ist zu beachten, dass es verfügbar ist. Sie müssen WebGL jedoch explizit aktivieren (aktivieren Sie das Entwicklermenü und aktivieren Sie danach die Option Web GL.

8
Karol

Um Browser zu erkennen, die WebGL unterstützen, kann das Auslassen älterer Browser jedoch möglicherweise nicht gut unterstützt werden (wie in WebGL als unterstützt erkannt, wenn es eigentlich nicht ist zum Ausschluss von Android 4.4.2-Geräten), füge ich hinzu eine engere, wenn auch nicht zusammenhängende Prüfung:

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;
},
2
Jose Gómez
// 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);

* siehe "Potenzial, Kontexte oder Mem-Limit zu überschreiten", siehe https://bugs.chromium.org/p/chromium/issues/detail?id=226868

1
ekerner

Von 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>

0