Esta é uma tela do que está acontecendo apenas para que você possa obter um quadro de referência.
O problema que estou enfrentando é que meu jogo está desacelerando devido à quantidade de trocas de textura que estou fazendo durante minha chamada de empate. Como paredes, caracteres, pisos e todos os objetos estão em suas respectivas folhas de sprite que contêm esses tipos, por desenho de ladrilho, a textura carregada é trocada não menos de 3 a 5 ou mais vezes, enquanto ele alterna e desenha os sprites para que sejam estratificados adequadamente.
Agora, tentei juntar todos os objetos comuns em suas respectivas listas e, em seguida, usando o layerDepth, desenhando-os dessa maneira, o que melhora as coisas, mas o novo problema em que estou lidando tem a ver com a maneira como minhas portas / janelas são desenhados nas paredes. Ou seja, eu estava usando estênceis para limpar um bloco nas paredes desenhadas no formato da porta / janela, para que, quando a parede fosse desenhada, tivesse um buraco do tamanho de uma porta / janela.
Foi assim que meu desenho foi criado para paredes quando eu estava passando lado a lado em vez de agrupar objetos comuns.
- primeiro, verificaria se havia uma porta / janela nessa parede. Caso contrário, pularia todas as etapas e desenharia normalmente. De outra forma
- finalizar o spriteBatch atual
- Limpe os buffers com uma cor transparente para preservar o que já foi desenhado
- iniciar um novo spritebatch com configurações de estêncil
- desenhe a área da porta
- terminar o spriteBatch
- inicie um novo spritebatch que leve em consideração o estêncil definido anteriormente
- desenhe a parede que agora será desenhada com um buraco
- terminar esse spritebatch
- inicie um novo spritebatch com as configurações normais para continuar desenhando blocos
No desenho lado a lado, limpar os buffers de profundidade / estêncil não importava, pois eu não estava usando nenhuma layerDepth para organizar o que desenha sobre o que.
Agora que estou desenhando a partir de listas de objetos comuns, em vez de lado a lado, acelerou consideravelmente minha chamada, mas não consigo descobrir uma maneira de manter o sistema de estêncil para mascarar a área de uma porta ou janela será atraído para uma parede. A raiz do problema é que, quando eu finalizo um spriteBatch para alterar o DepthStencilState, ele nivela o RenderTarget atual e não há mais nenhuma classificação de profundidade para qualquer coisa desenhada mais abaixo na linha. Isso significa que as paredes sempre são desenhadas em cima de tudo, independentemente da profundidade ou do posicionamento no mundo do jogo e até uma em cima da outra, pois o estêncil precisa acontecer uma vez para cada parede que tem uma porta ou janela.
Alguém sabe uma maneira de contornar isso? Para resumir, eu preciso de uma maneira de desenhar, classificando as coisas pela profundidade da camada, além de poder estêncil / mascarar partes de sprites específicos.
Respostas:
Não conheço XNA suficiente para lhe dar uma solução adequada, mas posso lhe dar uma resposta geral.
O problema que você está tendo é o algoritmo do pintor . Especificamente, você precisa solicitar todas as coisas que deseja desenhar antes de poder desenhá-las. A maneira mais comum de evitar esse problema é com um buffer de profundidade. Curiosamente, isso também é chamado de buffer z, porque armazena os valores z no espaço da câmera.
No entanto, como você não possui Z (porque está escrevendo um jogo em 2D), não pode usar esta técnica. Ou você pode?
Considere o seguinte: uma projeção ortográfica não altera a perspectiva dos pontos nos pontos 3D. Isso é útil para itens como elementos da interface do usuário, porque você sempre deseja que eles sejam da mesma maneira.
O que eu sugiro é que você escreva um shader personalizado que use matrizes 3D e um valor de profundidade por vértice. Esse valor de profundidade deve ser usado para buffer de profundidade, mas não para projeção.
No pseudo-shadercode:
Depois de configurá-lo, você pode parar de se preocupar com a renderização dos objetos na ordem errada e, em vez disso, definir o valor da profundidade.
Agora você deve poder renderizar tudo em uma chamada de empate, sem se preocupar em criar seções da tela.
fonte