0

私は(別の)MineCraftクローンを作成していますが、興味深い問題が発生しました。特定のキューブが可能なすべてのキューブタイプを一覧表示するパブリック列挙型があり、キューブを保持する3D配列があります。各キューブには特定のタイプがあり、この配列を反復処理して各キューブの頂点を取得し、それらの頂点を特定のキューブタイプ用に指定された頂点バッファーに渡します。立方体のランダムな配列または単一の立方体を作成し、それがどのテクスチャであるかを指示すると、すべてが期待どおりに描画されます。私は今、草の立方体のランダムな「表面」を描画し、y軸上のものの下にあるすべてのものを土の立方体で埋める方法を見つけようとしています。しかし、最も奇妙なことが起こっています。一番上の立方体は汚れで、一番下の立方体はすべて草の立方体でいっぱいです。ループを無効にして地下を土で満たすと、

これが私がコードの関連部分であると信じているものです。キューブタイプが設定される場所は次のとおりです。

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

これがその2番目の部分です:

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

最も奇妙なことは、キューブタイプを手動で設定すると、すべてが期待どおりに適切なテクスチャで描画されることです。他にどのようなトラブルシューティングを試みる必要がありますか?キューブの種類ごとに特定の効果を出してみましたが、無駄になりました。

4

1 に答える 1

1

必死になってたくさんのランダムなことを試した後、私はこれに対する修正を見つけました。異なるテクスチャに同じBasicEffectを使用すると、割り当てられた最後のテクスチャのみが使用されることがわかります。VertexBufferのリストを繰り返し処理し、それぞれに異なるテクスチャを割り当てていました。すべてがビデオカードに渡されるまでに、最後に使用されたテクスチャのみがレンダリングされたため、表示されます。

解決策は、必要なテクスチャごとに個別のBasicEffectを作成し、必要なVertexBufferのみを特定のBasicEffectに割り当てることでした。

于 2011-09-05T20:57:51.427 に答える