2017-01-19 5 views
0

Diese Frage könnte seltsam sein, aber nehmen wir an, wir haben eine Leinwand, die zum Beispiel 3D-Inhalte wie diese zeichnet experiment.HTML Canvas Sniff Webgl Daten

Unabhängig von der Verwendung von ThreeJS, Babylon oder einer anderen Bibliothek, um denselben Effekt zu erzielen, ist es möglich, ein Intervall festzulegen, das die Geburt jedes Voxels kopiert und später wiederholt (neu zeichnet).

Ich möchte einfach den Canvas-Zeichenprozess aufzeichnen und wiedergeben, ohne RTC, Video oder Bildsequenz zu verwenden.

Was wurde getan?

Ich habe versucht, mit WebGl Context und Stream Capture, aber leider nicht das gewünschte Ergebnis erzielen konnte.

Kann mir jemand dabei helfen?

+1

Wie haben Sie den Stream Capture versucht? Es funktioniert gut für mich in dem angegebenen [Beispiel Link] (http://www.laplace2be.com/lab/PixelParticles/). Kopiere das in der Konsole: 'let s = mycanvas.captureStream(), r = neuer MediaRecorder (s), chunks = []; r.ondataavailable = e => chunks.push (e.data); r.onstop = e => { window.open (URL.createObjectURL (neuer Blob (Chunks))); }; r.start(); setTimeout (_ => r.stop(), 3000); ' – Kaiido

+0

@Kaiido vielen Dank für Ihren Kommentar, ich tat das, aber dieser Blob ist eigentlich ein Webm-Video, das in meinem Fall eigentlich keine optimale Lösung ist die Größe wird riesig sein. würdest du das bitte als antwort hinzufügen? – ProllyGeek

Antwort

1

Sie können den WebGL-Kontext umbrechen und alle Funktionsaufrufe erfassen. Ein Beispiel für die WebGL-Kontext Einwickeln wäre so etwas wie

const rawgl = document.querySelector("canvas").getContext("webgl"); 
 
const gl = wrapContext(rawgl); 
 

 
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); 
 
gl.enable(gl.SCISSOR_TEST); 
 
gl.scissor(40, 50, 200, 60); 
 
gl.clearColor(0,1,1,1); 
 
gl.clear(gl.COLOR_BUFFER_BIT); 
 
gl.scissor(60, 40, 70, 90); 
 
gl.clearColor(1,0,1,1); 
 
gl.clear(gl.COLOR_BUFFER_BIT); 
 

 
function wrapContext(gl) { 
 
    const wrapper = {}; 
 
    for (let name in gl) { 
 
    var prop = gl[name]; 
 
    if (typeof(prop) === 'function') { 
 
     wrapper[name] = wrapFunction(gl, name, prop); 
 
    } else { 
 
     wrapProperty(wrapper, gl, name); 
 
    } 
 
    } 
 
    return wrapper; 
 
} 
 

 
function wrapFunction(gl, name, origFn) { 
 
    // return a function that logs the call and then calls the original func 
 
    return function(...args) { 
 
    log(`gl.${name}(${[...args].join(", ")});`); 
 
    origFn.apply(gl, arguments); 
 
    }; 
 
} 
 

 
function wrapProperty(wrapper, gl, name) { 
 
    // make a getter because these values are dynamic 
 
    Object.defineProperty(wrapper, name, { 
 
    enumerable: true, 
 
    get: function() { 
 
     return gl[name]; 
 
    }, 
 
    }); 
 
} 
 

 
function log(...args) { 
 
    const elem = document.createElement("pre"); 
 
    elem.textContent = [...args].join(" "); 
 
    document.body.appendChild(elem); 
 
}
canvas { border: 1px solid black; } 
 
pre { margin: 0; }
<canvas></canvas>

In Ihrem Fall statt Protokollierung der Anrufe, die Sie sie zu einem gewissen Array von Anrufen hinzufügen würde nur auf die Bilder, die Sie erfasst werden soll.

Sie müssen dann irgendwie den Überblick behalten aller Ressourcen (Puffer, Texturen Framebuffer, renderbuffers, Shadern, Programme) und alle ihre Parameter (wie Filtereinstellungen auf Texturen), und Sie müssen auch einheitliche Einstellungen usw.

verfolgen

Die WebGL-Inspector tut dies und kann Frames wiedergeben, so dass es ein gutes Beispiel sein könnte. Es gibt auch diese webgl-capture Bibliothek.

Was Sie für Ihr Programm erfassen müssen, hängt von Ihrem Programm ab. Wenn Sie zum Beispiel wissen, dass sich Ihre Puffer und Texturen nie ändern und sie sich immer noch im Speicher befinden, wenn Sie sie wiedergeben wollen, dann müssen Sie möglicherweise nicht versuchen, den Zustand der Puffer und Texturen zu erfassen, was beide oben genannten Beispiele zu tun haben.

+0

Wie lässt sich eine Bildlaufleiste in Ihrer Antwort anzeigen? – J3STER

+0

Was meinst du? [Es scrollt für mich] (http://imgur.com/a/qkhY1). Wenn es nicht für Sie scrollt, schlage ich vor, dass Sie [einen Fehler melden] (http://meta.stackoverflow.com). Sonst bekommt jeder Code Block, der länger als 40 Zeilen lang ist, automatisch eine Bildlaufleiste – gman

+0

Danke für deine Hilfe @gman, deine Antwort hat mich dazu gebracht viele Dinge zu entdecken, die ich vorher nicht bemerkt habe. – ProllyGeek

1

Ich weiß nicht, wie Sie mit der captureStream Methode versucht haben, aber auf Ihrer Beispielseite funktioniert dieser Code.

let s = mycanvas.captureStream(), 
r = new MediaRecorder(s), 
chunks = []; 
r.ondataavailable = e => chunks.push(e.data); 
r.onstop = e => { 
    let videoURL = URL.createObjectURL(new Blob(chunks)); 
    doSomethingWith(videoURL); 
    }; 
r.start(); 
setTimeout(_=>r.stop(), 3000); // records 3 seconds 

Nun, da Sie eine gültige blobURL haben die auf Ihre Leinwand Datensatz, können Sie es in einem <video> Element spielen, und dann draw it in your webgl context.