Pixmap and Blend modes.

BlitzMax Forums/BlitzMax Beginners Area/Pixmap and Blend modes.

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

You'd be better off getting the base pointer of the pixmap memory with PixmapPtr() and then using a pointer variable such as `writeto:Int Ptr` with casting such as If rgb<>0 writeto[0]=rgb, and handle the x and y locations incrementing by using your own counters.

If you jump into WritePixel for every pixel, it has to look up the pixmap, find the base pointer, add your x coordinate (which you have to also calculate before you can pass it), take your y coord (also needing constant calculation) and multiply it by the row bytes then add it to the total, THEN access the pixel at the memory address. Lots of work. Just keep your own pointer and increment it with each write, by 1 (since it's an int pointer, it actually adds 4 to the pointer). That should be a lot faster.

Here is a cut-and-paste of part of an alphablending routine ... the main part. You'll need to set up the variables. It might not be the fastest on the planet but I can confirm that it works.

Also to answer previous uncertaintly, yes pixmaps are entirely in main memory. When you grab a pixmap you are dumping the backbuffer to a pixmap in main memory, which goes over the graphics bus. Similarly when you draw a pixmap or convert it into an image, it goes over the bus from main memory to graphics memory.

This code just does one ROW of pixels, once set up. You'd need a for/next loop to do all rows.

				Local MRowBytesLeft:Int		'Row byte counter
				Local MSourcePointer4:Int Ptr=DataBankIntPtr+MSourceXYSkip		'For copying Int data from
				Local MDestPointer4:Int Ptr=MDest.DataBankIntPtr+MDestXYSkip		'For copying Int data to
				Local MSourceData:Int		'For storing source pixel data
				Local MDestData:Int		'For storing destination pixel data
				Local MFilterRed:Int=$FF000000		'To mask off Red data
				Local MFilterGreen:Int=$00FF0000		'To mask off Green data
				Local MFilterBlue:Int=$0000FF00		'To mask off Blue data
				Local MFilterAlpha:Int=$000000FF		'To mask off Alpha
				Local MDestRed:Int		'To compose Red
				Local MDestGreen:Int		'To compose Green
				Local MDestBlue:Int		'To compose Blue
				Local MAlpha:Int		'To get source alpha
				Local MSourceRatio:Float		'To calculate amount of source color
				Local MDestRatio:Float		'To calculate amount of dest color
				For Local MRow:Int=0 To MRows
					MRowBytesLeft=MRowBytes		'Initialize
While MRowBytesLeft>2		'Loopcounter=3 or more (at least 4 bytes/1 pixel to go)
						MSourceData=MSourcePointer4[0]		'Get source pixel data RGBA
						MDestData=MDestPointer4[0]		'Get destination pixel data RGBA
						MAlpha=MSourceData & MFilterAlpha		'Get source alpha
						MSourceRatio=(1.0/256.0)*MAlpha		'Calculate amount of source color
						MDestRatio=1.0-MSourceRatio		'Calculate amount of dest color
						MDestRed=Int((((MDestData & MFilterRed) Shr 24) *MDestRatio) + (((MSourceData & MFilterRed) Shr 24) *MSourceRatio))
						MDestGreen=Int((((MDestData & MFilterGreen) Shr 16) *MDestRatio) + (((MSourceData & MFilterGreen) Shr 16) *MSourceRatio))
						MDestBlue=Int((((MDestData & MFilterBlue) Shr 8) *MDestRatio) + (((MSourceData & MFilterBlue) Shr 8) *MSourceRatio))
						MDestPointer4[0]=(MDestData & MFilterAlpha) | (MDestRed Shl 24) | (MDestGreen Shl 16) | (MDestBlue Shl 8)		'AlphaBlend 1 pixel
						MRowBytesLeft:-4		'Just done 4 bytes/1 pixel
						MSourcePointer4:+1		'Jump past 1 pixel
						MDestPointer4:+1		'Jump past 1 pixel
					Wend
					MSourcePointer4:+MSourceRowSkip		'Next row in source
					MDestPointer4:+MDestRowSkip		'Next row in dest
     Next