21 Stimmen

Wie viele Mipmaps hat eine Textur in OpenGL

Ganz abgesehen davon, dass ich derjenige bin, der die Textur überhaupt erst erstellt hat, und ich genau wissen sollte, wie viele Mipmaps ich dafür geladen/erzeugt habe. Ich mache das für einen Unit-Test. Es scheint keine Möglichkeit zu geben glGetTexParameter Parameter, um dies herauszufinden. Am ehesten komme ich mit so etwas zurecht:

int max_level;
glGetTexParameter( GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, &max_level );
int max_mipmap = -1;
for ( int i = 0; i < max_level; ++i )
{
    int width;
    glGetTexLevelParameter( GL_TEXTURE_2D, i, GL_TEXTURE_WIDTH, &width );
    if ( 0 == width )
    {
        max_mipmap = i-1;
        break;
    }
)

Wie auch immer, glGetTexLevelParameter() gibt 0 width für eine nicht existierende mipmap zurück, wenn ich eine NVidia GPU verwende, aber mit Mesa gibt es GL_INVALID_VALUE was mich zu der Annahme veranlasst, dass dies sehr wohl die Das Falsche zu tun .

Wie finde ich heraus, mit welchen Mipmap-Ebenen ich eine Textur bestückt habe?

14voto

Nicol Bolas Punkte 409659

Die Spezifikation ist diesbezüglich etwas unklar. Sie besagt, dass Sie Folgendes erhalten GL_INVALID_VALUE wenn der Level-Parameter "größer als der maximal zulässige Level-of-Detail" ist. Wie dies genau definiert ist, wird nicht angegeben.

Le site Dokumentation für die Funktion klärt die Sache ein wenig auf, indem er sagt, dass es sich um die maximal mögliche Anzahl von LODs für die größtmögliche Textur handelt ( GL_MAX_TEXTURE_SIZE ). Andere ähnliche Funktionen wie die glFramebufferTexture Familie dies ausdrücklich als Grenze für GL_INVALID_VALUE . Ich würde das also erwarten.

Mesa hat also einen Fehler. Sie können dies jedoch umgehen, indem Sie annehmen, dass entweder 0 oder ein GL_INVALID_VALUE Fehler bedeutet, dass Sie das Ende des mipmap-Arrays verlassen haben.

In diesem Zusammenhang würde ich vorschlagen, Folgendes zu verwenden glTexStorage und nie wieder die Frage stellen zu müssen. Damit wird zwangsweise verhindert, dass jemand MAX_LEVEL auf einen zu großen Wert setzt. Es ist ziemlich neu, von GL 4.2, aber es ist implementiert (oder wird sehr bald sein) über alle Nicht-Intel-Hardware, die noch unterstützt wird.

13voto

jozxyqk Punkte 15244

Es sieht so aus, als gäbe es derzeit keine Möglichkeit, abzufragen, wie viele Mipmap-Ebenen eine Textur hat, abgesehen von den Versuchen und Irrtümern des Auftraggebers mit @NicolBolas' Prüfung auf ungültige Werte. Für die meisten Fälle schätze ich, dass die Leistung keine Rolle spielen würde, wenn sich die Größe der Ebene 0 nicht oft ändert.

Angenommen, die Textur verfügt nicht über eine begrenzte Anzahl von Ebenen geben die Spezifikationen die bevorzugte Berechnung an (beachten Sie die Verwendung von floor et no ceiling wie einige Beispiele zeigen):

numLevels = 1 + floor(log2(max(w, h, d)))
  1. Wie lautet die Dimensionsreduzierungsregel für jede kleinere Mipmap-Ebene?

    Jede kleinere Mipmap-Ebene entspricht der Hälfte der vorherigen Ebene, aber wenn dieser halbe Wert ein Bruchwert ist, sollten Sie auf die nächstgrößere ganze Zahl abrunden.
    ...
    Beachten Sie, dass diese Erweiterung mit der Unterstützung anderer Regeln kompatibel ist, da sie lediglich die Fehler- und Vollständigkeitsbedingungen für Mipmaps lockert. Gleichzeitig ist es sinnvoll, den Entwicklern eine einzige konsistente Regel zur Verfügung zu stellen, da es unwahrscheinlich ist, dass die Entwickler unnötigerweise Mipmaps für verschiedene Regeln erzeugen wollen. Eine vernünftige Regel ist ausreichend und vorzuziehen, und die "Floor"-Konvention ist die beste Wahl.

    [ARB_texture_non_power_of_two]

Dies kann natürlich mit der Methode des Auftraggebers überprüft werden, oder in meinem Fall, als ich eine GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT con glFramebufferTexture2D(..., numLevels) .

2voto

imallett Punkte 13858

Wenn man davon ausgeht, dass man Mipmaps auf die übliche Weise erstellt, ist die Anzahl der eindeutigen Bilder in etwa ceil(log_2(max(width,height)))+1. Dies lässt sich leicht ableiten, wenn man bedenkt, dass Mipmaps die Bildgröße jedes Mal um den Faktor zwei reduzieren, bis nur noch ein einziges Pixel übrig ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X