4 Stimmen

Spiegelung der Y-Achse in SFML

Hey, also ich bin die Integration von box2d und SFML, und box2D hat die gleiche ungerade, gespiegelt Y-Achse Koordinatensystem als SFML, was bedeutet, dass alles auf den Kopf gerendert wird. Gibt es eine Art von Funktion oder kurze Menge von Code, den ich setzen kann, die einfach spiegelt das Fenster Render-Inhalte?

Ich denke, ich kann etwas in sf::view setzen, um dabei zu helfen...

Wie kann ich leicht spiegeln die Y-Achse leicht, für Rendering-Zwecke, nicht Auswirkung auf die Körper Dimensionen/Locations?

2voto

Raven Punkte 4593

Ich weiß nicht, was ist box2d, aber wenn ich wollte, um Y-Achse mit openGL zu spiegeln, habe ich nur negative Skalierungsfaktor auf Projektionsmatrix, wie:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glScalef(1.0f, -1.0f, 1.0f);

Wenn Sie es unabhängig von OpenGL machen wollen, wenden Sie einfach eine sf::View mit einem negativen x-Wert an.

2voto

lnmx Punkte 10540

Es hört sich so an, als ob Ihr Modell ein konventionelles Koordinatensystem verwendet (positive y-Punkte nach oben), und Sie müssen es in das Bildschirmkoordinatensystem übersetzen (positive y-Punkte nach unten).

Beim Kopieren von Modell-/Box2D-Positionsdaten in ein beliebiges sf::Drawable muss manuell zwischen dem Modell- und dem Bildschirmkoordinatensystem transformiert werden:

b2Vec2 position = body->GetPosition();

sprite.SetPosition( position.x, window.GetHeight() - position.y )

Sie können dies in einer Wrapper-Klasse oder Funktion verstecken, aber es muss zwischen dem Modell und Renderer als Pre-Render-Transformation sitzen. Ich sehe keinen Ort, um das in SFML festzulegen.

Ich denke, Box2D hat das Koordinatensystem, das Sie wollen; setzen Sie einfach den Schwerkraftvektor basierend auf Ihrem Modell (0, -10) anstelle des Bildschirms.

0voto

ネロク Punkte 21203

Wie kann ich leicht spiegeln die Y-Achse leicht, für Rendering-Zwecke, nicht Auswirkung auf die Körper Dimensionen/Locations?

Durch die richtige Anwendung von Transformationen. Zunächst können Sie eine Transformation anwenden, die die untere linke Ecke des Fensters als Ursprung festlegt. Dann skalieren Sie das Y Achse um einen Faktor von -1 um sie als zweite Transformation zu spiegeln.

Hierfür können Sie Folgendes verwenden sf::Transformable um jede Transformation einzeln zu spezifizieren (d. h. die Festlegung des Ursprungs und der Skalierung) und dann - durch den Aufruf sf::Transformable::getTransform() - erhalten eine sf::Transform Objekt, das der zusammengesetzten Transformation entspricht.

Beim Rendern des entsprechenden Objekts übergeben Sie schließlich dieses Transformationsobjekt an die sf::RenderTarget::draw() Mitgliedsfunktion als zweites Argument. Eine sf::Transform Objekt konvertiert implizit in ein sf::RenderStates der der zweite Parametertyp des entsprechenden sf::RenderTarget::draw() Überlastung.

Ein Beispiel:

#include <SFML/Graphics.hpp>

auto main() -> int {
    auto const width = 300, height = 300;
    sf::RenderWindow win(sf::VideoMode(width, height), "Transformation");
    win.setFramerateLimit(60);

    // create the composed transform object
    const sf::Transform transform = [height]{
        sf::Transformable transformation;
        transformation.setOrigin(0, height); // 1st transform
        transformation.setScale(1.f, -1.f);  // 2nd transform
        return transformation.getTransform();
    }();

    sf::RectangleShape rect({30, 30});

    while (win.isOpen()) {
        sf::Event event;
        while (win.pollEvent(event))
            if (event.type == sf::Event::Closed)
                win.close();

        // update rectangle's position
        rect.move(0, 1);

        win.clear();

        rect.setFillColor(sf::Color::Blue);
        win.draw(rect); // no transformation applied

        rect.setFillColor(sf::Color::Red);
        win.draw(rect, transform); // transformation applied

        win.display();
    }
}

Es gibt eine einzige sf::RectangleShape Objekt, das zweimal mit unterschiedlichen Farben gerendert wird:

  1. Blau: Es wurde keine Transformation durchgeführt.
  2. Rot: die zusammengesetzte Transformation wurde angewendet.

Sie bewegen sich in entgegengesetzte Richtungen, da sie die Y Achse.

Transformation

Beachten Sie, dass die Objektraum Die Positionskoordinaten bleiben gleich. Beide gerenderten Rechtecke entsprechen demselben Objekt, d. h. es gibt nur ein einziges sf::RectangleShape Objekt, rect - wird nur die Farbe geändert. Die Position im Objektraum ist rect.getPosition() .

Der Unterschied zwischen diesen beiden gerenderten Rechtecken besteht darin, dass die Koordinatenreferenzsystem . Daher ist die absoluter Raum Die Positionskoordinaten dieser beiden gerenderten Rechtecke unterscheiden sich ebenfalls.

Sie können diesen Ansatz in einer Szenenbaum . In einem solchen Baum werden die Transformationen ausgehend von der Wurzel von oben nach unten von den Eltern auf ihre Kinder angewendet. Der Nettoeffekt ist, dass die Koordinaten der Kinder relativ zur absoluten Position der Eltern sind.

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