FILTEREDIMAGE/MIMAPPEDIMAGE exchange?

BlitzMax Forums/BlitzMax Beginners Area/FILTEREDIMAGE/MIMAPPEDIMAGE exchange?

Suco-X(Posted 2005) [#1]
Hi
Im a bit confused. To get an mipmapped Image in BlitzMax 1.10 i must use MIPMAPPEDIMAGE as Flag!?

Thats my Code:

Strict 


Graphics 1024,768,32



AutoMidHandle True
Local mipmap_img:TImage = CreateImage(256,256,1,MIPMAPPEDIMAGE|MASKEDIMAGE)
Local filter_img:Timage = CreateImage(256,256,1,FILTEREDIMAGE|MASKEDIMAGE)



For Local x:Int = 0 Until 256
	For Local y:Int = 0 Until 256
		SetColor Rand(0,255),Rand(0,255),Rand(0,255)
		Plot x,y
	Next 
Next 


SetScale 2.0,2.0

SetColor 128,0,0
DrawText "MIPMAPPED IMAGE",10,10

GrabImage(mipmap_img,0,0)

Cls

For Local x:Int = 0 Until 256
	For Local y:Int = 0 Until 256
		SetColor Rand(0,255),Rand(0,255),Rand(0,255)
		Plot x,y
	Next 
Next 


SetColor 128,0,0
DrawText "FILTERED IMAGE",10,10


GrabImage(filter_img,0,0)




Local Angle:Float = 0.0


Repeat
Cls


Angle:+1.0

SetScale 1.0,1.0
SetRotation Angle
SetColor 255,255,255
DrawImage mipmap_img,200,300
DrawImage filter_img,600,300


Flip
FlushMem()
Until KeyHit(KEY_ESCAPE)


The Mipmapped Image is filtered an the filtered Image is Mipmapped!?
Have i misunderstanded the Flags?
Thanks for Help
Mfg Suco


ImaginaryHuman(Posted 2005) [#2]
Filtering and mipmapping are two separate things and you may want your flags to be FILTEREDIMAGE|MIPMAPPEDIMAGE|MASKEDIMAGE.

Filtering and mipmapping are two separate things.

Filtering is otherwise known as antialiasing, or sub-pixel sampling, or re-sampling. With filtering switched on you are basically asking for your image to be `smoothed` and rendered with calculated pixel colors so that it `looks as though` the pixels from the source image are at specific fractional screen pixel locations.

So if you positioned your image at a floating point coordinate rather than an integer coordinate, the hardware will take the portion of the coordinate after the decimal place and use that to `weight` how much of the nearest left pixel it uses, and how much of the nearest right pixel (ie rounded up and down to nearest integers). It then combines those two colors in such a way that the final color, and the image overall, looks like it is positioned at a floating-point location. It is really an approximation but it looks very smooth especially when the image is moving in some way, rotating, scaling etc.

Filtering is just a way to remove the `aliasing` jagged-edges effect that you would get if you tried to scale or rotate the image using an `integer` based drawing system. It also `interpolates` ie smoothly transitions what the in-between pixels would need to be if you have scaled an image up to the point where it would normally look blocky.

Filtering, as in FILTEREDIMAGE, basically means that your source image is stored with integer accuracy - one whole pixel per color, but when drawn it is approximated to fit into a floating point screen display where it can be positioned at floating point coordinate, rotated by very small subtle amounts and zoomed in and out smoothly.

This has nothing to do with mipmapping. FILTEREDIMAGE also usually takes more GPU processing time and is usually slower than having it switched off. FILTERED IMAGE also only really filters (smooths) the interior of the image shape, it doesn't antialiase the edges to make them blend with the background (at least I think that's the case, right?).

Mip mapping, as in MIPMAPPEDIMAGE, is a technique whereby rendering of a scene that has some 3D depth is sped-up and made more efficient. This is based on the fact that when objects get further away from you, you can see less of their details. If you had a 256x256 image positioned on screen in the normal central Z coordinate, you would see all 256 pixels accross and down. If you pushed the image back away from the camera/screen, you might only see, for example, 50 of the pixels. Of course, enabling smoothing with FILTEREDIMAGE takes care of some of that problem to blend in some of the difference between whichever pixels it chooses to draw. But it doesn't produce a very great result because it skips some pixels and detail is lost. Also as the image moves around the hardware may need to select wildly different pixels to take the color from which can produce an annoying shimmering and loss of detail.

With mipmaps, what you're doing is you have your normal-sized version of the image, then you progressively have smaller and smaller versions of the image as additional textures. These are usually scaled by half in x and y each time. So the original might be 256x256, then 128x128, 64x64, 32x32, 16x16, 8x8, 4x4, 2x2 and 1x1. In OpenGL these `mip map levels` go all the way down to 1x1 from whatever size you started at. So you end up with a set of images. Each one is scaled down and drawn using, preferably, a good smoothing image processing technique.

BlitzMax scales the images down for you with some smoothing enabled. It then stores these scaled images as a whole set of images - mip map levels - a long with the original image. It takes up more video ram of course, especially since textures have to be at least 64x64 usually, internally.

What then happens is that if you then try to draw your image at a Z coordinate some distance away from the normal central position, like so it is 50x50 in size instead of 256x256, the hardware will look at which of the mip map level images is the closest in size. It does this separately for the case where the drawing size is larger than the nearest texture size, and where it is smaller - to decide which texture it reads the pixels from. It then reads the pixel color from that particular `nearest` texture when trying to figure out what color the pixel should be. I'm not sure but I think it might actually read the pixel color from the bigger-sized mipmap image AND the smaller-sized image and produce a combination of the two. This way, because the mipmapped texture is pre-shrunk and pre-smoothed, it gets a better `quality` zoomed pixel color to use, and regardless of whether FILTEREDIMAGE is on or not, the pixels that it ends up choosing to draw generally blend together better to give a smoother and nicer result.

There is also an efficiency benefit. Because pixels are stored sequentially in memory, if the hardware is able to grab pixels from a smaller `area` of memory in total, and doesn't have to skip a lot of pixels or jump around too much, the pixel data remains in the `cache` better (if it has caches) and this makes for faster reads from memory. Drawing a small version of an image, which triggers off the use of a pre-shrunk mipmapped image version, may be more efficient to read from memory than trying to just reference the big 256x256 original image.

Generally for your 2D purposes and especially in Max2D as it stands right now, you usually don't do a whole lot that would require you to need mipmapping to be enabled (if you don't specify MIPMAPPEDIMAGE it just doesn't generate the mip-map level images nor use the technique). The only case I can think of is if you were going to zoom a regular 2D image to make it smaller, perhaps if it were zooming in or out of the screen. In that case it might make use of mipmapping for better results and less `aliasing` jaggyness or `shimmering` effects. Otherwise mipmapping doesn't apply so that's probably why they now decided to turn it off by default. It would apply more to being used in a 3D scene where many many objects are positioned in the distance and need to be drawn with shrunken textures.

You could think if mipmaps as being a bit like fractals. Each larger-sized representation of the image contains higher-resolution detail. There's no need for the detail when the image is some distance away and can't be seen, so best to use a quality pre-scaled image. Then when it is up close you can tap into more detail.

What mipmapping does is really try to represent lots of scaled-down pixels within a single pixel, and instead of having to look at ALL of the source pixels to try and calculate a color to draw them as, it can just read a single pixel from the mipmapped image which was pre-shrunk and pre-calculated/filtered.

One thing to note is that it would be better if you could generate your own mipmap images in some image processing software using a high quality image-size-reduction algorithm, for example bicubic b-spline or something fancy. Then upload these as OpenGL textures for use as mipmap levels. However you'd have to then set up and manage the mipmapping yourself, something which Max2D makes easier for you.

There are different versions of mipmapping. At the most basic you have linear mipmapping where it just reads one pixel from the larger mipmap and one from the smaller mipmap and combines them to draw it. Then you have bilinear where it reads 4 pixels, and trilinear where it reads 8. I'm not sure how this is set up with graphics cards, I guess it's hardware dependent.

I hope this helps explain it.

So use FILTEREDIMAGE if you want the image to be drawn smoothly and to a sub-pixel precision, and use MIPMAPPEDIMAGE if you are drawing your image a scaled down size for whatever reason. Filtering can only do so much to pick appropriate colors to use and mipmapping gives a better quality result.


ImaginaryHuman(Posted 2005) [#3]
Read this for another explaination of mipmapping, it's a bit more concice and probably more accurate:

http://www.cs.unc.edu/~mueller/GP/mipmap.txt

I tried to find a good picture that would show the difference between mipmapping and filtering but no luck.