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

Author Topic: Error while capturing resized window?  (Read 4029 times)

0 Members and 2 Guests are viewing this topic.

Billy2600

  • Newbie
  • *
  • Posts: 9
  • RIP Oderus Urungus
    • View Profile
    • Retro of the Week (dead)
    • Email
Error while capturing resized window?
« on: June 14, 2017, 03:42:37 am »
I'm trying to capture the window in order to do a sort of transition effect, but when I capture a resized window it seems to only capture a portion of the screen or display it incorrectly. There are other ways to do the effect I'm looking for, but I'm hoping to get this method working. I am currently developing on Win10 with VS2015. See the following webms:

Default window size: https://webmshare.com/play/Zro60

Resized window: https://webmshare.com/play/jzxXa

This is the code I'm using to capture the window:
txTrans.create( game->window.getSize().x, game->window.getSize().y );
txTrans.update( game->window );
sprTrans.setTexture( txTrans );
 

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Error while capturing resized window?
« Reply #1 on: June 14, 2017, 07:49:17 am »
Try
sprTrans.setTexture( txTrans, true );
Laurent Gomila - SFML developer

Billy2600

  • Newbie
  • *
  • Posts: 9
  • RIP Oderus Urungus
    • View Profile
    • Retro of the Week (dead)
    • Email
Re: Error while capturing resized window?
« Reply #2 on: June 15, 2017, 01:49:45 am »
Thank you for your reply, but that didn't seem to solve the problem, even after rebuilding.

dabbertorres

  • Hero Member
  • *****
  • Posts: 505
    • View Profile
    • website/blog
Re: Error while capturing resized window?
« Reply #3 on: June 15, 2017, 03:03:30 am »
Do you have any transformations applied to the sprite?

Might just be the video, but it looks to me like there *might* be some scaling going on.

Billy2600

  • Newbie
  • *
  • Posts: 9
  • RIP Oderus Urungus
    • View Profile
    • Retro of the Week (dead)
    • Email
Re: Error while capturing resized window?
« Reply #4 on: June 15, 2017, 03:11:44 am »
Nope. The only things I'm calling from the sprite are setTexture, move, and getGlobalBounds.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: Error while capturing resized window?
« Reply #5 on: June 15, 2017, 06:11:55 am »
So does it display okay and just captures wrong?
What capturing software do you use?
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Billy2600

  • Newbie
  • *
  • Posts: 9
  • RIP Oderus Urungus
    • View Profile
    • Retro of the Week (dead)
    • Email
Re: Error while capturing resized window?
« Reply #6 on: June 15, 2017, 02:53:06 pm »
It displays incorrectly whether being captured by external software or not. By "capture", I meant the built-in function to apply the window's contents to a texture.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: Error while capturing resized window?
« Reply #7 on: June 15, 2017, 03:08:07 pm »
Can you provide a MCVE?
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Billy2600

  • Newbie
  • *
  • Posts: 9
  • RIP Oderus Urungus
    • View Profile
    • Retro of the Week (dead)
    • Email
Re: Error while capturing resized window?
« Reply #8 on: June 16, 2017, 04:11:39 am »
Okay, hopefully this will show you what you need to know. Anything you don't see defined is a member variable or a #define (defines are all caps). Both of these functions run every frame.

