Pixel perfect question

Blitz3D Forums/Blitz3D Programming/Pixel perfect question

Ross C(Posted 2006) [#1]
I have been looking through the pixel perfect code from the archives, but i can't pick out what part actually does the pixel perfect positioning/scaling. Don't think my head is screwed on right today.


jfk EO-11110(Posted 2006) [#2]
well it's pretty simple, you need to position a quad or sprite in front of the camera in a way that gives you the same amount of texels and pixels onscreen. If you once got that, you need to move the quad/sprite by a half pixel, because texels are centered, pixels are not.

You should use a texture flag that turns off mipmapping to get a sharp texture, eg. flag 256.


skidracer(Posted 2006) [#3]
In my pixie code it is a magic pivot that they are parented to that provides the precision.


Stevie G(Posted 2006) [#4]
Ross,

The majic pivot in skidracers code confused me a bit so, a simpler way to get a texel's width on screen is initialising GUIsx, GUIsy with ...

GUIplane = CreatePlane( 1, GUIcamera )
RotateEntity GUIplane, -90,0,0
PositionEntity GUIplane, 0,0,1
EntityPickMode GUIplane, 2
CameraPick ( GUIcamera, 0,0 )
sx# = PickedX()
sy# = PickedY()
CameraPick ( GUIcamera, 1,1 )
GUIsx# = PickedX() - sx 
GUIsy# = sy - PickedY() 
FreeEntity GUIplane


Create quads like so ...

Function GUI_Quad( sx#, sy#, Texture=0 , Free = False , ox#=0, oy#=0 , oz# = 0 , order=-998 )

	mesh = CreateMesh( GUIcamera )
	s = CreateSurface( mesh )
	For iy = 0 To 1
		For ix = 0 To 1
			px# = ( ix * sx - ox ) * GUIsx
			py# = ( -iy * sy + oy ) * GUIsy
			AddVertex s, px, py, oz, ix+.5*(1.0/sx), iy+.5*(1.0/sy )
		Next
	Next
	AddTriangle s, 0,1,3
	AddTriangle s, 3,2,0
	EntityFX mesh, 1
	
	If Texture > 0
		EntityTexture mesh , Texture
		If Free FreeTexture Texture
	EndIf
		
	EntityOrder mesh, order
		
	Return mesh

End Function


Then position with .....

Function GUI_Position( Entity , x#, y# )

	PositionEntity Entity, ( x - HGW ) * GUIsx , ( HGH - y ) * GUIsy, 0

End Function


Where HGW, HGH are half graphics width / height

Stevie


Ross C(Posted 2006) [#5]
Ah, thanks stevie, that's more like it :o)


octothorpe(Posted 2006) [#6]
I always preferred mapping units to pixels/texels. If you move the camera back far enough (or your pixel-perfect pivot forward far enough) you don't need to do arithmetic when positioning quads:

PositionEntity quad\entity, quad\x, quad\y, 0


Half of one, point five of the other.


Ross C(Posted 2006) [#7]
I got that working ;o) Tis very handy, as you can use, rects overlap to select the quads :o)


Steven Noyce(Posted 2006) [#8]
I am lost. What are texels? What is Pixel Perfect?


Stevie G(Posted 2006) [#9]
Ross, any chance of a look at the code? This may be a better option for me too ( rects overlap instead of camerapicks ) but not sure how you go about scaling so that 1 textel = 1 unit.

Assume rects overlap allows the use of textures?

Cheers
Stevie


Ross C(Posted 2006) [#10]
Nope, all you do is get the x,y co-ord of the sprite/quad, stick in the width and height, and your sorted. This uses 1 pixel = 1 blitz unit. Thus your able to move the meshes, in 2d co-ords. The Y is inverted because of the 3d co-ords uses Y differently.

www.rosscrooks.pwp.blueyonder.co.uk/editor1.zip


Ross C(Posted 2006) [#11]
This part, from the "buttons.bb"

Global GUI_cam_piv = CreatePivot()
EntityParent GUI_cam_piv,camera
PositionEntity GUI_cam_piv,-1,0.75,1


Global GUI_texture = LoadTexture("images/icons.png")

Global GUI_mesh = CreateMesh()
Global GUI_surf = CreateSurface(GUI_mesh)

	EntityParent GUI_mesh,GUI_cam_piv
	PositionEntity GUI_mesh,0,0,0
	ScaleEntity GUI_mesh,0.03125,0.03125,0.03125
	EntityTexture GUI_mesh,GUI_texture
	EntityFX GUI_mesh,1+2+32
	EntityPickMode GUI_mesh,2

Global GUI_pm# = 0.0625 * (1024.0/gwidth)
Global GUI_quad_size# = 1024.0/gwidth
Global GUI_icon_size# = 32 ; the pixel size of the icons.


I've worked out the scalings. So, using that code... you add a quad by:

add_quad(GUI_pm * b\x ,GUI_pm * -b\y,0,b\icon,0)


The parameters use the variable GUI_pm, which, when multiplied by your pixel value, give the co-ords in 3d, where to place the quad. The Y is minus because your using 3d co-ords mind, but they equate to 2d co-ords.

Now, this isn't 1 texel = 1 pixel. This is, 1 blitz unit, = 1 pixel. That's why the GUI_mesh is scaled. The last two parameters in that function are for choosing the texture co-ords, by passing an icon variable. The function will multiple that by 32, to get the image of the icon. Completely irrevant to what your wanting though :o)

Oh and:
Global GUI_quad_size# = 1024.0/gwidth


This part simply works out the difference in size, for my icons to appear the same size, regardless of the resolution. It would be the same if you were trying to draw a rect the same size in different resolutions. The scaling was based on a screen size of 1024x768.

Any questions on that code, feel free to post.


Ross C(Posted 2006) [#12]
Actually, if you just include the "buttons.bb" into your project and call the create_quad() function, it will return the first vertex, so you can store that and move it. You'll need to have the buttons image file though. I'll need to work on that to make it more generic.


Stevie G(Posted 2006) [#13]
Thanks Ross .. I'll take a look. Looks mode complex than the method I use though.

Cheers again
Stevie


Ross C(Posted 2006) [#14]
Well most of it is just for the editor :o)


Steven Noyce(Posted 2006) [#15]
What is Pixel Perfect?
Please?


Ross C(Posted 2006) [#16]
Pixel perfect is when you align the texels of a texture (the pixels that make up the texture), to the pixels that make up the screen. So, th ewidth of a texel on screen, is the width of a pixel onscreen, so they match up perfectly, and you get a clear display.

In my case, i'm using the term to describe the matching of 3d co-ords to 2d screen co-ords, by scaling the mesh to a certain size.


Steven Noyce(Posted 2006) [#17]
Thanks, that makes scence.


xmlspy(Posted 2006) [#18]



Sir Gak(Posted 2006) [#19]
Umm, what's a texel? Is that a textured pixel, or something else? If it's the former, how is that different from your plain old garden-variety pixel?


Ross C(Posted 2006) [#20]
A texel is a pixel on a texture basically. If your texture was 128x128, it would have 128x128 texels on it :o)