ID3DXFont and Depth

Started by
8 comments, last by ms291052 18 years, 9 months ago
Is there any way to specify a Z coordinate at which ID3DXFont renders? I imagine it's in screen space and thus would use Z coords in the set [0.0, 1.0) but I can't find any way to do it since the only positional argument is a RECT. Anyone have any ideas? Thanks, ms
Advertisement
bump
Since all the transforms are handled through the font's ID3DXSprite interface, you could try using ID3DXSprite::SetTransform() before drawing text. However, the ID3DXFont interface might set its own transforms before drawing text, meaning that your transform would be erased. I think I used the SetTransform() method when I made a sprite engine, though, and it worked for setting the Z depth of the sprites. I used D3DXMatrixTranslation(mat,0,0,zdepth); to generate the matrix and passed it into SetTransform().

If using SetTransform() doesn't work, well, the only way to draw your text in a specific Z order would be to sort it yourself, and draw from back to front.
_______________________________________________________________________Hoo-rah.
Quote:Original post by Drakex
Since all the transforms are handled through the font's ID3DXSprite interface, you could try using ID3DXSprite::SetTransform() before drawing text. However, the ID3DXFont interface might set its own transforms before drawing text, meaning that your transform would be erased. I think I used the SetTransform() method when I made a sprite engine, though, and it worked for setting the Z depth of the sprites. I used D3DXMatrixTranslation(mat,0,0,zdepth); to generate the matrix and passed it into SetTransform().

If using SetTransform() doesn't work, well, the only way to draw your text in a specific Z order would be to sort it yourself, and draw from back to front.


Using ID3DXSprite::SetTransform() does indeed work for ID3DXFont.
Actually SetTransform doesn't help since I'm working in screen space (Pretransformed [RHW] coordinates). I managed to hack together a little solution where it draws the text to a texture with a purple (0xFFFF00FF) background and white text. Then I can use ID3DXSprite to render the texture, remove the purple with colorkeying, then use the modulation color parameter of ID3DXSprite::Draw to make it the right color. And of course ID3DXSprite::Draw takes a 3D position that includes a nice Z component.

Thanks for the input guys, and if anyone has any other suggestions, please post a reply!
Quote:Original post by ms291052
Actually SetTransform doesn't help since I'm working in screen space (Pretransformed [RHW] coordinates). I managed to hack together a little solution where it draws the text to a texture with a purple (0xFFFF00FF) background and white text. Then I can use ID3DXSprite to render the texture, remove the purple with colorkeying, then use the modulation color parameter of ID3DXSprite::Draw to make it the right color. And of course ID3DXSprite::Draw takes a 3D position that includes a nice Z component.

Thanks for the input guys, and if anyone has any other suggestions, please post a reply!


Why should it matter that you're in screen space? Unless you specify otherwise, calling ID3DXSprite::Begin() automatically switches to "screen space" mode anyway. SetTransform() works perfectly fine, here's a snippet:

void nxt::Direct3D::DrawText(const float x, const float y, const std::string& text, const nxt::Color& color, const float depth) const{		D3DXMATRIX positionMatrix;		D3DXMatrixTranslation(&positionMatrix, x, y, depth);	m_d3dSprite->SetTransform(&positionMatrix);	m_d3dFont[m_fontID]->DrawText(m_d3dSprite, text.c_str(), -1, NULL, DT_LEFT | DT_NOCLIP,	ToD3DColor(color));}


The valid values for the z coordinate (the depth) are [0, 1], with 0 being the closest and 1 being the farthest.

EDIT: Also, make sure ID3DXSprite::Begin() is being passed D3DXSPRITE_SORT_DEPTH_FRONTTOBACK and not being passed D3DXSPRITE_SORT_TEXTURE. D3DXSPRITE_SORT_TEXTURE seems to ignore the z coordinates specified and gives every texture their own seemingly random depth.
Here's my text class's Render method:

void Render(){	Point AbsPos = GetAbsPosition(); //Gets the absolute position of this text object	LPD3DXSPRITE sprite;	D3DXCreateSprite(m_pD3D->m_pd3dDevice, &sprite); //Create a sprite	D3DXMATRIX m; //Setup the transforms	D3DXMatrixTranslation(&m, AbsPos.x, AbsPos.y, m_Z);	sprite->SetTransform(&m);	RECT r = {0, 0, 800, 600}; //The whole window, just to test	m_pD3D->GetFont()->DrawText(sprite, m_Caption.c_str(), -1, &r, DT_LEFT, color); //Draw	sprite->Release(); //Cleanup}


I know I create and release the sprite every frame and all that; this is just a prototype to see if it works. When I do this the text still appears on top of everything else, including opaque objects with a lower z-value. When I use the render-to-texture method it works just fine.

I was under the impression that the whole point of RHW coords is that they are pre-transformed and thus aren't affected by any other transforms. Am I incorrect?

Please correct me if I've done something wrong with the above code, but I'm afraid it simply doesn't seem to go to any depth value other than 0.0.

Thanks for your help, load_bitmap_file, and further suggestions are, of course, appreciated.

ms
Quote:When I do this the text still appears on top of everything else, including opaque objects with a lower z-value


Wait.. so you want to draw the text interleaved with (or behind) 3D objects? I'm not sure if that's entirely possible with ID3DXFont. You can certainly change the overall rendering order (by rendering text first, and then rendering objects), but to render text in a 3D scene, I don't know if that's possible with ID3DXFont.

What exactly are you aiming to do?
_______________________________________________________________________Hoo-rah.


Quote:Original post by Drakex
Quote:When I do this the text still appears on top of everything else, including opaque objects with a lower z-value


Wait.. so you want to draw the text interleaved with (or behind) 3D objects? I'm not sure if that's entirely possible with ID3DXFont. You can certainly change the overall rendering order (by rendering text first, and then rendering objects), but to render text in a 3D scene, I don't know if that's possible with ID3DXFont.

What exactly are you aiming to do?


If what Drakex says is correct, i.e. drawing text behind other 3d objects then I don't think the SetTransform() isn't going to work unless all the objects are between [0, 1] on the z-axis, and assuming you're working in 3d, they won't be. I guess you'd have to call the draw to the text first and then the other stuff manually sorted outself as Drakex said.

If you're not working with 3d, then try calling sprite->Begin(D3DXSPRITE_ALPHABLEND | D3DXSPRITE_SORT_DEPTH_FRONTTOBACK) before you draw the text.

That's all I can think of right now.
Well darn, I had simply forgotten to call Begin and End. With them it seems to work pretty well. Thank you to everyone for your help, especially load_bitmap_file.


By the way, this is all for a HUD type of thing, so it's in no way interleaved with 3D objects, but it is interleaved with many layers of 2D objects in a fashion that is approaching almost GUI-ness.

Thanks again,

ms

This topic is closed to new replies.

Advertisement