Textured Poly help?

BlitzMax Forums/BlitzMax Beginners Area/Textured Poly help?

Dex(Posted 2008) [#1]
Hi, I found this piece of code for Bmax on the forums for texturing polygons, works great and just what I needed, except it fails to scale properly. have tried to sort it, but think it needs soemone with a bigger brain than mine! Also wondering would it be simpler and faster to just make GL function instead?


Strict
Rem
'SetGraphicsDriver GLMax2DDriver()
Graphics 800,600

Local Image:TImage = LoadImage("clock.png") ' 32x32 256x256 e.t.c
Local TestImage:TImage = LoadImage("sun.png")

Local xyuv:Float[] = [ ..
100.0,100.0, 0.5, 0.5,..
100.0, 36.0, .5, 0.0, ..
145.2, 54.0, .85, 0.14 ..
]

SetBlend AlphaBlend
SetScale 2,2
SetAlpha .5
'DrawImage TestImage, 0, 0
DrawTexturedPoly Image, xyuv
'DrawImage TestImage, 200, 200

Flip
WaitKey
End Rem

Function DrawTexturedPoly( image:TImage,xyuv#[],frame=0, vertex = -1)
Local handle_x#, handle_y#
GetHandle handle_x#, handle_y#
Local origin_x#, origin_y#
GetOrigin origin_x#, origin_y#

Local D3DDriver:TD3D7Max2DDriver = TD3D7Max2DDriver(_max2dDriver)

Assert Image, "Image not found"

If D3DDriver Then
DrawTexturedPolyD3D ..
D3DDriver,..
TD3D7ImageFrame(image.Frame(frame)), ..
xyuv, handle_x, handle_y, origin_x,origin_y, vertex*4
Return
End If
Local OGLDriver:TGLMax2DDriver = TGLMax2DDriver(_max2dDriver)
If OGLDriver Then
DrawTexturedPolyOGL ..
OGLDriver,..
TGLImageFrame(image.Frame(frame)), ..
xyuv, handle_x, handle_y, origin_x,origin_y, vertex*4
Return
End If
End Function


Function DrawTexturedPolyD3D( Driver:TD3D7Max2DDriver, Frame:TD3D7ImageFrame,xyuv#[],handlex#,handley#,tx#,ty# , vertex)
If Driver.islost Return
If xyuv.length<6 Return
Local segs=xyuv.length/4
Local len_ = Len(xyuv)

If vertex > - 1 Then
segs = vertex / 4
len_ = vertex
End If
Local uv#[] = New Float[segs*6] ' 6


Local c:Int Ptr=Int Ptr(Float Ptr(uv))

Local ii:Int = 0
For Local i=0 Until len_ Step 4
Local x# = xyuv[i+0]+handlex
Local y# = xyuv[i+1]+handley
uv[ii+0] = x*Driver.ix+y*Driver.iy+tx
uv[ii+1] = x*Driver.jx+y*Driver.jy+ty
uv[ii+2] = 0 ' *********** THIS IS THE Z-COORDINATE
c[ii+3] = Driver.DrawColor
uv[ii+4] = xyuv[i+2]
uv[ii+5] = xyuv[i+3]
ii:+6
Next
Driver.SetActiveFrame Frame
Driver.device.DrawPrimitive(D3DPT_TRIANGLEFAN,D3DFVF_XYZ| D3DFVF_DIFFUSE | D3DFVF_TEX1,uv,segs,0)
End Function

Function DrawTexturedPolyOGL (Driver:TGLMax2DDriver, Frame:TGLImageFrame, xy#[],handle_x#,handle_y#,origin_x#,origin_y#, vertex)
Private
Global TmpImage:TImage
Public

If xy.length<6 Return

Local rot# = GetRotation()
Local tform_scale_x#, tform_scale_y#
GetScale tform_scale_x, tform_scale_y

Local s#=Sin(rot)
Local c#=Cos(rot)
Local ix= c*tform_scale_x
Local iy=-s*tform_scale_y
Local jx= s*tform_scale_x
Local jy= c*tform_scale_y

glBindTexture GL_TEXTURE_2D, Frame.name
glEnable GL_TEXTURE_2D

glBegin GL_POLYGON
For Local i=0 Until Len xy Step 4
If vertex > -1 And i >= vertex Then Exit
Local x#=xy[i+0]+handle_x
Local y#=xy[i+1]+handle_y
Local u#=xy[i+2]
Local v#=xy[i+3]
glTexCoord2f u,v
glVertex2f x*ix+y*iy+origin_x,x*jx+y*jy+origin_y
Next
glEnd
If Not tmpImage Then tmpImage = CreateImage(1,1)
DrawImage tmpImage, -100, - 100 ' Chtob zbit' flag texturi
End Function


ImaginaryHuman(Posted 2008) [#2]
I don't think SetScale is going to work to scale these polygons, (i could be wrong) - because SetScale is a part of Max2D and these two polygon functions are going directly to the driver to create the polygon. You may have to adjust your x and y coordinates to create the impression of scaling, while keeping your u and v the same.


plash(Posted 2008) [#3]
You can use this tweak to get the transformation variables instead of calculating them each time you draw. (used here)


Dex(Posted 2008) [#4]
Thank you both for your help, think I undrstand what your saying, -will give it a go and see, but dont be surprised if you see me back here asking for more help lol! Thanks again, much appreciated..


Dex(Posted 2008) [#5]
Tried the 'GetTransformVars' tweak in glmax2d.bmx, but keep getting 'GetTransformVars not recognised when I compile? I must be doing something wrong here?


plash(Posted 2008) [#6]
Import brl.glmax2d?


Dex(Posted 2008) [#7]
Still having trouble here, refuses to recognise the function,something I have overlooked somewhere, will keep trying, thanks for the help Plash


Warpy(Posted 2008) [#8]
OK, I've worked it out. Proger was getting the ix,iy,jx,jy values himself in the DrawTexturedPolyOGL function, but he made them ints so they were getting rounded down to the nearest whole number, and hence not working right when you've change the scale or rotation.

Here's the fixed thing:

Function DrawTexturedPolyOGL (Driver:TGLMax2DDriver, Frame:TGLImageFrame, xy#[],handle_x#,handle_y#,origin_x#,origin_y#, vertex) 
	Private
	Global TmpImage:TImage
	Public
	
	If xy.length<6 Return
	
	Local rot#  = GetRotation()
	Local tform_scale_x#, tform_scale_y#
	GetScale tform_scale_x, tform_scale_y
	
	Local s#=Sin(rot)
	Local c#=Cos(rot)
	Const scale#=1.28
	Local ix#= c*tform_scale_x*scale
	Local iy#= -s*tform_scale_y*scale
	Local jx#= s*tform_scale_x*scale
	Local jy#= c*tform_scale_y*scale
	
	glBindTexture GL_TEXTURE_2D, Frame.name
	glEnable GL_TEXTURE_2D
	
	glBegin GL_POLYGON
	For Local i=0 Until Len xy Step 4
		If vertex > -1 And i >= vertex Then Exit
		Local x#=xy[i+0]+handle_x
		Local y#=xy[i+1]+handle_y
		Local u#=xy[i+2]
		Local v#=xy[i+3]
		glTexCoord2f u,v
		glVertex2f x*ix+y*iy+origin_x,x*jx+y*jy+origin_y
	Next
	glEnd
	If Not tmpImage Then tmpImage = CreateImage(1,1)
	DrawImage tmpImage, -100, - 100 ' Chtob zbit' flag texturi
End Function


and an example (you'll need an image called fatgiraffe.jpg, I recommend this one)

Graphics 640,480,0

img:timage=LoadImage("fatgiraffe.jpg")

While Not KeyHit(KEY_ESCAPE)
	mx=MouseX()-320
	my=MouseY()-240
	
	d#=Sqr(mx*mx+my*my)*.01
	an#=ATan2(my,mx)
	
	SetScale 1,1
	SetRotation 0
	
	DrawText "scale = "+String(d),0,0
	DrawText "rotation = "+String(an),0,15
	
	SetRotation an
	SetScale d,d

	Local ix#, iy#, jx#, jy#
	GetTransformVars( ix, iy, jx, jy )
	
	'draw a rectangle
	SetOrigin 200,240
	DrawRect 0,0,100,100
	
	'draw a normal polygon in the shape of a rectangle
	SetOrigin 400,240
	Local poly2#[8]
	poly2=[	0.0,0.0, 100.0,0.0, 100.0,100.0, 0.0,100.0 ]
	DrawPoly poly2
	
	'draw a textured polygon in the shape of a rectangle
	SetOrigin 320,240
	Local poly#[16]
	poly=[	0.0,0.0,0.0,0.0, 100.0,0.0,1.0,0.0, 100.0,100.0,1.0,1.0, 0.0,100.0,0.0,1.0 ]
	drawtexturedpoly( img, poly )
	
	SetOrigin 0,0
	SetScale 1,1
	SetRotation 0

	DrawText "ix = "+String(ix),0,60
	DrawText "iy = "+String(iy),0,75
	DrawText "jx = "+String(jx),0,90
	DrawText "jy = "+String(jy),0,105
	
	
	Flip
	Cls
Wend


If anyone can tell me why I need to scale everything by 1.28 to get it to match up with the rect and polygon, I'd be grateful.


Yan(Posted 2008) [#9]
At first glance (although with the way my flu addled brain is working at the moment, meh!) it appears that the above code doesn't take into account the whole TImage texture resizing thing.

Does the amount of scaling required vary with different image sizes?

[edit]
Now that I've noticed the link to the image you used, I'm certain it's the pixel to texel conversion thang...1024/800 = 1.28...
[/edit]


Warpy(Posted 2008) [#10]
aaaaaahhh


plash(Posted 2008) [#11]
Dex, did you rebuild glmax2d after the edit?


MGE(Posted 2008) [#12]
Warpy, any chance of a DX and OGL solution? Thanks.


Warpy(Posted 2008) [#13]
Sorry MGE, I'm running linux at the moment so I can't test a directx version.


Dex(Posted 2008) [#14]
Thanks Warpy, Plash and Yan, havent tried the changes yet, just got here lol! Rebuld glmax2d??? Ive only been pasting the function into glmax2d.bmx and saving, - you have to rebuild, didnt realise this, ok now I need find how to rebuild mods, ah! But hadnt noticed the Ints problem, makes sence now why the scaling was stepped rather than smooth??!!


Dex(Posted 2008) [#15]
The TexturedPoly Func works perfectly now that the Ints have been changed to Floats, thanks warpy. Just one thing though, I noticed that the line,

DrawImage tmpImage, -100, - 100 ' Chtob zbit' flag texturi

at the end of the function is there to correct a colour problem? Without this call to DrawImage the colours go screwy and are to dark. I managed to hide the image behind my poly tiles, which is fine except this extra call to DrawImage is an overhead my code could do without.

Even tried checking the 'glmax2D' mod to try found out how drawimage is correcting the colour,without any luck! Does anyone have any idea how to correct the colour without having to use DrawImage?

I thought of drawing all the tiles first them calling DrawImage to correct the colour, but Im making an Iso map, so need to layer my tiles with Bmps,so am forced to make the extra DrawImage function call each tile draw to corret the colour first.