Animating Multiple Surface Textures

Blitz3D Forums/Blitz3D Programming/Animating Multiple Surface Textures

Omnicode(Posted 2016) [#1]
Hello all,
Recently i've been messing around with a single texture / multiple surface mesh. A difficult problem arose when adding 'animated' textures to brushes (as each frame of a brush is treated to its own surface) and having them display correctly. Especially when the brush contains the rest of the content for the map. i.e crates.. bushes etc. I'm attempting to animate fire/water using this configuration. I got a small function to achieve the task but cases occur where the animation seems to stop after an update or two to the core mesh.

Is there a better way to identify what FRAME of a parent brush you're using than what i've got here?

Dim Material$(99)
Material$(0)="Air"
Material$(1)="Stone"
Material$(2)="Dirt"
Material$(3)="Grass"
Material$(4)="Sand"
Material$(5)="Steel"
Material$(6)="Planks"
Material$(7)="Leaves:Transparent"
Material$(8)="Glass:Transparent"

Material$(9)="Fire:Transparent:Animated[16]" ;8 frames
Material$(10)="Fire:Animated_1"
Material$(11)="Fire:Animated_2"
Material$(12)="Fire:Animated_3"
Material$(13)="Fire:Animated_4"
Material$(14)="Fire:Animated_5"
Material$(15)="Fire:Animated_6"
Material$(16)="Fire:Animated_7"

Material$(17)="Water:Transparent:Animated[24]" ;8 frames
Material$(18)="Water:Animated_1"
Material$(19)="Water:Animated_2"
Material$(20)="Water:Animated_3"
Material$(21)="Water:Animated_4"
Material$(22)="Water:Animated_5"
Material$(23)="Water:Animated_6"
Material$(24)="Water:Animated_7"

ClearTextureFilters()
Global Section_Texture=LoadAnimTexture("Media\Textures\Texture.png",1+4,64,64,0,24)

;Usage Within Program
					For Surfs=1 To CountSurfaces(AMS\Mesh)
						;Temp_Brush=GetSurfaceBrush(GetSurface(AMS\Mesh,Surfs))
						Animate_Textures(AMS\Mesh)
						;FreeBrush Temp_Brush
					Next
;Usage Within Program

Function Animate_Textures(mesh)
	Compare_Brush=CreateBrush()
	For i=8 To 24
		If Instr(Material$(i),"Animated")<>0
			BrushTexture(Compare_Brush,Section_Texture,i,0)
			Current_Surface=FindSurface(mesh,Compare_Brush)
			If Current_Surface
				If Instr(Material$(i),"Fire")<>0
					i=Cycle_Value(i+1,9,15)
					BrushTexture(Compare_Brush,Section_Texture,i,0)
					PaintSurface(Current_Surface,Compare_Brush)
				EndIf
				If Instr(Material(i),"Water")<>0
					i=Cycle_Value(i+1,17,23)
					BrushTexture(Compare_Brush,Section_Texture,i,0)
					PaintSurface(Current_Surface,Compare_Brush)
				EndIf
			EndIf
		EndIf
	Next
	FreeBrush Compare_Brush
End Function

Function Cycle_Value(val,low,high)
	If val<low Then Return high
	If val>high Then Return low
	Return val
End Function


I have a global array that holds the material$ present at a part of the mesh. Segments of the array are taken up by filler for animation frames... i'd like to change that.

Works by looking for the flag of "Animated" in the material name then animating the applicable surface texture.


RemiD(Posted 2016) [#2]

as each frame of a brush is treated to its own surface


Are you sure about that ? As i understand it, a frame of an animated texture is simply a part of a texture, nothing to do with different brushes or different surfaces.
Knowing this, a way to animate a texture is simply to store the current offset on the texture and use positiontexture() depending on the frame you want to display.


Omnicode(Posted 2016) [#3]
I meant more along the lines of how my program is setup, not how blitz actually handles brushes being applied to surfaces. I TREAT EACH SURFACE AS A FRAME OF THE GLOBAL TEXTURE. ~

However, positiontexture may be an alternative... I just wanted a bit of insight. Lol


RemiD(Posted 2016) [#4]
Yes do a test with positiontexture() it will probably help.

However, with positiontexture you may need to use one different texture for each surface using an animated texture else all will probably move the same way. (not tested but i suppose)


Omnicode(Posted 2016) [#5]
The speed for this method isn't slow enough to really cause too much problems as the program stands. Having multiple textures may have to be introduced anyways as flagging a brush with alphaFX defeats the method altogether.

The greater question I have on hand is why it would randomly stop animating for some particular reason USING this method.

Fixed!
I'm still using one texture. However I realized I was making a bunch of checks I really didn't need to make. At the time I thought it would be necessary to check back to the material$ to see if the next frame would be considered animated. This isn't needed and I can simplify my code.

	Frame=Animation_Tick
	Compare_Brush=CreateBrush()
	
	;Fire
	BrushTexture(Compare_Brush,Section_Texture,9+Animation_Tick,0)
	Current_Surface=FindSurface(mesh,Compare_Brush)
	If Current_Surface
		BrushTexture(Compare_Brush,Section_Texture,Cycle_Value(9+(Frame+1),9,16),0)
		PaintSurface(Current_Surface,Compare_Brush)
	EndIf
	
	;Water
	BrushTexture(Compare_Brush,Section_Texture,17+Animation_Tick,0)
	Current_Surface=FindSurface(mesh,Compare_Brush)
	If Current_Surface
		BrushTexture(Compare_Brush,Section_Texture,Cycle_Value(17+(Frame+1),17,24),0)
		PaintSurface(Current_Surface,Compare_Brush)
	EndIf
	
	FreeBrush Compare_Brush