SFML community forums
Help => Graphics => Topic started by: REM on April 14, 2010, 10:00:48 pm
-
Hello, I've been switching a project I am working on from SDL to SFML in order to take advantage of the better performance.
I'd like to use LoadFromPixels in order to draw my image buffer as quickly as possible but Im having a bit of trouble porting the logic from the SDL handles pixels over to SFML.
I am creating my image buffer as follows:
Uint8 * screen = new sf::Uint8[(640*480) * 4];
Am I correct in understanding that I need 4 Uint8 values per pixel (RGBA)? I would then think I need my resolutions worth of pixel of that size...?
To get the location of a pixel in my buffer I am then doing:
Uint8 * pixel = &screen[ ( y1 * 640 ) + x1 ];
In order to set the components I would think I need to do something like:
*pixel = 255; // r
*(pixel+1) = 255; //g
*(pixel+2) = 255; //b
*(pixel+3) = 255; //a
Can anyone point out what might be my error here?
I am currently drawing an image to the buffer but its not working quite right in terms of getting each channel displaying.
Im guessing Im just off somewhere with my pointer arithmetic.
Any examples on this would be very appreciated!
-
Uint8 * pixel = &screen[ ( y1 * 640 ) + x1 ];
The * 4 is missing here. The rest should be ok ;)
-
Adding the * 4 gets me to the right position in the image (at least I think) but when I set the values *pixel = .... I am still having issues.
I am feeding in an int value there, i.e. int r = 245; etc
Is it possible I need to cast that to a Uint8 before assignment?
EDIT:
So there problem was elsewhere (where I was trying to be smart)
When I am drawing a span of pixels I do the initial position calculation once and then do positionPointer++ to save a few muls along the way.
But now I need +=4 since I am stepping RGBA 'blocks'
Works now thanks!
-
Hi, I'm curious, are you blitting your entire screen as a 640x480 image?
-
Yes.
-
You're not doing that for every frame, right? This library isn't designed around bit blitting images. It's incredibly slow.
-
I am actually doing this every frame. I've written a software 3D renderer and I am using SFML to display the buffer that I render to the screen.
Clearly, this process is going to be quite slow. That being said, if I render a scene that has nothing in it and check the clock.ElapsedTime() its only a millisecond or two. Im not thrilled about losing time for this blit but Im not aware of any other option(s).
Using the LoadFromPixels seems to be pretty quick.
Another alternative Ive considered is to use GLUT to create a window and then make my buffer an FBO or similar just to draw it onto the screen.
If anyone is aware of a faster method of doing this I would be more than thrilled to hear it! (I am really hoping there is a better way)
Here is an example of a 3D scene I render (into my buffer) and then blit with SFML:
(http://i.imgur.com/M3jo2.png)
-
I'd have to see a demo before I can really comment.
Off the top of my head you can prerender a lot of that as sprites and use a speedy raycaster. Pngs and blendmodes can do lighting effects, or even faster--you can bake most of it straight in with prepainting your images.
True 3D rendering should be reserved for anything that is not a box or primitive that can be faked--which is just about everything--especially with shaders.
-
Perhaps if I give a bit more context it will help.
This level is actually loaded from a Quake 3 BSP file, so I'm already using precomputed light maps.
Obviously if I start using various hacks it might run faster but the point of this hobby project is to implement real 3D rendering with perspective correction, depth buffer etc
What I'm curious about is whether once I've created my image buffer, what's the fastest way to blit it to screen?
-
What's your blitting algorithm?
When you are in 3D the entire screen is usually changing every frame.
It seems like the renderer is the bottleneck, not the blitting.
-
All Im doing right now is taking my SFML Image and calling LoadFromPixels on my image buffer. Then Im setting the sprite's source to that image. Then Im drawing it into my RenderWindow instance and calling display.
As you point out, Im definitely spending the the vast amount of time on the actually 3D. Theres things I can do (not related to SFML) to improve that and Im looking into those.
However, I'd also want to make sure that Im not wasting time doing something obviously wrong when getting my image up onto the screen.
-
Well, as for wasting your time--quake 3 is a free and fast engine, I don't know what rendering it in 2D is for...
Drawing the image isn't the problem, it's rendering fast enough to build up a stack. SMFL was built for managing many images like sprites, but if you are not going to take advantage of it you are basically using it like a video player.
You seem pretty adamant on using SFML this way so the only other advice I have is to write a shader to do the rendering.
-
LoadFromPixels is optimized for this particular usage, so it ends up being almost the fastest solution.
I think the best one is using the OpenGL's Pixel Buffer Objects, which are designed to optimize the CPU <--> GPU pixel transfers.
But you can probably stick to LoadFromPixels and don't bother with that ;)