63 votes

Comment détecter correctement le support WebGL ?

Je tente de détecter la prise en charge de WebGL sur plusieurs navigateurs et j'ai rencontré le scénario suivant. La version actuelle de Firefox semble signaler une prise en charge positive en utilisant la vérification suivante, même lorsque la carte vidéo du visiteur est sur liste noire et/ou que WebGL est désactivé :

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

J'ai essayé de demander à mes utilisateurs d'activer WebGL en suivant les étapes suivantes. Cela a fonctionné dans certains cas, mais pas toujours. Évidemment, ce n'est pas quelque chose que je peux demander au grand public :

  1. Type about:config dans la barre d'adresse de Firefox
  2. Pour activer WebGL, définissez webgl.force-enabled à vrai

Cela m'a conduit à créer ma propre méthode de détection du support, qui utilise jQuery pour injecter un élément de toile afin de détecter le support. Cette méthode s'inspire d'un certain nombre de techniques que j'ai trouvées dans diverses bibliothèques et plugins WebGL. Le problème est qu'il est extrêmement difficile de la tester (tout commentaire sur le fonctionnement du lien ci-dessous sera apprécié !) Pour en faire une question objective, J'aimerais savoir s'il existe une méthode universellement acceptée pour détecter le support de WebGL sur tous les navigateurs. .

URL DU TEST :

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

1 votes

Eek, je n'avais aucune idée qu'il y avait d'autres moyens d'obtenir le contexte webgl au-delà de experimental-webgl Merci de l'avoir souligné.

0 votes

Et que voulez-vous dire par votre méthode est difficile à tester ? Avez-vous peur qu'elle crée de faux positifs/négatifs ? Il me semble que si vous demandez un contexte webgl et que vous ne l'obtenez pas, alors votre application ne peut pas continuer. A moins que quelque chose ne m'échappe ?

0 votes

@MattGreer, c'est difficile à tester dans le sens où il est difficile de trouver une machine de test avec la combinaison spécifique de Firefox et une carte vidéo sur liste noire et/ou des graphiques non supportés. Plus précisément, j'essaie de savoir dans quelles circonstances ma méthode de test renvoie "false" dans la dernière version de Firefox.

62voto

user2070775 Points 523

L'excellente bibliothèque Three dispose, en effet, d'un mécanisme permettant de détecter ce qui suit :

  1. Prise en charge de WebGL
  2. Support de l'API fichier
  3. Soutien aux travailleurs

Pour WebGL, en particulier, voici le code qui est utilisé :

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

Ce bout de code fait partie d'un Détecteur qui peut également afficher les messages d'erreur correspondants à l'utilisateur.

7 votes

Joli et compact. exactement ce que l'auteur a demandé. je ne comprends pas pourquoi les gens incluent le code supplémentaire non pertinent dans leurs réponses.

0 votes

Quel est le but de l'opérateur double not : !!window.WebGLRenderingContext ?

0 votes

37voto

Andrew Points 8248

[ Oct 2014] J'ai mis à jour l'exemple de modernizrs pour correspondre à leur application actuelle qui est une version épurée de http://get.webgl.org/ plus bas.

Modernizr fait,

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;

Chrome Les points suivants http://get.webgl.org/ pour l'implémentation du support canonique,

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

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

0 votes

@Cupidvogel : Tous Navigateurs supportant la toile donc 88,94%. Vous pouvez obtenir 100% en l'enveloppant dans un déclaration try-catch .

2 votes

@Cupidvogel Cela ne fonctionne pas avec Safari (à partir de la version 7.0.3), qui ne prend pas encore en charge les fonctions suivantes getContext("webgl") et ne fonctionnera qu'avec getContext("experimental-webgl") o getContext("webkit-3d") .

20voto

iglooJuan Points 153

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

Il s'agit d'une fonction javascript appropriée pour détecter la prise en charge de WebGL, avec toutes sortes de noms de contextes WebGL expérimentaux et avec la vérification de cas spéciaux, comme le blocage des fonctions WebGL par NoScript ou TorBrowser.

Il signalera l'un des trois états de capacité WebGL :

  • WebGL est activé - retournez TRUE, ou retournez
  • Objet WebGL, si le premier argument a été transmis.
  • WebGL est désactivé - retournez FALSE, vous pouvez le changer si vous en avez besoin.
  • WebGL n'est pas implémenté - retourner 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;
}

0 votes

Pourquoi la double négation de window.WebGLRenderingContext ?

0 votes

Je ne suis pas vraiment sûr, j'ai collé le code qui a fonctionné pour moi à partir du lien ci-dessus, mais voici quelques explications à ce sujet : stackoverflow.com/questions/784929/

3 votes

@sijpkes double négations convertit les valeurs truthy/falsey en leur représentation booléenne : !!"" === false && !!1 === true

8voto

Carlos Points 2308

En plus de la réponse de @Andrew, il existe également un mode expérimental qui peut être pris en charge. J'ai écrit le bout de code suivant :

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

Cambia canvasID variable en fonction de votre ID.

Testé sur Chrome, Safari, Firefox, Opera et IEs (8 à 10). Dans le cas de Safari, rappelez-vous qu'il est disponible, mais vous devez activer WebGL explicitement (activer le menu de développement et activer l'option Web GL après).

2voto

Jose Gómez Points 1867

Afin de détecter les navigateurs qui prennent en charge WebGL, mais en laissant de côté les navigateurs plus anciens qui ne le prennent pas bien en charge (comme cela est nécessaire dans l'application WebGL détecté comme étant supporté alors qu'il ne l'est pas en réalité pour exclure les appareils Android 4.4.2), j'ajoute une vérification plus stricte, bien que sans rapport :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X