Texture on a textured terrain

Blitz3D Forums/Blitz3D Beginners Area/Texture on a textured terrain

mmm...
i want to place a texture on a textured terrain...
like a circle to indicate what unit i have selected...
how can I?

You mean like a sprite? I don't understand i think

Yes, now i'm sure. You have to make a sprite. Well, maybe there's another possibillity. I'm also not to good in blitzbasic

Here it is an example:
As you can see under the main character there is a circle that is not a sprite...

Yes, i understand. I'm german so I've problems with the speech. I would make it with a sprite. And if u want to put screenshots in the forum, just copy the url in your post, without any "[img]"

yeah sorry for the image :D

After EntityTexture you can put a "index" parameter, that indicates which level of the entity is textured.
So you could apply the new texture using EntityTexture Terrain, texture2, 0, 1. If you want to move it, try using PositionTexture.

yeah but the texture is repeated for the whole extension of the terrain! i don't want that!

Then, use ScaleTexture texture, TerrainSize(terrain), TerrainSize(terrain)

it's the same! the only difference is that the pieces of textures are smaller!

Ah, so that is going into the right direction, then! Maybe try entering values yourselve, ie. ScaleTexture texture, 1024, 1024
And there is a EntityFX that is used for "clamping". You can disable repeating the texture on the sides of a mesh. Not sure about terrains though.

can't find the entityfx command you are talking about...
fx -
0: nothing (default)
1: full-bright
2: use vertex colors instead of brush color
4: flatshaded
8: disable fog
16: disable backface culling
32: force alpha-blending

there is nothing for clamping...

Yes, you are right. The right command is TextureFilter. (edit)However I tried it and it does not work.
Here is an example of what I mean:
;setup graphics
Graphics3D 800, 600, 0, 2
SetBuffer BackBuffer()

;create 1st texture
texture1 = CreateTexture(512, 512)
Cls
Color 0, 0, 255
For i = 0 To 512 Step 10
	Line i, 0, i, 512
	Line 0, i, 512, i
Next
CopyRect 0, 0, 512, 512, 0, 0, BackBuffer(), TextureBuffer(texture1)

;create 2nd texture
Color 255, 255, 255
texture = CreateTexture(512, 512)
Cls
Oval 236, 236, 40, 40, 0
CopyRect 0, 0, 512, 512, 0, 0, BackBuffer(), TextureBuffer(texture)
ScaleTexture texture, 4, 4
PositionTexture texture, 0.5, 0.5

;create terrain
tw = 512 ;terrainwidth
terrain = CreateTerrain(tw)
EntityTexture terrain, texture1
EntityTexture terrain, texture, 0, 1
TextureBlend texture, 3
ScaleTexture texture, tw, tw


;create camera
camera = CreateCamera()
;CameraProjMode camera, 2
PositionEntity camera, tw/2, 500, tw/2
RotateEntity camera, 90, 0, 0

;main loop
Repeat
	;calculate x/y position circle
	time = time + 1
	x# = Cos(time) / 4
	y# = Sin(time) / 4
	;position circle
	PositionTexture texture, x#, y#
	;render
	RenderWorld()
	Flip
;until ESC is pressed
Until KeyHit(1)

End

!note!edited

oh ok thnx

I tweaked the example a bit and it seems that the best way to go for a clamping version, is using a big texture for the circle (terrainsize*3) and then scaling it up so only 1/3rd of the entire texture is shown. Finally, use PositionTexture to move it. That way, even when the circle crosses the edge of the terrain, the repetition of the circle on the other side still remains outside of the visible area. So then it doesn't repeat in sight.
(edit)OR: take 4 points. Read the TerrainHeight from their position and place them on top of the terrain. Then, move a quad to match these 4 points. This method is faster, but less precise. The more points the quad has, the better it 'fits' on the terrain.
;setup graphics
Graphics3D 800, 600, 0, 2
SetBuffer BackBuffer()

;create 1st texture
texture1 = CreateTexture(512, 512)
Cls
Color 0, 0, 255
For i = 0 To 512 Step 10
	Line i, 0, i, 512
	Line 0, i, 512, i
Next
CopyRect 0, 0, 512, 512, 0, 0, BackBuffer(), TextureBuffer(texture1)

;create terrain
tw = 512 ;terrainwidth
terrain = CreateTerrain(tw)
EntityTexture terrain, texture1

