Welcome! Log In Create A New Profile Wiibrew Wiki HackMii Blog

Advanced

How do I read pixels from an External Framebuffer as RGB values?

Posted by TheCodingBrony 
How do I read pixels from an External Framebuffer as RGB values?
September 13, 2015 04:42AM
I wanted to improve upon the gdl::SaveScreen() function of my MTek-GDL library where I wanted it to read pixels from an external framebuffer instead of the embedded framebuffer of the GX as it is much faster to read pixels from main RAM instead of peeking pixels from the GX and it allows me to take screenshots in anti-aliased mode as well.

However, I've read that the pixel format of the external framebuffer is YUV2 which is a pixel format that I'm not exactly familiar with and I couldn't find a single piece of code as to how to read and convert a pixel from it as an RGB8 color value.

Also, is it advisable to just have one XFB and have the GX copy pixels from its EFB into it right after a VSync? To me, I think it'll work well since the GX can copy pixels from its EFB to the XFB fast enough that there's no flicker or screen tearing issues I've seen based on a prototype I made that demonstrates a single XFB and it saves a few hundred kilobytes worth of 1T-SRAM when having only one XFB.

Any useful help will be greatly appreciated...
Re: How do I read pixels from an External Framebuffer as RGB values?
September 13, 2015 05:34AM
Google "convert YUY2 to RGB", plenty of algorithms for that around.

Restricting yourself to one XFB means you can't start drawing the next frame until the previous one has been copied out, so you're potentially wasting useful CPU cycles while waiting for vsync. For simple scenes this won't matter but if you have large scenes that occasionally take longer than the frame period to draw, you will drop frames.
Re: How do I read pixels from an External Framebuffer as RGB values?
September 14, 2015 02:48PM
Re: How do I read pixels from an External Framebuffer as RGB values?
September 14, 2015 10:28PM
You don't have to use GX_DrawDone(), you can use GX_SetDrawDoneCallback() and GX_SetDrawDone() to avoid blocking.
Regardless in the code you posted much more time will be spent blocking in VIDEO_WaitVSync() than GX_DrawDone(), and if you hit a frame where drawing takes longer than the frame period your framerate will drop. If you were using two XFBs you would have a one frame buffer to guard against that happening.
Sorry, only registered users may post in this forum.

Click here to login