Anyone Interesting in working together on a ....

Blitz3D Forums/Blitz3D Programming/Anyone Interesting in working together on a ....

A Free Full Featured 3D Mesh-based GUI Library?

After putting my major projects on hold and waiting for six months for one to make an appearance, I've decided to start developing one myself.

My goal is to developed a 'Animated' 2D GUI with Pixel Perfect/Single Surface 3D Quad-Mesh and unique Model-Mesh 3D GUI integrated into one Library. Also, develop Editor needed to easily create user interfaces for games and applications.

Any interested parties inquire within.

Please, not another team pr

%¤L"%;:[NO CARRIER]

nawi, thanks for your interest.

If I knew what it was you wanted I'd know a bit more than I do now Frank;

What input are you looking for?

I'm not so hot with all the latest acronyms and buzzwords but I do fine with plain english mostly! ;O)

I generally try to help where I am able.

I found creation of a basic mesh (sprite) based 2D GUI pretty straightforward. In my case I use 2 full-screen source images and texture-fetch the controls onto sprites. I use a seperate Orthographic camera positioned away from the main scene and place the controls sprites in front of this, then set the cameraproject of the two cameras to 'off' as needed to render the UI over the 3D scene. I use the pixel perfect sprites routine (pixies) by skidracer. This has given me a pixel-perfect 2D interface that runs fast in 3D unlike my original 2D drawing operations from a previous UI attempt.

It wouldn't be too hard to modify to have a single surface where you blit the control graphics onto it, but this will be less old-hardware friendly because of large-surface texture slowdown. For some bizarre reason textures applied to a large (screen percentage) surface causes mega slowdown on older GPUs. That's why IMO it's better to break the UI into lots of smaller components.

Note that my interface needs are basic, and I'm not aiming for a conplex WIMP system which the availble UI libs seem to aimed at. I want icons to click, and text, and I'll add a slider thing. I don't care for resizable windows, gadgets, and other shenanigans.

polygoon

Thanks for your interest. I'll try to keep the buzzwords to a low, however, I'll hip you with my definitions of the words i've mentioned. Anyone is welcome to correct my definitions.

Pixel Perfect - Clarity of pixels of a Texture on 3D Sprite equal the clarity of pixels of 2D Image.

Single Surface - A optization technique using one 3D Surface and one texture to create and manipulate several meshes.

Quad-Mesh - Mesh that contains 4 vertex (two triangles) commonly used for flat panels or sprites.

What I will need help with is working some of the math and interactivity. I have a working paper design and some code im playing with. By getting in at start it will be easier to understand and work with the code as grows.

Shifty Geezer

Your camera technique sounds very interesting. There is some pain in working out the math for positioning the sprite's depth in relation to screen's dimensions for pixel perfect clarity. Using an Orthogonal Cam could probably eliminate unnecessary math, I really like to see this system in action.

I start to run into trouble with the texturing the sprites. I haven't quite figured out the formula to map the texturecoords with the sprite and maintain clarity in proportion to the sprites dimensions. Single Surface sprites adds more complexity.

I intend to have animated motion and image effects. The GUI is being designed more so with Games in mind. But, Games can have built in apps like editors and such, so I want to support them as well.

Another area of my concern is maintaining high performance and drawing of text and shapes like rects and ovals. I fear that these functions will be slower than Blitz2D commands.

Truly appreciate the insight.

Working Paper Design. I'm using this Working Paper to help figure out the objects, functions, and control for the gui Lib and editors.

MAUI for Blitz3D
Mesh and Animation User Interface
by Frankie Taylor

MAUI2D

MAUI2D is a 3D quad-mesh based version of the typical 2D windows style GUI. The GUI system is based on a rectangle area defined by a start x,y screen coords and width,height coords. I call this area the GUI Primitive. A GUI Primitive can function as one or all of the following: boundbox -> image -> portal.

As a boundbox. It defines the area for collision detection with a pointer device. Pointer Events is the detection of collision and input by the Pointer within a boundbox during or after collision. Pointer Events: PointerMover, PointerEnter, PointerExit, PointerHover, PointerDown#, PointerUp#.

PointerMove – Pointer Moves
PointerEnter – Pointer enters a boundbox
PointerExit – Pointer exits a bound box
PointerHover – Pointer hovers within a bound box
PointerDown#. Pointer Button# is held down.
PointerUp# - Pointer Button# is released.