void StateGameplay::ScreenTransition( const float dt )
{
        if( !captured )
        {
                // Capture the screen
                txTrans.create( game->window.getSize().x, game->window.getSize().y );
                txTrans.update( game->window );
                sprTrans.setTexture( txTrans, true );
                captured = true;
        }
        else
        {
                sf::Vector2f move;
                switch( lastMove )
                {
                case Directions::N:
                        move = sf::Vector2f( 0, -TRANS_SPEED );
                        break;
                case Directions::E:
                        move = sf::Vector2f( TRANS_SPEED, 0 );
                        break;
                case Directions::S:
                        move = sf::Vector2f( 0, TRANS_SPEED );
                        break;
                case Directions::W:
                        move = sf::Vector2f( -TRANS_SPEED, 0 );
                        break;
                }

                sprTrans.move( move * dt );

                // State gets switched here
}

void StateGameplay::Draw() const
{
        if( transition && captured )
        {
                game->window.draw( sprTrans );
                return; // Don't draw anything else
        }
       
        // etc
}
 

Rosme

  • Full Member
  • ***
  • Posts: 169
  • Proud member of the shoe club
    • View Profile
    • Code-Concept
Re: Error while capturing resized window?
« Reply #9 on: June 16, 2017, 03:27:55 pm »
This is not a MCVE. The concept of a MCVE is that I can take the code and compile it to reproduce the problem. It is minimal and complete. By producing one, it might also show you where the problem reside as you cut more and more of the complexity of your code. At some point, the problem might stop occuring and you can figure out what you cut that actually produces the problem.
GitHub
Code Concept
Twitter
Rosme on IRC/Discord

Billy2600

  • Newbie
  • *
  • Posts: 9
  • RIP Oderus Urungus
    • View Profile
    • Retro of the Week (dead)
    • Email
Re: Error while capturing resized window?
« Reply #10 on: June 21, 2017, 01:20:44 am »
Sorry for the delay, here's a proper MCVE that's exhibiting the same issue.
#include <SFML/Graphics.hpp>
#include <cstdlib>

#define WIN_WIDTH 640
#define WIN_HEIGHT 480
#define NUM_SHAPES 5
#define MOVE_SPEED 0.05f
#define TRANS_SPEED 0.05f
#define TRANS_DELAY 2000

sf::RenderWindow window( sf::VideoMode( WIN_WIDTH, WIN_HEIGHT ), "SFML Capture MCVE" );
sf::RectangleShape shapes[NUM_SHAPES];
sf::RectangleShape player;
bool transition = false;
bool captured = false;
sf::Int8 lastMove = 0;
sf::Texture txTrans;
sf::Sprite sprTrans;
sf::Clock clkTrans;

void ScreenTransition( const sf::Int8 lastMove ) // 0 = N, 1 = E, 2 = S, 3 = W
{
        if ( !captured )
        {
                // Capture the screen
                txTrans.create( window.getSize().x, window.getSize().y );
                txTrans.update( window );
                sprTrans.setTexture( txTrans, true );
                captured = true;
                clkTrans.restart();
        }
        else
        {
                sf::Vector2f move;
                switch ( lastMove )
                {
                case 0:
                        move = sf::Vector2f( 0, -TRANS_SPEED );
                        break;
                case 1:
                        move = sf::Vector2f( TRANS_SPEED, 0 );
                        break;
                case 2:
                        move = sf::Vector2f( 0, TRANS_SPEED );
                        break;
                case 3:
                        move = sf::Vector2f( -TRANS_SPEED, 0 );
                        break;
                }

                sprTrans.move( move );

                // Fake resetting state
                if ( clkTrans.getElapsedTime().asMilliseconds() > TRANS_DELAY )
                {
                        transition = false;
                        captured = false;
                        player.setPosition( 10, 10 );
                        sprTrans.setPosition( 0, 0 );
                }
        }
}

int main()
{
        for ( int i = 0; i < NUM_SHAPES; i++ )
        {
                shapes[i].setFillColor( sf::Color::Blue );
                shapes[i].setPosition( rand() % WIN_WIDTH, rand() % WIN_HEIGHT );
                shapes[i].setSize( sf::Vector2f( rand() % 1 + 100, rand() % 1 + 100 ) );
        }
        player.setSize( sf::Vector2f( 50, 50 ) );
        player.setPosition( sf::Vector2f( 10, 10 ) );
        player.setFillColor( sf::Color::Red );
        sprTrans.setPosition( sf::Vector2f( 0, 0 ) );

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

                if ( sf::Keyboard::isKeyPressed( sf::Keyboard::Key::D ) )
                        player.move( MOVE_SPEED, 0 );
                else if ( sf::Keyboard::isKeyPressed( sf::Keyboard::Key::A ) )
                        player.move( -MOVE_SPEED, 0 );
                else if ( sf::Keyboard::isKeyPressed( sf::Keyboard::Key::W ) )
                        player.move( 0, -MOVE_SPEED );
                else if ( sf::Keyboard::isKeyPressed( sf::Keyboard::Key::S ) )
                        player.move( 0, MOVE_SPEED );

                if ( player.getPosition().x < 0 )
                {
                        transition = true;
                        lastMove = 3;
                }
                else if ( player.getPosition().x + 50 > WIN_WIDTH )
                {
                        transition = true;
                        lastMove = 1;
                }
                else if ( player.getPosition().y < 0 )
                {
                        transition = true;
                        lastMove = 0;
                }
                else if ( player.getPosition().y + 50 > WIN_HEIGHT )
                {
                        transition = true;
                        lastMove = 2;
                }

                if ( transition )
                {
                        ScreenTransition( lastMove );
                }

                window.clear();
                if ( transition && captured )
                {
                        window.draw( sprTrans );
                }
                else
                {
                        for ( int i = 0; i < NUM_SHAPES; i++ )
                        {
                                window.draw( shapes[i] );
                        }
                        window.draw( player );
                }
               
                window.display();
        }

        return 0;
}
 

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: Error while capturing resized window?
« Reply #11 on: June 21, 2017, 02:10:53 am »
So by "resize" you mean, you made the window slightly bigger?
Do you adjust the view?
You'll have to use the same view on the render texture as on the window.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Billy2600

  • Newbie
  • *
  • Posts: 9
  • RIP Oderus Urungus
    • View Profile
    • Retro of the Week (dead)
    • Email
Re: Error while capturing resized window?
« Reply #12 on: June 24, 2017, 04:09:43 am »
Sorry, I thought "resize" would be self-explanatory. I did experiment with the MCVE, but you definitely pointed me toward the solution:

txTrans.create( window.getSize().x, window.getSize().y );
sf::View view;
view = window.getDefaultView();
view.setSize( window.getSize().x, window.getSize().y );
view.setCenter( window.getSize().x / 2, window.getSize().y / 2 );
window.setView( view );
txTrans.update( window );
sprTrans.setTexture( txTrans, true );
 

And then after the transition is done, reset the view (because my intention is to keep the image stretched, not increase the viewport):

window.setView( window.getDefaultView() );
 

I'm sure there's optimizations I can do. Regardless, thank you all for your input.