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

Author Topic: Fast Pixel Drawing  (Read 6555 times)

0 Members and 1 Guest are viewing this topic.

sisms92

  • Newbie
  • *
  • Posts: 3
    • View Profile
Fast Pixel Drawing
« on: February 18, 2010, 01:46:56 am »
Hi, I'm trying to set the colour of specific pixels in an sf::RenderWindow. Unfortunately the only way I've found so far is by setting the colour of pixels on an image and then drawing that. This is quite slow, and so I'm looking for alternatives.

Is there any way to do this in SFML2? If not, what would be the equivalent OpenGL code, and how hard would it be to mix SFML2 and OpenGL?

I appreciate any input  :wink:

OniLinkPlus

  • Hero Member
  • *****
  • Posts: 500
    • View Profile
Re: Fast Pixel Drawing
« Reply #1 on: February 18, 2010, 04:11:10 am »
Quote from: "sisms92"
Hi, I'm trying to set the colour of specific pixels in an sf::RenderWindow. Unfortunately the only way I've found so far is by setting the colour of pixels on an image and then drawing that. This is quite slow, and so I'm looking for alternatives.

Is there any way to do this in SFML2? If not, what would be the equivalent OpenGL code, and how hard would it be to mix SFML2 and OpenGL?

I appreciate any input  :wink:
I use rendering the pixels to an sf::Image and then drawing that through OpenGL. It works REALLY fast, and even old Laptops using the Intel Celeron can generate Mandelbrots pretty quickly using sf::Image with this technique. As in, under 10 seconds. The OpenGL code just involves calling sf::Image's Bind function, then drawing a quad at coordinates (-1.0,-1.0), (-1.0,1.0), (1.0,1.0), (1.0,-1.0), in that order, with proper TexCoords(0 to 1, invert the Y axis(1 for top, 0 for bottom)).
I use the latest build of SFML2

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Fast Pixel Drawing
« Reply #2 on: February 18, 2010, 07:55:23 am »
Quote
Hi, I'm trying to set the colour of specific pixels in an sf::RenderWindow. Unfortunately the only way I've found so far is by setting the colour of pixels on an image and then drawing that. This is quite slow, and so I'm looking for alternatives.

Can you show your code?
Using SetPixel is quite slow, the best solution is to work on your own array of pixels and then update the image with LoadFromPixels (which is optimized for this kind of situations).

Quote
I use rendering the pixels to an sf::Image and then drawing that through OpenGL. It works REALLY fast, and even old Laptops using the Intel Celeron can generate Mandelbrots pretty quickly using sf::Image with this technique. As in, under 10 seconds. The OpenGL code just involves calling sf::Image's Bind function, then drawing a quad at coordinates (-1.0,-1.0), (-1.0,1.0), (1.0,1.0), (1.0,-1.0), in that order, with proper TexCoords(0 to 1, invert the Y axis(1 for top, 0 for bottom)).

Well, for drawing a quad why don't you use sf::Sprite? This part is not what slows performances down anyway.
Laurent Gomila - SFML developer

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Fast Pixel Drawing
« Reply #3 on: February 18, 2010, 03:00:03 pm »
You could also use GL_POINTS directly in OpenGL. However, this requires to set up the view and the matrices corresponding to SFML, so that you can use the same coordinate system.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

sisms92

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Fast Pixel Drawing
« Reply #4 on: February 18, 2010, 03:50:36 pm »
Quote from: "OniLink10"
I use rendering the pixels to an sf::Image and then drawing that through OpenGL. It works REALLY fast, and even old Laptops using the Intel Celeron can generate Mandelbrots pretty quickly using sf::Image with this technique. As in, under 10 seconds. The OpenGL code just involves calling sf::Image's Bind function, then drawing a quad at coordinates (-1.0,-1.0), (-1.0,1.0), (1.0,1.0), (1.0,-1.0), in that order, with proper TexCoords(0 to 1, invert the Y axis(1 for top, 0 for bottom)).


Funnily enough that's what I want to render quicky, a mandlebrot set.

Quote from: "Laurent"

Can you show your code?
Using SetPixel is quite slow, the best solution is to work on your own array of pixels and then update the image with LoadFromPixels (which is optimized for this kind of situations).


I can't access my source code right now, but I'll definitely try the LoadFromPixels method when I can.

Quote from: "Nexus"
You could also use GL_POINTS directly in OpenGL. However, this requires to set up the view and the matrices corresponding to SFML, so that you can use the same coordinate system.


I tried using GL_POINTS a few months back, I completely forgot about it  :) If I remember right, I had a problem with pixels only rendering in the centre of the screen, and that they would only render if the vector I passed had co-ordinates 0, 0. The view and matrices set up might explain that..

