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

Author Topic: Unexpected result using sf::Lines primitive.  (Read 2001 times)

0 Members and 1 Guest are viewing this topic.

cire

  • Full Member
  • ***
  • Posts: 138
    • View Profile
Unexpected result using sf::Lines primitive.
« on: October 14, 2012, 02:41:23 am »
I'm not sure why the 'gaps' appear when I'm using the code below.  At first I thought perhaps it might be some float rounding thing, but that doesn't seem to be the case.


You can see the gaps (black lines) here:



Here is the (minimal, compilable) code that produces it on my system.  You'll have to pardon the naming style mismatch.

#include <SFML/Graphics.hpp>

const unsigned win_height = 600 ;
const unsigned win_width  = 800 ;
const unsigned line_height = 300 ;

void draw_vertical_line(sf::RenderTexture& t, unsigned x) ;
void update_texture(sf::RenderTexture& t) ;
void wait_for_close(sf::RenderWindow& window) ;

int main()
{
    sf::RenderWindow window(sf::VideoMode(win_width, win_height), "Vertical Lines") ;

    sf::RenderTexture texture ;
    if (texture.create(win_width, win_height))
    {
        update_texture(texture) ;
        window.clear() ;
        window.draw(sf::Sprite(texture.getTexture())) ;
        window.display() ;
    }
    wait_for_close(window) ;
}

void draw_vertical_line(sf::RenderTexture& t, unsigned x)
{
     sf::VertexArray line(sf::Lines, 2) ;

    line[0].position = sf::Vector2f(x, win_height) ;
    line[1].position = sf::Vector2f(x, win_height - line_height) ;
    line[0].color = line[1].color = sf::Color(0, 255, 256 * x / win_width) ;

    t.draw(line) ;
}

void wait_for_close(sf::RenderWindow& window)
{
    sf::Event event ;

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

void update_texture(sf::RenderTexture& t)
{
    t.clear() ;
    for ( unsigned i=0; i<win_width; ++i)
        draw_vertical_line(t, i) ;
    t.display() ;
}

Can anyone see what I'm doing wrong here?




Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Unexpected result using sf::Lines primitive.
« Reply #1 on: October 14, 2012, 09:02:32 am »
It works perfectly for me, so this might be a driver issue. Make sure that your graphics drivers are up to date.

You can also try to add 0.5 to your the x coordinates of your lines.
Laurent Gomila - SFML developer

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Unexpected result using sf::Lines primitive.
« Reply #2 on: October 14, 2012, 09:05:30 am »
By the way, your code would be much more efficient like this:
void draw_vertical_line(sf::RenderTexture& t, unsigned x)
{
    sf::Color color(0, 255, 256 * x / win_width);

    sf::Vertex lines[2] =
    {
        sf::Vertex(sf::Vector2f(x + 0.5f, win_height), color),
        sf::Vertex(sf::Vector2f(x + 0.5, win_height - line_height), color)
    };

    t.draw(lines, 2, sf::Lines) ;
}

This way you avoid allocating a small amount of heap memory on every call.
Laurent Gomila - SFML developer

cire

  • Full Member
  • ***
  • Posts: 138
    • View Profile
Re: Unexpected result using sf::Lines primitive.
« Reply #3 on: October 14, 2012, 10:58:35 am »
The drivers did need updating (in fact, they jumped up a major version,) but unfortunately it didn't resolve the problem.  Adding .5 to the x value does mask the problem though, so I can work with that for the time being.  It does have me wondering how else the problem might manifest.

That version of the function is certainly cleaner, but I don't think there's actually any heap memory involved is there?  It avoids calling the default constructor for the objects in the lines array in favor of direct initialization, but heap?  Maybe I'm misunderstanding.

In the "real" code,  the function looks a bit different.

Thanks for the assist!

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Unexpected result using sf::Lines primitive.
« Reply #4 on: October 14, 2012, 11:20:58 am »
sf::VertexArray is an encapsulated std::vector<sf::Vertex>, i.e. it allocates a dynamic array. When you have only few elements and you know in advance how many, a static array is more appropriate.

I however would use std::array (or std::tr1::array, if you don't have C++11): It is much safer, more comfortable, and as efficient as C arrays.
std::array<sf::Vertex, 2> lines =
{
    sf::Vertex(sf::Vector2f(x + 0.5f, win_height), color),
    sf::Vertex(sf::Vector2f(x + 0.5, win_height - line_height), color)
};

t.draw(lines.data(), lines.size(), sf::Lines);
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Unexpected result using sf::Lines primitive.
« Reply #5 on: October 14, 2012, 11:36:58 am »
Quote
Adding .5 to the x value does mask the problem though
It doesn't mask it, it solves it. Since your lines are 1-pixel wide, their position must be the center of the pixels so that they cover them completely.
Laurent Gomila - SFML developer

cire

  • Full Member
  • ***
  • Posts: 138
    • View Profile
Re: Unexpected result using sf::Lines primitive.
« Reply #6 on: October 14, 2012, 01:54:50 pm »
Quote from: Nexus
sf::VertexArray is an encapsulated std::vector<sf::Vertex>, i.e. it allocates a dynamic array.

Aha.  For some reason the array type didn't even occur to me.  Now that you point it out, it's pretty obvious.  Thanks!


Quote from: Laurent
It doesn't mask it, it solves it. Since your lines are 1-pixel wide, their position must be the center of the pixels so that they cover them completely.

That's good news, then!   :D