Locked Graphics Demo?

BlitzPlus Forums/BlitzPlus Programming/Locked Graphics Demo?

turtle1776(Posted 2003) [#1]
I'm pretty impressed by the fast pixel writing capabilities in Mark's lock_graphics demo, but I'd like to actually do something more useful than write the color red all over the screen.

Can anybody around here whip up a short demo would show how to do the same thing, but with an existing image (like a rock or a tree or a spaceship, or whatever)?

BTW, I'm not talking about writing on an existing image, though that would be interesting, too. I'm talking about writing the image to the backbuffer using Mark's method rather than DrawImage.


Michael Reitzenstein(Posted 2003) [#2]
Using WritePixelFast and ReadPixelFast to draw an image is extremely slow in comparison to Blitting the said image, and completely useless unless you want to do some pixel color manipulation (alpha, brightness etc). What exactly did you have in mind?


Beaker(Posted 2003) [#3]
If you can track down FlameDuck on IRC, he has a nice demo that uses LockedPixels.


DJWoodgate(Posted 2003) [#4]
Some nice demos with source by obviousdisaster are here... http://www.blitzcoder.com/cgi-bin/showcase/showcase_showentry.pl?id=obviousdisaster03032003142359&comments=no


turtle1776(Posted 2003) [#5]
Thanks all,

@DJWoodgate
Interesting demos. Unfortunately, after looking at both those demos and Mark's lock_graphics demo, it seems that to actually use this new capability, you need to understand lines like this:

u=(hu Shr 8)And$1FF

Anybody have any suggestions, resources, or tutorials on this kind of thing?

@Michael Reitzenstein
I know blitting is faster, but I want to learn how these new techniques work so I can do all the special effects stuff I was doing with writePixelFast with the new, faster techniques that are offered by B+.


FlameDuck(Posted 2003) [#6]
If you can track down FlameDuck on IRC, he has a nice demo that uses LockedPixels.
The demo (if we're talking about the same one that is) is available very much as-is from my website (you'll want the file called bp-colorblend-win32.rar). There are a few things to note: a) it's totally unoptimized at this point and b) It'll only work in ARGB 32-bit. I have some code to convert between the formats but I figured the example as it is now is more academic.

u=(hu Shr 8)And$1FF

Anybody have any suggestions, resources, or tutorials on this kind of thing?
Not really. Short of suggesting a Google search for "Binary Arithmetic" and asking questions on this forum, I'm fresh out of ideas. If you're feeling particularilly adventurous you could teach yourself some assembly language. :o>


turtle1776(Posted 2003) [#7]
Hmmm. Time to tap into the generousity of one of you higher level gurus. Any chance someone could whip up a function that can poke the proper color into a designated bank/buffer?

What I have in mind is something like: writeColor(bank or buffer,rgb,x,y), which will write the specified rgb color to the specified bank at the specified x,y location. It would only write one pixel to that location, but if someone wanted more than 1 pixel per function call, they could use this function as the basic example of how to do it.

As near as I can tell, this function would need to include options for each of the possible rgb formats.


FlameDuck(Posted 2003) [#8]
As near as I can tell, this function would need to include options for each of the possible rgb formats.
If you want a general function using WritePixelFast is most likely the way to go. The "LockedPixels" is really (IMHO) more suitable for "hardcoded" solutions based on your particular game. The example mentioned above for example could probably be optimized by a factor of ten or so by using constants in place of variables, and a less flexible "wipe" code.


turtle1776(Posted 2003) [#9]
Okay, I *think* this might clarify how the faster B+ pixel drawing works.

Here is Mark's lock_graphics demo with a bit more added to show how to add the correct colors. The functions slow things down a bit, but you can easily optimize it. Comments are welcome.


[CODE]
;Note that this is B+ code.
Const FORMAT_RGB565=1 ;16 bit 565
Const FORMAT_XRGB1555=2 ;16 bit 555
Const FORMAT_RGB888=3 ;24 bit
Const FORMAT_XRGB8888=4 ;32 bit

Graphics 640,480,16,1;fullscreen!

timer=CreateTimer(60)

Repeat

Select WaitEvent()

Case $103 ;key down
If EventData()=27 End

Case $4001 ;timer tick

tm=MilliSecs()
LockBuffer
bank=LockedPixels()

For y=0 To 479
offset=y*LockedPitch()

Select LockedFormat()
Case FORMAT_RGB565
For x=0 To 319
PokeShort bank,offset+x*4,Get16Bit565RGB(255,0,255)
PokeShort bank,offset+x*4+2,Get16Bit565RGB(255,0,255)
Next
Case FORMAT_XRGB1555
For x=0 To 319
PokeShort bank,offset+x*4,Get16Bit555RGB(255,0,0)
PokeShort bank,offset+x*4+2,Get16Bit555RGB(255,0,0)
Next
Case FORMAT_RGB888
For x=0 To 639
PokeInt bank,offset+x*4,GetRGB(255,0,0)
Next
Case FORMAT_XRGB8888
For x=0 To 639
PokeInt bank,offset+x*4,GetRGB(255,0,0)
Next
End Select
Next

UnlockBuffer
tm=MilliSecs()-tm

Text 0,0,tm
Text 100,0,LockedFormat()
Flip

End Select

Forever
End


Function GetRGB(r,g,b)
;24/32 Bit Conversion - ignore first 8 bits, which are reserved for alpha info
;r 00000000111111110000000000000000 = 00FF0000
;g 00000000000000001111111100000000 = 0000FF00
;b 00000000000000000000000011111111 = 000000FF
;Note: 32 bits = 4 bytes = 2 shorts = 1 int

Return b Or (g Shl 8) Or (r Shl 16)
End Function

Function Get16Bit555RGB(r,g,b)
;16 bit 555 Conversion - 1st bit is empty
;r 0111110000000000 = 7C00 = 7*16^3 + 12*16^2 = 31744
;g 0000001111100000 = 03E0
;b 0000000000011111 = 001F = 31
;Note: 16 bits = 2 bytes = 1 short
Return (r/8 Shl 10) Or (g/8 Shl 5) Or (b Shr 3)
End Function
Function Get16Bit565RGB(r,g,b)
;16 bit 565 conversion - middle green value gets 6 bits
;r 1111100000000000 = F800 = 63488
;g 0000011111100000 = 07E0
;b 0000000000011111 = 001F = 31
;Note: 16 bits = 2 bytes = 1 short
Return (r/8 Shl 11) Or (g/4 Shl 5) Or (b Shr 3)
End Function
[/CODE]


Snarty(Posted 2003) [#10]
http://www.blitzbasic.com/codearcs/codearcs.php?code=585

dunno if you missed that in the code-arc's


turtle1776(Posted 2003) [#11]
Very cool, Snarty. I wish I had seen that earlier. Would have saved me a few hours. Oh well, at least I got the conversions right!


Griz(Posted 2003) [#12]
How about doing the opposite and reading pixels from the locked buffer and seperating their red, green and blue components? That would provide both reading and writing capabilities.


Snarty(Posted 2003) [#13]
Griz:

Here's an example of converting RGB Int's or Shorts to Red, Green and Blue Components.
; RGB to Red, Greed, Blue
; By Paul Snart (Snarty)

LockBuffer
LBank=LockedPixels()
LPitch=LockedPitch()
LFormat=LockedFormat()

Select LFormat

	Case 1
		For y=0 To Height-1
			YPos=y*LPitch
			For x=0 To Width-1
				RGB=PeekShort(LBank,YPos+(x*2))
				Red=((RGB And $F800) Shr 11) Shl 3
				Green=((RGB And $7E0) Shr 5) Shl 2
				Blue=(RGB And $1F) Shl 3
			Next
		Next

	Case 2 ; 1555
		For y=0 To Height-1
			YPos=y*LPitch
			For x=0 To Width-1
				RGB=PeekShort(LBank,YPos+(x*2))
				Red=((RGB And $7C00) Shr 10) Shl 3
				Green=((RGB And $3E0) Shr 5) Shl 3
				Blue=(RGB And $1F) Shl 3					
			Next
		Next		
			
	Case 3,4
		For y=0 To Height-1
			YPos=Y*LPitch
			For x=0 To Width-1
				RGB=PeekInt(LBank,YPos+(x*LFormat))
				Red=(RGB And $FF0000) Shr 16
				Green=(RGB And $FF00) Shr 8
				Blue=RGB And $FF
			Next
		Next

End Select
UnlockBuffer

The Above code will need adjustment to suit your needs, but the conversions are correct.