Pergunta

Fundo: Estou usando o Wrapper Slimdx C# para o DirectX e estou desenhando muitos sprites 2D usando a classe Sprite (tradicionalmente da extensão Direct3DX nas DLLs subjacentes). Estou desenhando várias centenas de sprites para a tela de uma só vez, e o desempenho é incrível-no meu quad core, está usando algo como 3-6% do processador para todo o meu jogo, incluindo lógica para mais de 10.000 objetos, ai Rotinas em um segundo fio, etc, etc. Então, claramente os sprites estão sendo desenhados usando aceleração completa de hardware, e tudo é como deveria ser.

Questão: O problema ocorre quando começo a introduzir chamadas para a classe de linha. Assim que desenho 4 linhas (para uma caixa de seleção de arrasto), o uso do processador Skyrockets para 13-19%. Isso é com apenas quatro linhas!

Coisas que tentei:

  1. Deslocando a linha Antialiasing Off and On.
  2. Desligando e ligando as glas.
  3. Chamando manualmente a linha.BEGIN e LINE.END em torno das minhas chamadas para desenhar.
  4. Omitindo todas as chamadas para line.begin e line.end.
  5. Garantir que minhas chamadas para linha.Draw não estejam dentro de um sprite.BEGIN / SPRITE.END BLOCO.
  6. Chamando a linha.
  7. Renderizando 4 linhas ou renderizando 300.
  8. Desligando toda a renderização do sprite e o texto, e apenas deixando a renderização da linha para 4 linhas (para ver se isso era algum tipo de problema de mudança de modo).
  9. A maioria das combinações do exposto.

Em geral, nenhum deles teve um impacto significativo no desempenho. O número 3 reduziu o uso do processador em talvez 2%, mas mesmo assim ainda é 8% ou mais mais alto do que deveria. O mais estranho é que o número 7 de cima teve um impacto absolutamente zero no desempenho - foi tão lento com 4 linhas quanto com 300. A única coisa que posso imaginar é que isso está sendo executado em software por algum motivo, e/ou que está fazendo com que a placa gráfica alterne continuamente entre algum tipo de modos de desenho.

Abordagem Matrix:

Se alguém souber de alguma correção para a edição acima, eu adoraria ouvi -lo!

Mas estou supondo que isso possa ser apenas um problema dentro do DirectX em geral, por isso tenho seguido outra rota-fazendo minha própria linha baseada em Sprite. Essencialmente, eu tenho uma imagem branca de 1px e estou usando a cor difusa e as transformações para desenhar as linhas. Isso funciona, em termos de desempenho-desenhando 300 das "linhas" como essa me coloca na faixa de desempenho de utilização de processadores de 3-6% que estou procurando no meu quadche.

Eu tenho dois problemas com minha técnica de linha de pixels-stretch, com a qual espero que alguém mais conhecedor sobre transformações possa me ajudar. Aqui está o meu código atual para uma linha horizontal:

    public void DrawLineHorizontal( int X1, int X2, int Y, float HalfHeight, Color Color )
    {
        float width = ( X2 - X1 ) / 2.0f;
        Matrix m = Matrix.Transformation2D( new Vector2( X1 + width, Y ), 0f, new Vector2( width, HalfHeight ),
            Vector2.Zero, 0, Vector2.Zero );
        sprite.Transform = m;

        sprite.Draw( this.tx, Vector3.Zero, new Vector3( X1 + width, Y, 0 ), Color );
    }

Isso funciona, na medida em que desenha linhas principalmente do tamanho certo, principalmente no local certo na tela. No entanto, as coisas parecem mudar para a direita, o que é estranho. Não tenho certeza se minha abordagem matricial está certa: só quero escalar um sprite 1x1 por uma quantidade de pixels horizontalmente e uma quantidade diferente verticalmente. Então eu preciso poder posicioná-los-pelo ponto central está bem, e acho que é isso que vou ter que fazer, mas se eu pudesse posicioná-lo por parte superior esquerda, isso seria ainda melhor. Parece um problema simples, mas meu conhecimento de matrizes é bastante fraco.

Isso ficaria em linhas puramente horizontais e puramente verticais funcionando para mim, que é a maior parte da batalha. Eu poderia viver com isso e usar algum outro tipo de gráfico em locais que atualmente estou usando linhas angulares. Mas seria muito bom se houvesse uma maneira de desenhar linhas angulares usando essa abordagem de pixel esticada. Em outras palavras, desenhe uma linha de 1,1 para 7,19, por exemplo. Com a rotação da matriz, etc., parece que isso é viável, mas não sei por onde começar além de adivinhar e verificar, o que levaria uma eternidade.

Toda e qualquer ajuda é muito apreciada!

Foi útil?

Solução

Parece uma barraca de pipeline. Você está alterando algum modo entre renderizar sprites e renderizar linhas, que força a placa gráfica a esvaziar seu pipeline antes de começar com o novo primitivo.

Antes de adicionar as linhas, esses sprites eram tudo o que você renderizou ou já havia outros elementos na tela, já usando outros modos?

Outras dicas

Ok, eu consegui fazer com que as linhas horizontais funcionassem após muita experimentação. Isso funciona sem a estranha compensação que eu estava vendo antes; O mesmo princípio também funcionará para linhas verticais. Este tem muito Melhor desempenho do que a classe de linha, então é isso que vou usar para linhas horizontais e verticais. Aqui está o código:

    public void DrawLineHorizontal( int X1, int X2, int Y, float HalfHeight, Color Color )
    {
        float width = ( X2 - X1 );
        Matrix m = Matrix.Transformation2D( new Vector2( X1, Y - HalfHeight ), 0f, new Vector2( width, HalfHeight * 2 ),
            Vector2.Zero, 0, Vector2.Zero );
        sprite.Transform = m;

        sprite.Draw( this.tx, Vector3.Zero, new Vector3( X1, Y - HalfHeight, 0 ), Color );
    }

Eu gostaria de ter uma versão disso que funcionaria para linhas em ângulos também (como mencionado acima). Alguma sugestão para isso?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top