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

Author Topic: Updating part of the screen?  (Read 5086 times)

0 Members and 2 Guests are viewing this topic.

mk12

  • Newbie
  • *
  • Posts: 5
    • View Profile
Updating part of the screen?
« on: August 03, 2010, 03:05:22 am »
How can I only update a certain part (rect) of the screen, like in SDL ? RenderWindow.Display() doesn't give the option to specify a rect. In SDL doing this sped things up a lot for me, so is there some reason I can't in SFML?

Walker

  • Full Member
  • ***
  • Posts: 181
    • View Profile
Updating part of the screen?
« Reply #1 on: August 03, 2010, 05:57:08 am »
No, the only method I can think of doing this in 1.6 and older (I'm not sure about SFML2 render targets, but I can't see them giving you any performance benefit) is running through an image pixel by pixel, which more than likely wouldn't give you any performance increase.

May I ask why you feel the need to? SFML is on a whole faster than SDL anyway.

mk12

  • Newbie
  • *
  • Posts: 5
    • View Profile
Updating part of the screen?
« Reply #2 on: August 03, 2010, 06:10:24 am »
In my little program, each frame one point is drawn. Updating the whole screen vs one pixel makes a huge difference. In SFML it is really slow because of that and as far as I know I can't set an individual pixel either, so I have to use a circle with a radius of 0.5 (using a shape with a single point didn't seem to work).

I guess I could use OpenGL but I don't see why this kind of thing isn't implemented.

Wait, does SFML Graphics use OpenGL internally? With SDL it went much faster updating only one pixel because otherwise it blits the whole frame, but OpenGL does its own calculations for what parts to update, no?

EDIT: Ok I just realized it's going "slow" because I had it V-synced, drawing only one dot per frame. So I will just draw many times each frame. But is there a way to draw points besides using tiny circles?

What it's doing by the way is this: http://en.wikipedia.org/wiki/Chaos_game .

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Updating part of the screen?
« Reply #3 on: August 03, 2010, 08:34:51 am »
The best strategy is to draw to an off-screen buffer rather than directly to the screen. This way you can mainpulate individual pixels (rather than drawing a tiny circle composed of 40 points -- a rectangle would have 10x less points by the way ;)), and you can update the screen whenever you want.

Then you display your off-screen pixel buffer through a screen-wide image and sprite.

If you have to change many pixels per update, you should use a raw array of sf::Uint8 and update the image once with the LoadFromPixels function (which is optimized for this purpose). Otherwise, if you just want to update a single pixel every frame, you can directly use the image as the off-screen buffer, and use its SetPixel function to modify it.
Laurent Gomila - SFML developer

mk12

  • Newbie
  • *
  • Posts: 5
    • View Profile
Updating part of the screen?
« Reply #4 on: August 03, 2010, 06:33:05 pm »
Ok, so I have an sfImage and an sfSprite (which has its Image set to my image), and an array likes this : "sfUint8 pixels[ScreenHeight][ScreenWidth]" ? Then every frame I calculate as many points as I want, set their colour in the pixels array, load those into the image,  draw the Sprite into the window?

One question: how come I have to use 1-byte integers? Won't this limit me to 8 bpp color depth?
UPDATE: Just realized it says it assumes RGBA colour. So does this mean my pixels array will have to be malloc(ScreenHeight  * ScreenWidth * 4 * sizeof(sfUint8)) ?

Also, I didn't realize the circles always use 40 points. Why not have SFML calculate how many are necessary?

BTW I'm using csfml 2.0.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Updating part of the screen?
« Reply #5 on: August 03, 2010, 06:54:07 pm »
Quote
Ok, so I have an sfImage and an sfSprite (which has its Image set to my image), and an array likes this : "sfUint8 pixels[ScreenHeight][ScreenWidth]" ? Then every frame I calculate as many points as I want, set their colour in the pixels array, load those into the image, draw the Sprite into the window?

Absolutely.

Quote
UPDATE: Just realized it says it assumes RGBA colour. So does this mean my pixels array will have to be malloc(ScreenHeight * ScreenWidth * 4 * sizeof(sfUint8)) ?

Absolutely, except that you should use std::vector, not malloc ;)

Quote
Also, I didn't realize the circles always use 40 points. Why not have SFML calculate how many are necessary?

It's impossible to know before the circle is actually drawn.
Laurent Gomila - SFML developer

mk12

  • Newbie
  • *
  • Posts: 5
    • View Profile
Updating part of the screen?
« Reply #6 on: August 03, 2010, 07:42:12 pm »
Ok I tried the one pixel per frame method, but it can only run at ~30 fps. Are you sure drawing the whole image like this is a good idea? It's fullscreen at 1920x1200, so if I did the pixel array thing, that would be 2.3mb copied to the image, then drawn to the window every frame.

BTW I can't use std::vector because I'm using Csfml.

Shoud I just use OpenGL?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Updating part of the screen?
« Reply #7 on: August 03, 2010, 07:47:00 pm »
Quote
Ok I tried the one pixel per frame method, but it can only run at ~30 fps. Are you sure drawing the whole image like this is a good idea? It's fullscreen at 1920x1200, so if I did the pixel array thing, that would be 2.3mb copied to the image, then drawn to the window every frame.

Indeed it becomes pretty heavy with this kind of size. SFML 2 has an option to update only a part of an image.

Quote
Shoud I just use OpenGL?

It would be much easier, yes.
Laurent Gomila - SFML developer

mk12

  • Newbie
  • *
  • Posts: 5
    • View Profile
Updating part of the screen?
« Reply #8 on: August 03, 2010, 10:02:15 pm »
Ok, I did it in OpenGL with GL_POINTS and it's much better. SFML makes the windowing/input/etc. very easy though :). Thanks for your help.