Beispiel #1
0
        /// <summary>Add a block face to a VBO using flat lighting. Same light color is used for all 4 vertices.</summary>
        public static void AddBlockFaceToVbo(ChunkVbo chunkVbo, Face face, float x, float y, float z, byte lightColor)
        {
            var colorRgb = new ColorRgb(lightColor, lightColor, lightColor);

            AddBlockFaceToVbo(chunkVbo, face, x, y, z, new[] { colorRgb, colorRgb, colorRgb, colorRgb });
        }
Beispiel #2
0
        private static void AddBlockFaceToVbo(ChunkVbo chunkVbo, Face face, float x0, float y0, float z0, ColorRgb[] colors)
        {
            //position calculations
            float x1 = x0 + 1f;             //x starting left at 0 in block
            float y1 = y0 + 1f;             //y starting bottom at 0 in block
            float z1 = z0 + 1f;             //z starting back at 0 in block

            switch (face)
            {
            case Face.Front:
                // v0-v1-v2-v3 (front)
                chunkVbo.Positions.Add(new Vector3(x1, y1, z1));
                chunkVbo.Positions.Add(new Vector3(x0, y1, z1));
                chunkVbo.Positions.Add(new Vector3(x0, y0, z1));
                chunkVbo.Positions.Add(new Vector3(x1, y0, z1));
                break;

            case Face.Right:
                // v5-v0-v3-v4 (right)
                chunkVbo.Positions.Add(new Vector3(x1, y1, z0));
                chunkVbo.Positions.Add(new Vector3(x1, y1, z1));
                chunkVbo.Positions.Add(new Vector3(x1, y0, z1));
                chunkVbo.Positions.Add(new Vector3(x1, y0, z0));
                break;

            case Face.Top:
                // v5-v6-v1-v0 (top)
                chunkVbo.Positions.Add(new Vector3(x1, y1, z0));
                chunkVbo.Positions.Add(new Vector3(x0, y1, z0));
                chunkVbo.Positions.Add(new Vector3(x0, y1, z1));
                chunkVbo.Positions.Add(new Vector3(x1, y1, z1));
                break;

            case Face.Left:
                // v1-v6-v7-v2 (left)
                chunkVbo.Positions.Add(new Vector3(x0, y1, z1));
                chunkVbo.Positions.Add(new Vector3(x0, y1, z0));
                chunkVbo.Positions.Add(new Vector3(x0, y0, z0));
                chunkVbo.Positions.Add(new Vector3(x0, y0, z1));
                break;

            case Face.Bottom:
                // v3-v2-v7-v4 (bottom)
                chunkVbo.Positions.Add(new Vector3(x1, y0, z1));
                chunkVbo.Positions.Add(new Vector3(x0, y0, z1));
                chunkVbo.Positions.Add(new Vector3(x0, y0, z0));
                chunkVbo.Positions.Add(new Vector3(x1, y0, z0));
                break;

            case Face.Back:
                // v6-v5-v4-v7 (back)
                chunkVbo.Positions.Add(new Vector3(x0, y1, z0));
                chunkVbo.Positions.Add(new Vector3(x1, y1, z0));
                chunkVbo.Positions.Add(new Vector3(x1, y0, z0));
                chunkVbo.Positions.Add(new Vector3(x0, y0, z0));
                break;
            }

            if (Settings.OutlineChunks)             //highlights chunk edges in yellow, the actual chunk edge line is the line between the 2 yellow block strips (use /outline to toggle)
            {
                var rgbYellow = new ColorRgb(255, 255, 50);
                chunkVbo.Colors.AddRange(WorldData.IsOnChunkBorder((int)x0, (int)z0) ? new[] { rgbYellow, rgbYellow, rgbYellow, rgbYellow } : colors);
            }
            else
            {
                chunkVbo.Colors.AddRange(colors);
            }
            chunkVbo.TexCoords.AddRange(TexCoords);
        }
