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

Homeprogrammer

Frischling

  • »Homeprogrammer« ist der Autor dieses Themas

Beiträge: 8

Wohnort: Darmstadt

Beruf: Student

  • Private Nachricht senden

1

05.01.2013, 02:44

[gelöst] Textur enthält Fraktale in OpenGL

Hallo,
ich habe in ein 2D Projekt von mir einen gekachelten Hintergrund eingefügt. Er besteht aus 5x5 OpenGL Einheiten großen Quads mit (bei bester Einstellung) 500x500 px großer Textur darauf. Das Vergrößerungs- und Verkleinerungsverhalten von OpenGL habe ich auf linear gestellt, trotzdem enthält der Hintergrund wenn der Kameraausschnitt wächst, er also kleiner wird, Fraktale, welche aber gleichzeitig auch kleiner werden und deshalb in der Textur kaum wahrgenommen werden. Wird der Kameraausschnitt kleiner, treten diese Fraktale sehr deutlich hervor. Ich habe ein kleines Vergleichsbild dazu angefertigt. Die obere Hälfte stammt aus einem Screenshot, dort ist die Textur meinem Taschenrechner zu Folge etwa 1,48 fach vergrößert zum Original darunter. Man sieht deutlich ein Muster aus vielen kleinen Vierecken in der oberen Bildhälfte, obwohl das ganze Bild innerhalb einer Kachel ist.
Meine Frage ist nun, sind diese Fraktale normal und durch irgendwelche Tricks vermeidbar oder stimmt etwas mit meinem OpenGL nicht?

Hier das Laden der Textur. Nicht wundern, ich nutze SDL und darin OpenGL für die Grafik:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
bool GLFlatObject::load(const std::string& filename)
{
    glDeleteTextures(1, &Texture);  //Eventuell alte Textur löschen
    //Textur unter Linux bzw. Windows laden
    #ifdef LINUX
    #define Buffer 1024
    char Path[Buffer] = {0};
    ssize_t Length = readlink("/proc/self/exe", Path, Buffer);
    if(Length < Buffer) Path[Length] = 0; else Path[Buffer] = 0;    //terminierende Null anhängen
    std::string Fullfilename = std::string(Path);
    size_t End = Fullfilename.find_last_of("/");
    Fullfilename.erase(End+1);
    Fullfilename += filename;
    SDL_Surface* surface = IMG_Load(Fullfilename.c_str());
    #else
    SDL_Surface* surface = IMG_Load(filename.c_str());
    #endif
    if(!surface) return false;
    W = surface->w;
    H = surface->h;
    W = 0.5 * W/H; //0.5 weil doppelte Weite um Mittelpunkt 2D Cursor zeichnet, damit zentriert
    H = 0.5;
    glPixelStorei(GL_UNPACK_ALIGNMENT,4);
    glGenTextures(1, &Texture);
    glBindTexture(GL_TEXTURE_2D, Texture);
    SDL_PixelFormat *format = surface->format;
    if(format->Amask)
    {
        gluBuild2DMipmaps(GL_TEXTURE_2D, 4,
        surface->w, surface->h, GL_RGBA,GL_UNSIGNED_BYTE, surface->pixels);
    } else {
        gluBuild2DMipmaps(GL_TEXTURE_2D, 3,
        surface->w, surface->h, GL_RGB, GL_UNSIGNED_BYTE, surface->pixels);
    }
    SDL_FreeSurface(surface);

    //Lineare Filterung für Groß- und Kleinzoomen von Textur aktivieren
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

    //Texturmapping allgemein aktivieren
    glEnable(GL_TEXTURE_2D);

    return true;
}


Und hier das Rendern einer Kachel:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
    //Wenn gewünscht, additives Blending aktivieren
    if(getAdd()) glBlendFunc(GL_ONE, GL_ONE);

    //Matrix reseten (Rotation usw.)
    glLoadIdentity();

    //Objekt transformieren
    //Position des oberen linken Eckpunkts auslesen
    double StartX = Camera->getLeft();
    double StartY = Camera->getTop();
    if(Camera->getDimensions() == 2)
        StartY = Camera->getBottom();

    //An richtige lokale oder globale Position setzen
    if(getLocal())
    {
        glTranslatef(StartX + X, StartY + Y, -Z);
    } else {
        glTranslatef(X, Y, -Z);
    }

    //Bei Z < 0 kein Tiefentest
    if(Z < 0) glDisable(GL_DEPTH_TEST);

    getRot(X, Y, Z);
    glRotatef(X, 1, 0, 0);
    glRotatef(Y, 0, 1, 0);
    glRotatef(Z, 0, 0, 1);

    getSkale(X, Y, Z);
    glScalef(X, Y, Z);

    //Textur verwenden(Mehrere
    glBindTexture(GL_TEXTURE_2D, Texture);

    //Gefärbt
    if(getA() == 1)
        glColor3f(getR(), getG(), getB());
    else
    //Gefärbt und teilweise sichtbar
        glColor4f(getR(), getG(), getB(), getA());

    //Objekt zeichnen und Textur Mappen
    glBegin(GL_QUADS);
        glTexCoord2f(0, 1); glVertex3f(-1*W, 1*H, 0); //Texturkoordinate für Eckpunkt, Y geht von unten nach oben!
        glTexCoord2f(1, 1); glVertex3f( 1*W, 1*H, 0);
        glTexCoord2f(1, 0); glVertex3f( 1*W,-1*H, 0);
        glTexCoord2f(0, 0); glVertex3f(-1*W,-1*H, 0);
    glEnd();

    //Einfärben wieder aufheben
    glColor3f(1, 1, 1);

    //Blenden auf Grundeinstellung
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    //Tiefentest wieder aktivieren
    glEnable(GL_DEPTH_TEST);


Danke schonmal fürs durchlesen :-)
»Homeprogrammer« hat folgendes Bild angehängt:
  • Fraktalgras.png
makeGame(std::string type);

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Homeprogrammer« (05.01.2013, 12:29)


David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

2

05.01.2013, 10:19

Wo soll denn da ein Fraktal sein?
Weißt du überhaupt, was ein Fraktal ist? Jedenfalls gibt es hier keins.
Die Textur ist einfach unscharf, vermutlich wegen der komischen Größe von 500x500. Die wird runtergerechnet auf die nächste kleinere Zweierpotenz, was 256x256 ist. Am besten gehst du also auf 512x512.
Und bitte schau mal bei Wikipedia nach, was ein Fraktal ist, dir selbst zuliebe ;)

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

3

05.01.2013, 11:03

Er meint bestimmt Artefakte :)

Homeprogrammer

Frischling

  • »Homeprogrammer« ist der Autor dieses Themas

Beiträge: 8

Wohnort: Darmstadt

Beruf: Student

  • Private Nachricht senden

4

05.01.2013, 12:27

Tatsache, hat geholfen. Ich wusste nicht, dass die Grafikkarte immer die nächst kleinere Zweierpotenz verwendet, ich dachte das Bild wird zur nächst größeren gestreckt um keine Bildinformationen zu verlieren.
Jetzt weiß ich zumindest, dass diese Artefakte bei zu starker Vergrößerung auftreten und jetzt weiß ich auch, weshalb bei meinen 500x500 px Texturen schon bei geringem Zoom so stark vergrößert wird.

Jetzt kann ich erstmal einige Texturen neu machen. :S

Danke für die Hilfe :thumbup:
makeGame(std::string type);

Werbeanzeige