Note: The word “Pointer” was chosen instead of Mouse as a generic term for the screen pointer as it may controlled by a keyboard, mouse, joystick or other input device.

As an image it acts as a portal to display of graphics that reside in a texture or screen buffer. The visible area of the buffer is restricted to the image’s boundbox. Textures may contain single or composite images to include single and animated image strips.

As a portal it is a boundbox that performs clipping on other boundboxes and images within its dimensions. Portals are very useful for displaying several images and performing several boundbox checks within a small area on screen.

Gizmos

Gizmos are objects that contain GUI Primitive, and other properties used to control, communicate between the user and application. Gizmos use images and sound its state. In most cases a pointer event or another gizmo’s state transition controls the state of a gizmo.

Composite Gizmos

Composite Gizmos are assembled from simple gizmos. ComboBoxes, ListBoxes, DiaglogBoxes, Sliders are all examples of a composite Gizmo. Unlike most GUI Libraries, MAUI2D integrates BlitzScript3D to provide a scriptable Behavior and Action System. This allows for the creation of unique composite gizmos. Default Behaviors will be provided for the typical gizmos: Windows, Labels, Buttons, Tabs, TabPages, CheckBoxes, TextBoxes, Listboxes, ComboBoxes, Radios, CheckBoxes, Frames, Images, Sliders, Spinners, Progresses, Horizontal/Vertical Menus, Fill Bars, CameraBuffers.


Methods

MAUI2D_Event() - Device Input, Position, and Collision
MAUI2D_Message() - Provides a means of assigning and accessing Gizmo Properties
MAUI2D_Behavior() – Script executed directly on gizmo or related gizmos during an Event
MAUI2D_Action() – Script executed on the application during an event.
MAUI2D_Display - Display the control, Play sound.

MAUI2D collision uses either entitypick or boundbox collision, supporting both will allow maui2d controls to be animated with 3d movement.

Parents and Siblings



Parenting gizmos is simple mechanism for controlling the hierarchy and order of gizmos/composite gizmos. This is supported in the Editor with Auto-Parenting.

Editor

The Editor is combination of a Traditional GUI Editor and user-friendly 2D Animator similar to PowerPoint or CoffeeCup Firestarter. The 2D Editor works simultaneously with the 3D Scene Editor.




What function do the textures serve in thiis useage? I mean this is hardly a run of the mill context so I may need to ask some questions that sound daft at first.

Are they decorative or are they constructive?

What function do the textures serve in thiis useage? I mean this is hardly a run of the mill context so I may need to ask some questions that sound daft at first.

Are they decorative or are they constructive?

Since we are using custom made 3D quad-mesh for sprites we must use textures to paint them with a image.

I'm going to start coding tonight. I will be playing basic functionality of Pointer events. I will most likely play with this in standard 2D until I figure out how i will handle events.

So these are decorative, but as far as I understood it, they are gui gadgets?

If so, then why not just make the design as part of the button itself? This would make it even lighter in it's need for resources wouldn't it?

Given a set of images showing more or less what symbols you want, I'd imagine I could come up with a suitable set of meshes in fairly short order, subject to one or two other projects I have going on at present not eating too much time over the weekend or maybe a few days following - I got a sort of time window opening up for a fair bit of next week as another person has taken a holiday, leaving me a small gap also as a result.

Blitz is crying out for something like this .... any programer knows that the menus and gui stuff is the bane of our lives ... If there is anything I can help with then let me know!!

StevieG

polygoon

Textures are required with 3D meshes. MAUI will work to types of meshes a custom quad-mesh (sprite) and model-meshes. When it comes to single surfaces it can get tricky manipulating texture vertex coords to produce animations on a single sprite. Theres is were I'm really gonna need help.

My current goal is to tackle the pixel perfect issues with the 2D Windows Style GUI first which IMHO will be the toughest challenge. This is require me to create quad-meshes on a single surface and play with a composite texture.

Due to fact MAUI will make true 3D GUI's not just 2D in 3D, I labeling the controls as Gizmos instead of Gadgets.

StevieG, can you program? Can you read others code? Do you have a problem with someone else modifying your code? If your output is 1-1-0 then I can use your help!

Frank,

Let me just concentrate on the first paragraph, as it seems to be the one where I know for sure what I'm on about.

Frank> Textures are required with 3D meshes.

