[solved] Render 3d object at known 2d coordinates

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
sunside
Posts: 9
Joined: Tue May 25, 2010 4:13 pm

[solved] Render 3d object at known 2d coordinates

Post by sunside »

Hi everyone.

I need to create some sort of 3D HUD; Basically a rotating coordinate system (three calls to draw3Dline()) that shows the orientation of the user selected scene node (the active camera, in my case).

I also remember older games like Conflict Freespace, where the model of the targeted enemy ship was displayed in the upper right corner of the screen, showing it's current flight direction. I assume this would be possible with multiple viewports and cameras, but that would fill the background and I guess it should also be possible in a different way.

I tried to use getRayFromScreenCoordinates() for this purpose, but somehow it always returns the same ray starting point, the coordinates of the active camera, and then gives #QNAN for the target point, which isn't particularly helpful. :)

Any pointers to get me started?
Markus
Last edited by sunside on Thu May 27, 2010 12:15 am, edited 2 times in total.
ent1ty
Competition winner
Posts: 1106
Joined: Sun Nov 08, 2009 11:09 am

Post by ent1ty »

Render to texture
irrRenderer 1.0
Height2Normal v. 2.1 - convert height maps to normal maps

Step back! I have a void pointer, and I'm not afraid to use it!
sunside
Posts: 9
Joined: Tue May 25, 2010 4:13 pm

Post by sunside »

Ah, yes. I used the IGUIImage with setUseAlphaChannel(true) and that worked perfectly.

I have a problem with the render to texture part, though.
I followed tutorial 13 (Render to texture) and created a texture, a fixed camera and an FPS camera. In the main loop I begin the scene, set the target to the texture, select the fixed camera, draw some stuff and call drawAll(), then repeat it for the frame buffer and the FPS camera, calling drawAll() again.

When I do this, however, the screen gets cleared as I expect it to, but thenn all the things in the second part won't get displayed. Additionally, the mouse now moves the camera in the overlaid texture. If I comment out the first drawAll() -- the one in the render to texture part -- then, obvously, there's nothing in the texture (except the fill color) but the controls are okay.

Am I missing some vital thing?

Here's the code:

Code: Select all

	void GameEngine::OnSceneLoop(f32 elapsedTime) { 
		
		beginScene();

		video::IVideoDriver *driver = getDriver();
		scene::ISceneManager *smgr = getSceneManager();

		// Render to texture
		driver->setRenderTarget(renderTarget, true, true, video::SColor(0,0,0,255));
		smgr->setActiveCamera(renderTargetCamera);

		driver->setMaterial(getUnlitMaterial());
		driver->setTransform(video::ETS_WORLD, core::matrix4());
		driver->draw3DBox(core::aabbox3d<f32>(-0.5, -0.5, -0.5, 0.5, 0.5, 0.5));
		
		// If I comment this out, I get an empty texture.
		// If I leave it in, I get no scene and the FPS controls are messed up.
		smgr->drawAll();

		// Render to screen
		driver->setRenderTarget(video::ERT_FRAME_BUFFER, true, true, video::SColor(255,128,32,0));
		smgr->setActiveCamera(mainCamera);

		// Draw a cage around the main camera (for orientation)
		drawCameraOrientationCage(mainCamera);
		smgr->drawAll();

		// Display image
		gui::IGUIImage *image = getGUIEnvironment()->addImage(core::rect<s32>(5, 5, 55, 55));
		image->setUseAlphaChannel(true);
		image->setImage(renderTarget);
		renderGui();

		endScene();
	}
Edit:
I fear that there's something f***ed up. If I remove everything except beginScene(), drawAll() and endScene() and add nothing but an FPS camera and a cube node, then all I see is a short flickering cube, followed by fill color for the rest of the time. I don't get it.
sunside
Posts: 9
Joined: Tue May 25, 2010 4:13 pm

Post by sunside »

Things I learned today:

