4

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

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

为了渲染目的,我怎样才能轻松地轻松翻转 Y 轴,而不影响主体尺寸/位置?

4

3 回答 3

2

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

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

如果你想独立于 openGL 来做,只需应用一个带有负 x 值的 sf::View 。

于 2011-07-28T13:18:41.413 回答
2

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

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

b2Vec2 position = body->GetPosition();

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

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

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

于 2011-08-05T19:19:58.443 回答
0

为了渲染目的,我怎样才能轻松地轻松翻转 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()

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

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

于 2020-10-11T16:29:05.343 回答