2011-01-12 9 views
5

Ho sbattuto la testa contro questo problema per ore. Quello che voglio fare è disegnare un cubo, con trame diverse su ciascun lato; o più nello specifico, voglio essere in grado di specificare la texture che voglio per lato. Ho usato l'esempio here per iniziare, quindi ho tentato di svilupparlo ulteriormente, in modo da avere più di una texture. Tuttavia, indipendentemente da ciò che faccio, utilizza sempre l'ultima texture applicata all'effetto e non presta attenzione ai precedenti incarichi. Qui è la mia classe di forma:Disegno di un cubo strutturato con più lati in XNA 4.0

public class BasicShape { 

public Vector3 shapeSize; 
public Vector3 shapePosition; 
private VertexPositionNormalTexture[][] shapeVertices; 
private int shapeTriangles; 
private VertexBuffer shapeBuffer; 
public Texture2D topTexture; 
public Texture2D frontTexture; 
public Texture2D backTexture; 
public Texture2D leftTexture; 
public Texture2D rightTexture; 
public Texture2D bottomTexture; 

public BasicShape(Vector3 size, Vector3 position) { 
    shapeSize = size; 
    shapePosition = position; 
} 

private void BuildShape() { 
    shapeTriangles = 12; 

    shapeVertices = new VertexPositionNormalTexture[6][]; 
    for(int i = 0; i < 6; i++) { 
     shapeVertices[i] = new VertexPositionNormalTexture[6]; 
    } 

    Vector3 topLeftFront = shapePosition + 
    new Vector3(0.0f, 1.0f, 0.0f) * shapeSize; 
    Vector3 bottomLeftFront = shapePosition + 
    new Vector3(0.0f, 0.0f, 0.0f) * shapeSize; 
    Vector3 topRightFront = shapePosition + 
    new Vector3(1.0f, 1.0f, 0.0f) * shapeSize; 
    Vector3 bottomRightFront = shapePosition + 
    new Vector3(1.0f, 0.0f, 0.0f) * shapeSize; 
    Vector3 topLeftBack = shapePosition + 
    new Vector3(0.0f, 1.0f, 1.0f) * shapeSize; 
    Vector3 topRightBack = shapePosition + 
    new Vector3(1.0f, 1.0f, 1.0f) * shapeSize; 
    Vector3 bottomLeftBack = shapePosition + 
    new Vector3(0.0f, 0.0f, 1.0f) * shapeSize; 
    Vector3 bottomRightBack = shapePosition + 
    new Vector3(1.0f, 0.0f, 1.0f) * shapeSize; 

    Vector3 topLeftFront2 = shapePosition + 
    new Vector3(0.0f, 1.0f, 0.0f) * shapeSize; 
    Vector3 bottomLeftFront2 = shapePosition + 
    new Vector3(0.0f, 0.0f, 0.0f) * shapeSize; 
    Vector3 topRightFront2 = shapePosition + 
    new Vector3(1.0f, 1.0f, 0.0f) * shapeSize; 
    Vector3 bottomRightFront2 = shapePosition + 
    new Vector3(1.0f, 0.0f, 0.0f) * shapeSize; 
    Vector3 topLeftBack2 = shapePosition + 
    new Vector3(0.0f, 1.0f, 1.0f) * shapeSize; 
    Vector3 topRightBack2 = shapePosition + 
    new Vector3(1.0f, 1.0f, 1.0f) * shapeSize; 
    Vector3 bottomLeftBack2 = shapePosition + 
    new Vector3(0.0f, 0.0f, 1.0f) * shapeSize; 
    Vector3 bottomRightBack2 = shapePosition + 
    new Vector3(1.0f, 0.0f, 1.0f) * shapeSize; 

    Vector3 topLeftFront3 = shapePosition + 
    new Vector3(0.0f, 1.0f, 0.0f) * shapeSize; 
    Vector3 bottomLeftFront3 = shapePosition + 
    new Vector3(0.0f, 0.0f, 0.0f) * shapeSize; 
    Vector3 topRightFront3 = shapePosition + 
    new Vector3(1.0f, 1.0f, 0.0f) * shapeSize; 
    Vector3 bottomRightFront3 = shapePosition + 
    new Vector3(1.0f, 0.0f, 0.0f) * shapeSize; 
    Vector3 topLeftBack3 = shapePosition + 
    new Vector3(0.0f, 1.0f, 1.0f) * shapeSize; 
    Vector3 topRightBack3 = shapePosition + 
    new Vector3(1.0f, 1.0f, 1.0f) * shapeSize; 
    Vector3 bottomLeftBack3 = shapePosition + 
    new Vector3(0.0f, 0.0f, 1.0f) * shapeSize; 
    Vector3 bottomRightBack3 = shapePosition + 
    new Vector3(1.0f, 0.0f, 1.0f) * shapeSize; 

    Vector3 frontNormal = new Vector3(0.0f, 0.0f, 1.0f) * shapeSize; 
    Vector3 backNormal = new Vector3(0.0f, 0.0f, -1.0f) * shapeSize; 
    Vector3 topNormal = new Vector3(0.0f, 1.0f, 0.0f) * shapeSize; 
    Vector3 bottomNormal = new Vector3(0.0f, -1.0f, 0.0f) * shapeSize; 
    Vector3 leftNormal = new Vector3(-1.0f, 0.0f, 0.0f) * shapeSize; 
    Vector3 rightNormal = new Vector3(1.0f, 0.0f, 0.0f) * shapeSize; 

    Vector2 textureTopLeft = new Vector2(1f * shapeSize.X, 0.0f * shapeSize.Y); 
    Vector2 textureTopRight = new Vector2(0.0f * shapeSize.X, 0.0f * shapeSize.Y); 
    Vector2 textureBottomLeft = new Vector2(1f * shapeSize.X, 1f * shapeSize.Y); 
    Vector2 textureBottomRight = new Vector2(0.0f * shapeSize.X, 1f * shapeSize.Y); 

    // Front face. 
    shapeVertices[0][0] = new VertexPositionNormalTexture(
    topLeftFront, frontNormal, textureTopLeft); 
    shapeVertices[0][1] = new VertexPositionNormalTexture(
    bottomLeftFront, frontNormal, textureBottomLeft); 
    shapeVertices[0][2] = new VertexPositionNormalTexture(
    topRightFront, frontNormal, textureTopRight); 
    shapeVertices[0][3] = new VertexPositionNormalTexture(
    bottomLeftFront, frontNormal, textureBottomLeft); 
    shapeVertices[0][4] = new VertexPositionNormalTexture(
    bottomRightFront, frontNormal, textureBottomRight); 
    shapeVertices[0][5] = new VertexPositionNormalTexture(
    topRightFront, frontNormal, textureTopRight); 

    // Back face. 
    shapeVertices[1][0] = new VertexPositionNormalTexture(
    topLeftBack, backNormal, textureTopRight); 
    shapeVertices[1][1] = new VertexPositionNormalTexture(
    topRightBack, backNormal, textureTopLeft); 
    shapeVertices[1][2] = new VertexPositionNormalTexture(
    bottomLeftBack, backNormal, textureBottomRight); 
    shapeVertices[1][3] = new VertexPositionNormalTexture(
    bottomLeftBack, backNormal, textureBottomRight); 
    shapeVertices[1][4] = new VertexPositionNormalTexture(
    topRightBack, backNormal, textureTopLeft); 
    shapeVertices[1][5] = new VertexPositionNormalTexture(
    bottomRightBack, backNormal, textureBottomLeft); 

    // Top face. 
    shapeVertices[2][0] = new VertexPositionNormalTexture(
    topLeftFront2, topNormal, textureBottomLeft); 
    shapeVertices[2][1] = new VertexPositionNormalTexture(
    topRightBack2, topNormal, textureTopRight); 
    shapeVertices[2][2] = new VertexPositionNormalTexture(
    topLeftBack2, topNormal, textureTopLeft); 
    shapeVertices[2][3] = new VertexPositionNormalTexture(
    topLeftFront2, topNormal, textureBottomLeft); 
    shapeVertices[2][4] = new VertexPositionNormalTexture(
    topRightFront2, topNormal, textureBottomRight); 
    shapeVertices[2][5] = new VertexPositionNormalTexture(
    topRightBack2, topNormal, textureTopRight); 

    // Bottom face. 
    shapeVertices[3][0] = new VertexPositionNormalTexture(
    bottomLeftFront2, bottomNormal, textureTopLeft); 
    shapeVertices[3][1] = new VertexPositionNormalTexture(
    bottomLeftBack2, bottomNormal, textureBottomLeft); 
    shapeVertices[3][2] = new VertexPositionNormalTexture(
    bottomRightBack2, bottomNormal, textureBottomRight); 
    shapeVertices[3][3] = new VertexPositionNormalTexture(
    bottomLeftFront2, bottomNormal, textureTopLeft); 
    shapeVertices[3][4] = new VertexPositionNormalTexture(
    bottomRightBack2, bottomNormal, textureBottomRight); 
    shapeVertices[3][5] = new VertexPositionNormalTexture(
    bottomRightFront2, bottomNormal, textureTopRight); 

    // Left face. 
    shapeVertices[4][0] = new VertexPositionNormalTexture(
    topLeftFront3, leftNormal, textureTopRight); 
    shapeVertices[4][1] = new VertexPositionNormalTexture(
    bottomLeftBack3, leftNormal, textureBottomLeft); 
    shapeVertices[4][2] = new VertexPositionNormalTexture(
    bottomLeftFront3, leftNormal, textureBottomRight); 
    shapeVertices[4][3] = new VertexPositionNormalTexture(
    topLeftBack3, leftNormal, textureTopLeft); 
    shapeVertices[4][4] = new VertexPositionNormalTexture(
    bottomLeftBack3, leftNormal, textureBottomLeft); 
    shapeVertices[4][5] = new VertexPositionNormalTexture(
    topLeftFront3, leftNormal, textureTopRight); 

    // Right face. 
    shapeVertices[5][0] = new VertexPositionNormalTexture(
    topRightFront3, rightNormal, textureTopLeft); 
    shapeVertices[5][1] = new VertexPositionNormalTexture(
    bottomRightFront3, rightNormal, textureBottomLeft); 
    shapeVertices[5][2] = new VertexPositionNormalTexture(
    bottomRightBack3, rightNormal, textureBottomRight); 
    shapeVertices[5][3] = new VertexPositionNormalTexture(
    topRightBack3, rightNormal, textureTopRight); 
    shapeVertices[5][4] = new VertexPositionNormalTexture(
    topRightFront3, rightNormal, textureTopLeft); 
    shapeVertices[5][5] = new VertexPositionNormalTexture(
    bottomRightBack3, rightNormal, textureBottomRight); 
} 

public void SetTopTexture(Texture2D tex) { 
    topTexture = tex; 
} 
public void SetSideTexture(Texture2D tex) { 
    frontTexture = tex; 
    backTexture = tex; 
    leftTexture = tex; 
    rightTexture = tex; 
} 
public void SetBottomTexture(Texture2D tex) { 
    bottomTexture = tex; 
} 

public void RenderShape(GraphicsDevice device, Effect effect) { 
    BuildShape(); 


    effect.Parameters["xTexture"].SetValue(topTexture); 
    device.DrawUserPrimitives(PrimitiveType.TriangleList, shapeVertices[2], 0, 2); 
    effect.Parameters["xTexture"].SetValue(bottomTexture); 
    device.DrawUserPrimitives(PrimitiveType.TriangleList, shapeVertices[3], 0, 2); 
    effect.Parameters["xTexture"].SetValue(frontTexture); 
    device.DrawUserPrimitives(PrimitiveType.TriangleList, shapeVertices[0], 0, 2); 
    effect.Parameters["xTexture"].SetValue(backTexture); 
    device.DrawUserPrimitives(PrimitiveType.TriangleList, shapeVertices[1], 0, 2); 
    effect.Parameters["xTexture"].SetValue(leftTexture); 
    device.DrawUserPrimitives(PrimitiveType.TriangleList, shapeVertices[4], 0, 2); 
    effect.Parameters["xTexture"].SetValue(rightTexture); 
    device.DrawUserPrimitives(PrimitiveType.TriangleList, shapeVertices[5], 0, 2); 

} 

}