I accept that you may know why, and that to you it's obvious, but I can't for the life of me see why.

Frank> MAUI will work to types of meshes a custom quad-mesh (sprite) and model-meshes.

Erm, this does not quite make sense as it is written, and since it's a critical point perhaps, then I'd like you to please just polish it that little bit so I can understand what you are trying to say too.

I get the sense that you are trying to aim for a square-ish thing, made of two triangles, and then you want to map images on to it, and as far as I can tell you want that so it can appear to be animated. Does that come close as a first stab at a guess on my part?

Frank> When it comes to single surfaces it can get tricky manipulating texture vertex coords to produce animations on a single sprite.

I'm not at all surprised it gets tricky, can't you just have two states (one mesh for each) and swap between them? Then the issue of texture co-ordinates is gone forever! (promise ;O)

Frank> Theres is were I'm really gonna need help.

I'm trying to do that, but I'm not sure if I am explaining it right. I'm in essence suggesting each target to be hit by the pointer has two meshes and you show them one at a time. Hence it gets animated. I'm suggesting meshes with the image attribute etched into it's surface.

I got a window open as I type this and it has 3 gadgets in it's top right hand corner. I could very probably make you instances that look like them, but are made from mesh. They will be self coloured and if you want two of each to flip between then that's no problem either. I feel fairly sure this get's your job done; doesn't it? Oh and not a texture issue in sight either! ;O)

I'm sure I've got this all wrong for some reason I don't yet know of, but it seems like it's right.

Why won't this work like I am suggesting?

Can do you an alphabet too if you like, no problem really. <shrug>

polygoon,

Textures are required with 3D meshes.

I accept that you may know why, and that to you it's obvious, but I can't for the life of me see why.

Textures are images loaded into whats called a texture buffer and 'mapped' (projected) onto a 3D surface. Per Blitz3D its the only way to apply an image on to a 3D object. This is standard hardware and software approach due to memory issues. I recommend researching the internet for more info on Texture Mapping.

MAUI will work two types of meshes a custom quad-mesh (sprite) and model-meshes.

Quad-meshes contain only two triangles used to emulate Blitz3D's native 3D Sprites. The difference is that they are created on a single surface.

Why Single Surface? This is due to performance issues with using many surfaces. From what I know about Blitz3D, it uses one surface per primitive mesh or sprite. Using many Blitz3D Sprites can impact performance which is why you see many "Single Surface" Libs out there.

Surfaces are sections of mesh which are then used to attach triangles to. You must have at least one surface per mesh in order to create a visible mesh. I have never used a model with more than one surface, although blitz supports it, I dont think popular modeling tools do.

Creating quad-meshes on a Single Surface is like a creating a model with a 1000 triangles, breaking it up into 500 independent quads (two-triangles each) . The only way to access the quads, is to access the surface and manipulate the vertices and texturecoords directly and independently. This is why the math can get tricky. I'm sure there are formulas, I just have to find them.

From what I understand about textures you can only have one per surface. Thus I could not texture 250 quads with one texture and the other 250 with another if they are part of the same surface. So we have to improvise and create one large texture with several images in it. A composite texture.

Now the trick will be telling Blitz3D how to translate our 500 quads on screen, mapping the image from the composite texture, ensure pixel perfect resolution, maximum performance.

MAUI will render Quad-Meshes and Model-Meshes differently which is the only distinction beyond editing them. All of what I mentioned above pertains to the Quad-Meshes to mimic the typical 2D Windows-Style GUI.

Model-Meshes are animated and static models that you point and click on to do something in the game/application. No matter the shape of the models. They are interactive 3D scenes directed with lights, camera, and action control. A true 3D GUI. Both forms of GUIs will work hand in hand.

I think I must be out of my depth here; sorry, but I probably can't help after all, but thank you for helping us find that out. :O)

Good luck with it anyway, I'll be interested to see how it turns out.

polygoon

Perhaps some code will help. Have you worked with the 3D commandset?

@Frank

Nope, I'm just a 3d model maker. I was simply trying to make sure you got some meshes to work with.

I can see that I'd struggle and maybe even fail to make them how you want them.

Initially I thought it was going simple straight forward stuff, but can now see that's it's going to be way over my head!

Sorry for eating into your time, but it looks like I'm not the guy you're looking for on this one.

You can't hit a coconut every time I guess! ;O)

Like I said, I'll watch from time to time with interest to see how it goes.

