在 SFML 中镜像 Y 轴

发布于 2024-11-18 14:47:08 字数 209 浏览 4 评论 0 原文

嘿,所以我正在集成 box2d 和 SFML,并且 box2D 具有与 SFML 相同的奇怪的镜像 Y 轴坐标系,这意味着所有内容都被颠倒渲染。是否有某种函数或少量代码可以简单地镜像窗口的渲染内容?

我想我可以在 sf::view 中放入一些东西来帮助解决这个问题...

我如何轻松翻转 Y 轴,以实现渲染目的,而不影响主体尺寸/位置?

Hey so I'm integrating box2d and SFML, and box2D has the same odd, mirrored Y-axis coordinate system as SFML, meaning everything is rendered upside down. Is there some kind of function or short amount of code I can put that simply mirrors the window's render contents?

I'm thinking I can put something in sf::view to help with this...

How can i easily flip the Y-axis easily, for rendering purposes, not effecting the bodies dimensions/locations?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

束缚m 2024-11-25 14:47:08

我不知道什么是 box2d 但当我想使用 openGL 翻转 Y 轴时,我只是将负缩放因子应用于投影矩阵,例如:

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

如果您想独立于 openGL 进行操作,只需应用带有负值的 sf::View x 值。

I don't know what is box2d but when I wanted to flip Y axis using openGL, I just applied negative scaling factor to projection matrix, like:

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

If you want to do it independent of openGL simply apply a sf::View with a negative x value.

野却迷人 2024-11-25 14:47:08

听起来您的模型使用传统的坐标系(正 y 点向上),您需要将其转换为屏幕坐标系(正 y 点向下)。

将模型/Box2D 位置数据复制到任何 sf::Drawable 时,在模型和屏幕坐标系之间手动转换:

b2Vec2 position = body->GetPosition();

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

您可以将其隐藏在包装类或函数中,但它需要作为预渲染位于模型和渲染器之间转换。我在 SFML 中没有看到可以设置它的地方。

我认为Box2D有你想要的坐标系;只需根据您的模型(0,-10)而不是屏幕设置重力矢量。

It sounds like your model uses a conventional coordinate system (positive y points up), and you need to translate that to the screen coordinate system (positive y points down).

When copying model/Box2D position data to any sf::Drawable, manually transform between the model and screen coordinate systems:

b2Vec2 position = body->GetPosition();

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

You can hide this in a wrapper class or function, but it needs to sit between the model and renderer as a pre-render transform. I don't see a place to set that in SFML.

I think Box2D has the coordinate system you want; just set the gravity vector based on your model (0, -10) instead of the screen.

酷炫老祖宗 2024-11-25 14:47:08

为了渲染目的,我如何轻松翻转 Y 轴,而不影响主体尺寸/位置?

通过正确应用变换。首先,您可以应用将窗口的左下角设置为原点的变换。然后,将 Y 轴缩放 -1 因子以将其翻​​转作为第二个变换。

为此,您可以使用 sf::Transformable 单独指定每个变换(即原点和缩放的设置),然后 - 通过调用 sf::Transformable::getTransform() – 获取sf::Transform 对应的对象到组合变换。

最后,在渲染相应对象时,将此变换对象传递给 sf::RenderTarget::draw() 成员函数作为其第二个参数。 sf::Transform 对象隐式转换为 sf::RenderStates即对应sf::RenderTarget::draw() 超载。

举个例子:

#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();
    }
}

有一个 sf::RectangleShape 对象,用不同的颜色渲染两次:

  1. 蓝色:未应用变换。
  2. 红色:应用了组合变换。

由于翻转 Y 轴,它们向相反的方向移动。

转换

请注意,对象空间位置坐标保持不变。两个渲染的矩形对应于同一个对象,即只有一个 sf::RectangleShape 对象,rect – 仅更改了颜色。对象空间位置是rect.getPosition()

这两个渲染矩形的不同之处在于坐标参考系。因此,这两个渲染矩形的绝对空间位置坐标也不同。

您可以在场景树中使用此方法。在这样的树中,从根开始,从父级到子级以自上而下的方式应用变换。最终效果是子级的坐标是相对于其父级的绝对位置的。

How can i easily flip the Y-axis easily, for rendering purposes, not effecting the bodies dimensions/locations?

By properly applying transforms. First, you can apply a transform that sets the window's bottom-left corner as the origin. Then, scale the Y axis by a factor of -1 to flip it as the second transform.

For this, you can use sf::Transformable to specify each transformation individually (i.e., the setting of the origin and the scaling) and then – by calling sf::Transformable::getTransform() – obtain an sf::Transform object that corresponds to the composed transform.

Finally, when rendering the corresponding object, pass this transform object to the sf::RenderTarget::draw() member function as its second argument. An sf::Transform object implicitly converts to a sf::RenderStates which is the second parameter type of the corresponding sf::RenderTarget::draw() overload.

As an example:

#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();
    }
}

There is a single sf::RectangleShape object that is rendered twice with different colors:

  1. Blue: no transform was applied.
  2. Red: the composed transform was applied.

They move in opposite directions as a result of flipping the Y axis.

Transformation

Note that the object space position coordinates remain the same. Both rendered rectangles correspond to the same object, i.e., there is just a single sf::RectangleShape object, rect – only the color is changed. The object space position is rect.getPosition().

What is different for these two rendered rectangles is the coordinate reference system. Therefore, the absolute space position coordinates of these two rendered rectangles also differ.

You can use this approach in a scene tree. In such a tree, the transforms are applied in a top-down manner from the parents to their children, starting from the root. The net effect is that children's coordinates are relative to their parent's absolute position.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文