1.) camera->setNearValue(0) is evil
2.) I should call sceneManager->drawAll() first, then draw overlay lines (like bounding boxes)
3.) IGUIImage does not scale images by default; You have to tell it to do that.
4.) If you have to call draw3Dbox() etc. before drawAll(), then you have to set the view matrix of the current camera in addition to the world matrix.
5.) Creating the same GUI element 800 times per second leads to creating the same GUI element <20 times per second ... d'oh. :D

Oh boy ...
Last edited by sunside on Thu May 27, 2010 9:21 am, edited 1 time in total.
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

sunside wrote:1.) camera->setNearValue(0) is evil
Learning to Love your Z-buffer.

TL;DR: Always put zNear as far from the eye as you can tolerate.

:wink:
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
sunside
Posts: 9
Joined: Tue May 25, 2010 4:13 pm

Post by sunside »

Interesting read. I never looked at it this way! Thanks alot!

I wonder if it makes sense - generally - to use two render passes, one for distant objects and one for near objects with different zNear and zFar values. For example, zNear = 10, zFar = 100 for an indoor level, then zNear = 0.5, zFar = 10 for the player's gun.


edit: zFar = 10, instead of 2. TooLessCoffeeException.
Last edited by sunside on Sat May 29, 2010 3:17 pm, edited 1 time in total.
shadowslair
Posts: 758
Joined: Mon Mar 31, 2008 3:32 pm
Location: Bulgaria

Post by shadowslair »

sunside wrote: I wonder if it makes sense - generally - to use two render passes, one for distant objects and one for near objects with different zNear and zFar values. For example, zNear = 10, zFar = 100 for an indoor level, then zNear = 0.5, zFar = 2 for the player's gun.
Well, having two render passes would be a great waste of resources and quite senseless. And take a look what you proposed:
1st render pass: zNear=10 zFar=100 Level is rendered
2nd render pass zNear=0.5 zFar=2 Player weapon(?!) is rendered

Ok, how about all the objects in the 2 to 10 z interval?! When are they gonna be rendered? They will be ugly clipped.
These two values are simply the distances from the camera point, definig the near and far clip plane of the view frustum. Which highly depends on your world scale. You basically test and decide how many Irrlicht units we need to see and you set the far dist. If you get unwanted clipping of closeby objects, you decrease the near value. All precision, z-fighting etc. issues are coming from too big difference between the two values- like say 0.01 to 20000. Smaller difference means better precision. Simple as that.
"Although we walk on the ground and step in the mud... our dreams and endeavors reach the immense skies..."
sunside
Posts: 9
Joined: Tue May 25, 2010 4:13 pm

Post by sunside »

Nah, the 2/10 difference came from editing the post twice. :) That obviously that doesn't make sense, what I meant was 10...1000 and 2..10, for example. In the second pass the differences are much smaller, resulting in higher precision for close object. Of course you'd be disabling all "non-near" objects and only render close ones in the second pass.
Think FPS; Since the weapon is always close to the display, it should be rendered with the highest possible precision - hence the quesion, is something like that necessary or is the precision generally high enough?

What about an FPS game in a wide (outside) world? I know comparing the Cryengine to Irrlicht is a bit awkward anyway, but they must have experienced such a precision problem.

I'm just curious. :)
shadowslair
Posts: 758
Joined: Mon Mar 31, 2008 3:32 pm
Location: Bulgaria

Post by shadowslair »

Still, unless you`re experiencing z-fighting problems, which I highly doubt, you don`t even need to think of all this stuff. Again, rendering at two passes will be a waste of calculations IMO, because for example you`ll need to do one of these:
- to browse and check every node twice
- if you decide to put all nodes rendered at the first pass, not to test them twice, then keeping track of which you rendered already will waste some time too
- (...) some other method

And all this for "higher precision" of your weapon? If it`s only the weapon you`re worried about, then you can render it alone etc.
My advice as a noob is not to get too obsessed with this. If you get z-buffer issues for your gun, then sth with your model should`ve gone terribly wrong... :D If you`re that curious, you can always ask them. I`m pretty sure they never thought about that... :lol:
"Although we walk on the ground and step in the mud... our dreams and endeavors reach the immense skies..."
sunside
Posts: 9
Joined: Tue May 25, 2010 4:13 pm

Post by sunside »

Word. :D
Post Reply