Right, I better get back to the old draining board! ;O)

polygoon

Although I have been focused on the programming aspects of MAUI, a 3d model maker will be needed for the demo, so please do not throw in the towel just yet;)

At the moment, I'm not quite sure what the demo will be like, but, I can imagine it going something like this for my Sci Fi FPS GunVertor:

The game starts up with a pitch black screen. {Robotic Voice}"GuunVerrtooor", START - OPTIONS - EXIT meshes warp from the depths of 3D Space into your face. The meshes gyrate slowy until you move the 3D Pointer over them one at a time.

Upon moving the pointer over each mesh, it fades from a dark color to bright one then pulsates (shrinking/growing) until you click on it. When the selection is made, {Robotic Voice} "Intruder Alert!" and each Mesh fades out one at the time until the screen returns to pitch black. "Loading...."



To any interested parties,

I have a zip file that contains the current source and design docs. I've already integrated BlitzScript3D and have basic Pointer/Gizmo (2D) Event Interaction working.

Frank - Now I understand the project I agree it's a valuable/necessary addition to the Blitz library and good luck to you!

Shifty,

I'm very interested in your Camera technique. You wouldn't mind share some code would ya?

Okay, here's a cut-down version of my UI that illustrates the ortho camera use. I've left out nice button structures and interface loading, and scaling of objects etc. for different resolutions as these'll want to be designed for the end UI. My clunky solutions won't be wanted! But that's what some of the pointer type's fields are for though not used in this example.

Save this code as "_lib_ToodeeGooey.bb"
; Shifty's New Toodee-Gooey Library basics
; Constucts a UI from rectangular sprites.
; Positions them from an orthogonal camera.

; USE : Call TG_Initialse() to set up UI. Follow with TG_SetPointer() to set mouse pointer
; Use TG_Load_Sprite to create a 2D button sprite from a texture
; Use Scene_cam as your main program camera
; Use TG_Draw_UI() instead of UpdateWorld+RenderWorld
; Placment of UI components is in screen pixel coords
;   -  Z value  determines z order. High values have higer priority (front of interface). Float values
;   -  add UI_distance to objects to move them in front of UI camera
;   -  Range of Z defined by TG_Initialise/CameraRange TG_camera\camera,1,xxx
;   -  default is 100 for a range of 1-100. Mouse placed at 20. Fractional
; eg. PositionEntity button,100,100,UI_distance+5

Const UI_distance=-10000	; Camera distance for UI camera

Global TG_pointer.TG_point
Global TG_camera.TG_cam
Global Scene_cam
Global TG_sprite			; rectangle mesh

Type TG_point
	; Rectangle for pointer
	Field sprite%		; Pointer to rectangle mesh
	Field texture%	; pointer to texture
	Field pos_x%		; x position
	Field pos_y%		; y position
	Field prev_x%	; previous x position
	Field prev_y%	; previous y position
	Field siz_x%		; x size
	Field siz_y%		; y size
;	Field buffer%		; Buffer of underlying image to be restored	
End Type
Type TG_cam
	Field camera%		; Pointer to camera entity
	Field pos_x%
	Field pos_y%
	Field siz_x%
	Field siz_y%
End Type

TG_pointer.TG_point = New TG_point
TG_camera.TG_cam = New TG_cam

; UI constructors
Function TG_Initialise()
	; FUNCTION :  initialise UI camera and mouse pointer
	; loads rectangular mesh that's basis of all UI sprites
	HidePointer()
	
	TG_sprite = CreateMesh() 
	surf = CreateSurface(TG_sprite) 
	
	v0 = AddVertex (surf, 0,0,0, 0,0) 
	v1 = AddVertex (surf, 10,0,0, 1,0) 
	v2 = AddVertex (surf, 10,-10,0, 1,1) 
	v3 = AddVertex (surf, 0,-10,0, 0,1) 
	AddTriangle (surf,v0,v1,v2) 
	AddTriangle (surf,v0,v2,v3) 
	
	TG_camera\camera=CreateCamera()
	PositionEntity TG_camera\camera,0,0,UI_distance
	CameraProjMode(TG_camera\camera,0)				; 0 to hide, 2 to render
	CameraClsMode(TG_camera\camera,0,1)
	CameraRange TG_camera\camera,1,100

