GUI in 3d

BlitzMax Forums/MiniB3D Module/GUI in 3d

kronholm(Posted 2007) [#1]
Forgive me, I am but a lowly newbie in the world of 3d programming, but I would be glad if anyone could help me a bit along here. I searched and only came up with one solution, described below, but that spawned another question.

I wish to create a FPS style game, at some point when my skills are good enough, but what is the best method of making a GUI the player sees? For instance inventory, hitpoints etc. displayed on the screen at all times.

I read somewhere it was best to use seperate poly planes and dedicated textures for it, that seems like a good idea I guess. But would these poly planes then be constricted to the camera via parenting?

Basically I'm looking for the best way to do this, I know it's a simple question but bear with me. Also if anyone can point me to some resources (preferably online, I hate books), on general 3d game design theory, such as the question posted above, I'd be even more appreciative :)

Maybe there's a unique way in bmax + minib3d to approach the gui, for instance having a regular bmax canvas in front of the minib3d graphics3d window?

All the best,
Dan


simonh(Posted 2007) [#2]
Sprites parented to the camera, and positioned just in front of it are probably your best bet.


kronholm(Posted 2007) [#3]
And there's no chance that the sprite will somehow lag away from the camera during intense action and whatnot?

Just curious how it's done in all other games..


Barbapapa(Posted 2007) [#4]
why not simply create a new camera simply for the GUI and switch between both.


bradford6(Posted 2007) [#5]
why don't you knock up a simple example and try it out?
we can discuss it here...


Chris C(Posted 2007) [#6]
thats a good idea bradford6 why dont you? ;p

just a thought but wouldnt it be easier to render all the 3d stuff then just use pure max2d to render your 2d content like scores etc?

I keep meaning to do a true 3d gui a bit like in sauerbraten, but somehow never get round to it


bradford6(Posted 2007) [#7]
OK Chris, here you go :)

EDIT: Changed entity to a sprite and added a 'weapon' sprite to the hud.
I also added a bunch of comments that will hopefully help.

Kronhelm, play around with this.





kronholm(Posted 2007) [#8]
Oh my god Bill, I think I love you. Just what I was looking for (made a quick compile). I will dissect immediately to learn from it, THANK YOU!


Chris C(Posted 2007) [#9]
problem is you're clearing the whole backbuffer twice each frame, at least experiment with rendering 3d with minib3d and then using max2d for scores etc, it gonna be a lot faster


kronholm(Posted 2007) [#10]
That was also my idea but I have no idea how to implement that? I mean drawing 2d max stuff on the graphics3d canvas


Chris C(Posted 2007) [#11]
was under the impression that max 2d worked off the bat
but its easy enough to use gl stuff

in this example I stole some code from brls graphics to enable orthographic "mode" (ie non perspective)



You should only use textures drop backbuffer renders as a very last resort.

its easy enough to use raw opengl or nick bits of code to do what you want and FAR faster


bradford6(Posted 2007) [#12]
That is a nice example Chris.


regarding my example:
You do not have to clear the backbuffer. That was just to show how to render to texture (to render the topdown map) there are 100s of ways to do this.

you can affix multiple sprites to the camera, or even affix a 3D HUD model (like a cockpit) and it will rotate with the camera movements.

One thing to try is to put actual 3D models in there as HUD elements (not sprites). I'll knock up a demo of what I mean later. I am currently making Homemade pizza with my kids. gotta get the water temp just right of the yeast won't activate...


klepto2(Posted 2007) [#13]
For those, where the 'max2d in minib3d' isn't currently working. It seems that I have forgotten 1 simple command which has to be included at the top of the RenderWorld() Function.

At least there is a simple workaround without rebuilding the whole module. Add the following right before the RenderWorld()command in your main loop:

glDisable(GL_TEXTURE_2D)


Or add this at the top of the RenderWorld() function in TGlobal.bmx and rebuild the module.
That seems to bugfix a lot of the 2d bugs.


bradford6(Posted 2007) [#14]
Thanks Klepto.

OK , here you go. The water volume in the cylinder will continuously decrease, when it gets toa certain point it will turn red. The idea is a visual representation of something (health, water, mana , sexual potency , whatever. depends on the game (although I am not sure I want to see a sexual potency icon !) )

The idea is to be creative and make a symbol that is consistent with the them of your game and conveys alot of meaning ( a picture *can be* worth a thousand words)





klepto2(Posted 2007) [#15]
Replace the Hud3D part and Hud3DVolume part with the following:
' Create the 3D Cylinder Volume Object that will be our visual referenc for Health
		temp.HUD3DVolume = CreateCylinder(8,1,temp.HUD3D)
			EntityColor temp.HUD3DVolume , 0,00,100 ' Blue
			EntityAlpha temp.HUD3DVolume,0.75
			ScaleEntity temp.HUD3DVolume , 0.175,0.175,0.175,1
			temp.Volume = 0.175
			EntityOrder temp.Hud3DVolume,0
			
		
		' this is a special camera that we will use to render the HUD MAP
		temp.HUDCam:Tcamera =CreateCamera()
			RotateEntity temp.HUDCam,90,0,0
			PositionEntity temp.HUDCam,0,20,0
			CameraViewport temp.HUDCam,0,0,128,128
			CameraClsColor temp.HUDCam,0,0,0
			'CameraZoom temp.HUDcam,0.75
			CameraClsColor temp.HUDCam , 0, 0, 200
			
			CameraClsMode temp.HUDCam,False,True


this keeps the Hud always in front of every other object.


bradford6(Posted 2007) [#16]
thanks Klepto.
try
EntityOrder temp.Hud3D, -1
EntityOrder temp.HUD3DVolume , -1


as well. this turns off Z sorting and in this case always draws those things on top.


Oldbone(Posted 2007) [#17]
Forgive me - I'm new to 3d.

But, I poured over your code and I can't see where you actually "drew" the "ground"...

If someone could point me there, I'd very much appreciate it!


impixi(Posted 2007) [#18]
Oldbone,

The ground in the example is simply a cube stretched significantly in the x and z directions and positioned appropriately:

box = CreateCube()
ScaleEntity box,240,0.5,240
EntityColor box , Rnd(0,200) , Rnd(0,200) , Rnd(0,200)
PositionEntity box ,-120,0,-120
EntityType box ,2

It is then drawn along with all the other cubes whenever the Renderworld command is issued. (Every object when created or loaded is added automatically to the rendering list.)