2011-01-12 16 views
5

Kafamı şu anda saatlerce bu problem karşısında becermeye başladım. Yapmak istediğim şey, her bir tarafta farklı dokulara sahip bir küp çizmek; ya da daha özel olarak, her bir taraf için istediğim dokuları belirtmek istiyorum. Başlamak için here örneğini kullandım ve daha sonra geliştirmeye çalıştım, böylece birden fazla dokuya sahip olabilirdim. Bununla birlikte, ne yaptığımın bir önemi yok, yine de sadece etkiyi uygulayan son dokuyu kullanıyor ve herhangi bir önceki ödeve dikkat etmiyor.XNA 4.0'da çoklu kenarlı dokulu bir küp çizimi

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); 

} 

}

Ve oyun için Çizim yönteminde

: Gördüğünüz gibi, farklı dokular yükleme, henüz am

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); 

    } 

sonuç şudur İşte benim şekli sınıftır :

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

Ben dokular farklı olduğundan emin değilim, Yine de aynı doku her tarafta çizilir. Her bir taraf için ayrı bir etkiye ihtiyacım var mı? Bu kesinlikle overkill gibi görünüyor.

+0

sen olmadığını kontrol ettiniz 'TextureLoader.GetTexture (35)' bunu dönmek için beklediğiniz dönüyor:

Kişisel RenderShape fonksiyonu gibi görünmelidir? – ChrisF

+0

@ChrisF - Doku 35, gösterilen tek doku, bu yüzden olduğunu farz ediyorum. Ayrıca, RenderShape'deki draw kodunun ilk iki satırını alıp sonuna koyarsam, doku 4'ü oluşturur. Bu yüzden yalnızca son uygulanan doku oluşturulur. – Bevin

+0

Sorunuza eklemeniz gereken faydalı bilgiler gibi görünüyor. Cevabında yardım edemem ama - xna ile aşina değilim. – ChrisF

cevap

4

EffectPass.Apply() öğesini çağırıncaya kadar, efekt üzerinde ayarlanan tüm parametreler uygulanmaz. Bunun nedeni, bir etkiye yapılan değişikliklerin uygulanması pahalıdır ve bir seferde birden fazla değişiklik yapmak isteyebilirsiniz.

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 - Yani, bunun bunu yapmanın önerilen yolu olmadığını mı söylüyorsunuz? Daha hızlı bir yol ne olurdu? Bu küplerin birçoğunu çizmek zorundayım, bu yüzden mümkün olduğunca optimize etmem gerekiyor. – Bevin

+0

Performans sorunları yaşamadan genellikle yalnızca birkaç yüz durum değişikliği (toplu iş adı verilir) yapabilirsiniz. Kodunuzda, her küpün oluşturulması 6 gruptan oluşur. Bu, muhtemelen, kare hızınız kabul edilemez olmaya başlamadan önce 100'den az küp oluşturabileceğinizi gösterir. Mümkün olduğunca az sayıda çizim çağrısı yapmak istiyorsunuz, bu yüzden tüm küp yüzlerini tek bir çizimde aynı dokuya çizin. Daha iyisi, altı yapınızı tek bir dokuda birleştirir (doku atlası). Ayrıca verteks tamponları PC'de DrawUserPrimitive çağrılarından çok daha hızlıdır. – Empyrean

+0

En hızlı yol, doku atlaslaması kullanmak ve küplerin hareket edip etmediğine bağlı olarak statik veya dinamik köşe arabelleği kullanarak tek bir aramada tüm küpleri oluşturmak olacaktır. Bazıları hareket etmiyorsa, olanlar için statik bir köşe arabelleği ve olanlar için dinamik köşe tamponu kullanın. Yinelenen köşe noktalarını kullanmamak için dizin kullanmalısınız. Çoğaltılmış köşe noktalarının her ikisi de dönüştürülmeli ve bunlar, kafeslerinizdeki dikişleri biraz farklı bir şekilde değiştirebilir. – Empyrean