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

Author Topic: Working with LoadFromPixels  (Read 4551 times)

0 Members and 2 Guests are viewing this topic.

REM

  • Newbie
  • *
  • Posts: 6
    • View Profile
Working with LoadFromPixels
« 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!

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Working with LoadFromPixels
« Reply #1 on: April 14, 2010, 10:15:07 pm »
Quote
Uint8 * pixel = &screen[ ( y1 * 640 ) + x1 ];

The * 4 is missing here. The rest should be ok ;)
Laurent Gomila - SFML developer

REM

  • Newbie
  • *
  • Posts: 6
    • View Profile
Working with LoadFromPixels
« Reply #2 on: April 14, 2010, 10:31:52 pm »
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!

Ashenwraith

  • Sr. Member
  • ****
  • Posts: 270
    • View Profile
Working with LoadFromPixels
« Reply #3 on: April 14, 2010, 11:16:25 pm »
Hi, I'm curious, are you blitting your entire screen as a 640x480 image?

REM

  • Newbie
  • *
  • Posts: 6
    • View Profile
Working with LoadFromPixels
« Reply #4 on: April 14, 2010, 11:17:15 pm »
Yes.

Breakman79

  • Jr. Member
  • **
  • Posts: 58
    • View Profile
Working with LoadFromPixels
« Reply #5 on: April 14, 2010, 11:33:38 pm »
You're not doing that for every frame, right?  This library isn't designed around bit blitting images.  It's incredibly slow.

REM

  • Newbie
  • *
  • Posts: 6
    • View Profile
Working with LoadFromPixels
« Reply #6 on: April 14, 2010, 11:38:15 pm »
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:


Ashenwraith

  • Sr. Member
  • ****
  • Posts: 270
    • View Profile
Working with LoadFromPixels
« Reply #7 on: April 14, 2010, 11:52:17 pm »
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.

REM

  • Newbie
  • *
  • Posts: 6
    • View Profile
Working with LoadFromPixels
« Reply #8 on: April 15, 2010, 12:30:03 am »
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?

Ashenwraith

  • Sr. Member
  • ****
  • Posts: 270
    • View Profile
Working with LoadFromPixels
« Reply #9 on: April 15, 2010, 12:43:59 am »
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.

REM

  • Newbie
  • *
  • Posts: 6
    • View Profile
Working with LoadFromPixels
« Reply #10 on: April 15, 2010, 01:37:21 am »
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.

Ashenwraith

  • Sr. Member
  • ****
  • Posts: 270
    • View Profile
Working with LoadFromPixels
« Reply #11 on: April 15, 2010, 02:31:29 am »
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.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Working with LoadFromPixels
« Reply #12 on: April 15, 2010, 08:29:30 am »
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 ;)
Laurent Gomila - SFML developer