在SFML中镜像Y轴

时间:2011-07-03 07:08:29

标签: c++ graph rendering coordinate-systems sfml

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

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

如何轻松翻转Y轴,出于渲染目的,不影响身体尺寸/位置?

3 个答案:

答案 0 :(得分:2)

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

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

如果你想独立于openGL这样做,只需使用负x值的sf :: View。

答案 1 :(得分:2)

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

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

b2Vec2 position = body->GetPosition();

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

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

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

答案 2 :(得分: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 轴,它们沿相反的方向移动。

Transformation

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

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

您可以在场景树中使用此方法。在这样的树中,从根开始,以自顶向下的方式从父级到子级应用转换。最终结果是孩子的坐标相对于父母的绝对位置。