2017-02-03 5 views
0

In meiner App erzeuge ich Mipmaps für die 6x4096x4096 Cube Map Textur. Als nächstes muss ich einige andere Änderungen an dieser Textur vornehmen, die zeitabhängig sind. Die gesamte Zeichnung wird innerhalb der requestAnimationFrame-Schleife ausgeführt.Ist generateMipmap fertig?

Je nach Browser, Gerät usw. dauert es manchmal drei, manchmal vier oder sogar fünf aufeinanderfolgende Frames der Schleife, um schließlich diese Mipmaps zu generieren, und ich muss wissen, in welchem ​​Frame genau Mipmaps bereits fertig sind.

Also die Frage ist: wie in welchen Frame der Anfrage zu überprüfenAnimationFrame-Schleife Mipmaps für die "TEXTURE_CUBE_MAP" durch den WebGL-Befehl generiert "generateMipmap" bereit sind? Gibt es ein Flag zum Überprüfen des Status des Abschlusses "generateMipmap"?

Antwort

1

Es gibt keine Möglichkeit herauszufinden, wann generateMipmap fertig ist oder wie lange es dauern wird. Ich würde überrascht sein, dass es so lange dauert, aber wenn der Punkt ist, dass Sie jank eine Lösung vermeiden möchten, würden Sie Ihre eigenen Mips machen. Auf diese Weise können Sie eine lod pro Gesicht pro Rahmen oder sogar in kleineren Schritten hochladen.

Eine andere mögliche Lösung, aber wahrscheinlich funktioniert nur auf Chrome ist nur zu erraten, und ein paar Frames mit Code warten wie

gl.generateMipmap(...); 
gl.flush(); // make sure the previous command will be executed 

// now do something to wait 4 frames like 
var framesToWait = 4; 
function render() { 
    if (framesToWait) { 
    --framesToWait; 
    } else { 
    ... call drawArrays ... 
    } 
    requestAnimationFrame(render); 
} 
requestAnimationFrame(render); 

Diese Macht Arbeit, weil Chrom Multi-Prozess ist. Ich bin mir nicht sicher, was der Punkt wäre.

In WebGL2 können Sie ein FenceSync-Objekt verwenden, um herauszufinden, wann etwas fertig ist.

0

generateMipmap ist ein "synchroner" Anruf. Während Browser versuchen können, sie zu optimieren, indem sie sofort von dort zurückkehren, bevor das Erzeugen von Mip-Levels tatsächlich durchgeführt wird, wird die erste Verwendung einer Textur, für die generateMipmap aufgerufen wurde, sicherstellen, dass Mip-Levels bereit sind zu verwenden. Um es in Code setzen:

const texture = gl.createTexture(); 
gl.activeTexture(gl.TEXTURE0); 
gl.bindTexture(gl.TEXTURE_2D, texture); 
gl.texImage2D(gl.TEXTURE_2D, /* ... */); 
gl.generateMipmap(gl.TEXTURE_2D); 
gl.uniform1i(someSamplerUniform, 0); 
gl.drawArrays(/* ... */); // Here WebGL implementation will make sure that 
          // mip-levels for tetxure are ready. If they aren't, 
          // this call will cause blocking. 

Wenn Sie Inhalte von 0 Mip-Ebene der Textur ändern, müssen Sie generateMipmap wieder anrufen.

Here's ein bisschen mehr Informationen über dieses Verhalten.

+0

Vielen Dank für Ihre Antwort. Mein Problem liegt nicht in der Reihenfolge der WebGL-Befehle, sondern im Schleifenverhalten des requestAnimationFrames. Nehmen wir an, ich rufe "generateMipmap" bei der Bildnummer 0 auf. Dann würde ich gerne wissen, wie viele Frames benötigt würden, um die Erzeugung der Mipmaps abzuschließen, da ich im letzten dieser Frames die Funktion wie "drawArrays" aufrufen möchte ". Ich muss die genaue Anzahl der Frames nicht im Voraus wissen, sondern muss nur eine Art "if" -Aufgabe verwenden, wenn der Job (Mipmaps erstellen) fertig ist. –

+0

Es gibt keine API dafür. Darüber hinaus kann 'generateMipmap', wie gesagt, gesperrt werden, bis es fertig ist. Auch die Hardware des Benutzers spielt hier eine wichtige Rolle, daher gibt es auch keine Möglichkeit, zuverlässig die Anzahl von Frames zu erhalten, die Mip-Level erzeugen würden. Wenn Sie Mipmaps nicht häufig neu generieren müssen, empfehle ich, die Textur nur im selben Frame (oder vielleicht auch im nächsten Frame) zu verwenden. Wenn Sie die Textur häufig aktualisieren müssen, sollten Sie nach Möglichkeiten suchen, die Verwendung von MipMaping zu vermeiden. –

+0

Der Grund für das, was ich brauche (was auf den ersten Blick seltsam erscheinen mag) ist, dass ich einen Zeitparameter t verwende, den ich an den "DrawArrays" -ähnlichen Aufruf übergebe. Ich muss wissen, wann "generateMipmap" fertig ist (in welchem ​​Frame), so dass ich "drawArrays (t)" den richtigen Wert von t übergeben kann (ich messe die Dauer jedes Frames der Schleife des requestAnimationFrame). –