E nel metodo Draw per il mio gioco:

cubeEffect.CurrentTechnique = cubeEffect.Techniques["Textured"]; 
    foreach(EffectPass pass in cubeEffect.CurrentTechnique.Passes) { 
     pass.Apply(); 
     BasicShape s = new BasicShape(new Vector3(1, 1, 1), new Vector3(0, 0, 3)); 
     s.SetTopTexture(TextureLoader.GetTexture(4)); 
     s.SetSideTexture(TextureLoader.GetTexture(35)); 
     s.SetBottomTexture(TextureLoader.GetTexture(4)); 
     s.RenderShape(GraphicsDevice, cubeEffect); 

    } 

Come potete vedere, sto caricando diverse texture, ma il risultato è questo :

my cube http://www.tinyimg.org/images/769MinecraftClassic_2011_.bmp

sono sicuro che le texture sono diverse, eppure la stessa trama viene disegnata su tutti i lati. Ho bisogno di un effetto separato per ogni lato? Questo sembra decisamente eccessivo.

+0

Si è verificato che 'TextureLoader.GetTexture (35)' sta tornando quello che ci si aspetta per tornare? – ChrisF

+0

@ChrisF - Beh, la texture 35 è l'unica trama che mostra, quindi presumo che lo sia. Inoltre, se prendo le prime due righe del codice di disegno in RenderShape e lo metto alla fine, rende la texture 4. In questo modo viene eseguito il rendering dell'ultima texture applicata. – Bevin

