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

Author Topic: strange behaviour when resizing window  (Read 5763 times)

0 Members and 1 Guest are viewing this topic.

T.T.H.

  • Full Member
  • ***
  • Posts: 112
    • View Profile
strange behaviour when resizing window
« on: January 31, 2008, 09:50:43 pm »
Hi again

There is yet another thing which I don't understand yet: when I open a window and draw sprites into it everything looks fine. But when I resize the window the sprites get "scaled" somehow despite I didn't change their scale myself.

...and again in images:

Source image, 32 x 32 pixel, with colorful 1 pixel wide border and checkerboard within:



Screenshot after starting application, no resizing done:



Screenshot after resizing window, making it smaller:



Screenshot after resizing window, making it larger:



And finally my code:

Code: [Select]

// --- includes ---

// windows
#include <windows.h>

// SFML
#include "SFML/Graphics.hpp"

// STL
#include <iostream>

// --- defines ---

#define IMAGE_FILE "image_1x1.bmp"
const int SCREEN_WIDTH = 400;
const int SCREEN_HEIGHT = 400;
const int SPRITE_WIDTH_DEST = 32;
const int SPRITE_HEIGHT_DEST = 32;

// --- signal handler ---

BOOL WINAPI MyHandlerRoutine(DWORD dwCtrlType)
{
  std::cout << "exiting the hard way" << std::endl;
  exit(0);
  return TRUE;
}

// --- run ---

bool runSFML()
{
  // variables
  bool Looping(true);
  int X(0);
  int Y(0);
  sf::Event MyEvent;

  // render window
  sf::RenderWindow MyRenderWindow(sf::VideoMode(SCREEN_WIDTH, SCREEN_HEIGHT), "SFML", sf::Style::Close | sf::Style::Resize);
  MyRenderWindow.OptimizeForNonOpenGL(true);
  MyRenderWindow.SetBackgroundColor(sf::Color(255, 0, 255));

  // image
  sf::Image MyImage;
  if (!MyImage.LoadFromFile(IMAGE_FILE))
  {
    std::cout << "failed to load image '" << IMAGE_FILE << "'" << std::endl;
    return false;
  }
  MyImage.SetSmooth(false);

  // sprite
  sf::Sprite MySprite(MyImage);
  MySprite.Scale((float) SPRITE_WIDTH_DEST / (float) MyImage.GetWidth(), (float) SPRITE_HEIGHT_DEST / (float) MyImage.GetHeight());

  // big loop
  while (Looping)
  {
    // loop over screen
    for (Y = 0; Y < (int) MyRenderWindow.GetHeight(); Y += SPRITE_HEIGHT_DEST)
    {
      for (X = 0; X < (int) MyRenderWindow.GetWidth(); X += SPRITE_WIDTH_DEST)
      {
        // draw sprite
        MySprite.SetPosition((float) X, (float) Y);
        MyRenderWindow.Draw(MySprite);
      }
    }

    // display screen
    MyRenderWindow.Display();

    // poll events
    while (MyRenderWindow.GetEvent(MyEvent))
    {
      // check whether window was closed
      if (MyEvent.Type == sf::Event::Closed)
      {
        Looping = false;
      }

      // check whether escape was pressed
      if ((MyEvent.Type == sf::Event::KeyReleased) && (MyEvent.Key.Code == sf::Key::Escape))
      {
        Looping = false;
      }

      // check whether resized
      if ((MyEvent.Type == sf::Event::Resized)) {

        // ### WHAT TO DO HERE ?!? ###
      }
    }
  }

  return true;
}

// --- main ---

int main(int argc, char *argv[])
{
  // add signal handler routine
  if (!SetConsoleCtrlHandler(MyHandlerRoutine, TRUE))
  {
    std::cout << "failed to add signal handler routine" << std::endl;
    exit(1);
  }

  // start
  std::cout << "started" << std::endl;

  // run SFML
  runSFML();

  // stopped
  std::cout << "stopped" << std::endl;

  return 0;
}


