Textures - realtime replacing textures

Blitz3D Forums/Blitz3D Programming/Textures - realtime replacing textures

MadsNy(Posted 2004) [#1]
Hi.

I've been looking all over for a way to change my texture in realtime... sorry if i've been looking the wrong places but now this simple things is really nagging me...

i want to grap the screen image and map it to an object (sprite or quad, anyway just an entity)...

i've tried diff things. like a function that creat a temp texture and entitytexture it to the object.. but this is super super slow, even thou i free'ed the temp stuff after....
?????

aome one...
guides or snippets are more than welcome..
Kind regards
Mads


Ross C(Posted 2004) [#2]
Copying from video memory is pretty slow really. If you create a texture though, and give it the VRAM flag on creation, this will speed up the copying process.

Here's some code i have on my computer i wrote a while ago, before i used functions :O

Note this:
mirrortex=CreateTexture(256,256,256)


The 256 Flag - VRAM. Means the texture will remain in Video RAM fo quicker copying or something like that :o) Well, on most cards anyway :o)

Graphics3D 800,600,16

cube=CreateCube()
PositionEntity cube,-3,0,2

plane=CreatePlane()
EntityColor plane,40,40,200
MoveEntity plane,0,-2,0

planetex=CreateTexture(256,256)
SetBuffer TextureBuffer(planetex)
For loop=0 To 255 Step 2
	For loop1=0 To 255 Step 2
		Color 50,50,200
		Rect loop,loop1,1,1
		Color 20,20,200
		Rect loop+1,loop,1,1
		Color 50,50,200
		Rect loop,loop1+1,1,1
		Color 20,20,200
		Rect loop+1,loop1+1,1,1
	Next
Next

SetBuffer BackBuffer()

ScaleTexture planetex,200,200
EntityTexture plane,planetex

sphere=CreateSphere()


camera=CreateCamera(sphere)
PositionEntity camera,0,3,-5
CameraRange camera,1,100

mirror=CreateCube()
PositionEntity mirror,0,3,10
ScaleEntity mirror,3,1.5,0.2

mirrorframe=CreateCube()
PositionEntity mirrorframe,0,3,10.2
ScaleEntity mirrorframe,3.3,1.7,0.3
RotateEntity mirrorframe,20,180,0
EntityColor mirrorframe,70,70,200

mirrorcam=CreateCamera(mirror)
PositionEntity mirrorcam,0,0,0
HideEntity mirrorcam
CameraRange mirrorcam,1,100
CameraZoom mirrorcam,3

mirrortex=CreateTexture(256,256,256)
EntityTexture mirror,mirrortex
ScaleTexture mirrortex,-1,1

light=CreateLight()

RotateEntity mirror,20,180,0

Color 255,255,255

While Not KeyHit(1)
	
	
	If KeyDown(200) Then MoveEntity sphere,0,0,0.1
	If KeyDown(208) Then MoveEntity sphere,0,0,-0.1
	If KeyDown(203) Then TurnEntity sphere,0,1,0
	If KeyDown(205) Then TurnEntity sphere,0,-1,0

	If MilliSecs()<timer+1000 Then
								frame=frame+1
	Else
								fps=frame
								frame=0
								timer=MilliSecs()
	End If
	Gosub updatemirror
	UpdateWorld
	RenderWorld
	Text 0,0,"fps="+fps
	Flip
Wend
End

.updatemirror
	HideEntity camera
	ShowEntity mirrorcam
	RotateEntity mirrorcam,0,-EntityYaw(sphere),0
	RenderWorld

	CopyRect 252,117,255,255,0,0,BackBuffer(),TextureBuffer(mirrortex)

	HideEntity mirrorcam
	ShowEntity camera
Return



