public SceneControl(ScreenComponent manager, string style = "") :
            base(manager, style)
        {
            player = manager.Player;
            camera = manager.Camera;

            Manager = manager;

            simpleShader = manager.Game.Content.Load <Effect>("simple");
            sunTexture   = manager.Game.Content.Load <Texture2D>("Textures/sun");

            List <Bitmap> bitmaps     = new List <Bitmap>();
            var           definitions = DefinitionManager.GetBlockDefinitions();

            foreach (var definition in definitions)
            {
                bitmaps.AddRange(definition.Textures);
            }

            int    size   = (int)Math.Ceiling(Math.Sqrt(bitmaps.Count));
            Bitmap blocks = new Bitmap(size * TEXTURESIZE, size * TEXTURESIZE);

            using (Graphics g = Graphics.FromImage(blocks))
            {
                int counter = 0;
                foreach (var bitmap in bitmaps)
                {
                    int x = counter % size;
                    int y = (int)(counter / size);
                    g.DrawImage(bitmap, new System.Drawing.Rectangle(TEXTURESIZE * x, TEXTURESIZE * y, TEXTURESIZE, TEXTURESIZE));
                    counter++;
                }
            }

            using (MemoryStream stream = new MemoryStream())
            {
                blocks.Save(stream, ImageFormat.Png);
                stream.Seek(0, SeekOrigin.Begin);
                blockTextures = Texture2D.FromStream(manager.GraphicsDevice, stream);
            }

            planet = ResourceManager.Instance.GetPlanet(0);

            _manager = ResourceManager.Instance.GetManagerForPlanet(planet.Id);

            chunkRenderer = new ChunkRenderer[
                (int)Math.Pow(2, VIEWRANGE) * (int)Math.Pow(2, VIEWRANGE),
                planet.Size.Z];

            for (int i = 0; i < chunkRenderer.GetLength(0); i++)
            {
                for (int j = 0; j < chunkRenderer.GetLength(1); j++)
                {
                    chunkRenderer[i, j] = new ChunkRenderer(simpleShader, manager.GraphicsDevice, camera.Projection, blockTextures);
                }
            }

            // Entfernungsarray erzeugen
            //for (int x = -VIEWRANGE; x <= VIEWRANGE; x++)
            //    for (int y = -VIEWRANGE; y <= VIEWRANGE; y++)
            //        for (int z = 0; z <= planet.Size.Z; z++)
            //            distances.Add(new Index3(x, y, z));
            //distances = distances.OrderBy(d => d.LengthSquared()).ToList();

            backgroundThread              = new Thread(BackgroundLoop);
            backgroundThread.Priority     = ThreadPriority.Lowest;
            backgroundThread.IsBackground = true;
            backgroundThread.Start();

            selectionLines = new[]
            {
                new VertexPositionColor(new Vector3(-0.001f, +1.001f, +1.001f), Microsoft.Xna.Framework.Color.Black * 0.5f),
                new VertexPositionColor(new Vector3(+1.001f, +1.001f, +1.001f), Microsoft.Xna.Framework.Color.Black * 0.5f),
                new VertexPositionColor(new Vector3(-0.001f, -0.001f, +1.001f), Microsoft.Xna.Framework.Color.Black * 0.5f),
                new VertexPositionColor(new Vector3(+1.001f, -0.001f, +1.001f), Microsoft.Xna.Framework.Color.Black * 0.5f),
                new VertexPositionColor(new Vector3(-0.001f, +1.001f, -0.001f), Microsoft.Xna.Framework.Color.Black * 0.5f),
                new VertexPositionColor(new Vector3(+1.001f, +1.001f, -0.001f), Microsoft.Xna.Framework.Color.Black * 0.5f),
                new VertexPositionColor(new Vector3(-0.001f, -0.001f, -0.001f), Microsoft.Xna.Framework.Color.Black * 0.5f),
                new VertexPositionColor(new Vector3(+1.001f, -0.001f, -0.001f), Microsoft.Xna.Framework.Color.Black * 0.5f),
            };

            billboardVertices = new[]
            {
                new VertexPositionTexture(new Vector3(-0.5f, 0.5f, 0), new Vector2(0, 0)),
                new VertexPositionTexture(new Vector3(0.5f, 0.5f, 0), new Vector2(1, 0)),
                new VertexPositionTexture(new Vector3(-0.5f, -0.5f, 0), new Vector2(0, 1)),
                new VertexPositionTexture(new Vector3(0.5f, 0.5f, 0), new Vector2(1, 0)),
                new VertexPositionTexture(new Vector3(0.5f, -0.5f, 0), new Vector2(1, 1)),
                new VertexPositionTexture(new Vector3(-0.5f, -0.5f, 0), new Vector2(0, 1)),
            };

            selectionIndeces = new short[]
            {
                0, 1, 0, 2, 1, 3, 2, 3,
                4, 5, 4, 6, 5, 7, 6, 7,
                0, 4, 1, 5, 2, 6, 3, 7
            };

            sunEffect = new BasicEffect(manager.GraphicsDevice);
            sunEffect.TextureEnabled = true;

            selectionEffect = new BasicEffect(manager.GraphicsDevice);
            selectionEffect.VertexColorEnabled = true;

            MiniMapTexture          = new RenderTarget2D(manager.GraphicsDevice, 128, 128, false, SurfaceFormat.Color, DepthFormat.Depth24Stencil8); // , false, SurfaceFormat.Color, DepthFormat.Depth24Stencil8, 0, RenderTargetUsage.PreserveContents);
            miniMapProjectionMatrix = Matrix.CreateOrthographic(128, 128, 1, 10000);
        }
        public void RegenerateVertexBuffer()
        {
            if (!ChunkPosition.HasValue)
            {
                return;
            }

            // Chunk nachladen
            if (chunk == null)
            {
                chunk = _manager.GetChunk(ChunkPosition.Value);
                if (chunk == null)
                {
                    return;
                }
            }

            List <VertexPositionNormalTexture> vertices = new List <VertexPositionNormalTexture>();
            List <int> index          = new List <int>();
            int        textureColumns = textures.Width / SceneControl.TEXTURESIZE;
            float      textureWidth   = 1f / textureColumns;

            // BlockTypes sammlen
            Dictionary <IBlockDefinition, int> textureOffsets = new Dictionary <IBlockDefinition, int>();
            // Dictionary<Type, BlockDefinition> definitionMapping = new Dictionary<Type, BlockDefinition>();
            int definitionIndex = 0;

            foreach (var definition in DefinitionManager.GetBlockDefinitions())
            {
                int textureCount = definition.Textures.Count();
                textureOffsets.Add(definition, definitionIndex);
                // definitionMapping.Add(definition.GetBlockType(), definition);
                definitionIndex += textureCount;
            }

            for (int z = 0; z < Chunk.CHUNKSIZE_Z; z++)
            {
                for (int y = 0; y < Chunk.CHUNKSIZE_Y; y++)
                {
                    for (int x = 0; x < Chunk.CHUNKSIZE_X; x++)
                    {
                        ushort block = chunk.GetBlock(x, y, z);
                        if (block == 0)
                        {
                            continue;
                        }

                        IBlockDefinition blockDefinition = DefinitionManager.GetBlockDefinitionByIndex(block);
                        if (blockDefinition == null)
                        {
                            continue;
                        }

                        int textureIndex;
                        if (!textureOffsets.TryGetValue(blockDefinition, out textureIndex))
                        {
                            continue;
                        }

                        // Textur-Koordinate "berechnen"
                        Vector2 textureOffset = new Vector2();
                        Vector2 textureSize   = new Vector2(textureWidth - 0.005f, textureWidth - 0.005f);


                        ushort           topBlock          = _manager.GetBlock((ChunkPosition.Value * Chunk.CHUNKSIZE) + new Index3(x, y, z + 1));
                        IBlockDefinition topBlockDefintion = DefinitionManager.GetBlockDefinitionByIndex(topBlock);

                        // Top
                        if (topBlock == 0 || (!topBlockDefintion.IsBottomSolidWall(_manager, x, y, z + 1) && topBlock != block))
                        {
                            textureOffset = new Vector2(
                                (((textureIndex + blockDefinition.GetTopTextureIndex(_manager, x, y, z)) % textureColumns) * textureWidth) + 0.002f,
                                (((textureIndex + blockDefinition.GetTopTextureIndex(_manager, x, y, z)) / textureColumns) * textureWidth) + 0.002f);

                            Vector2[] points = new[] {
                                textureOffset,
                                new Vector2(textureOffset.X + textureSize.X, textureOffset.Y),
                                textureOffset + textureSize,
                                new Vector2(textureOffset.X, textureOffset.Y + textureSize.X)
                            };
                            int rotation = -blockDefinition.GetTopTextureRotation(_manager, x, y, z);

                            int localOffset = vertices.Count;
                            vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 0, y + 1, z + 1), new Vector3(0, 0, 1), points[(4 + rotation) % 4]));
                            vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 1, y + 1, z + 1), new Vector3(0, 0, 1), points[(5 + rotation) % 4]));
                            vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 0, y + 0, z + 1), new Vector3(0, 0, 1), points[(7 + rotation) % 4]));
                            vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 1, y + 0, z + 1), new Vector3(0, 0, 1), points[(6 + rotation) % 4]));
                            index.Add(localOffset + 0);
                            index.Add(localOffset + 1);
                            index.Add(localOffset + 3);
                            index.Add(localOffset + 0);
                            index.Add(localOffset + 3);
                            index.Add(localOffset + 2);
                        }

                        ushort           bottomBlock          = _manager.GetBlock((ChunkPosition.Value * Chunk.CHUNKSIZE) + new Index3(x, y, z - 1));
                        IBlockDefinition bottomBlockDefintion = DefinitionManager.GetBlockDefinitionByIndex(bottomBlock);


                        // Unten
                        if (bottomBlock == 0 || (!bottomBlockDefintion.IsTopSolidWall(_manager, x, y, z - 1) && bottomBlock != block))
                        {
                            textureOffset = new Vector2(
                                (((textureIndex + blockDefinition.GetBottomTextureIndex(_manager, x, y, z)) % textureColumns) * textureWidth) + 0.002f,
                                (((textureIndex + blockDefinition.GetBottomTextureIndex(_manager, x, y, z)) / textureColumns) * textureWidth) + 0.002f);

                            Vector2[] points = new[] {
                                textureOffset,
                                new Vector2(textureOffset.X + textureSize.X, textureOffset.Y),
                                textureOffset + textureSize,
                                new Vector2(textureOffset.X, textureOffset.Y + textureSize.X)
                            };
                            int rotation = -blockDefinition.GetBottomTextureRotation(_manager, x, y, z);

                            int localOffset = vertices.Count;
                            vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 1, y + 1, z + 0), new Vector3(0, 0, -1), points[(6 + rotation) % 4]));
                            vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 0, y + 1, z + 0), new Vector3(0, 0, -1), points[(7 + rotation) % 4]));
                            vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 1, y + 0, z + 0), new Vector3(0, 0, -1), points[(5 + rotation) % 4]));
                            vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 0, y + 0, z + 0), new Vector3(0, 0, -1), points[(4 + rotation) % 4]));
                            index.Add(localOffset + 0);
                            index.Add(localOffset + 1);
                            index.Add(localOffset + 3);
                            index.Add(localOffset + 0);
                            index.Add(localOffset + 3);
                            index.Add(localOffset + 2);
                        }

                        ushort           southBlock          = _manager.GetBlock((ChunkPosition.Value * Chunk.CHUNKSIZE) + new Index3(x, y + 1, z));
                        IBlockDefinition southBlockDefintion = DefinitionManager.GetBlockDefinitionByIndex(southBlock);

                        // South
                        if (southBlock == 0 || (!southBlockDefintion.IsNorthSolidWall(_manager, x, y + 1, z) && southBlock != block))
                        {
                            textureOffset = new Vector2(
                                (((textureIndex + blockDefinition.GetSouthTextureIndex(_manager, x, y, z)) % textureColumns) * textureWidth) + 0.002f,
                                (((textureIndex + blockDefinition.GetSouthTextureIndex(_manager, x, y, z)) / textureColumns) * textureWidth) + 0.002f);

                            Vector2[] points = new[] {
                                textureOffset,
                                new Vector2(textureOffset.X + textureSize.X, textureOffset.Y),
                                textureOffset + textureSize,
                                new Vector2(textureOffset.X, textureOffset.Y + textureSize.X)
                            };

                            int rotation = -blockDefinition.GetSouthTextureRotation(_manager, x, y, z);

                            int localOffset = vertices.Count;
                            vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 0, y + 1, z + 0), new Vector3(0, 1, 0), points[(6 + rotation) % 4]));
                            vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 1, y + 1, z + 0), new Vector3(0, 1, 0), points[(7 + rotation) % 4]));
                            vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 0, y + 1, z + 1), new Vector3(0, 1, 0), points[(5 + rotation) % 4]));
                            vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 1, y + 1, z + 1), new Vector3(0, 1, 0), points[(4 + rotation) % 4]));
                            index.Add(localOffset + 0);
                            index.Add(localOffset + 1);
                            index.Add(localOffset + 3);
                            index.Add(localOffset + 0);
                            index.Add(localOffset + 3);
                            index.Add(localOffset + 2);
                        }

                        ushort           northBlock          = _manager.GetBlock((ChunkPosition.Value * Chunk.CHUNKSIZE) + new Index3(x, y - 1, z));
                        IBlockDefinition northBlockDefintion = DefinitionManager.GetBlockDefinitionByIndex(northBlock);

                        // North
                        if (northBlock == 0 || (!northBlockDefintion.IsSouthSolidWall(_manager, x, y - 1, z) && northBlock != block))
                        {
                            textureOffset = new Vector2(
                                (((textureIndex + blockDefinition.GetNorthTextureIndex(_manager, x, y, z)) % textureColumns) * textureWidth) + 0.002f,
                                (((textureIndex + blockDefinition.GetNorthTextureIndex(_manager, x, y, z)) / textureColumns) * textureWidth) + 0.002f);

                            Vector2[] points = new[] {
                                textureOffset,
                                new Vector2(textureOffset.X + textureSize.X, textureOffset.Y),
                                textureOffset + textureSize,
                                new Vector2(textureOffset.X, textureOffset.Y + textureSize.X)
                            };
                            int rotation = -blockDefinition.GetNorthTextureRotation(_manager, x, y, z);

                            int localOffset = vertices.Count;
                            vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 0, y + 0, z + 1), new Vector3(0, -1, 0), points[(4 + rotation) % 4]));
                            vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 1, y + 0, z + 1), new Vector3(0, -1, 0), points[(5 + rotation) % 4]));
                            vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 0, y + 0, z + 0), new Vector3(0, -1, 0), points[(7 + rotation) % 4]));
                            vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 1, y + 0, z + 0), new Vector3(0, -1, 0), points[(6 + rotation) % 4]));
                            index.Add(localOffset + 0);
                            index.Add(localOffset + 1);
                            index.Add(localOffset + 3);
                            index.Add(localOffset + 0);
                            index.Add(localOffset + 3);
                            index.Add(localOffset + 2);
                        }

                        ushort           westBlock          = _manager.GetBlock((ChunkPosition.Value * Chunk.CHUNKSIZE) + new Index3(x - 1, y, z));
                        IBlockDefinition westBlockDefintion = DefinitionManager.GetBlockDefinitionByIndex(westBlock);

                        // West
                        if (westBlock == 0 || (!westBlockDefintion.IsEastSolidWall(_manager, x - 1, y, z) && westBlock != block))
                        {
                            textureOffset = new Vector2(
                                (((textureIndex + blockDefinition.GetWestTextureIndex(_manager, x, y, z)) % textureColumns) * textureWidth) + 0.002f,
                                (((textureIndex + blockDefinition.GetWestTextureIndex(_manager, x, y, z)) / textureColumns) * textureWidth) + 0.002f);

                            Vector2[] points = new[] {
                                textureOffset,
                                new Vector2(textureOffset.X + textureSize.X, textureOffset.Y),
                                textureOffset + textureSize,
                                new Vector2(textureOffset.X, textureOffset.Y + textureSize.X)
                            };
                            int rotation = -blockDefinition.GetWestTextureRotation(_manager, x, y, z);

                            int localOffset = vertices.Count;
                            vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 0, y + 1, z + 0), new Vector3(-1, 0, 0), points[(7 + rotation) % 4]));
                            vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 0, y + 1, z + 1), new Vector3(-1, 0, 0), points[(4 + rotation) % 4]));
                            vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 0, y + 0, z + 0), new Vector3(-1, 0, 0), points[(6 + rotation) % 4]));
                            vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 0, y + 0, z + 1), new Vector3(-1, 0, 0), points[(5 + rotation) % 4]));
                            index.Add(localOffset + 0);
                            index.Add(localOffset + 1);
                            index.Add(localOffset + 3);
                            index.Add(localOffset + 0);
                            index.Add(localOffset + 3);
                            index.Add(localOffset + 2);
                        }

                        ushort           eastBlock          = _manager.GetBlock((ChunkPosition.Value * Chunk.CHUNKSIZE) + new Index3(x + 1, y, z));
                        IBlockDefinition eastBlockDefintion = DefinitionManager.GetBlockDefinitionByIndex(eastBlock);

                        // Ost
                        if (eastBlock == 0 || (!eastBlockDefintion.IsWestSolidWall(_manager, x + 1, y, z) && eastBlock != block))
                        {
                            textureOffset = new Vector2(
                                (((textureIndex + blockDefinition.GetEastTextureIndex(_manager, x, y, z)) % textureColumns) * textureWidth) + 0.002f,
                                (((textureIndex + blockDefinition.GetEastTextureIndex(_manager, x, y, z)) / textureColumns) * textureWidth) + 0.002f);

                            Vector2[] points = new[] {
                                textureOffset,
                                new Vector2(textureOffset.X + textureSize.X, textureOffset.Y),
                                textureOffset + textureSize,
                                new Vector2(textureOffset.X, textureOffset.Y + textureSize.X)
                            };

                            int rotation = -blockDefinition.GetEastTextureRotation(_manager, x, y, z);

                            int localOffset = vertices.Count;
                            vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 1, y + 1, z + 1), new Vector3(1, 0, 0), points[(5 + rotation) % 4]));
                            vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 1, y + 1, z + 0), new Vector3(1, 0, 0), points[(6 + rotation) % 4]));
                            vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 1, y + 0, z + 1), new Vector3(1, 0, 0), points[(4 + rotation) % 4]));
                            vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 1, y + 0, z + 0), new Vector3(1, 0, 0), points[(7 + rotation) % 4]));
                            index.Add(localOffset + 0);
                            index.Add(localOffset + 1);
                            index.Add(localOffset + 3);
                            index.Add(localOffset + 0);
                            index.Add(localOffset + 3);
                            index.Add(localOffset + 2);
                        }
                    }
                }
            }

            vertexCount = vertices.Count;
            indexCount  = index.Count;

            VertexBuffer vb2 = null;
            IndexBuffer  ib2 = null;

            if (vertexCount > 0)
            {
                try
                {
                    vb2 = new VertexBuffer(graphicsDevice, VertexPositionNormalTexture.VertexDeclaration, vertexCount, BufferUsage.WriteOnly);
                    vb2.SetData <VertexPositionNormalTexture>(vertices.ToArray());

                    ib2 = new IndexBuffer(graphicsDevice, IndexElementSize.ThirtyTwoBits, indexCount, BufferUsage.WriteOnly);
                    ib2.SetData <int>(index.ToArray());
                }
                catch (Exception) { }
            }

            VertexBuffer vbOld = vb;
            IndexBuffer  ibOld = ib;

            lock (this)
            {
                vb     = vb2;
                ib     = ib2;
                loaded = true;
            }

            if (vbOld != null)
            {
                vbOld.Dispose();
            }

            if (ibOld != null)
            {
                ibOld.Dispose();
            }

            lastReset = chunk.ChangeCounter;
        }