Using SFML revision 442 with Visual C++ 2005 Express under Windows 2000 including a Sapphire ATI Radeon 9800 Pro with ATI Catalyst 4.4.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
strange behaviour when resizing window
« Reply #1 on: February 01, 2008, 02:48:58 am »
One more weird thing :D

Ok, I'll check this too.
Laurent Gomila - SFML developer

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
strange behaviour when resizing window
« Reply #2 on: February 03, 2008, 09:47:28 am »
I've just tried your code.

Actually, there's a bug in it. Your drawing loop uses the size of the window,  which will change each time you resize it, and the sprite's size, which is a constant.

Your loop would be ok if you used SCREEN_WIDTH and SCREEN_HEIGHT instead of window's size. That's because the view (ie. the rectangle that maps into the window) doesn't change, so the size of your 2D world remains the same even after the window has been resized.
Laurent Gomila - SFML developer

T.T.H.

  • Full Member
  • ***
  • Posts: 112
    • View Profile
strange behaviour when resizing window
« Reply #3 on: February 04, 2008, 07:53:41 pm »
Quote from: "Laurent"
Actually, there's a bug in it. Your drawing loop uses the size of the window,  which will change each time you resize it, and the sprite's size, which is a constant.

Your loop would be ok if you used SCREEN_WIDTH and SCREEN_HEIGHT instead of window's size. [...]

I would not call that a bug but intentional: I want to draw the whole screen, not more, not less, and so the screen size (in pixel) is my reference. When the screen size changes I want to draw a different amount of things. And I want to stay pixel precise between source image and screen.

Quote from: "Laurent"
[...]That's because the view (ie. the rectangle that maps into the window) doesn't change, so the size of your 2D world remains the same even after the window has been resized.

That information finally gave me the clue: when the screen changes, the view does not. I actually have to manually update the view to the new screen size, too, to get what I want.

In my example application that would like this, where now a) event handling comes before drawing and b) RenderWindow.SetView is called:
Code: [Select]

  // big loop
  while (Looping)
  {
    // poll events
    while (MyRenderWindow.GetEvent(MyEvent))
    {
      // check whether resized
      if ((MyEvent.Type == sf::Event::Resized)) {

        // >>> set new view !!! <<<
        MyRenderWindow.SetView(
          &sf::View(
            sf::FloatRect(
              0.0f,
              0.0f,
              (float) MyRenderWindow.GetWidth(),
              (float) MyRenderWindow.GetHeight())));
      }
    }

    // loop over screen
    for (Y = 0; Y < (int) MyRenderWindow.GetHeight(); Y += SPRITE_HEIGHT_DEST)
    {
      for (X = 0; X < (int) MyRenderWindow.GetWidth(); X += SPRITE_WIDTH_DEST)
      {
        // draw sprite
        MySprite.SetPosition((float) X, (float) Y);
        MyRenderWindow.Draw(MySprite);
      }
    }


Unfortunately I could not find any hint in the documentation about the relation of "screen size changes" and "view size stays the same". In addition I (personally) consider that default behavior quite unintuitive. I would prefer that the view internally would get adjusted automatically with me worrying only about screen size in pixel. If you have good reasons against that, a hint in the documentation of "sf::Event::Resized" or so would be helpful for newbies like me.

Nevertheless thanks for your effort.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
strange behaviour when resizing window
« Reply #4 on: February 05, 2008, 02:22:24 am »
Quote
Unfortunately I could not find any hint in the documentation about the relation of "screen size changes" and "view size stays the same". In addition I (personally) consider that default behavior quite unintuitive

To me, this is the most intuitive solution. But I guess it highly depends on people and what they are expecting. A beginner will maybe just expect everythink to be resized with the window, as the expert may expect nothing to happen and do whatever he needs manually.
Laurent Gomila - SFML developer