DirectX gerenciado: especificando a profundidade (ordem Z) de Sprites contendo textura e texto
-
29-10-2019 - |
Pergunta
Estou usando o DirectX gerenciado para tentar desenhar uma textura e um pedaço de texto na tela usando um Sprite.Infelizmente, se eu colocar o texto e a textura no mesmo sprite, a textura sobrescreve (sobrescreve?) O texto, independentemente da ordem em que faço os comandos de desenho.
Já que irei eventualmente intercalar texturas e texto, como faço para especificar uma ordem Z para esses sprites.Cada camada precisa estar em um sprite separado?
Aqui está o código atual:
m_device.BeginScene();
m_device.Clear(ClearFlags.Target, Color.Black, 1.0f, 0);
m_sprite.Begin(SpriteFlags.SortTexture | SpriteFlags.AlphaBlend);
// Switching the order of following two statements doesn't change the Z-Order!
m_sprite.Draw(m_texture, Vector3.Empty, new Vector3(0, 0, 0),
Color.White.ToArgb());
m_d3dFont.DrawText(m_sprite, m_text, x, y, color);
m_sprite.End();
m_device.EndScene();
m_device.Present();
Observação: o uso de SpriteFlags.SortDepthBackToFront ou SpriteFlags.SortDepthBackToFront não altera o comportamento.
Este é provavelmente um mal-entendido conceitual da minha parte, mas se o código for útil, aceitarei com gratidão exemplos em DirectX não gerenciado usando C ++ ou qualquer outra linguagem.
Muito obrigado antecipadamente!
Solução
Se você deseja alterar a ordem Z de renderização, você deve definir o valor Z no comando Desenhar.Se você definir tudo para 0, obterá todos os tipos de estranheza.Seu maior problema é que DrawText não permite que você defina um Z-Depth, que é todo tipo de lixo.
Portanto, sua única chance é usar ID3DXSprite :: SetTransform.Você precisa deslocar apenas a coordenada Z de volta com ela para a posição de pedido z relevante.Portanto, você pode definir suas transformações (assumindo que está usando matrizes de mundo de identidade) da seguinte forma (exemplo C ++)
D3DXMATRIX mat( 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, zOrder, 1.0f );
m_Sprite->SetTransform( &mat );
Você então continua passando uma posição de (0, 0, 0) para renderização e o texto também ganhará a profundidade correta para ordenação z.
Espero que ajude.
Outras dicas
Aqui está a resposta que eu (o autor da postagem) dei:
Goz forneceu a maioria das informações necessárias para resolver o problema.Essencialmente, para texturas, você pode especificar a ordem z usando o terceiro parâmetro do segundo Verctor3.A experimentação deixou claro que (1) a ordem z vai de 0,0 a 1,0, com 0,0 sendo o mais próximo e 1,0 sendo o mais distante.Qualquer coisa fora desse intervalo não aparece.
Para texto, porque não há oportunidade de especificar z na chamada, você precisa usar a sugestão de Goz de uma matriz de transformação.
No final, este é o código que usei.
m_device.BeginScene();
m_device.Clear(ClearFlags.Target, Color.Black, 1.0f, 0);
m_sprite.Begin(SpriteFlags.SortDepthFrontToBack | SpriteFlags.SortTexture | SpriteFlags.AlphaBlend);
// The "1.0f" is the z-order of texture1. This places it at the very back.
m_sprite.Draw(m_texture1, Vector3.Empty, new Vector3(0, 0, 1.0f),
Color.White.ToArgb());
// The text1 is placed at z-order 0.8f, in order to place it in front of texture1
Microsoft.DirectX.Matrix t = Microsoft.DirectX.Matrix.Identity;
t.Translate(new Vector3(0, 0, 0.8f));
m_sprite.Transform = t;
m_d3dFont.DrawText(m_sprite, m_text1, 200, 200, color1);
m_sprite.Transform = Microsoft.DirectX.Matrix.Identity;
// The "0.6f" is the z-order of texture2. This places it at the very back.
m_sprite.Draw(m_texture2, Vector3.Empty, new Vector3(220, 220, 0.6f),
Color.White.ToArgb());
// The text2 is placed at z-order 0.4f, in order to place it in front of texture2
t = Microsoft.DirectX.Matrix.Identity;
t.Translate(new Vector3(0, 0, 0.4f));
m_sprite.Transform = t;
m_d3dFont.DrawText(m_sprite, m_text2, 240, 240, color2);
m_sprite.Transform = Microsoft.DirectX.Matrix.Identity;
m_sprite.End();
m_device.EndScene();
m_device.Present();