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

Author Topic: Example of utilizing VertexArray?  (Read 12139 times)

0 Members and 1 Guest are viewing this topic.

ChonDee

  • Jr. Member
  • **
  • Posts: 62
    • View Profile
Example of utilizing VertexArray?
« on: January 26, 2012, 06:25:34 pm »
Hi,

I have read the documentation for VertexArray, but I am not sure how to convert my current "loop through every sprite in a container and Draw" implementation to it.

I have a vector<Particle>, each Particle has its own Sprite, and every frame I loop through, calling Particle->show(); that does some logic and the Draw calls
(I didn't separate logic and render for these so I don't have to loop through them twice, which would have a performance hit)

From this, how would I go to using a VertexArray?

Thanks in advance!

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Example of utilizing VertexArray?
« Reply #1 on: January 26, 2012, 07:46:03 pm »
There are several possible solutions.

Here is one of them:
Code: [Select]
void ParticleSystem::Initialize(unsigned int particleCount)
{
    myVertexArray.SetPrimitiveType(sf::Quads);
    myVertexArray.Resize(particleCount * 4);
}

void ParticleSystem::Draw(sf::RenderTarget& target)
{
    foreach (particle)
        particle->Update(&myVertexArray[i * 4]);

    target.Draw(myVertexArray);
}

void Particle::Update(sf::Vertex* vertices)
{
    // compute current position, color and texture coordinates...
    ...

    vertices[0].Position = ...;
    vertices[0].Color = ...;
    vertices[0].TexCoords = ...;

    ... fill the 3 other vertices ...
}
Laurent Gomila - SFML developer

ChonDee

  • Jr. Member
  • **
  • Posts: 62
    • View Profile
Example of utilizing VertexArray?
« Reply #2 on: February 11, 2012, 12:02:18 pm »
Quote from: "Laurent"
There are several possible solutions.

Here is one of them:...


Thank you very much.
The only thing I don't seem to understand, is where/how the actual texture is passed or assigned to the vertices/vertex array.

I see that each vertex has its position, color and texture coordinates. Specifying texture coordinates serves as a subrectangle selection from a texture? If yes, where is it told what texture are they dealing with?
If no, I seem to be misunderstanding it.

Some clarification would be much appreciated.
Thanks in advance!

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Example of utilizing VertexArray?
« Reply #3 on: February 11, 2012, 04:59:57 pm »
You're right, I forgot the texture in my code, sorry.

The texture to use for drawing is set in the render states that can be passed to the Draw function:
Code: [Select]
sf::RenderStates states;
states.Texture = &myTexture;
target.Draw(myVertexArray, states);

Render states allow to set the texture, shader, blend mode and transform.

sf::RenderStates has implicit constructors, so this code can be simplified:
Code: [Select]
target.Draw(myVertexArray, &myTexture);
Laurent Gomila - SFML developer

ChonDee

  • Jr. Member
  • **
  • Posts: 62
    • View Profile
Example of utilizing VertexArray?
« Reply #4 on: February 11, 2012, 09:52:00 pm »
Thank you, I get it now.

ChonDee

  • Jr. Member
  • **
  • Posts: 62
    • View Profile
Example of utilizing VertexArray?
« Reply #5 on: February 12, 2012, 04:15:58 am »
If I may have one more question:

So a particle will be a class having some basic position, velocity, color information, and a sf::Vertex verices[4] array.

If I want to scale, rotate a particle, am I supposed to write my own rotateQuad(sf::Vertex v[4]) function, where I deal with the individual vertices, or are there some SFML functions that can handle transformations that I could use, like sf::Sprite.SetRotation()?

EDIT: Should I make my Particle class inherit from sf::Transformable?
If yes, what do I need to do in order for the transformations to be "linked" with the 4 vertices, so that if I rotate/scale my particle, each particle's vertices' positions will be changed accordingly?

I see in the documentation, a custom Transformable class can be created like this:
Code: [Select]
class MyEntity : public sf::Transformable, public sf::Drawable
 {
     virtual void Draw(sf::RenderTarget& target, sf::RenderStates states) const
     {
         states.Transform *= GetTransform();
         target.Draw(..., states);
     }
 };


But my Particle is not Drawable, the VertexArray is, and for all the particles, there is only one draw call with one RenderStates in it, so if RenderStates contains the transformation information, then I am not sure how to pass a separate RenderStates for each Particle in the VertexArray.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Example of utilizing VertexArray?
« Reply #6 on: February 12, 2012, 09:21:14 am »
You can also use sf::Transform and its member function TransformPoint().
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

ChonDee

  • Jr. Member
  • **
  • Posts: 62
    • View Profile
Example of utilizing VertexArray?
« Reply #7 on: February 12, 2012, 09:44:09 am »
Quote from: "Nexus"
You can also use sf::Transform and its member function TransformPoint().


