SFML community forums
Help => Graphics => Topic started by: sisms92 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:
-
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)).
-
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).
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.
-
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 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.
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.
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 :)
-
If you only update your image once per frame, I can definitely tell you that Image::LoadFromPixels is fast enough ;)
-
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.
-
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
-
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)
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.
-
why is SetPixel that slow?
-
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.
-
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 :?
-
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!