   ID3DX10Font question
  I have searched the forums trying to find an answer to this question, but I couldn't find a solution. My problem is this. I have a ID3DX10Font object and I am drawing text with it. My scene consists of a spinning textured cube and I want to draw the fps in the upper left corner of the frame. I can draw the textured cube just fine. When I try to add  the text in the upper left corner my cube disappears and the text is not drawn. When I only draw the text and not the cube the text appears. So there is a problem with trying to draw both in the same frame.I figure that i need to save some sort of state before i call DrawText and then set that state back again after the call as I am certain that the DrawText function of ID3DX10Font changes certain states. I have tried resetting the input layout every frame as was suggested in a thread here, but that has not worked.This is my draw function:void DX10Device::drawString( const String& szText, RECT rBounds ) {    if ( !m_pFont )   throw std::exception( "Unable to draw string. No font set." );    m_pFont->getFont()->DrawText( m_pSprite, szText.c_str(), szText.length(), &rBounds, DT_LEFT, D3DXCOLOR( Color::WHITE ) );}m_pSprite is a ID3DX10Sprite that has been intialized and m_pFont->getFont() returns the ID3DX10Font object. ID3DX10Sprite->Begin() has been called before this method call as well.Again, I think I need to save some state before the call to DrawText, but I'm not sure what state exactly. Any suggestions?Thanks[Edited by - dustin10 on May 14, 2009 9:54:24 AM]
  Are you calling sprite->End() after the drawString() method?;Quote:Original post by dustin10I have searched the forums trying to find an answer to this question, but I couldn't find a solution. My problem is this. I have a ID3DX10Font object and I am drawing text with it. My scene consists of a spinning textured cube and I want to draw the fps in the upper left corner of the frame. I can draw the textured cube just fine. When I try to add  the text in the upper left corner my cube disappears and the text is not drawn. When I only draw the text and not the cube the text appears. So there is a problem with trying to draw both in the same frame.I figure that i need to save some sort of state before i call DrawText and then set that state back again after the call as I am certain that the DrawText function of ID3DX10Font changes certain states. I have tried resetting the input layout every frame as was suggested in a thread here, but that has not worked.This is my draw function:*** Source Snippet Removed ***m_pSprite is a ID3DX10Sprite that has been intialized and m_pFont->getFont() returns the ID3DX10Font object. ID3DX10Sprite->Begin() has been called before this method call as well.Again, I think I need to save some state before the call to DrawText, but I'm not sure what state exactly. Any suggestions?ThanksI still can't image how many people fall into this thing (me too when i began XD).It is a normal behaviour, your font object is changing some state that doesn't allow you to render the cube. Differently from the DX9 object the DX10 one doesn't restore the states.You need to be sure to set all the states, input layout, typology, etc.. accordingly before any kind of draw of 3d geometry.If you need more information just post the code of the draw of the textured cube with all the set of states/input layout etc.. and i can tell you what's missing.   ;Quote:Original post by feal87I still can't image how many people fall into this thing (me too when i began XD).It is a normal behaviour, your font object is changing some state that doesn't allow you to render the cube. Differently from the DX9 object the DX10 one doesn't restore the states.You need to be sure to set all the states, input layout, typology, etc.. accordingly before any kind of draw of 3d geometry.If you need more information just post the code of the draw of the textured cube with all the set of states/input layout etc.. and i can tell you what's missing.Ok here is all of the drawing code:// draw the framevoid DemoApplication::frame( void ) {    ...    m_pDeviceController->getDevice()->clear( true, true, true );    m_pDeviceController->getDevice()->beginFrame();    // m_pScene only contains one node which is the Cube    m_pScene->draw( m_pDeviceController->getDevice() );    renderStats();    m_pDeviceController->getDevice()->endFrame();    m_pDeviceController->getDevice()->present();    ...}// render fps to the screenvoid DemoApplication::renderStats( void ) {    std::stringstream ss;    ss << "Stream Demo\n" << floor( 1.0f / m_fFrameElapsed ) << " fps";    RECT r;    SetRectEmpty( &r );    m_pDeviceController->getDevice()->measureString( ss.str().c_str(), &r );    m_pDeviceController->getDevice()->drawString( ss.str().c_str(), &r );}// cube draw functionvoid Cube::update( Device* pDevice ) {   ...    // setVertexBuffer just sets the m_pActiveVertexBuffer of the device    pDevice->setVertexBuffer( 0, m_pVertexBuffer );    pDevice->setTexture( "CrateTexture", m_pTexture );    pDevice->drawIndexed( m_pIndexBuffer, m_iNumIndices, 0 );    SceneNode::update( pDevice );}// the cube uses my device interface's drawIndexed functionvoid DX10Device::drawIndexed( IndexBuffer* pIndexBuffer, int iNumIndices, int iOffset ) {    CGpass cgPass = cgGetFirstPass( m_cgTechnique );    setupDeviceForRendering( &cgPass );    ID3D10Buffer* pBuffer = ( (DX10IndexBuffer*) pIndexBuffer )->getBuffer();    m_pD3DDevice->IASetIndexBuffer( pBuffer, DXGI_FORMAT_R32_UINT, iOffset * pIndexBuffer->getIndexSize() );    cgSetMatrixParameterfr( m_cgWorldMatrix, m_matWorld );    cgSetMatrixParameterfr( m_cgViewMatrix, m_matView );    cgSetMatrixParameterfr( m_cgProjectionMatrix, m_matProjection );    while ( cgPass ) {   cgSetPassState( cgPass );    m_pD3DDevice->DrawIndexed( iNumIndices, 0, 0 );    cgResetPassState( cgPass );cgPass = cgGetNextPass( cgPass );    }}// sets up the device for renderingvoid DX10Device::setupDeviceForRendering( CGpass* pPass ) {    if ( !m_pActiveVertexBuffer )   return;    ID3D10Buffer* pBuffer = ( (DX10VertexBuffer*) m_pActiveVertexBuffer )->getBuffer();    VertexFormat vfFormat = m_pActiveVertexBuffer->getVertexFormat();    std::vector<D3D10_INPUT_ELEMENT_DESC> vElemDescs;    for ( int i = 0; i < vfFormat.getNumElements(); ++i ) {   const VertexElement& ve = vfFormat.getElementAt( i );D3D10_INPUT_ELEMENT_DESC elemDesc;ZeroMemory( &elemDesc, sizeof( D3D10_INPUT_ELEMENT_DESC ) );elemDesc.SemanticIndex = ve.getIndex();elemDesc.SemanticName = ve.getName().c_str();elemDesc.AlignedByteOffset = D3D10_APPEND_ALIGNED_ELEMENT;elemDesc.InputSlotClass = D3D10_INPUT_PER_VERTEX_DATA;switch ( ve.getSize() ) {    case 4:   elemDesc.Format = DXGI_FORMAT_R32_FLOAT;break;    case 8:   elemDesc.Format = DXGI_FORMAT_R32G32_FLOAT;break;    case 12:   elemDesc.Format = DXGI_FORMAT_R32G32B32_FLOAT;break;    case 16:   elemDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;break;    default:   elemDesc.Format = DXGI_FORMAT_UNKNOWN;}vElemDescs.push_back( elemDesc );    }    ID3D10Blob* pSignature = cgD3D10GetIASignatureByPass( *pPass );    ID3D10InputLayout* pInputLayout = NULL;    HRESULT hr = m_pD3DDevice->CreateInputLayout( &vElemDescs[ 0 ], vElemDescs.size(), pSignature->GetBufferPointer(), pSignature->GetBufferSize(), &pInputLayout );    if ( FAILED( hr ) )   throw std::exception( "Unable to create input layout." );    m_pD3DDevice->IASetInputLayout( pInputLayout );    UINT uiStride = m_pActiveVertexBuffer->getVertexFormat().getSize();    UINT uiOffset = 0;    m_pD3DDevice->IASetVertexBuffers( 0, 1, &pBuffer, &uiStride, &uiOffset );    m_pD3DDevice->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST );}Again, everything works fine if i draw the fps and the cube separately. If you need any more info please let me know. Thanks for you help.;  Can you post the shader you are using for drawing that cube? From the code you posted i do not see any kind of problem. (and if you can also the measurestring and drawstring)P.S. Creating an input declaration each frame is a BAD thing to do. In fact CREATING anything during the draw of a frame is a bad thing, it is VERY slow.   ;Quote:Original post by feal87Can you post the shader you are using for drawing that cube? From the code you posted i do not see any kind of problem. (and if you can also the measurestring and drawstring)P.S. Creating an input declaration each frame is a BAD thing to do. In fact CREATING anything during the draw of a frame is a bad thing, it is VERY slow.I understand that it is very slow, but I am just trying to get things working correctly right now.Here is the shader: (I'm using the same shader for the D3D10, D3D9 and OpenGL implementations of my device interface, so you can just ignore the other techniques as they are not being used right now)sampler2D CrateTexture = sampler_state {    AddressU = Wrap;    AddressV = Wrap;};struct VS_INPUT {float3 position: POSITION;float2 tex0 : TEXCOORD0;};struct VS_OUTPUT {float4 position : POSITION;float2 tex0 : TEXCOORD0;};struct PS_OUTPUT {float4 color : COLOR;};float4x4 matWorld : WORLDMATRIX;float4x4 matView : VIEWMATRIX;float4x4 matProjection : PROJECTIONMATRIX;VS_OUTPUT vs( VS_INPUT input ) {VS_OUTPUT output;output.position = float4( input.position, 1.0 );output.position = mul( output.position, matWorld );output.position = mul( output.position, matView );output.position = mul( output.position, matProjection );output.tex0 = input.tex0;return output;}PS_OUTPUT ps( VS_OUTPUT input, uniform sampler2D crate : TEXUNIT0 ) {PS_OUTPUT output;output.color = tex2D( crate, input.tex0 );return output;}technique texture_dx10 {pass {AlphaBlendEnable = false;//CullMode = CCW;FillMode = Solid; VertexProgram = compile vs_4_0 vs();FragmentProgram = compile ps_4_0 ps( CrateTexture );}}technique texture_opengl {pass {AlphaBlendEnable = false;//CullFaceEnable = true;//FrontFace = CW;FillMode = Solid; VertexProgram = compile latest vs();FragmentProgram = compile latest ps( CrateTexture );}}technique texture_dx9 {pass {AlphaBlendEnable = false;//CullMode = CW;FillMode = Solid; VertexProgram = compile vs_3_0 vs();FragmentProgram = compile ps_3_0 ps( CrateTexture );}}Here are the measureString() and drawString() methods: (nothing special here)// measure stringvoid DX10Device::measureString( const String& szText, LPRECT pRect ) {    if ( !m_pFont )   throw std::exception( "Unable to measure string. No font set." );    m_pFont->getFont()->DrawText( m_pSprite, szText.c_str(), szText.length(), pRect, DT_CALCRECT | DT_LEFT, D3DXCOLOR( Color::WHITE ) );}// draw stringvoid DX10Device::drawString( const String& szText, LPRECT pRect ) {    if ( !m_pFont )   throw std::exception( "Unable to draw string. No font set." );    m_pFont->getFont()->DrawText( m_pSprite, szText.c_str(), szText.length(), pRect, DT_LEFT, D3DXCOLOR( Color::WHITE ) );};  I need you to do a test. Try putting null into the drawstring and measurestring sprite parameter like this :    m_pFont->getFont()->DrawText( 0, szText.c_str(), szText.length(), &rBounds, DT_LEFT, D3DXCOLOR( Color::WHITE ) );If it resolve the issue, you are not ending the sprite before drawing the 3D graphics. You should divide your draw in Sprite managed and non-Sprite managed.Remember that the Sprite class is only a dinamic vertex/index buffer that draw textured quads, the actual draw is not executed until you call the End in the sprite class.Using NULL as pointer to the sprite class you force the system to draw immediately the text. (it is slower so you should anyway use the sprite)EDIT : Obviously in the test you shouldn't do Sprite->Begin() Sprite->End() anymore.   ;Quote:Original post by feal87I need you to do a test. Try putting null into the drawstring and measurestring sprite parameter like this :*** Source Snippet Removed ***If it resolve the issue, you are not ending the sprite before drawing the 3D graphics. You should divide your draw in Sprite managed and non-Sprite managed.Remember that the Sprite class is only a dinamic vertex/index buffer that draw textured quads, the actual draw is not executed until you call the End in the sprite class.Using NULL as pointer to the sprite class you force the system to draw immediately the text. (it is slower so you should anyway use the sprite)EDIT : Obviously in the test you shouldn't do Sprite->Begin() Sprite->End() anymore.I commented out the Sprite->Begin() and Sprite->End() and substituted NULL for m_pSprite in the DrawText() calls.Now when I try to render both the cube and the text at the same time only the text renders where before nothing would render. Both still render perfectly if I do one or the other.Any other ideas? Should I be drawing all text BEFORE i draw any geometry? I am doing it after right now.;  Can you try with Pix to capture a frame where it only render the text and not the cube and see what happen at the rendering of the cube?If you post an executable i can do it for you and tell you exactly what's happening. :D   ;Quote:Original post by feal87Can you try with Pix to capture a frame where it only render the text and not the cube and see what happen at the rendering of the cube?If you post an executable i can do it for you and tell you exactly what's happening. :DCan you give me a link where I can get Pix?