2011-09-04 60 views
0

我正在製作(另一個)MineCraft克隆,我遇到了一個有趣的問題。我有一個公共枚舉,它列出了一個特定立方體可以存在的所有立方體類型,並且我有一個包含立方體的3d數組。每個立方體都有一個特定的類型,我遍歷這個數組以獲得每個立方體的頂點,然後將這些頂點傳遞給爲特定立方體類型指定的頂點緩衝區。當我創建一個隨機數組的多維數據集或單個多維數據集,並告訴它它應該是什麼樣的紋理都按預期繪製。我現在試圖弄清楚如何繪製草立方體的隨機「表面」,並用灰塵立方體填充y軸以下的所有東西。最奇怪的事情發生了,最頂級的立方體是泥土,它用草立方體填充所有底部的立方體!當我禁用循環以填充地下污垢時,最頂端的立方體正按預期顯示草。XNA正在拖動錯誤的紋理?

這是我認爲是代碼的相關部分。這裏是立方體類型設置:

  // Create a random surface level 
     Perlin perlin = new Perlin(); 

     for (int x = 0; x < Game.ChunkWidth_X; x++) 
     { 
      for (int z = 0; z < Game.ChunkDepth_Z; z++) 
      { 
       double XVal = Convert.ToDouble(x) * 1.1; 
       double ZVal = Convert.ToDouble(z) * 1.1; 
       double YVal = Game.ChunkHeight_Y/2 * 1.1; 

       double PerlinValue = perlin.GetValue(XVal, YVal, ZVal); 
       int YVal_new = Convert.ToInt32(YVal + (PerlinValue * 10)); 
       if (YVal_new > Game.ChunkHeight_Y - 1) { YVal_new = Game.ChunkHeight_Y - 1; } 
       if (YVal_new < 0) { YVal_new = 0; } 

       // Set the grass cube 
       Cube NewCube = new Cube(new Vector3(0.5f, 0.5f, 0.5f), new Vector3(x, YVal_new, z)); 
       NewCube.cubeType = CubeType.Grass; 
       CubeGrid[x, YVal_new, z] = NewCube; 

       // Fill below it with dirt 
       for (int y = YVal_new - 1; y >= 0; y--) 
       { 
        Cube NewCube2 = new Cube(new Vector3(0.5f, 0.5f, 0.5f), new Vector3(x, y, z)); 
        NewCube2.cubeType = CubeType.Dirt; 
        CubeGrid[x, y, z] = NewCube2; 
       } 

       // Fill above it with air 
       for (int y = YVal_new + 1; y < Game.ChunkHeight_Y; y++) 
       { 
        Cube NewCube2 = new Cube(new Vector3(0.5f, 0.5f, 0.5f), new Vector3(x, y, z)); 
        NewCube2.cubeType = CubeType.Air; 
        CubeGrid[x, y, z] = NewCube2; 
       } 

      } 
     } 

這是我拉來放入適當的緩衝頂點:

  Dictionary<CubeType, List<VertexPositionNormalTexture>> DrawableVertices = new Dictionary<CubeType, List<VertexPositionNormalTexture>>(); 

     // Get the proper vertices for each cube type and put in the appropriate dictionary 
     for (int x = 0; x < Game.ChunkWidth_X; x++) 
     { 
      for (int z = 0; z < Game.ChunkDepth_Z; z++) 
      { 
       for (int y = 0; y < Game.ChunkHeight_Y; y++) 
       { 
        CubeGrid[x,y,z].CreateVertices(); 
        string test = CubeGrid[x, y, z].cubeType.ToString(); 

        foreach (VertexPositionNormalTexture TargetVertex in CubeGrid[x, y, z].DisplayableVertices) 
        { 
         if (!DrawableVertices.ContainsKey(CubeGrid[x, y, z].cubeType)) 
         { 
          List<VertexPositionNormalTexture> NewList = new List<VertexPositionNormalTexture>(); 
          NewList.Add(TargetVertex); 
          DrawableVertices.Add(CubeGrid[x, y, z].cubeType, NewList); 
         } 
         else 
         { 
          DrawableVertices[CubeGrid[x, y, z].cubeType].Add(TargetVertex); 
         } 
        } 
       } 
      } 
     } 

這裏是它的第二部分:

  foreach (KeyValuePair<CubeType, List<VertexPositionNormalTexture>> KVP in DrawableVertices) 
     { 
      VertexBuffer cubeBuffer = new VertexBuffer(device, typeof(VertexPositionNormalTexture), KVP.Value.Count, BufferUsage.WriteOnly); 
      cubeBuffer.SetData(KVP.Value.ToArray()); 

      // Update our collection of vertex buffers 
      CubeType_VertexBuffers[KVP.Key] = cubeBuffer; 

      // Get the triangle count for the buffer 
      CubeType_TriangleCount[KVP.Key] = KVP.Value.Count/3; 

     } 

最後,這裏是我的畫:

  // Go through each vertex buffer we have created, and draw it. 
     foreach (KeyValuePair<CubeType, VertexBuffer> KVP in CubeType_VertexBuffers) 
     { 
      foreach (EffectPass pass in testEffect.CurrentTechnique.Passes) 
      { 
       if (CubeType_TriangleCount[KVP.Key] > 0) // if this buffer has triangles, draw it. 
       { 
        pass.Apply(); 
        testEffect.View = camera.ViewMatrix; 
        testEffect.TextureEnabled = true; 
        testEffect.Projection = camera.ProjectionMatrix; 
        testEffect.World = worldMatrix; 
        testEffect.Texture = CubeType_Texture[KVP.Key]; 

        device.SetVertexBuffer(KVP.Value); 
        device.DrawPrimitives(PrimitiveType.TriangleList, 0, CubeType_TriangleCount[KVP.Key]); 
       } 
      } 
     } 


     base.Draw(gameTime); 

最奇怪的是,當我手動設置多維數據集類型時,所有內容都按照預期繪製出適當的紋理。我應該嘗試解決哪些其他問題?我試圖對每個立方體類型做出特定的效果都無濟於事。

回答

1

在絕望中嘗試了一堆隨機的東西后,我找到了一個解決方案。事實證明,如果對不同的紋理使用相同的BasicEffect,它只會使用分配給它的最後一個紋理。我遍歷VertexBuffers列表併爲每個紋理分配不同的紋理。當所有事情都交給視頻卡時,只有最後使用的紋理被渲染,或者看起來如此。

解決方案是爲我需要的每個紋理創建一個單獨的BasicEffect,並僅將需要的VertexBuffers分配給特定的BasicEffect。