Beispiel #3
0
 /// <summary>Add a block face to a VBO using smooth shade lighting. Each vertex has a unique lighting color.</summary>
 public static void AddBlockFaceToVbo(ChunkVbo chunkVbo, Face face, float x, float y, float z, byte v0Color, byte v1Color, byte v2Color, byte v3Color)
 {
     AddBlockFaceToVbo(chunkVbo, face, x, y, z, new[] { new ColorRgb(v0Color, v0Color, v0Color), new ColorRgb(v1Color, v1Color, v1Color), new ColorRgb(v2Color, v2Color, v2Color), new ColorRgb(v3Color, v3Color, v3Color) });
 }
Beispiel #4
0
        /// <summary>Decide if this block face needs to be added to a VBO and rendered. XYZ are world relative coordinates.</summary>
        private void AddBlockFace(ref Block block, Face face, int x, int y, int z)
        {
            int adjacentX = x, adjacentY = y, adjacentZ = z;

            //check if surface is adjacent to another solid texture (if so dont draw it)
            switch (face)
            {
                case Face.Right: adjacentX++; break;
                case Face.Left: adjacentX--; break;
                case Face.Top: adjacentY++; break;
                case Face.Bottom: adjacentY--; break;
                case Face.Front: adjacentZ++; break;
                default: adjacentZ--; break; //back
            }

            //todo: possible optimization, get the Block from this.Blocks array when x/z are NOT on chunk edge, would result in not looking up chunk in World.GetBlock 99% of time, but tiny bit more checks for blocks on edges, try it out some other time
            //-could accept a bool param needToCheckOverChunkEdge, the DTL logic would always pass false for it because its alrdy figured it out, so both ways get the optimization
            #region todo: none of this would need to be checked for the DTL added faces, could grab the block straight out of this chunk instead, wouldnt need to check adjacent block either
            if (!WorldData.IsValidBlockLocation(adjacentX, adjacentY, adjacentZ)) return; //adjacent block is outside the world so theres no need to render this face
            var adjacentBlock = WorldData.GetBlock(adjacentX, adjacentY, adjacentZ);
            if (!adjacentBlock.IsTransparent) return; //no need to render this face because the adjacent face is not transparent

            //dont render inner faces of neighboring transparent blocks of same type, makes trees hollow and doesnt draw additional water faces under water
            //improves fps by limiting the number of faces needed and looks better on weak laptop gpu's as well (note: we know the adjacent face is transparent if we get this far)
            if (block.IsTransparent && block.Type == adjacentBlock.Type) return;
            #endregion

            var texture = Block.FaceTexture(block.Type, face);
            //check if there is an existing vbo for this chunk/texture to add this face to
            if (_chunkVbos[(int)texture] == null)
            {
                //vbo not created yet for this chunk/texture so we need to start one
                _chunkVbos[(int)texture] = new ChunkVbo(ref block, TextureLoader.GetBlockTexture(texture));
            }

            //we need position 4 no matter what, so retrieve it here, position 4 is used for the lighting values of all 4 vertices of this face when smooth lighting is off
            byte lightColor = WorldData.GetBlockLightColor(adjacentX, adjacentY, adjacentZ);

            _shortestFaceHeightTemp = Math.Min(_shortestFaceHeightTemp, y);

            if (block.Type == Block.BlockType.Leaves || block.Type == Block.BlockType.SnowLeaves)
            {
                //dont bother with smooth lighting for leaves, it would rarely matter anyway
                if (face == Face.Bottom) lightColor = (byte)(lightColor * 0.6); //make bottom leaves faces darker by giving them 60% of the light they would otherwise have
                BlockRender.AddBlockFaceToVbo(_chunkVbos[(int)texture], face, x, y, z, lightColor);
                return;
            }

            if (Config.SmoothLighting)
            {
                #region Smooth Lighting
                //SMOOTH LIGHTING MAP (block 4 is used by all 4 vertices, blocks 1,3,5,7 are used by 2 vertices each, blocks 0,2,6,8 are used by one vertex only)
                //	0  1  2
                //   v1 v0
                //	3  4  5
                //   v2 v3
                //	6  7  8
                var xyz = new Position[9];
                var smoothLighting = new byte[9];
                smoothLighting[4] = lightColor; //we already have the directly adjacent color which goes in position 4
                switch (face)
                {
                    case Face.Right: //X is constant
                        xyz[0] = new Position(adjacentX, adjacentY + 1, adjacentZ + 1);
                        xyz[1] = new Position(adjacentX, adjacentY + 1, adjacentZ);
                        xyz[2] = new Position(adjacentX, adjacentY + 1, adjacentZ - 1);
                        xyz[3] = new Position(adjacentX, adjacentY, adjacentZ + 1);
                        xyz[5] = new Position(adjacentX, adjacentY, adjacentZ - 1);
                        xyz[6] = new Position(adjacentX, adjacentY - 1, adjacentZ + 1);
                        xyz[7] = new Position(adjacentX, adjacentY - 1, adjacentZ);
                        xyz[8] = new Position(adjacentX, adjacentY - 1, adjacentZ - 1);
                        break;
                    case Face.Left: //X is constant
                        xyz[0] = new Position(adjacentX, adjacentY + 1, adjacentZ - 1);
                        xyz[1] = new Position(adjacentX, adjacentY + 1, adjacentZ);
                        xyz[2] = new Position(adjacentX, adjacentY + 1, adjacentZ + 1);
                        xyz[3] = new Position(adjacentX, adjacentY, adjacentZ - 1);
                        xyz[5] = new Position(adjacentX, adjacentY, adjacentZ + 1);
                        xyz[6] = new Position(adjacentX, adjacentY - 1, adjacentZ - 1);
                        xyz[7] = new Position(adjacentX, adjacentY - 1, adjacentZ);
                        xyz[8] = new Position(adjacentX, adjacentY - 1, adjacentZ + 1);
                        break;
                    case Face.Top: //Y is constant
                        xyz[0] = new Position(adjacentX - 1, adjacentY, adjacentZ - 1);
                        xyz[1] = new Position(adjacentX, adjacentY, adjacentZ - 1);
                        xyz[2] = new Position(adjacentX + 1, adjacentY, adjacentZ - 1);
                        xyz[3] = new Position(adjacentX - 1, adjacentY, adjacentZ);
                        xyz[5] = new Position(adjacentX + 1, adjacentY, adjacentZ);
                        xyz[6] = new Position(adjacentX - 1, adjacentY, adjacentZ + 1);
                        xyz[7] = new Position(adjacentX, adjacentY, adjacentZ + 1);
                        xyz[8] = new Position(adjacentX + 1, adjacentY, adjacentZ + 1);
                        break;
                    case Face.Bottom: //Y is constant
                        xyz[0] = new Position(adjacentX - 1, adjacentY, adjacentZ + 1);
                        xyz[1] = new Position(adjacentX, adjacentY, adjacentZ + 1);
                        xyz[2] = new Position(adjacentX + 1, adjacentY, adjacentZ + 1);
                        xyz[3] = new Position(adjacentX - 1, adjacentY, adjacentZ);
                        xyz[5] = new Position(adjacentX + 1, adjacentY, adjacentZ);
                        xyz[6] = new Position(adjacentX - 1, adjacentY, adjacentZ - 1);
                        xyz[7] = new Position(adjacentX, adjacentY, adjacentZ - 1);
                        xyz[8] = new Position(adjacentX + 1, adjacentY, adjacentZ - 1);
                        break;
                    case Face.Front: //Z is constant
                        xyz[0] = new Position(adjacentX - 1, adjacentY + 1, adjacentZ);
                        xyz[1] = new Position(adjacentX, adjacentY + 1, adjacentZ);
                        xyz[2] = new Position(adjacentX + 1, adjacentY + 1, adjacentZ);
                        xyz[3] = new Position(adjacentX - 1, adjacentY, adjacentZ);
                        xyz[5] = new Position(adjacentX + 1, adjacentY, adjacentZ);
                        xyz[6] = new Position(adjacentX - 1, adjacentY - 1, adjacentZ);
                        xyz[7] = new Position(adjacentX, adjacentY - 1, adjacentZ);
                        xyz[8] = new Position(adjacentX + 1, adjacentY - 1, adjacentZ);
                        break;
                    default: //Back; Z is constant
                        xyz[0] = new Position(adjacentX + 1, adjacentY + 1, adjacentZ);
                        xyz[1] = new Position(adjacentX, adjacentY + 1, adjacentZ);
                        xyz[2] = new Position(adjacentX - 1, adjacentY + 1, adjacentZ);
                        xyz[3] = new Position(adjacentX + 1, adjacentY, adjacentZ);
                        xyz[5] = new Position(adjacentX - 1, adjacentY, adjacentZ);
                        xyz[6] = new Position(adjacentX + 1, adjacentY - 1, adjacentZ);
                        xyz[7] = new Position(adjacentX, adjacentY - 1, adjacentZ);
                        xyz[8] = new Position(adjacentX - 1, adjacentY - 1, adjacentZ);
                        break;
                }

                //need to know if blocks on positions 1,3,5,7 are transparent, each value is used twice
                //-for example neither 1 or 5 are transparent, then vertex0 should not have any influence from light at position 2 and should use the darkest value instead for a dark corner
                //		-position 2 might be on the other side of a wall and then we get sunlight coming into ceiling corners etc
                //-if the coords of any of these positions are outside the world then consider them transparent
                bool transparent1 = !xyz[1].IsValidBlockLocation || xyz[1].GetBlock().IsTransparent;
                bool transparent3 = !xyz[3].IsValidBlockLocation || xyz[3].GetBlock().IsTransparent;
                bool transparent5 = !xyz[5].IsValidBlockLocation || xyz[5].GetBlock().IsTransparent;
                bool transparent7 = !xyz[7].IsValidBlockLocation || xyz[7].GetBlock().IsTransparent;

                smoothLighting[0] = transparent1 || transparent3 ? xyz[0].LightColor : Lighting.DARKEST_COLOR;
                smoothLighting[1] = xyz[1].LightColor;
                smoothLighting[2] = transparent1 || transparent5 ? xyz[2].LightColor : Lighting.DARKEST_COLOR;
                smoothLighting[3] = xyz[3].LightColor;
                smoothLighting[5] = xyz[5].LightColor;
                smoothLighting[6] = transparent3 || transparent7 ? xyz[6].LightColor : Lighting.DARKEST_COLOR;
                smoothLighting[7] = xyz[7].LightColor;
                smoothLighting[8] = transparent5 || transparent7 ? xyz[8].LightColor : Lighting.DARKEST_COLOR;

                //average 4 colors to get the color for each vertex
                var v0Color = (byte)((smoothLighting[1] + smoothLighting[2] + smoothLighting[4] + smoothLighting[5]) / 4);
                var v1Color = (byte)((smoothLighting[0] + smoothLighting[1] + smoothLighting[3] + smoothLighting[4]) / 4);
                var v2Color = (byte)((smoothLighting[3] + smoothLighting[4] + smoothLighting[6] + smoothLighting[7]) / 4);
                var v3Color = (byte)((smoothLighting[4] + smoothLighting[5] + smoothLighting[7] + smoothLighting[8]) / 4);

                BlockRender.AddBlockFaceToVbo(_chunkVbos[(int)texture], face, x, y, z, v0Color, v1Color, v2Color, v3Color);
                #endregion
            }
            else //use simple lighting
            {
                BlockRender.AddBlockFaceToVbo(_chunkVbos[(int)texture], face, x, y, z, lightColor);
            }
        }
