Decal on texture

Blitz3D Forums/Blitz3D Programming/Decal on texture

abacadabad(Posted 2003) [#1]
Hi,
Is there a way to use the WritePixel command to paint a preset texture onto another texture, like a stamp?


EOF(Posted 2003) [#2]
Try this code. You just need to call:
ApplyDecal source_texture , dest_texture [,r,g,b]
Both 'texture' parameters should point to a loaded texture.
The source texture is the DECAL and the destination texture is where the decal is applied.
The optional rgb flags are used for masking the decal.
In the example below the decals background is masked out using 255,0,255

The two test images I used:






; Applying a DECAL to a texture
; Syntax Error

Graphics3D 640,480
SetBuffer BackBuffer()
cam=CreateCamera() : light=CreateLight()
cube=CreateCube() : MoveEntity cube,0,0,4
cubetex=LoadTexture("wood.jpg")
EntityTexture cube,cubetex

decal=LoadTexture("decal.png")

Repeat
	TurnEntity cube,0.5,0.6,0.7
	If KeyHit(57) ApplyDecal decal,cubetex ,255,0,255
	RenderWorld
	Text 10,10,"Press [SPACE] to apply the decal ..."
	Flip
Until KeyHit(1)
End


; Apply source texture to destination texture (with optional masking)
Function ApplyDecal(sourceb,destb,maskR=0,maskG=0,maskB=0)
	Local gb=GraphicsBuffer() , rgb
	Local sb=TextureBuffer(sourceb) , db=TextureBuffer(destb)
	Local maxw=TextureWidth(sourceb) , maxh=TextureHeight(sourceb)
	If TextureWidth(destb)<maxw Then maxw=TextureWidth(destb)
	If TextureHeight(destb)<maxh Then maxh=TextureHeight(destb)
	LockBuffer sb : LockBuffer db
	For x=0 To maxw-1
		For y=0 To maxh-1
			rgb=ReadPixelFast(x,y,sb) And $00FFFFFF
			If Not rgb=((maskR Shl 16)+(maskG Shl 8)+maskB)
				WritePixelFast x,y,(rgb Or $FF000000),db
			EndIf
		Next
	Next
	UnlockBuffer sb : UnlockBuffer db
	SetBuffer gb
End Function



abacadabad(Posted 2003) [#3]
hi,
Thanks very much! Im planning on making a 1024x1024 texture as a groundmap, and to paint the texture onto the ground directly, and allow things like rocks to change the colour of the texture, so this should work well.
thanks again!
:-) :-)


jhocking(Posted 2003) [#4]
The same thing can be accomplished with multitexturing and normal transparency ie. masked or alpha textures. Depending on how many levels of multitexturing you have there wouldn't be any slowdown (even really old video hardware supports two texture layers per pass; newer hardware supports several times that) and it is much faster to setup/load than using WritePixel commands.


abacadabad(Posted 2003) [#5]
Hi there,
Yeah I originally thought of using multitexturing, but I want the texture to be of random islands and reefs with actual textured beaches smoothly flowing into the water, kind of like photorealistic terrain...a pretty hard task (random photorealistic terrain) but hopefully this *might* work. I have already come up against one problem though, when I use;

WritePixelFast x+200,y+200,(rgb Or $FF000000),db

The x & y of the decal is displaced by 200, but when I use a variable;

xno=200
yno=200
WritePixelFast x+xno,y+yno,(rgb Or $FF000000),db

It doesnt work at all :-(

Any ideas?
Thanks :-)


DJWoodgate(Posted 2003) [#6]
Pass xno and yno into the function as parameters or make them global.


abacadabad(Posted 2003) [#7]
Hi,
It works! Thankyou!
:-)