Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

kiba

Alter Hase

  • »kiba« ist der Autor dieses Themas

Beiträge: 327

Wohnort: NRW

Beruf: Azubi: Fach-Info. Anw.

  • Private Nachricht senden

1

26.04.2009, 06:58

gluBuild2DMipmaps vs glTexImage

Hab hab mal wieder eine Problem.
Für die MipMap sollte man ja gluBuild2DMipmaps verwenden wenn man ein"ungerades" Bild hat aber gluBuild2DMipmaps ist ziemlich langsam (Glaube das muss den Pixel Array in ein passenden Array kopieren und dann noch mit glTexImage in die Texture laden)
Ich kann bestimmt die passende Größe des Pixel Arrays schon in der Surface Klasse setzen.
Und dann muss man später einfach nur noch mit glTexImage die Surface laden.

Die Frage ist:
Jetzt wie ermittle ich jetzt die richtige Größe und den level(Detailstufe) ?

Damit man die Texture auch im MipMap Modus sehen kann.
(Es ist ja auch so das Alte Grafikkarte(Treiben) die Texturen nicht anzeigen können die nicht die passende größe haben)

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

2

26.04.2009, 08:53

Was ist denn an gluBuild2DMipMaps zu langsam? Die Mipmaps erzeugst du doch ohnehin nur einmal beim Ladevorgang und das ist im Allgemeinen nicht so extrem Zeitkritisch.

Wenn du alles von Hand machen willst musst du die Textur in jedem Fall erstmal passend Dimensionieren und dann für jeden Mipmaplevel resamplen. Die Daten kannst du dann per glTexImage* hochladen, wobei du im 2. Parameter den entsprechenden Mipmaplevel angeben musst.
Ähnlich macht das gluBuild2DMipMaps aber auch (allerdings stark optimiert), also schätze ich mal das deine Implementierung nicht wesentlich schneller sein wird.

Alternativ kannst du allerdings hardwareunterstützt Mipmaps erzeugen (falls das deine Karte mitmacht). Da gibt's zwei gängige Wege: Wenn GL_EXT_framebuffer_object nicht vorhanden ist kannst du per glTexParameteri den Parameter GL_GENERATE_MIPMAP setzen. Falls die Erweiterung verfügbar sein sollte kannst du die Mipmaps per glGenerateMipmapEXT erzeugen lassen.

kiba

Alter Hase

  • »kiba« ist der Autor dieses Themas

Beiträge: 327

Wohnort: NRW

Beruf: Azubi: Fach-Info. Anw.

  • Private Nachricht senden

3

26.04.2009, 09:03

Aber es kann ja sein das man die Surface neuladen muss wenn man etwas daran verändert hat.
Und dann würde glTexImage doch ausreichen wenn man die Werte schon in der Surface berechnet hat.
Anstatt alles um zuwandeln und dann die Texture zu laden.
Benötigt man doch nur die Werte an glTexImage zu übergeben und der würde dann die Textur in den Speicher laden.

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

4

26.04.2009, 09:44

Von was für Änderungen redest du eigentlich? Wenn du die Pixeldaten änderst musst du die MipMaps ohnehin neu erzeugen. Und gluBuild2DMipMaps macht ja nichts anderes.

kiba

Alter Hase

  • »kiba« ist der Autor dieses Themas

Beiträge: 327

Wohnort: NRW

Beruf: Azubi: Fach-Info. Anw.

  • Private Nachricht senden

5

26.04.2009, 10:01

Veränderungen wie z.b. setpixel,bild laden,blt,fill......
So das man die Werte für eine MipMap in der Surface berechnet z.b. wenn man ein neues Bild ladet oder die Größe scaliert wird. Dann braucht man nur noch später mit glTexImage die Surface
in den Speicher laden , denn es kann ja sein das man die selben Surface mit den selben Pixles noch mal in den Speicher ladet.
Und damit man nicht immer gluBuild2DMipMaps aufruft und die ganzen werte berechnet sollte eine einfaches glTexImage doch schneller sein.

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

