DirectX gerenciado: especificando a profundidade (ordem Z) de Sprites contendo textura e texto

StackOverflow https://stackoverflow.com/questions/7387598

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!

Foi útil?

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();
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top