Beispiel #5
0
        private static void AddBlockFaceToVbo(ChunkVbo chunkVbo, Face face, float x0, float y0, float z0, ColorRgb[] colors)
        {
            //position calculations
            float x1 = x0 + 1f; //x starting left at 0 in block
            float y1 = y0 + 1f; //y starting bottom at 0 in block
            float z1 = z0 + 1f; //z starting back at 0 in block

            switch (face)
            {
                case Face.Front:
                    // v0-v1-v2-v3 (front)
                    chunkVbo.Positions.Add(new Vector3(x1, y1, z1));
                    chunkVbo.Positions.Add(new Vector3(x0, y1, z1));
                    chunkVbo.Positions.Add(new Vector3(x0, y0, z1));
                    chunkVbo.Positions.Add(new Vector3(x1, y0, z1));
                    break;
                case Face.Right:
                    // v5-v0-v3-v4 (right)
                    chunkVbo.Positions.Add(new Vector3(x1, y1, z0));
                    chunkVbo.Positions.Add(new Vector3(x1, y1, z1));
                    chunkVbo.Positions.Add(new Vector3(x1, y0, z1));
                    chunkVbo.Positions.Add(new Vector3(x1, y0, z0));
                    break;
                case Face.Top:
                    // v5-v6-v1-v0 (top)
                    chunkVbo.Positions.Add(new Vector3(x1, y1, z0));
                    chunkVbo.Positions.Add(new Vector3(x0, y1, z0));
                    chunkVbo.Positions.Add(new Vector3(x0, y1, z1));
                    chunkVbo.Positions.Add(new Vector3(x1, y1, z1));
                    break;
                case Face.Left:
                    // v1-v6-v7-v2 (left)
                    chunkVbo.Positions.Add(new Vector3(x0, y1, z1));
                    chunkVbo.Positions.Add(new Vector3(x0, y1, z0));
                    chunkVbo.Positions.Add(new Vector3(x0, y0, z0));
                    chunkVbo.Positions.Add(new Vector3(x0, y0, z1));
                    break;
                case Face.Bottom:
                    // v3-v2-v7-v4 (bottom)
                    chunkVbo.Positions.Add(new Vector3(x1, y0, z1));
                    chunkVbo.Positions.Add(new Vector3(x0, y0, z1));
                    chunkVbo.Positions.Add(new Vector3(x0, y0, z0));
                    chunkVbo.Positions.Add(new Vector3(x1, y0, z0));
                    break;
                case Face.Back:
                    // v6-v5-v4-v7 (back)
                    chunkVbo.Positions.Add(new Vector3(x0, y1, z0));
                    chunkVbo.Positions.Add(new Vector3(x1, y1, z0));
                    chunkVbo.Positions.Add(new Vector3(x1, y0, z0));
                    chunkVbo.Positions.Add(new Vector3(x0, y0, z0));
                    break;
            }

            if (Settings.OutlineChunks) //highlights chunk edges in yellow, the actual chunk edge line is the line between the 2 yellow block strips (use /outline to toggle)
            {
                var rgbYellow = new ColorRgb(255, 255, 50);
                chunkVbo.Colors.AddRange(WorldData.IsOnChunkBorder((int)x0, (int)z0) ? new[] {rgbYellow, rgbYellow, rgbYellow, rgbYellow} : colors);
            }
            else
            {
                chunkVbo.Colors.AddRange(colors);
            }
            chunkVbo.TexCoords.AddRange(TexCoords);
        }
Beispiel #6
0
 /// <summary>Add a block face to a VBO using flat lighting. Same light color is used for all 4 vertices.</summary>
 public static void AddBlockFaceToVbo(ChunkVbo chunkVbo, Face face, float x, float y, float z, byte lightColor)
 {
     var colorRgb = new ColorRgb(lightColor, lightColor, lightColor);
     AddBlockFaceToVbo(chunkVbo, face, x, y, z, new[] {colorRgb, colorRgb, colorRgb, colorRgb});
 }
Beispiel #7
0
 /// <summary>Add a block face to a VBO using smooth shade lighting. Each vertex has a unique lighting color.</summary>
 public static void AddBlockFaceToVbo(ChunkVbo chunkVbo, Face face, float x, float y, float z, byte v0Color, byte v1Color, byte v2Color, byte v3Color)
 {
     AddBlockFaceToVbo(chunkVbo, face, x, y, z, new[] { new ColorRgb(v0Color, v0Color, v0Color), new ColorRgb(v1Color, v1Color, v1Color), new ColorRgb(v2Color, v2Color, v2Color), new ColorRgb(v3Color, v3Color, v3Color) });
 }