Rendering an image without backbuffer

BlitzMax Forums/BlitzMax Beginners Area/Rendering an image without backbuffer

pc_tek(Posted 2011) [#1]
This has probably been asked...and answered before, but I am unable to find anything.

How do you go about pre-drawing an image then pasting the whole thing to the backbuffer?

In B3d, this was very easy to do using CreatImage then setting the imagebuffer...etc. Is there an equivalent in MAX?


therevills(Posted 2011) [#2]
Piximaps?


skidracer(Posted 2011) [#3]
Check the example code for GrabImage.


ima747(Posted 2011) [#4]
There is no render target built into max. You have 3 options (to my memory)
1) Draw what you want but don't flip it to the screen. Then use GrabImage or GrabPixmap to copy it so you can draw it as a single image in future.
2) If possible draw into a pixmap. This is sometimes faster, and sometimes slower than the backbuffer, depends on the hardware, graphics driver, processor, ram, etc. You also have to do draws manually, so you can't use fun stuff like rotation without rolling your own pixmap variant. This keeps everything off the graphics hardware, which sometimes is important (i.e. if you want to composite images on systems with garbage graphics cards like servers... but then there are other mods that are generally better...)
3) Check the forums for things related to render targets or the like. It is possible to create render targets like B3D does, but it's not built in. You have to find a way that works with the graphics driver you're using since it's not universal and you'll need to do atleast a few lower level calls... If you're going this route and you're planning to go cross platform you pretty much have to use the OpenGL driver since, well, DX is only on windows...

Plenty of options, they all have pros and cons. If speed isn't the main concern then GrabImage/GrabPixmap is by far the easiest way to go, but if you're trying to do something in realtime then it's probably not going to cut it (though it depends of course on what you're doing).


pc_tek(Posted 2011) [#5]
I have read somewhere that pixmaps are slooooow.

What I want is an area bigger than the screen resolution to draw to, then paste the image to the screens backbuffer before flipping.


xlsior(Posted 2011) [#6]
I have read somewhere that pixmaps are slooooow.


Pixmaps are stored in main memory instead of video memory, so any time you want to draw one it first has to transfer it into video memory, which is significantly slower than drawing an image which already exists in video memory.

On a fast computer the overhead isn't that bad, but on a low-end computer it can be prohibitive.


ima747(Posted 2011) [#7]
How frequently do you want to update it, and how big do you need it if it's bigger than the screen (what's the extra space for?). Might it be possible to draw to multiple screen sized blocks? Are you 100% sure you need to render to another image? Drawing (if done properly) can often be so fast (compared to moving large images in and out of vram) that you might be better off just drawing each image that would make up your master image with scaling (and possibly room for other optimizations...). There may be alternatives that are better based on what your ultimate goal might be.

I use Brucy's FreeImage module to do screen independent compositing, but again, it's not intended for real time processing, and it's an extra module so that may be beyond scope for what you want...


ima747(Posted 2011) [#8]
a little run down to expand on xlsior's statement, and my own regarding slowness etc.

When you first load or create an image it exists in main memory. To draw it you have to move it to the graphics card by uploading it into VRAM where the graphics system can actually get at it. This upload process takes FOREVER (relative to actually drawing the image). Grabbing a buffer out of the graphics card and back into main memory is even slower (modern graphics cards HATE sharing back with the system). This means every time you want to draw a picture the graphics card hasn't seen before (or has removed on it's own because you haven't used it in a while) you have to upload it again which takes a long time again. So the reason pixmaps are slow to work with is
a) they exist in main memory, meaning to draw them you have to upload them
b) existing in main memory also means that they're not offloaded to the graphics card for things like scaling, etc.

The advantage is since they exist in main memory you can manipulate them. With a graphics card you can push (slowly), order it to draw something it has (VERY VERY VERY fast) or pull (VERY slow). With a pixmap, it's just 1s and 0s and you can do anything you want to it.

Render targets are essentially extra buffers on the graphics card you can render to. Since they exist on the graphics card they're very fast to draw to (just as fast as the back buffer because they're basically the same thing) and also very fast to draw (no pushing or pulling to/from vram, it's already there). The down side is they're driver dependent and there's no abstraction layer build into BlitzMax. So you have to roll your own implementation (again, poke around the forum for code).

Regarding using FreeImage: It is designed for image file manipulation and creation, as such it doesn't touch the graphics card. It's quite fast for what it does, but it's all on the processor side. As a result when you have made the image you want to draw, in order to draw it you need to first convert it from a freeimage data set to a pixmap, and then you can push that to the graphics card for drawing.

The difference between image and pixmap: A pixmap is a map of pixels, that's it. It's just a block of data. To draw it you have to push it to the graphics card (as I've said many times). An Image in BlitzMax is a container for a pixmap that has already been pushed to the graphics card (or will automatically be pushed if it's not there already). As such, if you convert a pixmap to an image you can draw it faster (but you can't change it without locking it which basically wipes the pixmap from the graphics card and ques it for re-upload when you unlock it and ask it to draw again).

If you have to draw something more than once you probably want to convert it from a pixmap to an Image. If you want to change it CONSTANTLY it might make sense to keep it a pixmap (but pixmaps also loose out on a lot of fun drawing tools like rotation and scaling...). In either case if you're regularly making changes to a picture which is going to be shown you're going to have to upload it after each change (slow!) OR you're going to have to make and manage it on the graphics hardware directly (render target to it's own buffer). This is the down side to modern graphics cards vs. old direct access systems.