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

Author Topic: Floating point precision and sf::RenderTexture not compatible  (Read 2104 times)

0 Members and 1 Guest are viewing this topic.

Carlitox

  • Jr. Member
  • **
  • Posts: 53
    • View Profile
I draw my entities to a sf::RenderTextures and it caused a "vibration effect". That is solved using std::floor in my moving functions. But this affects to my collision system, I want to avoid to use render textures to draw entities but keep the map as a sf::RenderTexture.

I'm drawing my map into a sf::RenderTexture because I was having tearing problems and that solved the issue. So it seems that I'm forced to draw my entities also in the render texture The problem it's that I use 5 map layers, entities are drawn in the third ¿There is a way to render my entities without using a sf::RenderTexture? Using normal draw without the render texture doesn't show my entities, only after the last layer is drawn.

I cannot draw the entities between layers, and if I use render texture it causes the vibration effect.

PD: Forum quotes aren't working. The code draws map and entites into the buffer and display it.

void Map::draw_layer(sf::RenderTarget &target, int layer_id)
{
        if (tmx_info.num_layers >= layer_id)
        {
                sf::RenderStates states;
                states.texture = &map_layers[layer_id].texture;

                if (layer_id == 2)
                {
                        for (auto j : World::current_level->getSceneVector())
                        {
                                assert(j != nullptr);
                                texture_map.draw(*j);                  
                        }
                }

                texture_map.draw(map_layers[layer_id].entity_vertex, states);
                texture_map.display();
                sf::Sprite draw_map(texture_map.getTexture());
                target.draw(draw_map);
        }      
}
 
« Last Edit: March 20, 2016, 08:43:22 pm by Laurent »

Carlitox

  • Jr. Member
  • **
  • Posts: 53
    • View Profile
Re: Floating point precision and sf::RenderTexture not compatible
« Reply #1 on: March 20, 2016, 11:28:14 pm »
Now I can mix the entities with the map render texture but only on the back of the map.

Just making: window.draw(*entity).

I need to render it between layers. By the moment if I draw between layers it draws on the back.


Here is where I create the render texture and draw it with the entities. There are 4 layers and entities are drawn in the second.

void Map::draw_layer(int layer_id,  sf::RenderWindow &window)
{
        if (tmx_info.num_layers >= layer_id)
        {
                sf::RenderStates states;
                states.texture = &map_layers[layer_id].texture;
                texture_map.draw(map_layers[layer_id].map_vertex_array, states);
              texture_map.display();

                sf::Sprite draw_map(texture_map.getTexture());
                window.draw(draw_map,);

                if (layer_id == 2)
                {
                        for (auto &j : World::current_level->getSceneVector())
                        {
                                assert(j != nullptr);
                                window.draw(*j);
                        }
                }
        }
}

 

Here it's where I display it. I draw everything but first the entities and later the map causing that I cannot insert between layers.


window.clear();

for (unsigned int i = 1; i <= current_level->getNumLayers(); i++)
{      
        map->draw_layer(i,  window);           
}
       
window.display();
 


« Last Edit: March 21, 2016, 03:05:05 am by Carlitox »

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Floating point precision and sf::RenderTexture not compatible
« Reply #2 on: March 21, 2016, 12:55:26 pm »
I draw my entities to a sf::RenderTextures and it caused a "vibration effect". That is solved using std::floor in my moving functions. But this affects to my collision system
Consider separating your graphical entities from your logical collision frames.
For example, store a floatRect for each entity representing where the entity is and use that in the collision code (and, in fact, all logic).
Then, at the drawing stage, use the sprite (or whatever type of drawable you use) to display in the place of where that floatRect is. This, among other benefits, allows you to floor the drawable without affecting the actual object's abstract position.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Carlitox

  • Jr. Member
  • **
  • Posts: 53
    • View Profile
Re: Floating point precision and sf::RenderTexture not compatible
« Reply #3 on: March 21, 2016, 01:13:52 pm »
Finally I solved the tearing problem. Now I don't need the render texture and do the double buffering. The solution was to not use decimals in the setPosition. The collision problem was in slope moving but using floating points in this movements don't cause tearing. Not using double buffer consumes less cpu and I prefer that.

void Movement::moveNowInteger(sf::Vector2f n)
{
        if (n.x > 0) process_move_right += n.x;
        if (n.x < 0) process_move_left += (-n.x);
        if (n.y > 0) process_move_down += n.y;
        if (n.y < 0) process_move_up += (-n.y);
       

        if (process_move_right > 1.f)
        {
                moveNow(sf::Vector2f(std::floor(process_move_right), 0.f));
                process_move_right -= std::floor(process_move_right);
        }

        if (process_move_left > 1.f)
        {
                moveNow(sf::Vector2f(-std::floor(process_move_left), 0.f));
                process_move_left -= std::floor(process_move_left);
        }

        if (process_move_down > 1.f)
        {
                moveNow(sf::Vector2f(0.f, std::floor(process_move_down)));
                process_move_down -= std::floor(process_move_down) ;
        }

        if (process_move_up > 1.f)
        {
                moveNow(sf::Vector2f(0.f, -std::floor(process_move_up)));
                process_move_up -= std::floor(process_move_up);
        }
}
 
« Last Edit: March 21, 2016, 06:08:40 pm by Carlitox »

 

anything