Thanks for the input, I'll look using LoadFromPixels and then OpenGL and sum up which is the better way for me to go. I'll let you know how it goes :)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Fast Pixel Drawing
« Reply #5 on: February 18, 2010, 03:53:33 pm »
If you only update your image once per frame, I can definitely tell you that Image::LoadFromPixels is fast enough ;)
Laurent Gomila - SFML developer

OniLinkPlus

  • Hero Member
  • *****
  • Posts: 500
    • View Profile
Fast Pixel Drawing
« Reply #6 on: February 19, 2010, 01:39:22 am »
Quote from: "Laurent"


Quote
I use rendering the pixels to an sf::Image and then drawing that through OpenGL. It works REALLY fast, and even old Laptops using the Intel Celeron can generate Mandelbrots pretty quickly using sf::Image with this technique. As in, under 10 seconds. The OpenGL code just involves calling sf::Image's Bind function, then drawing a quad at coordinates (-1.0,-1.0), (-1.0,1.0), (1.0,1.0), (1.0,-1.0), in that order, with proper TexCoords(0 to 1, invert the Y axis(1 for top, 0 for bottom)).

Well, for drawing a quad why don't you use sf::Sprite? This part is not what slows performances down anyway.
Because of the problem I specified in the Graphics forum. Rendering with sf::Sprite still doesn't work with Win7, not even the RTM. :\ It's just all blank. OpenGL rendering is just fine, though.
I use the latest build of SFML2

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Fast Pixel Drawing
« Reply #7 on: February 19, 2010, 09:26:18 am »
Quote
Because of the problem I specified in the Graphics forum. Rendering with sf::Sprite still doesn't work with Win7, not even the RTM. :\ It's just all blank. OpenGL rendering is just fine, though.

Which problem is it?
If found this one, but it seems to be solved:
http://www.sfml-dev.org/forum/viewtopic.php?t=2110
Laurent Gomila - SFML developer

sisms92

  • Newbie
  • *
  • Posts: 3
    • View Profile
Fast Pixel Drawing
« Reply #8 on: February 19, 2010, 01:37:01 pm »
Thanks for all the help, LoadFromPixels is much faster than SetPixel as you said. As for the OpenGL method, I failed at that. Again, the pixel(s) would all render at the same position, dead centre of the screen, and only when I passed glVertex2i 0, 0. Something to look at in the future I guess. For now I'm just happy this works.

Next up, making my mandelbrot as fast as I can and then implementing zooming 8)

Quote from: "OniLink10"
Because of the problem I specified in the Graphics forum. Rendering with sf::Sprite still doesn't work with Win7, not even the RTM. :\ It's just all blank. OpenGL rendering is just fine, though.


Windows 7 seems to render sprites fine for me, by the way. I'm running the 64 Bit Professional edition if it makes a difference.

gsaurus

  • Sr. Member
  • ****
  • Posts: 262
    • View Profile
    • Evolution Engine
Fast Pixel Drawing
« Reply #9 on: February 19, 2010, 02:17:35 pm »
why is SetPixel that slow?
Pluma - Plug-in Management Framework

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Fast Pixel Drawing
« Reply #10 on: February 19, 2010, 02:31:19 pm »
Because it checks if the (x, y) parameters are valid, because you have the overhead of calling the function millions of times, because it manipulates the pixel as a sf::Color (which has its own assignment operator etc.) instead of sf::Uint8s directly, etc.

But it shouldn't be that slow (in Release mode of course), the critical operation of updating the texture in video memory is not performed everytime SetPixel is called, there is a lazy evaluation optimization.

Which means that it can get even slower if you call some other of the image's functions (such as Bind) between calls to SetPixel.
Laurent Gomila - SFML developer

gsaurus

  • Sr. Member
  • ****
  • Posts: 262
    • View Profile
    • Evolution Engine
Fast Pixel Drawing
« Reply #11 on: February 19, 2010, 02:55:31 pm »
Ah, off course  :P
I have figured out the second one, only Bind() updates texture, so SetPixel really just validate coordinates and assign the new colour directly on the array. But I ignored the small overheads of validating coordinates, sf::Color assign and function calls :?
Pluma - Plug-in Management Framework

OniLinkPlus

  • Hero Member
  • *****
  • Posts: 500
    • View Profile
Fast Pixel Drawing
« Reply #12 on: February 20, 2010, 01:34:13 am »
Quote from: "Laurent"
Quote
Because of the problem I specified in the Graphics forum. Rendering with sf::Sprite still doesn't work with Win7, not even the RTM. :\ It's just all blank. OpenGL rendering is just fine, though.

Which problem is it?
If found this one, but it seems to be solved:
http://www.sfml-dev.org/forum/viewtopic.php?t=2110
Oops, forgot to update it. Silly me!
I use the latest build of SFML2