Exemplo n.º 1
0
        /// <summary>
        /// Rebuilds this chunk's geometry.
        /// </summary>
        public void Rebuild(Graphics.SceneRenderer renderer)
        {
            ReconstructBlockFaceVisibility();
            ReconstructVertices(renderer);

            // Reset dirty flag.
            isDirty = false;
        }
Exemplo n.º 2
0
        public void Draw(Graphics.SceneRenderer renderer)
        {
            effect.View       = renderer.Camera.LookAtMatrix;
            effect.Projection = GameSettings.PfovMatrix;

            Chunk chunk;

            // Draw geometry
            for (int x = 0; x < width; ++x)
            {
                for (int z = 0; z < length; ++z)
                {
                    chunk = chunks[x, z];

                    // If necessary, rebuild the chunk's geometry.
                    if (chunk.IsDirty)
                    {
                        chunk.Rebuild(renderer);
                    }
                    else
                    {
                        // Else just rebuild transparent vertices to ensure correct draw order.
                        // TODO: Perform this only when the player moves, not every frame.
                        chunk.ReconstructVertices(renderer, true);
                    }

                    // If there are opaque vertices to draw, do so.
                    if (chunk.OpaqueVertexBuffer != null)
                    {
                        renderer.DrawVertices(chunk.OpaqueVertexBuffer, effect);
                    }

                    // Draw any alpha-blended vertices.
                    if (chunk.TransparentVertexBuffer != null)
                    {
                        renderer.DrawAlphaBlendedVertices(chunk.TransparentVertexBuffer, effect, new Vector3(x * Chunk.WIDTH, 0, z * Chunk.LENGTH));
                    }
                }
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Reconstructs voxel vertices for the world, based on visible block face data.
        /// </summary>
        /// <param name="renderer">The SceneRenderer which will be used to render the vertices.</param>
        /// <param name="alphaBlendedOnly">If true, only alpha-blended vertices will be reconstructed.</param>
        public void ReconstructVertices(Graphics.SceneRenderer renderer, bool alphaBlendedOnly = false)
        {
            Block block;
            List <VertexRebuildQueueItem>     alphaBlendedBlocksToRebuild = new List <VertexRebuildQueueItem>(); // Using a List so this can be depth-sorted.
            Queue <VertexRebuildQueueItem>    opaqueBlocksToRebuild       = new Queue <VertexRebuildQueueItem>();
            List <VertexPositionColorTexture> alphaBlendedVertices        = new List <VertexPositionColorTexture>();
            List <VertexPositionColorTexture> opaqueVertices = new List <VertexPositionColorTexture>();

            // TODO: Use an array instead of a list

            // Queue up blocks to be processed.
            for (int x = 0; x < WIDTH; ++x)
            {
                for (int y = 0; y < HEIGHT; ++y)
                {
                    for (int z = 0; z < LENGTH; ++z)
                    {
                        block = BlockAt(x, y, z);

                        if (block.BlockType.IsInvisible)
                        {
                            // Skip invisible blocks as they have no vertices.
                            continue;
                        }
                        else if (block.BlockType.IsAlphaBlended)
                        {
                            // Add alpha blended blocks to alpha blended queue.
                            VertexRebuildQueueItem queueItem = new VertexRebuildQueueItem();
                            queueItem.Block    = block;
                            queueItem.Position = new Vector3Int(x, y, z);
                            alphaBlendedBlocksToRebuild.Add(queueItem);
                        }
                        else if (!alphaBlendedOnly)
                        {
                            // Add opaque blocks to opaque queue.
                            VertexRebuildQueueItem queueItem = new VertexRebuildQueueItem();
                            queueItem.Block    = block;
                            queueItem.Position = new Vector3Int(x, y, z);
                            opaqueBlocksToRebuild.Enqueue(queueItem);
                        }
                    }
                }
            }

            // Depth-sort alpha blended block list.
            alphaBlendedBlocksToRebuild = alphaBlendedBlocksToRebuild.OrderBy(q => ((q.Position.ToVector3() - renderer.Camera.Position).LengthSquared())).ToList();

            // Reset primitive counts.
            transparentPrimitiveCount = 0;
            if (!alphaBlendedOnly)
            {
                opaquePrimitiveCount = 0;
            }

            // Process alpha-blended blocks.
            foreach (VertexRebuildQueueItem currentQueueItem in alphaBlendedBlocksToRebuild)
            {
                Vector3Int worldPosition = new Vector3Int(chunkX * WIDTH + currentQueueItem.Position.X, currentQueueItem.Position.Y, chunkZ * LENGTH + currentQueueItem.Position.Z);
                alphaBlendedVertices.AddRange(currentQueueItem.Block.GetVertices(worldPosition));
            }
            transparentPrimitiveCount = alphaBlendedVertices.Count / 3;

            // Process opaque blocks.
            if (!alphaBlendedOnly)
            {
                VertexRebuildQueueItem currentQueueItem;
                while (opaqueBlocksToRebuild.Count > 0)
                {
                    currentQueueItem = opaqueBlocksToRebuild.Dequeue();
                    Vector3Int worldPosition = new Vector3Int(chunkX * WIDTH + currentQueueItem.Position.X, currentQueueItem.Position.Y, chunkZ * LENGTH + currentQueueItem.Position.Z);
                    opaqueVertices.AddRange(currentQueueItem.Block.GetVertices(worldPosition));
                }
                opaquePrimitiveCount = opaqueVertices.Count / 3;
            }

            // For some reason list converts to an array in the wrong order, so reverse the lists.
            // TODO: Fix this.
            alphaBlendedVertices.Reverse();
            if (transparentPrimitiveCount == 0)
            {
                transparentVertexBuffer = null;
            }
            else
            {
                transparentVertexBuffer = new VertexBuffer(renderer.GraphicsDevice, typeof(VertexPositionColorTexture), alphaBlendedVertices.Count, BufferUsage.WriteOnly);
                transparentVertexBuffer.SetData <VertexPositionColorTexture>(alphaBlendedVertices.ToArray());
            }

            if (!alphaBlendedOnly)
            {
                opaqueVertices.Reverse();
                if (opaquePrimitiveCount == 0)
                {
                    opaqueVertexBuffer = null;
                }
                else
                {
                    opaqueVertexBuffer = new VertexBuffer(renderer.GraphicsDevice, typeof(VertexPositionColorTexture), opaqueVertices.Count, BufferUsage.WriteOnly);
                    opaqueVertexBuffer.SetData <VertexPositionColorTexture>(opaqueVertices.ToArray());
                }
            }
        }