Beispiel #3
0
        protected override void OnDrawContent(SpriteBatch batch, Rectangle contentArea, GameTime gameTime, float alpha)
        {
            if (!Visible || !Enabled)
            {
                return;
            }

            //Calculate FPS
            framecount++;
            seconds += gameTime.ElapsedGameTime.TotalSeconds;
            if (framecount == 10)
            {
                lastfps    = seconds / framecount;
                framecount = 0;
                seconds    = 0;
            }

            framebuffer[bufferindex++] = (float)gameTime.ElapsedGameTime.TotalSeconds;
            bufferindex %= buffersize;

            //Draw Control Info
            controlInfo.Text = Languages.OctoClient.ActiveControls + ": " + ScreenManager.ActiveScreen.Controls.Count;

            //Draw Position
            string pos = "pos: " + Player.ActorHost.Position.ToString();

            position.Text = pos;

            //Draw Rotation
            float  grad = (Player.ActorHost.Angle / MathHelper.TwoPi) * 360;
            string rot  = "rot: " +
                          (((Player.ActorHost.Angle / MathHelper.TwoPi) * 360) % 360).ToString("0.00") + " / " +
                          ((Player.ActorHost.Tilt / MathHelper.TwoPi) * 360).ToString("0.00");

            rotation.Text = rot;

            //Draw Fps
            string fpsString = "fps: " + (1f / lastfps).ToString("0.00");

            fps.Text = fpsString;

            //Draw Loaded Chunks
            loadedChunks.Text = Languages.OctoClient.LoadedChunks + ": " + resMan.GlobalChunkCache.LoadedChunks;

            //Get Number of Loaded Items/Blocks
            loadedInfo.Text = "" + (DefinitionManager.GetItemDefinitions() as IList <IItemDefinition>).Count + " " + Languages.OctoClient.Items + " - " +
                              (DefinitionManager.GetBlockDefinitions() as IList <IItemDefinition>).Count + " " + Languages.OctoClient.Blocks;

            //Additional Play Information

            //Active Tool
            if (Player.ActorHost.ActiveTool != null)
            {
                activeTool.Text = Languages.OctoClient.ActiveItemTool + ": " + Player.ActorHost.ActiveTool.Definition.Name;
            }

            //Fly Info
            if (Player.ActorHost.Player.FlyMode)
            {
                flyInfo.Text = Languages.OctoClient.FlymodeEnabled;
            }
            else
            {
                flyInfo.Text = "";
            }

            //Draw Box Information
            if (Player.SelectedBox.HasValue)
            {
                string selection = "box: " +
                                   Player.SelectedBox.Value.ToString() + " on " +
                                   Player.SelectedSide.ToString() + " (" +
                                   Player.SelectedPoint.Value.X.ToString("0.00") + "/" +
                                   Player.SelectedPoint.Value.Y.ToString("0.00") + ") -> " +
                                   Player.SelectedEdge.ToString() + " -> " + Player.SelectedCorner.ToString();
                box.Text = selection;
            }
            else
            {
                box.Text = "";
            }
        }