MadsNy(Posted 2004) [#3]
just to round up, i've made a little program that snap the screen and place it on a sprite texture, what's nice about this code is, that you can have planes infront of the camera with textures on that's in exact pixel ratio.

here i snap the screen buffer and map it to and sprite (a pixie) and then scale it to 320*240... so if you need some graphics on top of you kewl game that change it's image through some image manipulation thingies,, feel free to misuse this code snippiet. hehehe....

well documented for newbie's.. hehe... good luck..
my 2 cent.


; another way of using the pixicode...
; ------------------------------------
; this is an example for beginners on
; how to make a copy of the scene in 
; a scaled version on top of the stage
; in exact pixel ratio...

; thanks to Ross C, Pixie
; Mads Larsen - 2. nov. 2004.
; sorry for the bad spelling.

Graphics3D 800,600,32,2 
SetBuffer BackBuffer() 
SeedRnd MilliSecs()

;cam
camera=CreateCamera() 
MoveEntity camera, 0,0,-10
CameraRange camera, 1, 5000
CameraFogMode camera, 1
CameraFogColor camera, 0,155,155
CameraFogRange camera,1300, 3000


;light
L1=CreateLight() 
PositionEntity L1, -200,100,-150



;-------------------- PIXIE or sprite(the real name for it)
; it's always a good idea to make a square pixie, meaning placing a square
; texture/image into it, if you are planning to scale it to a precise
; pixel size later on....
; if you used an non square texture you could end up with a strange
; mid calcualtion for getting eks. a 320*240 sized pixie/entity...

scr_dumb = CreateImage(600,600)

; put a 1 at the end to tell the function that it's an image object and not a file
Pixie= CreatePixie(camera, scr_dumb,1)

; we can now safly used the right pixel size of our entity
ScaleEntity pixie, 320,240,0







;--------------------Texture for the pixie

; creating the texture, remember that blitz only works with square textures
; which means if you in this case create an 800*600 texture, it will inside
; the computer create an 1024*1024 texture automatic, whic is cool but give 
; you a scaling problem...

; if you want to change the texture in realtime it's best that you let
; blitz keep the texture in the Video ram,, VRAM, therefor the 256...
; look up createtexture for more info's

pixTexture = CreateTexture(800,600,256)

;placing the texture on our pixie object (a 3D sprite)
EntityTexture pixie, pixTexture





;-------------------- Scaling the texture properly
; since we are using a smaller image that the texture size we need to scale
; the texture to fit the 1024*1024 texture(remember that blitz automatically make
; the texture into an square 1024*1024 texture....

; so we need a scale ratio.. this is easy to calculate thou...
; our texture is 1024*1024 and the image is 800*600 and we want the 800*600
;pixels to strech out in the 1024*1024 plane.... therefor...

;scale x => 1024/800 = 1.28
;scale y => 1024/600 = 1.7

; and now applying them to the command...
ScaleTexture pixTexture, 1.28,   1.7; X , Y

;if you use smaller texture, well then change the 1024 value.



; ------------------------ building some 3D stuff.
obj1 = CreateCube()
obj2 = CreateCube()
obj3 = CreateCube()
obj4 = CreateCube()

PositionEntity obj1, Rnd(0,2), Rnd(0,2), -8
PositionEntity obj2, Rnd(0,2), Rnd(0,2), -8
PositionEntity obj3, Rnd(0,2), Rnd(0,2), -8
PositionEntity obj4, Rnd(0,2), Rnd(0,2), -8

num = 0
PointEntity camera, obj1


While Not KeyDown( 1 ) 
	num = num +1
	; simple rotation calc.
	RotateEntity obj1, num/0.43,num, num/1.43
	RotateEntity obj2, num/1.43,num, num/1.63
	RotateEntity obj3, num/0.63,num, num/2.43
	RotateEntity obj4, num/0.33,num, num/0.43
	
	; we don't want to draw our "mirrow" image,,, try without, looks cool
	HideEntity pixie
	; draw the wtuff to the buffer so we can copy it later on
	RenderWorld	
	; this is the magic, here we copy the backbuffer to the texture itself
	; look up the copyrect for more info's.
	CopyRect 0,0,800,600,0,0,BackBuffer(),TextureBuffer(pixTexture)
	; show our screen captured image on the screen again.
	ShowEntity pixie
	
	
	
	PositionEntity pixie,MouseX(),MouseY(),-0.01
	RenderWorld 

Flip 
Wend 

End



Function CreatePixie(camera,file$, state) ; state 1=file, 2=imgObj
; load squared texture
	If state = 1 Then
		;IMAGE
		image = file
		iwidth=ImageWidth(file)
		iheight=ImageHeight(file)
		;TEX	
		texture = CreateTexture(iwidth, iheight)
		width=TextureWidth(texture)
		height=TextureHeight(texture)
	Else	
		texture=LoadTexture(file)
		width=TextureWidth(texture)
		height=TextureHeight(texture)
		image=LoadImage(file)
		iwidth=ImageWidth(image)
		iheight=ImageHeight(image)
	End If
	
	If iwidth<>width Or iheight<>height
		buffer=TextureBuffer(texture)
		ibuffer=ImageBuffer(image)
		For y=0 To height-1
			For x=0 To width-1
				WritePixel x,y,ReadPixel(x,y,ibuffer),buffer
			Next
		Next
		ScaleTexture texture,Float(width)/iwidth,Float(height)/iheight ; will blitzmax need float()?
		width=iwidth
		height=iheight
	EndIf
;	FreeImage image
; change these for viewports
	viewwidth=GraphicsWidth()
	viewheight=GraphicsHeight()
; find existing pixiespace parented to camera
	magic=0
	n=CountChildren(camera)
	For i=1 To n
		If EntityName(GetChild(camera,i))="pixiespace" 
			magic=GetChild(GetChild(camera,i),1)
		EndIf
	Next
	If magic=0
		magic=CreatePivot(camera) 
		NameEntity(magic,"pixiespace")
		aspect#=Float(viewheight)/viewwidth
		PositionEntity magic,-1,aspect,1
		scale#=2.0/viewwidth 
		ScaleEntity magic,scale,-scale,-scale 
		magic=CreatePivot(magic)
		PositionEntity magic,-.5,-.5,0
	EndIf
; create sprite from texture as child of magic overlay	
	sprite=CreateSprite()
	EntityParent sprite,magic		;cludge for blitz bug in createsprite(parent)
	brush=CreateBrush()
	BrushFX brush,1
	BrushTexture brush,texture
	PaintEntity sprite,brush
	FreeBrush brush
	SpriteViewMode sprite,2 
	scale#=1.0/viewwidth 
	ScaleSprite sprite,width*scale,height*scale
	Return sprite
End Function


ps tomorrow i'll learn spelling hehe sorry.


Andy(Posted 2004) [#4]
You might want to take a look at this:
http://www.blitzbasic.com/Community/posts.php?topic=37318#411137

Andy