Help with Texture Manipulation

Blitz3D Forums/Blitz3D Beginners Area/Help with Texture Manipulation

-Rick-(Posted 2007) [#1]
I'm trying to program in a "pointer" onto my game map that will match the underlying texture. First I created a heightmap and saved it as a .bmp. Then I used LoadTerrain to create a terrain. Next I've created 2 textures for that terrain - Texture one is an actual texture of grass/mountain/water/etc while texture 2 is a simple hexgrid overlay.

My plan is to highlight the hex that that player's pointer is on.

My thought was to create a 3rd texture level that was the same size at the terrain textures and place a single colored hex on it. Then I could just use PositionTexture to move the texture around so that the single hex image on it would align with whatever hex the player pointer was on. The problem is that when I draw that 3rd layer it tiles the entire terrain with hexes.

Here is the relevant code I've used in making that 3rd texture and applying it :
Global gfxSelect		= CreateTexture(SCALE,SCALE)

skin = LoadImage ("graphics\selector.png")
	If Not skin Then RuntimeError "Missing graphics\selector.png file"
SetBuffer TextureBuffer(gfxSelect)
	DrawImage skin,0,0
SetBuffer BackBuffer()

EntityTexture Terrain,gfxMap,0,0
	EntityTexture Terrain,gfxHex,0,1
	EntityTexture Terrain,gfxSelect,0,2
	TextureBlend gfxMap,2
	TextureBlend gfxHex,3
	TextureBlend gfxSelect,3


SCALE is the size of the terrain (512)
selector.png is an image of a single hex

Here is the Normal Image :


Here it is when I try to put on the selector


Obviously I don't want all those little ones, just one big one that I can move around to the selected Hex. I know how to resize the texture, but how can I have it so Only 1 texture of the right size appears? How can i get it as a texture without tiling?

Thanks!


-Rick-(Posted 2007) [#2]
Hmm...I thought I had a solution, but I keep getting a memory access violation with this :

LockBuffer()
For x = 1 To ImageWidth(skin)
	For z = 1 To ImageHeight(skin)
		CopyPixelFast x,z,ImageBuffer(skin),x,z,TextureBuffer(gfxSelect)
	Next
Next
UnlockBuffer()


The size of the Image is 375x311 and the size of the texture gfxSelect is 512x512. The method I used to create my other textures was similar with the only difference being that I used 'writepixelfast' after converting the rgb codes from a value in an array :
r# = oilfield(x,z,0); And $FF0000/$1000
g# = oilfield(x,z,1); And $FF00/$100 
b# = oilfield(x,z,2); And $FF
rgb = Int(r)*65536 + Int(g)*256 + Int(b)
WritePixelFast x-1,z-1,rgb,TextureBuffer(gfxGeo)


Can I not read from an image and draw into a texture while using writepixelfast or copypixelfast?


GitTech(Posted 2007) [#3]
LockBuffer()
For x = 0 To ImageWidth(skin)-1
	For z = 0 To ImageHeight(skin)-1
		CopyPixelFast x,z,ImageBuffer(skin),x,z,TextureBuffer(gfxSelect)
	Next
Next
UnlockBuffer()


?


Stevie G(Posted 2007) [#4]
You need to make sure you're locking both buffers.

lockbuffer on it's own just locks the current buffer.

Use ..

lockbuffer imagebuffer( skin )
lockbuffer texturebuffer( gfxselect )

and the same when unlocking them.

Would you not be quicker using copyrect?

Stevie


-Rick-(Posted 2007) [#5]
And there I just learned something! Thank you Stevie! I was unaware that you could lock more than one buffer at a time! I thought that the last called lock command was the one that was active and any previous ones were automatically 'unlocked' as the new one was called.

I just tried locking both buffers and the program ran without the "memory access violation" error I've been getting. The results were not what I wanted, but at least I got to the point where I could see something without the error!

I'll tinker with this a bit more and see if I can now make some head way.

Thanks a million for helping me out :)


Axel Wheeler(Posted 2008) [#6]
I have the same problem, but I'm confused about the above solutions. I wouldn't think the way the texture is drawn would affect whether it repeats across the terrain.

I found that using flags 16 and 32 (Clamp U and V) in the CreateTexture or LoadTexture stopped the repeating - although I had to make sure the texture's edges were empty as it did bleed the last row of texels across otherwise.

My problem is that blending just doesn't seem to work. I've tried various modes and colors.

Here's my question; given Rick's scenario above (mine is similar) what blend modes should be used on the terrain, and on each of the various textures?

And, what color should the background of the top texture (the selection) be for the layer beneath to show through?

Is an alpha flag set somewhere?

I've seen this done in other blitz programs, I just don't know how it's done.

Thanks!


Ross C(Posted 2008) [#7]
If you set the backround to white, and use the multiply blend it will work fine. Multiply blend will blend white as invisible, all the way to pure black being totally see through, with RGB values in between with varying alpha.


Axel Wheeler(Posted 2008) [#8]
Thanks for the reply Ross.

It still isn't working for me, but I have to much going on in my program to tell what's really going on. I'll write a simplified version and do some testing.

Was I right about the clamping? In which case you wouldn't need a large texture, just one the size of the hex or target or whatever the image is being placed (plus one x and one y).

Do you feel this is generally the best approach, or are those guys above doing it a better way with copypixelfast()/writepixelfast()/copyrect() each frame?

I've just ordered the new version of the Blitz3D manual from Lulu; hopefully it has some guidance on best practices in general.

Thanks again!


Ross C(Posted 2008) [#9]
Clamping should be fine. Remember your vertex texture coords will determine which parts of the mesh are mapped with a texture.

A few other points. If your texture is manually created, then you will need to manually write alpha values for masking/alpha textures to work.

If you use this:

http://www.blitzbasic.com/codearcs/codearcs.php?code=1013

to give your texture a mask colour (it will write alpha values and enable masking on a specific colour you choose), and give your texture the mask flag from when it's created. I'm not sure about the blend modes, but a couple of them should work. Just make sure your texture cursor is on the *highest* layer.

EntityTexture cursor_texture,0,4<< 4 being the 5th texture layer.