SFML community forums

Help => Graphics => Topic started by: Power on June 01, 2020, 03:27:24 pm

Title: using push_back to modify only one parameter of the vertexAconstructor (setter?)
Post by: Power on June 01, 2020, 03:27:24 pm
Hello,
I took a pause from SFML a bit, but i came back to do something briefly.
I wanted to modify colors of a vertexArray randomly.
1. VertexArray is already declared, the vertices positions are known.
2. The function takes the VertexArray as a parameter and modify the vertices colors. Its a "ref".

bool VertexColorREAL(sf::VertexArray &VV )
        {

        std::size_t cnt=VV.getVertexCount(); ///count
        if(cnt==4)
        {
                sf::Color &c0=VV[0].color;
                sf::Color &c1=VV[1].color;
                sf::Color &c2=VV[2].color;
                sf::Color &c3=VV[3].color;

            c0.r = rand() % 255+ 0;
            c0.g = rand() % 255+ 0;
            c0.b = rand() % 255+ 0;
            c1.r = rand() % 255+ 0;
            c1.g = rand() % 255+ 0;
            c1.b = rand() % 255+ 0;
            c2.r = rand() % 255+ 0;
            c2.g = rand() % 255+ 0;
            c2.b = rand() % 255+ 0;
            c3.r = rand() % 255+ 0;
            c3.g = rand() % 255+ 0;
            c3.b = rand() % 255+ 0;
        }
        if(cnt==3)
        {
//..
        }

        return true;
        }
 

3. The function checks the number of vertices (if count==4).. etc

Is it possible to work with push_back, to modify only the colors ? I am trying to write something like this :

bool VertexColorREAL(sf::VertexArray &VV )
        {
            vector<sf::Vertex> vertices;


            for(int i=0;i<VV.getVertexCount();i++)
            {
                &vertices.push_back(sf::Vertex(sf::Color::Black)); // obviousely ERROR
           /// I am not quite sure how to do it.
            }

 

-> I am not quite sure how to do it, i don't know if push_back can be used as a setter somehow, the only use i know of is as a constructor, something like this :
vector<sf::Vertex> vertices; ///  (VECTOR  std c++)
    vertices.push_back(sf::Vertex(sf::Vector2f(110.f,110.f),sf::Color::Black));
    vertices.push_back(sf::Vertex(sf::Vector2f(210.f,110.f),sf::Color::Yellow));
    vertices.push_back(sf::Vertex(sf::Vector2f(210.f,210.f),sf::Color::Blue));
 
Is there a way to turn around this as a color setter instead of constructors?
Thanks
Title: Re: using push_back to modify only one parameter of the vertexAconstructor (setter?)
Post by: Hapax on June 01, 2020, 04:31:54 pm
If the vertices in the vertex array already exist, change the colours of those directly, as you do in your first example. What was wrong with that? (your rand should be rand%256, btw - 0-255)

If your question is about how to treat different number of vertices, the highest index would be the number of vertices (vertex count) minus 1:

std::size_t vertexCount{ VV.getVertexCount() };
for (std::size_t i{ 0u }; i < vertexCount; ++i)
{
    sf::Color randomColor; // choose your random colour how you want
    VV[i].color = randomColor;
}
This would assign a random colour to every vertex in the vertex array, VV.



Hope that all you wanted, but I should mention that you can also use a full on std::vector of sf::Vertex yourself instead of a vertex array (a vertex array is a wrapper around a vector that also stores its primitive type).
std::vector<sf::Vertex> vertices;
window.draw(vertices.data(), vertices.size(), sf::PrimitiveType::Quads);

So, if you were using this instead of a vertex array, you have to put more into the draw call but the entire random colour code would just be:
for (auto& vertex : vertices)
{
    vertex.color.r = rand % 256u;
    vertex.color.g = rand % 256u;
    vertex.color.b = rand % 256u;
}



It's worth noting that using "rand" is bad for a number of reasons. It's okay for testing purposes or very trivial randomness but, for more accurate representation of randomness, you should use std::random.


EDIT: fixed typo - changed sf::Primitive to sf::PrimitiveType
Title: Re: using push_back to modify only one parameter of the vertexAconstructor (setter?)
Post by: Power on June 01, 2020, 05:30:05 pm
Very comprehensive and complete answer, thank you.
I was aware "rand" was not good, that it had something to do with the processor clock etc.. but i did not bother searching for alternatives, i will check "random".

Quote
std::size_t vertexCount{ VV.getVertexCount() };
for (std::size_t i{ 0u }; i < vertexCount; ++i)
{
    sf::Color randomColor; // choose your random colour how you want
    VV[i].color = randomColor;
}
I completely missed this! It's so simple, i was focused on "vector".
Thanks again!
Title: Re: using push_back to modify only one parameter of the vertexAconstructor (setter?)
Post by: Hapax on June 02, 2020, 08:08:54 pm
You're welcome. Glad it helped!

std::random looks a bit complicated to start with but gets easier when you've used it a few times.