PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Erstellung von MipMap Texturen unter OpenGL


liquid
2003-10-04, 17:58:54
Tachen coders,

wie erstelle ich (nach Muster) eine gemipmappte Textur unter OpenGL?

Einschränkung: Kein Einsatz von GLU, wenn es sich vermeiden lässt.

Mein bisheriges Vorgehen:
GLuint texture_id;
glGenTextures(1, &texture_id);

glBindTexture(GL_TEXTURE_2D, texture_id);

und dann halt multiple Aufrufe von glTexImage2D:
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGB,
original_width,
original_height,
0, // no border,
GL_RGB,
GL_UNSIGNED_BYTE,
level0);

Das ganze dann nochmal mit original_width/2, original_height/2 und level1 als Pixel-Input. Und dann halt nochmal, so wie man lustig ist.
Ich habe insgesamt 4 Miplevels, aus denen die Textur aufgebaut ist (level0 bis level3).
Ich bekomme auch keine Error-Message wenn ich das so mache. Die Texturparameter sind auch richtig eingestellt (also Standardwerte) nur leider funktionieren diese Texturen nicht.
Wenn ich also versuche ein Quad, Dreieck, Polygon, etc. mit der Textur zu versehen (vorher natürlich hübsch binden) taucht das Primitiv gar nicht erst auf. Und auch keine Error-Message.

Es funktioniert NUR wenn ich die Textur ohne Miplevels erstelle. Dann ändere ich vorher die Filtereinstellugen (Min auch auf linear) und schiebe nur den level0 Miplevel rein.
Dann zeigt er die Textur auch ohne Probleme an, allerdings ohne Mipmapping.

Merkwürdig? Woran könnte das liegen? Es hat sicherlich etwas mit dem Mipmapping zu tun. Muss ich denn eine bestimmte Anzahl an Miplevels zur Verfügung stellen, damit die Texuren verwendet werden können oder gibt sich OpenGL auch nur mit 4 Levels zufrieden?
Oder muss ich noch etwas an den Filtereinstellungen ändern, damit das ganze funktioniert.

Bitte keine Antworten ala "benutz doch um alles in der Welt GLU zur Mipmap-Generierung, ist viel einfacher". Ich hab die Mipmaps nämlich schon und will sie nicht nocheinmal generieren. Außerdem würde das auch nicht mein eigentliches Problem lösen ;)

cya
liquid

Kant
2003-10-04, 18:08:56
Ich vermute mal, das du den 2. Wert bei glTexImage2D miterhöht hast (die Level).
Ich generiere mein MipMaps zT auch selbst, und das funkt ohne Probs, allerdings habe ich alle Level bis hin zu 1x1 belegt.
Wenn das Prob bei dir die zuwenigen vorhanden Level sind, schau mal unter
http://www.3dlabs.com/support/developer/GLmanpages/gltexparameter.htm

nach GL_TEXTURE_MAX_LEVEL_EXT

Damit scheint man MipMaps auf einen gewissen Level begrenzen zu können.

liquid
2003-10-04, 18:19:38
Der fragliche Codeteil sieht so aus:
GLuint SingleTex::createTexMipped(const palette& pal) const
{
// no validation check is done

// create texture
GLuint tex_id = 0;
glGenTextures(1, &tex_id);

glBindTexture(GL_TEXTURE_2D, tex_id); // bind

// no setup filtering
// using mipmapping

// allocate memory
uchar* pixels = new uchar[width * height * 3];

// decode mipmap-level 0 with palette
for (ulong i = 0; i < (width * height); ++i)
{
pixels[i * 3 + 0] = pal.getRGB(level0[i])[0];
pixels[i * 3 + 1] = pal.getRGB(level0[i])[1];
pixels[i * 3 + 2] = pal.getRGB(level0[i])[2];
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height,
0, GL_RGB, GL_UNSIGNED_BYTE, pixels);

// decode mipmap-level 1 with palette
for (ulong i = 0; i < ((width/2) * (height/2)); ++i)
{
pixels[i * 3 + 0] = pal.getRGB(level1[i])[0];
pixels[i * 3 + 1] = pal.getRGB(level1[i])[1];
pixels[i * 3 + 2] = pal.getRGB(level1[i])[2];
}
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGB, width/2, height/2,
0, GL_RGB, GL_UNSIGNED_BYTE, pixels);

// decode mipmap-level 2 with palette
for (ulong i = 0; i < ((width/4) * (height/4)); ++i)
{
pixels[i * 3 + 0] = pal.getRGB(level2[i])[0];
pixels[i * 3 + 1] = pal.getRGB(level2[i])[1];
pixels[i * 3 + 2] = pal.getRGB(level2[i])[2];
}
glTexImage2D(GL_TEXTURE_2D, 2, GL_RGB, width/4, height/4,
0, GL_RGB, GL_UNSIGNED_BYTE, pixels);

// decode mipmap-level 3 with palette
for (ulong i = 0; i < ((width/8) * (height/8)); ++i)
{
pixels[i * 3 + 0] = pal.getRGB(level3[i])[0];
pixels[i * 3 + 1] = pal.getRGB(level3[i])[1];
pixels[i * 3 + 2] = pal.getRGB(level3[i])[2];
}
glTexImage2D(GL_TEXTURE_2D, 3, GL_RGB, width/8, height/8,
0, GL_RGB, GL_UNSIGNED_BYTE, pixels);