;create camera
camera = CreateCamera()
;CameraProjMode camera, 2
PositionEntity camera, tw/2, 500, tw/2
RotateEntity camera, 90, 0, 0

;create quad
mesh = CreateMesh()
surf = CreateSurface(mesh)
AddVertex surf, -1, -1, 0, 0, 0
AddVertex surf,  1, -1, 0, 1, 0
AddVertex surf,  1,  1, 0, 1, 1
AddVertex surf, -1,  1, 0, 0, 1
AddTriangle surf, 0, 1, 2
AddTriangle surf, 0, 2, 3
RotateMesh mesh, 90, 0, 0 
ScaleMesh mesh, 10, 1, 10
FlipMesh mesh

;main loop
Repeat
	time = time + 1
	PositionEntity mesh, Cos(time) * 100 + tw/2, 0, Sin(time) * 100 + tw/2
	;calculate x/y position circle
	For t = 0 To 3
		TFormPoint VertexX(surf, t), VertexY(surf, t), VertexZ(surf, t), mesh, 0
		yy# = TerrainY(terrain, TFormedX(), TFormedY(), TFormedZ())
		TFormPoint TFormedX(), yy#, TFormedZ(), 0, mesh
		VertexCoords surf, t, TFormedX(), TFormedY(), TFormedZ()
	Next	
	
	;render
	RenderWorld()
	Flip
;until ESC is pressed
Until KeyHit(1)

End


I sprite would probably be alot easier to do :)

That is right. And considering that a character is above the terrain all the time, simply parenting the sprite to the object might work.
I guess every method has it's disadvantages. Using a sprite doesn't allow for moving the vertices up and down separately. Using EntityOrder causes the terrain to be rendered below any characters. The multitexture solution works, but it takes far more memory than needed. And using a quad (preferrably with multiple subdivisions) will also need some tweaking to get it right, because the distance between the vertices should somehow match the vertices of the terrain. Otherwise some parts of the quad will still end up under the terrain.
;setup graphics
Graphics3D 800, 600, 0, 2
SetBuffer BackBuffer()

;create 1st texture
texture1 = CreateTexture(512, 512)
Cls
Color 0, 0, 255
For i = 0 To 512 Step 10
	Line i, 0, i, 512
	Line 0, i, 512, i
Next
CopyRect 0, 0, 512, 512, 0, 0, BackBuffer(), TextureBuffer(texture1)
ScaleTexture texture1, 512, 512

;create terrain
tw = 512 ;terrainwidth
terrain = CreateTerrain(tw);LoadTerrain("c:\_Xfiles\height44.bmp")
ScaleEntity terrain, 1, 10, 1
EntityTexture terrain, texture1


;create camera
camera = CreateCamera()
;CameraProjMode camera, 2
PositionEntity camera, tw/2, 500, tw/2
RotateEntity camera, 90, 0, 0

;create quad
mesh = CreateMesh()
surf = CreateSurface(mesh)
AddVertex surf, -1, -1, 0, 0, 0
AddVertex surf,  1, -1, 0, 1, 0
AddVertex surf,  1,  1, 0, 1, 1
AddVertex surf, -1,  1, 0, 0, 1
AddTriangle surf, 0, 1, 2
AddTriangle surf, 0, 2, 3
RotateMesh mesh, 90, 0, 0 
;ScaleMesh mesh, 10, 1, 10
FlipMesh mesh

camera2 = CreateCamera(mesh)
MoveEntity camera2, 0, 20, -50
HideEntity camera

;main loop
Repeat
	time = time + 1
	PositionEntity mesh, Cos(time) * 100 + tw/2, 0, Sin(time) * 100 + tw/2
	;calculate x/y position circle
	For t = 0 To 3
		TFormPoint VertexX(surf, t), VertexY(surf, t), VertexZ(surf, t), mesh, 0
		yy# = TerrainY(terrain, TFormedX(), TFormedY(), TFormedZ()) + 1
		TFormPoint TFormedX(), yy#, TFormedZ(), 0, mesh
		VertexCoords surf, t, TFormedX(), TFormedY(), TFormedZ()
	Next	
	
	;render
	RenderWorld()
	Flip
;until ESC is pressed
Until KeyHit(1)

End


I think i will use a sprite...

:)