End Function
Function TG_SetPointer(img$)
	; FUNCTION : sets pointer image

	TG_pointer\texture= LoadTexture(img$,2)
	TG_pointer\sprite=TG_Create_Sprite(TG_pointer\texture)

	TG_pointer\pos_x=MouseX()
	TG_pointer\pos_y=MouseY()
	TG_pointer\siz_x=TextureWidth(TG_pointer\texture)
	TG_pointer\siz_y=TextureHeight(TG_pointer\texture)	
	PositionEntity TG_pointer\sprite, TG_pointer\pos_x, TG_pointer\pos_y, UI_distance+20
End Function
Function TG_Create_Sprite(texture,x_size#=0,y_size#=0)
	; Doctored sprite code from Skidracer
	; 'texture' is a pointer to a texture object, in sizes of squared powers of 2. eg. 128x128 or 256x256
	; this is because GPU's work fastest with power of 2 textures
	; optional x_size and y_size values crop the sprite to fit
	; eg. for a 27x18 button, create a 32x32 source image, load as texture, and call TG_Load_Sprite(texture,27,18)
	; No x_size or y_size values uses texture proportions
	
	width=TextureWidth(texture)
	If Not x_size
		x_size=width
	EndIf

	height=TextureHeight(texture)
	If Not y_size
		y_size=height
	EndIf

	; change these for viewports
	viewwidth=GraphicsWidth()
	viewheight=GraphicsHeight()
	; find existing pixiespace parented to camera
	magic=0
	n=CountChildren(TG_camera\camera)
	For i=1 To n
		If EntityName(GetChild(TG_camera\camera,i))="pixiespace" 
			magic=GetChild(GetChild(TG_camera\camera,i),1)
		EndIf
	Next
	If magic=0
		magic=CreatePivot(TG_camera\camera)
		NameEntity(magic,"pixiespace")
		aspect#=Float(viewheight)/viewwidth
		PositionEntity magic,-1,aspect,1 
		scale#=2.0/viewwidth 
		ScaleEntity magic,scale,-scale,-scale 
		magic=CreatePivot(magic)
		PositionEntity magic,-.5,-.5,0
	EndIf
	
	; create sprite from texture as child of magic overlay	
	sprite=CopyMesh(TG_sprite)
	EntityParent sprite,magic		;cludge for blitz bug in createsprite(parent)
	scale#=0.2/viewwidth 
	ScaleMesh sprite,x_size*scale,y_size*scale,1
	ScaleTexture texture,width/x_size, height/y_size
	EntityTexture sprite,texture
	EntityFX sprite,1

	Return sprite
End Function

; UI control
Function TG_Draw_UI()
	; cam is a pointer to the scene camera
	UpdateWorld
	RenderWorld
	
	PositionEntity TG_pointer\sprite,MouseX(),MouseY(),UI_distance+20
	
	CameraProjMode (Scene_cam,0)
	CameraProjMode (TG_camera\camera,2)
	
	RenderWorld
	
	CameraProjMode (Scene_cam,1)
	CameraProjMode (TG_camera\camera,0)
End Function

; Misc functions
Function texture_mask_colour(texture,r1,g1,b1)
	buf= TextureBuffer(texture)
	LockBuffer buf
	For loop=0 To TextureWidth(texture)-1
		For loop1=0 To TextureHeight(texture)-1

			RGB1=ReadPixelFast(loop,loop1,TextureBuffer(texture)) ; read the RGB value from the texture
			r=(RGB1 And $FF0000)Shr 16;separate out the red
			g=(RGB1 And $FF00) Shr 8;green
			b=RGB1 And $FF;and blue parts of the color
			a=255

			If r=r1 And g=g1 And b=b1; check RGB lies with the tolerance
				a=0
			End If

			newrgb= (a Shl 24) Or (r Shl 16) Or (g Shl 8) Or b ; combine the ARGB back into one value

			WritePixelFast(loop,loop1,newrgb,buf); write back to the texture
		Next
	Next
	UnlockBuffer buf
End Function


Here's an example program that uses it, with a mouse pointer and two 'buttons' (just 2D sprites).

; Example of using the UI code.
Include "_lib_ToodeeGooey.bb"

;Graphics3D 800,600,0,0
Graphics3D 1024,768,0,1
TG_Initialise()
TG_SetPointer("textures\pointer.png")

; Add a 'button' to the 2D UI. "texelchallenge.png" is a 128x128 checkered B&W square to prove pixel-perfect textures
Button_texture=LoadTexture("textures\texelchallenge.png")
Button_sprite=TG_Create_Sprite(Button_texture,40,120)
PositionEntity Button_sprite,400,200,UI_distance+2

; Add another button with alpha blending
Button_2_texture=LoadTexture("textures\texelchallenge.png")
Button_2_sprite=TG_Create_Sprite(Button_2_texture)
PositionEntity Button_2_sprite,500,200,UI_distance+2
EntityAlpha Button_2_sprite,0.75

;#Region *** Create scene with random 3D junk
	Scene_cam=CreateCamera()
	PositionEntity Scene_cam,0,0,0
	CameraZoom Scene_cam,2
	
	Scene_light=CreateLight(2,Scene_cam)
	LightColor Scene_light,64,64,64
	PositionEntity Scene_light,100,0,-100
	
	For n=0 To 150
		cube=CreateCube()
		ScaleEntity cube,Rnd(1,10),Rnd(1,10),Rnd(1,10)
		PositionEntity cube,Rnd(-200,200),Rnd(-200,200),Rnd(-200,200)
		EntityColor cube,Rnd(0,2)*128,Rnd(0,2)*128,Rnd(0,2)*128
		EntityShininess cube,1
	Next
;#End Region

While Not KeyHit(1)
	TurnEntity Scene_cam,0.01,0.005,0.02
	TG_Draw_UI()
	Flip False
Wend


You will need textures for the example obviously. Pointer was a 32x32 hand with transparent background. Anyone and their mother can easily create a basic UI from this, by checking for button clicks based on sprite positions. I use a button type with the structure...

Type TG_button
; Individual 'sprites' for controls
Field sprite% ; Pointer to rectangle mesh
Field texture% ; pointer to texture
Field pos_x% ; x position
Field pos_y% ; y position
Field siz_x% ; x size
Field siz_y% ; y size
Field ref_num% ; Reference number
Field state% ; State, relating to anim number
End Type

I use a Create_Button() function that loads a texture into button\texture, followed by "button\sprite=TG_Create_Sprite(button\texture). Changing this design to incorporate 3D meshes as buttons shouldn't be too hard, and maybe add a String field with an animation string, like model movement?

Shifty Geezer

Very interesting technique. I was expecting some negative performance, but, it operated fast and smooth. Good Work! Thanx for sharing.

Sharing's what's driving us forwards. I'd have no code at all if others didn't share their insights and knowhow!

I'm progressing very well. Single surface sprites are in! Pointer Event Detection is In! WIP Updated. Check the Blitz3D Open Dev Projects link below.

[img http://techlord.blackeve.com/ssspp.jpg]
A. 2D/3D
B. 3D/2D
C. 2D/2D
D. 3D/3D

Cast your vote here - hehe.

Single-Surface Sprite Hide, Show, and Order.

Hiding Single Surface Sprites is tricky. Using HideEntity is not an option. I've to use vertexalpha but the triangles continue to register as being rendered. Looking for ideas.

Ordering Single Surface Sprites is tricky too. From what I can see, Blitz draws the Single Surface Sprites based on the order they were created. This presents a problem with gizmos when It comes to display the gizmo(s) that has focus. Looking for ideas here too.

Even if you put the triangles off screen they are still rendered. If one part of a surfaces is showing, the whole surface is rendered. Either reuse the quads, OR, rebuild the surface from scratch.

As to ordering the quads, unless alpha is used, they are drawn in the order of distance. You could move the quads slightly forward. This however, will probably have a negative impact on the pixel perfect code.

Thanks Ross C,

I will give your suggestions a try.

Ross, to handle ordering im going to swap contents with the [i]last[i] sprite when the gizmo changes focus. Altering the position did negatively effect pixel perfect resolution.

Why not use FlipMesh() to invert the normals and cull the backface of the sprite?

Ross : I don't know what system Frank's using but certainly in my 2D system I can reposition sprites in 3D without affecting pixel-perfect drawing. That's how I achieve z-ordering.

Shifty Geezer

I'm working with Single Surface Sprites. You have to directly manupulate the Sprites vertices and texture coords to translate, move, rotate, etc. Unfortunately, there is no TriangleOrder command:(

Well, if you move a quad or sprite with a texture that's pixel perfect, you will be messing up the ratio or whatever it is that is used to acheive pixel perfectness.