delete [] pixels; pixels = NULL;

return tex_id;
}

Wegen des GL_TEXTURE_MAX_LEVEL. Wie muss ich das jetzt verändern, wenn ich nur 4 Miplevels habe?
Also Base bleibt ja 0, müsste ich dann MAX_LEVEL auf 3 setzen?

cya
liquid

Kant
2003-10-04, 18:25:53
Original geschrieben von liquid
Der fragliche Codeteil sieht so aus:

.
.
.

Wegen des GL_TEXTURE_MAX_LEVEL. Wie muss ich das jetzt verändern, wenn ich nur 4 Miplevels habe?
Also Base bleibt ja 0, müsste ich dann MAX_LEVEL auf 3 setzen?

cya
liquid
Yep, so habe ich das auch verstanden.
In dem Code sehe ich sonst keine Fehler, sollte mit max auf 3 laufen.
Oder aber du generierst die zusätzlichen MipMaps auch noch. Mann kann ja das letzte Array solange runterskalieren bis es 1x1 ist. Bin mir nämlich absolut nicht sicher, welche GraKas das manuelle setzen des max_levels erlauben.

Xmas
2003-10-04, 18:30:46
Jap, GL_TEXTURE_MAX_LEVEL (_EXT ist veraltet seit GL1.2) muss in deinem Fall 3 sein. Oder du setzt GL_GENERATE_MIPMAP beim definieren des letzten Levels auf GL_TRUE. Dann werden ab da alle Mipmaps erzeugt. Ach ja, du solltest den Filtermodus wirklich explizit auf GL_*_MIPMAP_* stellen. Es kann wirklich zu sehr kuriosen Ergebnissen kommen, wenn du Mipmaps definierst, aber kein Mipmap Filtering eingestellt ist (z.B. Zusammenblenden der vorherigen und der aktuellen Textur in den Mipmaps... :bonk: )

liquid
2003-10-04, 18:42:20
Original geschrieben von Kant
Yep, so habe ich das auch verstanden.
In dem Code sehe ich sonst keine Fehler, sollte mit max auf 3 laufen.
Oder aber du generierst die zusätzlichen MipMaps auch noch. Mann kann ja das letzte Array solange runterskalieren bis es 1x1 ist. Bin mir nämlich absolut nicht sicher, welche GraKas das manuelle setzen des max_levels erlauben.
Also mit dem Setzen von MAX_LEVEL scheint es zu gehen. Ich werde allerdings noch eine Methode hinzufügen, die vollständig Miplevels erzeugt.
Also das manuelle Setzen nicht geht, hätte mich auch gewundert, da es ein fester Bestandteil der GL ist.

cya
liquid

liquid
2003-10-04, 18:45:42
Original geschrieben von Xmas
Jap, GL_TEXTURE_MAX_LEVEL (_EXT ist veraltet seit GL1.2) muss in deinem Fall 3 sein. Oder du setzt GL_GENERATE_MIPMAP beim definieren des letzten Levels auf GL_TRUE. Dann werden ab da alle Mipmaps erzeugt. Ach ja, du solltest den Filtermodus wirklich explizit auf GL_*_MIPMAP_* stellen. Es kann wirklich zu sehr kuriosen Ergebnissen kommen, wenn du Mipmaps definierst, aber kein Mipmap Filtering eingestellt ist (z.B. Zusammenblenden der vorherigen und der aktuellen Textur in den Mipmaps... :bonk: )
glEnable(GL_GENERATE_MIPMAP)?? Finde ich nämlich im bluebook net.

Muss ich den Filter wirklich setzen? Schließlich ist der Standardwert für GL_TEXTURE_MIN_FILTER GL_NEAREST_MIPMAP_LINEAR und für GL_TEXTURE_MAG_FILTER GL_LINEAR. Und soweit ich das mitgekriegt habe sind das ja alles Per-Texture-Object Parameter, die mit der Textur gespeichert werden, oder liege ich da falsch?

cya
liquid

Xmas
2003-10-04, 20:05:35
Original geschrieben von liquid
glEnable(GL_GENERATE_MIPMAP)?? Finde ich nämlich im bluebook net.

Muss ich den Filter wirklich setzen? Schließlich ist der Standardwert für GL_TEXTURE_MIN_FILTER GL_NEAREST_MIPMAP_LINEAR und für GL_TEXTURE_MAG_FILTER GL_LINEAR. Und soweit ich das mitgekriegt habe sind das ja alles Per-Texture-Object Parameter, die mit der Textur gespeichert werden, oder liege ich da falsch?
GL_GENERATE_MIPMAP ist ein Texture Parameter, der ab OpenGL 1.4 verfügbar ist, wird also mit glTexParameter[i|f] gesetzt.

Zu den Mipmaps, da bin ich mir jetzt gar nicht so sicher ob ich da nicht auf einen groben Bug anderer Art gestoßen bin. Das angehängte Bild entbehrt ja nicht einer gewissen Ästhetik, korrekte Mipmaps sind das aber sicher nicht.

liquid
2003-10-04, 20:20:14
Ich sollte mir vielleicht doch mal die 1.4-Specs durchlesen :D

@Pic: Goil sieht es natürlich trotzdem aus *g*

cya
liquid