Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Vertex Array inconsistency across GPUs?  (Read 516 times)

0 Members and 1 Guest are viewing this topic.

DeyanDev

  • Newbie
  • *
  • Posts: 3
    • View Profile
Vertex Array inconsistency across GPUs?
« on: December 13, 2024, 07:32:34 pm »
Hi there,

I recently decided to resume work on one of my old SFML games. After I setup SFML 2.6.2 on a new laptop and ran my code, I was surprised that my backgrounds, which I drew using Vertex Arrays, looked completely different.

In the attached images, you can see screenshots of the very same program ran on two different machines: one on a win10 PC with a GTX 960, and the other on a win11 PC with an RTX 4060.

Is it normal for different GPUs to draw the same Vertex Array in such a vastly different way?

        BG.setPrimitiveType(sf::Quads);
        BG.resize(4);

        BG[0].position = sf::Vector2f(0.f, 1080.f);
        BG[1].position = sf::Vector2f(0.f, 0.f);
        BG[2].position = sf::Vector2f(1920.f, 0.f);
        BG[3].position = sf::Vector2f(1920.f, 1080.f);

        BG[0].color = sf::Color(255,0,0,255);
        BG[1].color = sf::Color(0,0,0,0);
        BG[2].color = sf::Color(255,255,255,255);
        BG[3].color = sf::Color(0,0,0,0);

vokazoo

  • Newbie
  • *
  • Posts: 19
    • View Profile
    • Email
Re: Vertex Array inconsistency across GPUs?
« Reply #1 on: December 13, 2024, 11:08:42 pm »
I may be mistaken, but it could be due to the order of vertices. Your snippet gives the result from old.png on my machine, but arrange it like this:
        BG[0].position = sf::Vector2f(0.f, 0.f);
        BG[1].position = sf::Vector2f(1920.f, 0.f);
        BG[2].position = sf::Vector2f(1920.f, 1080.f);
        BG[3].position = sf::Vector2f(0.f, 1080.f);

        BG[0].color = sf::Color(0, 0, 0, 0);
        BG[1].color = sf::Color(255, 255, 255, 255);
        BG[2].color = sf::Color(0, 0, 0, 0);
        BG[3].color = sf::Color(255, 0, 0, 255);
and the result is from new.png.

What happens in this situation for both of your machines?

What happens in this order?
(click to show/hide)

sf::quads is declared deprecated, so that might also be an issue (though I think that's just for mobile).

kojack

  • Sr. Member
  • ****
  • Posts: 346
  • C++/C# game dev teacher.
    • View Profile
Re: Vertex Array inconsistency across GPUs?
« Reply #2 on: December 14, 2024, 07:46:19 am »
Quads need to be triangulated (split into two triangles along the diagonal) by the GPU drivers before they can be rendered. There's two ways to do this (split along vertices 0 and 2 or 1 and 3). These two different ways give the two images you posted.
As far as I can see online, OpenGL doesn't define which way it will be split, so its up to the driver.
Quads were deprecated from OpenGL 16 years ago and OpenGLES doesn't have them.

To have a consistent appearance across all hardware and drivers, use two triangles instead.

DeyanDev

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Vertex Array inconsistency across GPUs?
« Reply #3 on: December 14, 2024, 08:13:27 am »
Thank you very much for the explanation. So, using instead 2 triangles...

This gives new.png (rtx4060):
        BG1[0].position = BottomLeft;
        BG1[1].position = BottomRight;
        BG1[2].position = TopLeft;

        BG1[0].color = sf::Color(255,   0,   0, 255);
        BG1[1].color = sf::Color(  0,   0,   0,   0);
        BG1[2].color = sf::Color(  0,   0,   0,   0);


        BG2[0].position = TopRight;
        BG2[1].position = TopLeft;
        BG2[2].position = BottomRight;

        BG2[0].color = sf::Color(255, 255, 255, 255);
        BG2[1].color = sf::Color(  0,   0,   0,   0);
        BG2[2].color = sf::Color(  0,   0,   0,   0);

And this gives old.png (gtx960):
        BG1[0].position = TopLeft;
        BG1[1].position = BottomLeft;
        BG1[2].position = TopRight;

        BG1[0].color = sf::Color(  0,   0,   0,   0);
        BG1[1].color = sf::Color(255,   0,   0, 255);
        BG1[2].color = sf::Color(255, 255, 255, 255);


        BG2[0].position = BottomRight;
        BG2[1].position = BottomLeft;
        BG2[2].position = TopRight;

        BG2[0].color = sf::Color(  0,   0,   0,   0);
        BG2[1].color = sf::Color(255,   0,   0, 255);
        BG2[2].color = sf::Color(255, 255, 255, 255);