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

Author Topic: Drawing Dots on an Image - Image Disappears  (Read 2495 times)

0 Members and 1 Guest are viewing this topic.

person

  • Newbie
  • *
  • Posts: 3
    • View Profile
Drawing Dots on an Image - Image Disappears
« on: February 12, 2016, 12:36:36 pm »
[Hi. I started learning SFML in the last week. If you think my question could be answered by reading the tutorials, please give me a link. Also if I'm doing something in an unecesserily complicated way, I'll appreciate it if you tell me. Thank you!]

I was trying display an image on the screen, and then put dots where the user pressed. Here's my code:

 //This is a type I defined. For this question, it's enough to know that it has a Texture member.
   static void create(imageAndButtons& myImage)

   {
      sf::Texture image(myImage.texture);
      sf::Sprite mySprite(image);


      sf::RenderWindow myWindow;
//Make window size match image size.      
      myWindow.create(sf::VideoMode(image.getSize().x,image.getSize().y),"screen");      
      myWindow.draw(mySprite);
      myWindow.display();
            
      sf::VertexArray point(sf::Points, 1);
      sf::Event event;
      while (true)
      {
         while (myWindow.pollEvent(event))
            if (event.type == sf::Event::MouseButtonPressed)
            {
            point[0].position.x = event.mouseButton.x;
            point[0].position.y = event.mouseButton.y;
            myWindow.draw(point);   
            myWindow.display();
            }
      }

The very strange (to me) result of this code was that each time the user presses the mouse button the image disappears and reappears alternately, while the dots are added to the screen and remain all the time.

I'll be happy to know what I should change in my code. Also I'd very much like to understand why the image disappears, and what makes it to reappear (We never left the while loop!)

ramaskrik

  • Newbie
  • *
  • Posts: 45
    • View Profile
Re: Drawing Dots on an Image - Image Disappears
« Reply #1 on: February 12, 2016, 01:45:52 pm »
You're rendering to the window only if a mouse button is pressed. Take it out of the inner loop.

Actually, I have just realized it needs a bit more than that.
  • window.display() doesn't display the window, but it shows on the screen what has been rendered so far. Call it once per frame.
  • window.draw() renders to the window. Call it once per frame, not only when an event is caught.
  • Every frame, clear the background and render stuff once again. This will allow you to remove the dots, for instance.
  • Because you're clearing the window every frame, you must keep track of your dots. std::vector should be just fine.
Here's a minimal example of how it should look like:

#include <SFML/Graphics.hpp>
#include <vector>

int main()
{
  sf::Texture image;
  image.loadFromFile("tex.jpg");
  sf::Sprite mySprite(image);
 
 
  sf::RenderWindow myWindow;
  //Make window size match image size.      
  myWindow.create(sf::VideoMode(image.getSize().x,image.getSize().y),"screen");
 
  std::vector<sf::VertexArray> points;
  sf::VertexArray point(sf::Points, 1);
 
  sf::Event event;
  while (true)
  {
    while (myWindow.pollEvent(event))
    {
      if (event.type == sf::Event::MouseButtonPressed)
      {
        point[0].position.x = event.mouseButton.x;
        point[0].position.y = event.mouseButton.y;
        points.push_back(point);
      }
    }
    myWindow.draw(mySprite);
    for(auto & p : points)
    {
      myWindow.draw(p);
    }
    myWindow.display();
  }

    return 0;
}
« Last Edit: February 12, 2016, 02:04:07 pm by ramaskrik »

person

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Drawing Dots on an Image - Image Disappears
« Reply #2 on: February 13, 2016, 05:53:10 pm »
Thank you very much. Appresciate your answer and your time.

ramaskrik

  • Newbie
  • *
  • Posts: 45
    • View Profile
Re: Drawing Dots on an Image - Image Disappears
« Reply #3 on: February 13, 2016, 08:24:31 pm »
You're welcome. I recommend you to check the tutorials out, as you'll find out there how should be the stuff used and also some best practices.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Drawing Dots on an Image - Image Disappears
« Reply #4 on: February 13, 2016, 10:03:41 pm »
1)
Using the vector method now means that it stores multiple vertex arrays (one for each point).
A vertex array can store multiple points and draw them all at once.
Modifying ramaskrik's code, you could do this:
#include <SFML/Graphics.hpp>

int main()
{
  sf::Texture image;
  image.loadFromFile("tex.jpg");
  sf::Sprite mySprite(image);
 
  // You can create the window directly in its constructor
  sf::RenderWindow myWindow(sf::VideoMode(image.getSize().x,image.getSize().y),"screen");
 
  sf::VertexArray points(sf::Points); // starts with no points
 
  sf::Event event;
  while (true)
  {
    while (myWindow.pollEvent(event))
    {
      if (event.type == sf::Event::MouseButtonPressed)
      {
        points.append(sf::Vertex(sf::Vector2f(event.mouseButton.x + 0.5f, event.mouseButton.y + 0.5f))); // without these halves, you will probably notice errors at some point. long story...
      }
    }
    myWindow.draw(mySprite);
    myWindow.draw(points);
    myWindow.display();
  }

  return EXIT_SUCCESS;
}

2)
However, it may be that you're trying to manipulate the image rather than just draw dots on top of it.
You can change the pixel of an image using setPixel(). The sprite, though, is linked to a texture so you'll need to constantly transfer between them.
Modifying code from 1):
#include <SFML/Graphics.hpp>

int main()
{
  sf::Texture image;
  image.loadFromFile("tex.jpg");
  sf::Texture texture;
  texture.loadFromImage(image);
  sf::Sprite mySprite(texture);
 
  // You can create the window directly in its constructor
  sf::RenderWindow myWindow(sf::VideoMode(image.getSize().x,image.getSize().y),"screen");
 
  sf::Event event;
  while (true)
  {
    while (myWindow.pollEvent(event))
    {
      if (event.type == sf::Event::MouseButtonPressed)
      {
        image.setPixel(event.mouseButton.x, event.mouseButton.y, sf::Color::Black);
        texture.update(image);
      }
    }
    myWindow.draw(mySprite);
    myWindow.display();
  }

  return EXIT_SUCCESS;
}
Note that copying an image to a texture can be slow, especially if trying to do a lot of times quickly.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

person

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Drawing Dots on an Image - Image Disappears
« Reply #5 on: February 16, 2016, 09:07:59 pm »
Thanks for the tips. I'll use them.