+0

Sembra un'informazione utile da includere nella domanda. Non posso aiutare con la risposta - non sono così familiare con xna. – ChrisF

risposta

4

Qualsiasi parametro impostato sull'effetto non viene applicato fino a quando non si chiama EffectPass.Apply(). Questo perché applicare modifiche a un effetto è costoso e potresti voler eseguire più modifiche in una volta sola.

La vostra funzione RenderShape dovrebbe essere simile:

public void RenderShape(GraphicsDevice device, Effect effect) 
{ 
    BuildShape(); 

    foreach (EffectPass pass in effect.CurrentTechnique.Passes) 
    { 
     effect.Parameters["xTexture"].SetValue(topTexture); 
     pass.Apply(); 
     device.DrawUserPrimitives(PrimitiveType.TriangleList, shapeVertices[2], 0, 2); 

     effect.Parameters["xTexture"].SetValue(bottomTexture); 
     pass.Apply(); 
     device.DrawUserPrimitives(PrimitiveType.TriangleList, shapeVertices[3], 0, 2); 

     effect.Parameters["xTexture"].SetValue(frontTexture); 
     pass.Apply(); 
     device.DrawUserPrimitives(PrimitiveType.TriangleList, shapeVertices[0], 0, 2); 

     effect.Parameters["xTexture"].SetValue(backTexture); 
     pass.Apply(); 
     device.DrawUserPrimitives(PrimitiveType.TriangleList, shapeVertices[1], 0, 2); 

     effect.Parameters["xTexture"].SetValue(leftTexture); 
     pass.Apply(); 
     device.DrawUserPrimitives(PrimitiveType.TriangleList, shapeVertices[4], 0, 2); 

     effect.Parameters["xTexture"].SetValue(rightTexture); 
     pass.Apply(); 
     device.DrawUserPrimitives(PrimitiveType.TriangleList, shapeVertices[5], 0, 2); 
    } 
} 
+0