6

26.04.2009, 10:08

OpenGL kennt keine "Surfaces". Was für Bibliotheken benutzt du denn sonst noch?

kiba

Alter Hase

  • »kiba« ist der Autor dieses Themas

Beiträge: 327

Wohnort: NRW

Beruf: Azubi: Fach-Info. Anw.

  • Private Nachricht senden

7

26.04.2009, 10:34

Eigen erstellt,es ist eine einfach Surface Klasse mit einen einfach ubyte Pixelarray.
setPixel,Scalieren,Bild laden und so sind auch da.
Und mit einer einfach Funktion kann man sich eben diesen Pixelarray ausgeben lasse und in die Textur laden.
Den entscheinden ist ja nur die 2er Potenz Größe(und das level) für die MipMap.
Also könnte man die Werte einfach in der Klasse berechen und entsprechen die Größe des Arrays setzen.
Anstatt jetzt ein Bild zu laden das z.b. 542x56 Pixel größ ist und kein MipMap ist ,diese dann "ausversehen" oder nur zur Aktualiereung 1000 mit der gluBuild2DMipMaps zu laden.
Würde die Surface Klasse ein 542x542 Array erstellen und da diw Bilddatein hinein kopieren.
Dann wäre es doch schneller die glTexImage zu benutzten und einfach nur den 2er Potenz Array(in der Surface berechnet) zu übergeben.
Anstatt alles 1000 mal neu zu berechenen.

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

8

26.04.2009, 10:59

Ja, wenn du sowiso schon alle Daten aufbereitet hast (inklusive erzeugter Mipmaps) dann kannst du natürlich glTexImage* verwenden um die Daten wieder hoch zu laden. Die passenden Dimensionen bekommst du indem du auf die nächsten Zweierpotenzen aufrundest: 500x120 würde dann zu 512x128 usw... Für jeden Mipmaplevel nimmst du die halbe Breite/Höhe des vorherigen Levels. Also, für das Beispiel (256x64, 128x32, 64x16, 32x8, 16x4, 8x2, 4x1, 2x1, 1x1). Du hast für deine Textur also 9 Levels + den Hauptlayer. Das lädst du dann per glTexImage* hoch und, ta-daaa Mipmaps sollten funktionieren.

kiba

Alter Hase

  • »kiba« ist der Autor dieses Themas

Beiträge: 327

Wohnort: NRW

Beruf: Azubi: Fach-Info. Anw.

  • Private Nachricht senden

9

26.04.2009, 11:20

Jop das wollte icj wissen aber..
:? hmm..verstehe immer noch nicht ganz wie ich das errechen sollte.
Wie soll man das den Runden?
Und das mit den lvl sollte so gehen, oder?

C-/C++-Quelltext

1
2
3
4
5
6
7
8
int lvl = 0;
    int w = width;
    int h = height;
    while(w > 0 || h > 0){
        w /= 2;
        h /= 2;
        lvl++;
    }

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

10

26.04.2009, 12:18

Um die nächste Zweierpotenz zu bekommen kannst du z.B. diese Funktion verwenden:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
inline int CeilPoT( int x )
{
    --x;
    x |= x >> 1;
    x |= x >> 2;
    x |= x >> 4;
    x |= x >> 8;
    x |= x >> 16;
    ++x;

    return x;
}


Zum erzeugen der MipMaps hier mal ein Codestück aus meinem Framework:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// ...


uint32 w = Math::CeilPoT( m_nWidth );
uint32 h = Math::CeilPoT( m_nHeight );

// ...


while ( w > 1 && h > 1 )
{
    if ( !Resample( ptr, w, h, 0 ) )
        return false;

    ptr += PixelFormatUtils::RawDataSize( w, h, 1, m_pixelFormat, 0, 1 );

    w >>= 1;
    h >>= 1;

    if ( w == 0 ) w = 1;
    if ( h == 0 ) h = 1;
}

Werbeanzeige