0

我有一个 10*10 的立方体平面。我只想绘制可见的立方体,所以我使用了 Bounding frustum。问题是当网格中的第一个立方体(在位置 0,0)离开截锥体时,所有立方体都消失了。

这是我的代码Cube.cs

public class Cube
    {
        Vector3 scale;
        float textureScale;

        GraphicsDevice device;
        Effect effect;
        VertexBuffer vertexBuffer;
        Texture2D texture;

        public Vector3 GlobalPosition = new Vector3(0, 0, 0);

        public Vector3[] vertices = new Vector3[36];

        public Cube(Vector3 scale, float textureScale, Effect effect, Texture2D texture, GraphicsDevice device)
        {

            this.scale = scale;
            this.textureScale = textureScale;
            this.device = device;
            this.effect = effect;
            this.texture = texture;

            vertices[0] = new Vector3(-1, 1, -1);
            vertices[1] = new Vector3(-1, -1, -1);
            vertices[2] = new Vector3(1, -1, -1);

            vertices[3] = new Vector3(1, -1, -1);
            vertices[4] = new Vector3(1, 1, -1);
            vertices[5] = new Vector3(-1, 1, -1);

            //Front
            vertices[6] = new Vector3(1, -1, 1);
            vertices[7] = new Vector3(-1, -1, 1);
            vertices[8] = new Vector3(-1, 1, 1);

            vertices[9] = new Vector3(-1, 1, 1);
            vertices[10] = new Vector3(1, 1, 1);
            vertices[11] = new Vector3(1, -1, 1);

            //Bottom
            vertices[12] = new Vector3(-1, -1, -1);
            vertices[13] = new Vector3(-1, -1, 1);
            vertices[14] = new Vector3(1, -1, -1);

            vertices[15] = new Vector3(1, -1, 1);
            vertices[16] = new Vector3(1, -1, -1);
            vertices[17] = new Vector3(-1, -1, 1);

            //Top
            vertices[18] = new Vector3(1, 1, -1);
            vertices[19] = new Vector3(-1, 1, 1);
            vertices[20] = new Vector3(-1, 1, -1);

            vertices[21] = new Vector3(-1, 1, 1);
            vertices[22] = new Vector3(1, 1, -1);
            vertices[23] = new Vector3(1, 1, 1);

            //Left
            vertices[24] = new Vector3(-1, -1, 1);
            vertices[25] = new Vector3(-1, -1, -1);
            vertices[26] = new Vector3(-1, 1, -1);

            vertices[27] = new Vector3(-1, 1, -1);
            vertices[28] = new Vector3(-1, 1, 1);
            vertices[29] = new Vector3(-1, -1, 1);

            //Right
            vertices[30] = new Vector3(1, -1, -1);
            vertices[31] = new Vector3(1, -1, 1);
            vertices[32] = new Vector3(1, 1, -1);

            vertices[33] = new Vector3(1, -1, 1);
            vertices[34] = new Vector3(1, 1, 1);
            vertices[35] = new Vector3(1, 1, -1);

            for (int i = 0; i < 36; i++)
            {
                vertices[i] = vertices[i] * scale + GlobalPosition;
            }

            VertexPositionNormalTexture[] verticesList = GetVPNT();
            vertexBuffer = new VertexBuffer(device, VertexPositionNormalTexture.VertexDeclaration, verticesList.Length, BufferUsage.WriteOnly);
            vertexBuffer.SetData<VertexPositionNormalTexture>(verticesList.ToArray());

        }
        public void Draw(Matrix View, Matrix Projection, Vector3 pos)
        {

            effect.CurrentTechnique = effect.Techniques["Textured"];
            effect.Parameters["xWorld"].SetValue(Matrix.Identity * Matrix.CreateTranslation(pos));
            effect.Parameters["xView"].SetValue(View);
            effect.Parameters["xProjection"].SetValue(Projection);
            effect.Parameters["xTexture"].SetValue(texture);

            effect.Parameters["xEnableLighting"].SetValue(true);
            effect.Parameters["xLightDirection"].SetValue(new Vector3(30, 30, 30));
            effect.Parameters["xAmbient"].SetValue(0.5f);

            foreach (EffectPass pass in effect.CurrentTechnique.Passes)
            {
                pass.Apply();
                device.SetVertexBuffer(vertexBuffer);
                device.DrawPrimitives(PrimitiveType.TriangleList, 0, vertexBuffer.VertexCount / 3);
            }
        }
        public VertexPositionNormalTexture[] GetVPNT()
        {
            VertexPositionNormalTexture[] vpnt = new VertexPositionNormalTexture[36];

            Vector2[] texCoords = CalculateTexCoords(vertices, "tile");

            for (int i = 0; i < 36; i++)
            {

                vpnt[i] = new VertexPositionNormalTexture(vertices[i], new Vector3(0, 0, 1), texCoords[i]);
            }

            return vpnt;
        }
        public Vector2[] CalculateTexCoords(Vector3[] vec, string type)
        {
            List<Vector2> texCoords = new List<Vector2>();

            for (int i = 0; i < 12; i++)
            {
                if (AllEqual<float>(vertices[i * 3 + 0].X, vertices[i * 3 + 1].X, vertices[i * 3 + 2].X))
                {
                    Vector2[] normvec = new Vector2[3];

                    normvec[0] = TexNorm(new Vector2(vertices[i * 3 + 0].Z, vertices[i * 3 + 0].Y), type);
                    normvec[1] = TexNorm(new Vector2(vertices[i * 3 + 1].Z, vertices[i * 3 + 1].Y), type);
                    normvec[2] = TexNorm(new Vector2(vertices[i * 3 + 2].Z, vertices[i * 3 + 2].Y), type);

                    texCoords.AddRange(normvec);
                }
                if (AllEqual<float>(vertices[i * 3 + 0].Y, vertices[i * 3 + 1].Y, vertices[i * 3 + 2].Y))
                {
                    Vector2[] normvec = new Vector2[3];

                    normvec[0] = TexNorm(new Vector2(vertices[i * 3 + 0].X, vertices[i * 3 + 0].Z), type);
                    normvec[1] = TexNorm(new Vector2(vertices[i * 3 + 1].X, vertices[i * 3 + 1].Z), type);
                    normvec[2] = TexNorm(new Vector2(vertices[i * 3 + 2].X, vertices[i * 3 + 2].Z), type);

                    texCoords.AddRange(normvec);
                }
                if (AllEqual<float>(vertices[i * 3 + 0].Z, vertices[i * 3 + 1].Z, vertices[i * 3 + 2].Z))
                {
                    Vector2[] normvec = new Vector2[3];

                    normvec[0] = TexNorm(new Vector2(vertices[i * 3 + 0].X, vertices[i * 3 + 0].Y), type);
                    normvec[1] = TexNorm(new Vector2(vertices[i * 3 + 1].X, vertices[i * 3 + 1].Y), type);
                    normvec[2] = TexNorm(new Vector2(vertices[i * 3 + 2].X, vertices[i * 3 + 2].Y), type);

                    texCoords.AddRange(normvec);
                }
            }
            return texCoords.ToArray();
        }
        public bool AllEqual<T>(params T[] values)
        {
            if (values == null || values.Length == 0)
                return true;
            return values.All(v => v.Equals(values[0]));
        }
        public Vector2 TexNorm(Vector2 vecIn, string type)
        {
            Vector2 vec = new Vector2();

            //Remove negative coordinates
            if (vecIn.Y < 0)
                vec.Y = 0;
            if (vecIn.X < 0)
                vec.X = 0;

            switch (type)
            {
                case "stretch":
                    {
                        if (vecIn.X > 0)
                            vec.X = 1;
                        if (vecIn.Y > 0)
                            vec.Y = 1;

                        break;
                    }
                case "tile":
                    {
                        if (vecIn.X > 0)
                            vec.X = textureScale;
                        if (vecIn.Y > 0)
                            vec.Y = textureScale;

                        break;
                    }
            }
            return vec;
        }
        public bool IsVisible(Matrix VP)
        {
            BoundingFrustum bf = new BoundingFrustum(VP);

            bool isVis = true;

            //Check weather at least one vertices are out of the frustum
            for (int i = 0; i < 36; i++)
            {
                if (bf.Contains(vertices[i]) != ContainmentType.Contains)
                {
                    isVis = false;
                    break;
                }
            }

            return isVis;
        }
    }

Draw()方法Main.cs

for (int i = 0; i < 10; i++)
            {
                for (int k = 0; k < 10; k++)
                {
                    Cube cube = new Cube(Vector3.One, 1, effect, woodTexture, device);

                    if (cube.IsVisible(View * Projection))
                    {
                        cube.Draw(View, Projection, new Vector3(2 * i, 0, 2 * k));
                    }
                }
            }

如果你能给我一个图集纹理教程/示例的链接,我也想知道,谢谢!

4

1 回答 1

0

您的 cube.IsVisible(...) 方法没有考虑您在绘制多维数据集时应用的后一种转换,即您始终检查原始多维数据集,而不是转换后的多维数据集。

请参考此答案,因为它涉及您的剔除问题(截锥盒)以及实例化。

于 2013-12-30T16:06:06.480 回答