@Empyrean - Quindi, stai dicendo che questo non è il modo consigliato di farlo? Quale sarebbe un modo più veloce? Dovrò disegnare un sacco di questi cubi, quindi ho bisogno di ottimizzarlo il più possibile. – Bevin

+0

In genere, è possibile apportare solo alcune centinaia di modifiche di stato (chiamate batch) prima di riscontrare problemi di prestazioni. Nel codice, il rendering di ciascun cubo consiste di 6 lotti. Ciò significa che probabilmente sarai in grado di eseguire il rendering di meno di 100 cubi prima che il framerate inizi a diventare inaccettabile. Si desidera che il numero minimo di chiamate sia possibile, quindi disegnare tutte le facce del cubo con la stessa trama in una sola chiamata. Meglio ancora unisci la tua sei texture in una singola texture (texture atlasing). Anche i buffer dei vertici sono molto più veloci sul PC rispetto alle chiamate DrawUserPrimitive. – Empyrean

+0

Il modo più veloce sarebbe utilizzare l'atlasatura delle texture e rendere tutti i cubi in una chiamata utilizzando il buffer dei vertici statico o dinamico a seconda che i cubi si spostino o no. Se alcuni di essi non si muovono, utilizzare un buffer di vertici statico per quelli e un buffer di vertici dinamico per quelli che lo fanno. Dovresti inoltre utilizzare gli indici per evitare l'uso di vertici duplicati. I vertici duplicati devono essere entrambi trasformati e possono trasformarsi leggermente in modo diverso dando cuciture nelle mesh. – Empyrean

Problemi correlati