Merkwürdige Verzerrungen

3D-Visualisierung mit der Open Graphics Library (OpenGL)
Antworten
Benutzeravatar
Architekt
Beiträge: 172
Registriert: Sa Mai 24, 2014 12:04 pm

Merkwürdige Verzerrungen

Beitrag von Architekt » Do Mai 14, 2015 10:28 pm

Moin an alle.
Ich arbeite gerade wieder mal (seit langem) mit OpenGL. Dabei rendere ich eine kleine TileMap und das ganze sieht folgendermaßen aus:
Bild
Da ich aber für jedes Teil zunächst einen Draw Call hatte, wollte ich alle Calls zusammenfassen und habe mir alle Vertices in ein zusammenhängendes Array geschrieben. Das ganze ist auch beinahe 30% schneller, aber es kommt zu einem Problem:
Bild
Ich sehe derartige Verzerrungen. Der Code ist korrekt und auch die Daten die ich mir natürlich habe ausprinten lassen sind alle ok (keine komischen floats). Hier einmal zur Ansicht:
https://gist.github.com/Dgame/5f4d2a47efaa6007c98b

Ein Vertex hat zunächst eine Position in Pixel, dann die Texture-Koordinaten und anschließend eine Farbe (hier weiß). Und wie man sehen kann: keine komischen float Ausreißer. Weiß jemand woran es liegen kann? Oder welche Gründe so etwas haben kann?
Als Primitive gebe ich GL_TRIANGLE_STRIP an, ich habe aber bereits die meisten anderen durch (von GL_QUADS über GL_QUAD_STRIP zu GL_TRIANGLE_FAN). Vielleicht bemerkt ja jemand etwas was ich nicht bemerke.

Hier einmal der Code wie ich ein Tile hinzufüge:

Code: Alles auswählen

    /**
     * Appends four Vertices arounds the given position with the given texture coordinates
     */
    void append()(auto ref const Vector2f position, auto ref const Rect texRect) pure nothrow {
        immutable float tx = float(texRect.x) / _texture.width;
        immutable float ty = float(texRect.y) / _texture.height;
        immutable float tw = float(texRect.width) / _texture.width;
        immutable float th = float(texRect.height) / _texture.height;

        immutable float tx_tw = tx + tw;
        immutable float ty_th = ty + th;
        immutable float cx_tw = position.x + texRect.width;
        immutable float cy_th = position.y + texRect.height;

        _vertices.reserve(4);

        _vertices ~= Vertex(
            position,
            Vector2f(tx, ty),
            Color4f.White
        );

        _vertices ~= Vertex(
            Vector2f(cx_tw, position.y),
            Vector2f(tx_tw, ty),
            Color4f.White
        );

        _vertices ~= Vertex(
            Vector2f(position.x, cy_th),
            Vector2f(tx, ty_th),
            Color4f.White
        );

        _vertices ~= Vertex(
            Vector2f(cx_tw, cy_th),
            Vector2f(tx_tw, ty_th),
            Color4f.White
        );
    }
edit: Es handelt sich bei der Sprache übrigens um D. ;)

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3091
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Merkwürdige Verzerrungen

Beitrag von cloidnerux » Fr Mai 15, 2015 2:01 pm

Hast du vlt irgendwelche Artefakte in deinem Array?
Das da Blöcke sind, die nicht da sein sollten und falsch parametrisiert sind?

Bzw, die Verzerrungen sind immer in den freien reihen? Hast du da in deinem Algorithmus ein Fehler drin, wenn eine Reihe leer bleiben soll?
Redundanz macht wiederholen unnötig.
quod erat expectandum

Benutzeravatar
Architekt
Beiträge: 172
Registriert: Sa Mai 24, 2014 12:04 pm

Re: Merkwürdige Verzerrungen

Beitrag von Architekt » Fr Mai 15, 2015 5:19 pm

Hm, jetzt verunsicherst du mich. Ich zeig einmal wie ich meine TileMap zusammenstelle (ist sehr primitiv):

Code: Alles auswählen

    enum ubyte MAP_WIDTH = 12;
    enum ubyte MAP_HEIGHT = 10;

    enum ubyte TILE_SIZE = 32;

    // 0 = empty, a = start, t = tile, z = target
    const char[MAP_WIDTH * MAP_HEIGHT] Tiles = [
        '0', 'a', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', 't', 't', 't', 't', 't', '0', '0', 't', 't', 't', '0',
        '0', '0', '0', 't', 't', 't', 't', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        't', 't', '0', '0', '0', '0', 't', 't', 't', 't', '0', 't',
        '0', '0', '0', '0', '0', 't', 't', 't', '0', '0', 't', 't',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', 't', 't', 't', 't', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', 'z',
        '0', '0', '0', 't', 't', 't', 't', 't', 't', 't', 't', 't',
    ];

    Texture tile_tex = Texture(Surface("Tile.png"));

    Vector2f start, target;

    VertexArray va = new VertexArray(tile_tex);

    ubyte x, y;
    foreach (ubyte idx, char c; Tiles) {
        if (Tiles[idx] == 't') {
            va.append(Vector2f(x * TILE_SIZE, y * TILE_SIZE));
        } else if (Tiles[idx] == 'a')
            start = Vector2f(x * TILE_SIZE, y * TILE_SIZE);
        else if (Tiles[idx] == 'z')
            target = Vector2f(x * TILE_SIZE, y * TILE_SIZE);

        x++;
        if (x >= MAP_WIDTH) {
            x = 0;
            y++;
        }
    }
Also eig. sehe ich da keinen Fehler. Ich gehe das Reihe für Reihe durch und gebe dann die Eck-Punkte an. Oder siehst du da was?

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8507
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Merkwürdige Verzerrungen

Beitrag von Xin » Mo Mai 18, 2015 2:43 pm

Wie sicher ist denn, dass die Daten wirklich hintereinander liegen? Wie ist _vertices implementiert?
Wenn Du vier Vertices hast, kann es doch sein, dass die nicht alle exakt gleich weit auseinander liegen.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Benutzeravatar
Architekt
Beiträge: 172
Registriert: Sa Mai 24, 2014 12:04 pm

Re: Merkwürdige Verzerrungen

Beitrag von Architekt » Mi Mai 20, 2015 8:21 am

Problem war, dass ich nicht daran gedacht hatte, das es Lücken dazwischen gibt. GL_TRIANGLES wie auch GL_QUAD_STRIP benötigen aber ein zusammenhängendes Gitter (logisch). Wenn man jetzt das Letzte und Vorletzte Vertex vertauscht, klappt es mit GL_QUADS

Antworten