Horde3D

Next-Generation Graphics Engine
It is currently 19.03.2024, 09:49

All times are UTC + 1 hour




Post new topic Reply to topic  [ 3 posts ] 
Author Message
PostPosted: 18.03.2012, 15:20 
Offline

Joined: 14.03.2012, 12:19
Posts: 3
Hey,

wanted to create a simple GameEngine component which could be used to show some sort of "gamer tag". Technically spoken, it should be able to display some overlay text exactly at the point where a GameEntity is currently rendered.

Image

For this purpose, I looked for a function within Horde3D to calculate window coordinates from given world coordinates, but couldn't find any. In Horde3DUtils, there are functions to pick a node at given window coordinates (PickRay, PickNode). So, I simply turned the PickRay function around:

Code:
DLLEXP void h3dutWorldToWindowCoordinates( H3DNode cameraNode, float x, float y, float z, float *nwx, float *nwy )
{
   // Get projection matrix
   Matrix4f projMat;
   h3dGetCameraProjMat( cameraNode, projMat.x );
   
   // Get camera view matrix
   const float *camTrans;
   h3dGetNodeTransMats( cameraNode, 0x0, &camTrans );      
   Matrix4f viewMat( camTrans );
   viewMat = viewMat.inverted();

   // Project
   Vec4f p = (projMat * viewMat) * Vec4f(x, y, z, 1);

   if (p.z == 0) {
      *nwx = Math::NaN;
      *nwy = Math::NaN;
   } else {
      p.x /= p.z;
      p.y /= p.z;

      // Transform from normalized device [-1, 1] to normalized window [0, 1] coordinates
      *nwx = 0.5f * p.x + 0.5f;
      *nwy = 0.5f * p.y + 0.5f;
   }
}


Using this, the text label can be displayed, for example, like this in the application's render function:
Code:
// get entity's world transformation
const float* trans = GameEngine::getEntityTransformation(GameEngine::entityWorldID("Player1"));

float wx, wy;

// calculate current window coordinates
h3dutWorldToWindowCoordinates(GameEngine::entitySceneGraphID(m_camID), trans[12], trans[13] + 2.5f, trans[14], &wx, &wy);

// show text, taking window aspect ratio into account
h3dutShowText( "Player1", wx * 4.0f/3.0f, 1.0f - wy, 0.04f, 0, 1.0f, 0.4f, _fontMatRes );


Now, is there some other way to achieve this (some way I missed in the Horde3D API)?
Particularly, is there some way to retrieve window coordinates from vertex shaders' output? This would be much more efficient than projecting the world coordinates on the CPU.

If the answer to these questions is "no" and "no", then I would propose to add the h3dutWorldToWindowCoordinates to Horde3DUtils. I think some users could make good use of it.

Best regards,

Christoph


Top
 Profile  
Reply with quote  
PostPosted: 20.03.2012, 00:33 
Offline
Engine Developer

Joined: 10.09.2006, 15:52
Posts: 1217
This projection is best done on the CPU, in general reading back data from the GPU is always problematic, as CPU and GPU run asynchronously for performance reasons.

It makes definitely sense to add a projection function to the Utils. In case you missed it, there is also a wiki entry which does basically the same (but divides by w which is more correct).


Top
 Profile  
Reply with quote  
PostPosted: 26.03.2012, 15:13 
Offline

Joined: 14.03.2012, 12:19
Posts: 3
Thanks, I wasn't aware of this wiki entry. You're right, dividing by w is a better solution. Also, checking for back projection is definitely not a bad idea. :roll:


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group