Thanks for your reply.

You mean using that instead of having my Particle inherit from Transformable?

Or have it inherit from Transformable, then when myTransformNeedUpdate == true I would manually change each vertices position?

Could you be a bit more specific? I'm quite a newbie in this.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Example of utilizing VertexArray?
« Reply #8 on: February 12, 2012, 09:45:24 am »
I think it's a very bad idea to handle each invidual particle as en entity with its own render states. You'll ruin the performances.

Position, size and color are straight-forward to compute directly. You usually don't need to rotate particles, but if you do, a simple sin/cos will do the job.
Laurent Gomila - SFML developer

ChonDee

  • Jr. Member
  • **
  • Posts: 62
    • View Profile
Example of utilizing VertexArray?
« Reply #9 on: February 12, 2012, 09:54:02 am »
Thank you, I'll try to do that.
The ones I need to rotate are sparks, that get rotated to the direction they are flying to and smoke/flame that are just very slowly rotating to some random direction.

For others I just use a random initial rotation, so all the particles don't look the same.

Contadotempo

  • Full Member
  • ***
  • Posts: 167
  • Firelink Shrine
    • View Profile
Re: Example of utilizing VertexArray?
« Reply #10 on: May 05, 2012, 12:05:36 pm »
Hello, sorry for the thread hijack but since my question falls under the same topic I think it's ok to ask here.

I'm trying to implement a particle system based on the example provided by Laurent, but I'm having a bit of trouble erasing a particle when requested. So far I'm doing it like this:

//Inside the particle system class
std::vector<Particle>   m_vectorParticle; //Holds the particles
std::vector<sf::Vertex> m_vectorVertex; //The vertex array
...
void update()
{
    for(unsigned int i = 0; i < m_vectorParticle.size(); ++i)
    {
        m_vectorParticle[i].update(&m_vectorVertex[i * 4], 1);
        if(//It's time to delete the particle)
        {
            m_vectorParticle.erase(m_vectorParticle.begin()+i);
            m_vectorVertex.erase(m_vectorVertex.begin()+i);
            m_vectorVertex.erase(m_vectorVertex.begin()+i+1);
            m_vectorVertex.erase(m_vectorVertex.begin()+i+2);
            if(m_vectorVertex.erase(m_vectorVertex.begin()+i+3) == m_vectorVertex.end())
                return;
        }
    }
}
 

However when it's time to erase a particle, the application seems to freezes and I'm not sure why. I don't believe I'm accessing or erasing anything invalid, or maybe I'm just being silly?
Could someone give me a tip to do this correctly?

Thanks,
Best regards.
« Last Edit: May 05, 2012, 01:02:27 pm by Laurent »

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Example of utilizing VertexArray?
« Reply #11 on: May 05, 2012, 12:26:52 pm »
Hello, sorry for the thread hijack but since my question falls under the same topic I think it's ok to ask here.
Please stop that, there are many threads which fall under the same topic. If you want to create a relation to this thread, add a link in your own, new thread.

Why do you erase elements inside std::vector? That's very inefficient. You can use the swap()-and-pop_back() idiom instead. And you make it wrong, begin() returns a different iterator after the first element has been erased. You can also look how I implemented thor::ParticleSystem with sf::VertexArray (or directly use it :P)
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Contadotempo

  • Full Member
  • ***
  • Posts: 167
  • Firelink Shrine
    • View Profile
Re: Example of utilizing VertexArray?
« Reply #12 on: May 06, 2012, 04:38:32 am »
Thanks! I took a look at thor's implementation and it's easy to understand though I saw something on ParticleSystem.cpp that confused me. Every time the draw function is called, an sf::VertexArray object seems to be created (ParticleSystem.cpp line 243).
Isn't this inefficient? I mean to create a vector/vertexarray every time draw is requested? Wouldn't it be faster to have it as a class member instead?

Thanks for the help,
Best regards

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Example of utilizing VertexArray?
« Reply #13 on: May 06, 2012, 09:23:24 am »
It would definitely be more efficient if the array was kept as a member, and cleared at the beginning of the draw function. This way, the memory usage would stabilize instead of allocating/deallocating the complete array everytime draw is called.
Laurent Gomila - SFML developer

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Example of utilizing VertexArray?
« Reply #14 on: May 06, 2012, 11:44:32 am »
That's true, I thought since sf::VertexArray would be refilled every time, it could be kept as a local object, and didn't think of the fact it's just a thin wrapper around std::vector<sf::Vertex> with the same allocation strategy.

Thanks a lot for pointing this out, I've fixed it. This approach has even allowed me to perform a further optimization: If update() isn't called, the vertex array won't be recomputed.
« Last Edit: May 06, 2012, 12:16:28 pm by Nexus »
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development: