/// <summary>
    /// 法线映射
    /// </summary>
    /// <param name="vertex"></param>
    /// <returns></returns>
    public Color01 NormalMappingWithLambert(Vertex vertex, Mesh mesh, Light light)
    {
        // 从法线贴图中取出法线(切线空间下的)
        Color01 UndecryptedNormal = Texture.Tex2D(normalTexture, vertex.u, vertex.v);
        // 把法线从[0,1]区间变回到[-1,1]区间
        Vector3 normal = new Vector3(
            UndecryptedNormal.R * 2 - 1,
            UndecryptedNormal.G * 2 - 1,
            UndecryptedNormal.B * 2 - 1
            );

        // 获得世界坐标下的法线
        Vector3 worldNormal = mesh.mMatrix * vertex.normal;

        worldNormal.Normlize();
        // 获得世界坐标下的切线
        Vector3 worldTangent = mesh.mMatrix * vertex.tangent;

        worldTangent.Normlize();
        // 获得世界坐标下的副切线
        Vector3 worldBinormal = Vector3.Cross(worldNormal, worldTangent) * vertex.tangent.W;

        worldBinormal.Normlize();

        // 构建 切线-世界 变换矩阵
        Matrix4x4 TtoW = new Matrix4x4();

        TtoW.Identity();

        TtoW.value[0, 0] = worldTangent.X;
        TtoW.value[1, 0] = worldTangent.Y;
        TtoW.value[2, 0] = worldTangent.Z;

        TtoW.value[0, 1] = worldBinormal.X;
        TtoW.value[1, 1] = worldBinormal.Y;
        TtoW.value[2, 1] = worldBinormal.Z;

        TtoW.value[0, 2] = worldNormal.X;
        TtoW.value[1, 2] = worldNormal.Y;
        TtoW.value[2, 2] = worldNormal.Z;

        // 将切线空间的法线变为世界坐标
        normal = TtoW * normal;
        normal.Normlize();

        // 增大凹凸比例
        normal.X *= 3;
        normal.Y *= 3;
        normal.Z *= MathF.Sqrt(1 - MathF.Clamp01(normal.X * normal.X + normal.Y * normal.Y));

        Color01 albedo = Texture.Tex2D(texture2D, vertex.u, vertex.v) * vertex.color;

        Vector3 worldPos = mesh.mMatrix * vertex.modelSpacePos;

        float radiance = Vector3.Dot(normal, light.GetDirection(worldPos)) * 0.5f + 0.5f;

        Color01 diffuse = albedo * radiance;

        return(diffuse);
    }
Пример #2
0
 static private Color01 _grad2(Color01 col1, Color01 col2, double x)
 {
     return(new Color01(
                (col2.R - col1.R) * x + col1.R,
                (col2.G - col1.G) * x + col1.G,
                (col2.B - col1.B) * x + col1.B
                ));
 }
    /// <summary>
    /// 基于半兰伯特光照模型的光照
    /// </summary>
    /// <param name="vertex"></param>
    /// <returns></returns>
    public Color01 LightingWithLambert(Vertex vertex, Mesh mesh, Light light)
    {
        // 将顶点的法线变换到世界空间下,对于一个只包含旋转变换的变换矩阵,他是正交矩阵
        // 使用m矩阵变换法线(仅适用于只发生旋转的物体)
        Vector3 worldNormal = mesh.mMatrix * vertex.normal;

        worldNormal.Normlize();

        // 获得顶点当前所在世界坐标
        Vector3 worldPos = mesh.mMatrix * vertex.modelSpacePos;

        // 根据平行光方向及当前法线方向,
        // 计算当前像素的辐照度
        Vector3 lightDirection = light.GetDirection(worldPos);

        // 使用半兰伯特表达式计算辐照度
        float radiance = Vector3.Dot(worldNormal, lightDirection) * 0.5f + 0.5f;

        // 获得贴图颜色
        //Color01 albedo = Texture.Tex2D(texture2D, vertex.u, vertex.v);
        Color01 albedo = Color01.White;

        // 使用Blinn-Phong模型计算高光反射

        // 获得世界坐标下的视角方向
        Vector3 worldViewDir = camera.position - worldPos;

        // 计算half向量
        Vector3 h = (worldViewDir + lightDirection);

        h.Normlize();

        // 光泽度
        float gloss = 32f;

        float spec = Math.Max(0, Vector3.Dot(h, worldNormal));

        // 计算高光反射
        Color01 specular = lightColor * (float)Math.Pow(spec, gloss);
        // 计算漫反射光照
        Color01 diffuse = albedo * radiance * light.lightColor;

        Color01 finalColor = diffuse + specular;

        // 计算光源衰减
        finalColor *= light.GetAtten(worldPos);

        finalColor.A = 1;

        return(finalColor);
    }
Пример #4
0
        public SpotLight(float outerAngle, float innerAngle, Vector3 spotDir, Color01 lightColor, Vector3 position)
        {
            this.outerAngle = outerAngle;
            this.cosPhi     = (float)Math.Cos(outerAngle * MathF.Deg2Rad);
            this.spotDir    = spotDir;



            this.innerAngle    = innerAngle;
            this.cosInnerAngle = (float)Math.Cos(innerAngle * MathF.Deg2Rad);

            this.lightColor = lightColor;

            this.position = position;
        }
Пример #5
0
    /// <summary>
    /// 基于半兰伯特光照模型的光照
    /// </summary>
    /// <param name="vertex"></param>
    /// <returns></returns>
    public Color01 LightingWithLambert(Vertex vertex)
    {
        // 将顶点的法线变换到世界空间下,对于一个只包含旋转变换的变换矩阵,他是正交矩阵
        // 使用m矩阵变换法线(仅适用于只发生旋转的物体)
        Vector3 worldNormal = vertex.mMatrix * vertex.normal;

        worldNormal.Normlize();

        // 根据平行光方向及当前法线方向,
        // 计算当前像素的辐照度
        //float radiance = Math.Max(0,Vector3.Dot(worldNormal, DirectionLight));
        // 使用半兰伯特表达式计算辐照度
        float radiance = Vector3.Dot(worldNormal, DirectionLight) * 0.5f + 0.5f;
        // 获得贴图颜色
        Color01 albedo = Texture.Tex2D(texture2D, vertex.u, vertex.v);

        // 使用Blinn-Phong模型计算高光反射

        // 获得顶点当前所在世界坐标
        Vector3 worldPos = vertex.mMatrix * vertex.modelSpacePos;

        // 获得世界坐标下的视角方向
        Vector3 worldViewDir = cameraPostion - worldPos;

        // 计算half向量
        Vector3 h = (worldViewDir + DirectionLight);

        h.Normlize();

        // 光泽度
        float gloss = 20f;

        // 计算高光反射
        Color01 specular = lightColor * (float)Math.Pow(Math.Max(0, Vector3.Dot(h, worldNormal)), gloss);
        // 计算漫反射光照
        Color01 diffuse = albedo * radiance * lightColor;

        Color01 finalColor = lightColor * radiance;

        finalColor.A = 1;

        return(finalColor);
    }
Пример #6
0
        private bool GetColorForLog(LogData log, out Color01 color)
        {
            switch (log.type)
            {
            default:
            case LogType.VeryVerbose:
            case LogType.Verbose:
            case LogType.Info:
                color = new Color01(0.3f, 0.3f, 0.3f, 0.7f);
                return(true);

            case LogType.Warning:
                color = new Color01(0.3f, 0.3f, 0f, 0.7f);
                return(true);

            case LogType.Error:
                color = new Color01(0.3f, 0f, 0f, 0.7f);
                return(true);
            }
        }
    /// <summary>
    /// 对应任意一种情况的光栅化线段的方法,
    /// 是Bresenham朴素算法的优化版,不出现浮点运算
    /// </summary>
    /// <param name="x1"></param>
    /// <param name="y1"></param>
    /// <param name="x2"></param>
    /// <param name="y2"></param>
    /// <param name="color"></param>
    private void DrawLine(Vertex v1, Vertex v2)
    {
        int x1 = (int)v1.pos.X;
        int y1 = (int)v1.pos.Y;
        int x2 = (int)v2.pos.X;
        int y2 = (int)v2.pos.Y;

        // 线段起点与终点在x轴上的距离(可能为负)
        int dx = x2 - x1;
        // 线段起点和终点在y轴上的距离(可能为负)
        int dy = y2 - y1;

        // 计算从x1到x2的方向是正方向还是负方向
        // 1<<1 = 2; 0<<1 = 0
        int stepX = ((dx > 0 ? 1 : 0) << 1) - 1;
        // 计算从y1到y2的方向是正方向还是负方向
        int stepY = ((dy > 0 ? 1 : 0) << 1) - 1;

        dx = Math.Abs(dx); dy = Math.Abs(dy);

        // 误差
        int eps = 0;

        if (dx > dy)
        {
            int y = y1;
            // 当x轴距离差更大时,将x作为自增变量
            for (int x = x1; x != x2; x += stepX)
            {
                float t = (float)(x - x1) / (float)(x2 - x1);

                // 当前顶点
                Vertex vertex = Vertex.LerpVertexData(v1, v2, t);
                vertex.pos.X = x;
                vertex.pos.Y = y;

                float z = vertex.pos.Z;

                // 对当前像素进行深度测试
                if (IsZTest)
                {
                    if (!ZTest(x, y, z))
                    {
                        continue;
                    }
                }

                // 透视插值矫正
                float realZ = 1.0f / z;
                vertex.u *= realZ;      // 变回原来的u
                vertex.v *= realZ;      // 变回原来的v

                float u = vertex.u;
                float v = vertex.v;

                // 对顶点颜色进行插值
                Color01 color = Color01.LerpColor(v1.color, v2.color, t);

                // 对纹理贴图进行采样
                Color01 textureColor = Texture.Tex2D(texture2D, u, v);

                Color01 finalColor = textureColor * color;

                if (drawingSkyBox)
                {
                    finalColor = CubeMap.TexCube(skyBox, vertex.modelSpacePos);
                    DrawPixel(x, y, finalColor);
                }
                else if (fragmentShaderOn)
                {
                    // 对所有光源进行着色器计算,然后将所有光源的结果叠加起来
                    // 即该片元的颜色由所有光源决定

                    finalColor = Color01.Black;

                    foreach (var light in lights)
                    {
                        finalColor += FragmentShader(vertex, light);
                    }

                    DrawPixel(x, y, finalColor);
                }
                else
                {
                    DrawPixel(x, y, finalColor);
                }

                // 增量误差
                eps += dy;

                // 误差大于0.5,那么y++
                if ((eps << 1) >= dx)
                {
                    y   += stepY;
                    eps -= dx;
                }
            }
        }
        else
        {
            int x = x1;
            // 当y轴距离差更大时,将y作为自增变量
            for (int y = y1; y != y2; y += stepY)
            {
                float t = (float)(y - y1) / (float)(y2 - y1);

                Color01 color = Color01.LerpColor(v1.color, v2.color, t);
                DrawPixel(x, y, color);

                // 增量误差
                eps += dx;

                if ((eps << 1) >= dy)
                {
                    x   += stepX;
                    eps -= dy;
                }
            }
        }
    }
 /// <summary>
 /// 在后备缓冲区中,对点(x,y)画上一个color的颜色
 /// </summary>
 /// <param name="x"></param>
 /// <param name="y"></param>
 /// <param name="color"></param>
 private void DrawPixel(int x, int y, Color01 color)
 {
     screenBuffer.SetPixel(x, y, color.ToColor());
 }
Пример #9
0
        public static void _draw()
        {
            var panel = _form.panel;

            _form.tickLabel.Text = MyStrategy.Universe.World.TickIndex + "";

            var drawArea = new Bitmap(panel.Size.Width, panel.Size.Height);

            panel.Image = drawArea;
            _graphics   = Graphics.FromImage(drawArea);

            var lookAtSquadId = MyStrategy.SquadCalculator.SquadList.FirstOrDefault(s => s.Id.ToString() == _form.lookAtTextBox.Text.Trim());

            if (lookAtSquadId != null)
            {
                var centralUnit = lookAtSquadId.CentralUnit;
                if (centralUnit != null)
                {
                    LookAt(new Point(centralUnit));
                }
            }

            #region WarFog

            // туман войны
            FillRect(Color.AntiqueWhite, 0, 0, MyStrategy.Universe.World.Width, MyStrategy.Universe.World.Height);
            foreach (var unit in MyStrategy.Universe.MyUnits.GetEnumeration())
            {
                FillCircle(Color.White, unit.X, unit.Y, unit.VisionRange);
            }
            #endregion

            #region BonusMap

            var squadData  = MyStrategy.BonusCalculator.BonusMapList.FirstOrDefault(s => s.Key.ToString() == _form.lookAtTextBox.Text.Trim()).Value;
            var bonusMapId = 0;
            var squadId    = 0;
            int.TryParse(_form.mapIdTextBox.Text.Trim(), out bonusMapId);
            int.TryParse(_form.lookAtTextBox.Text.Trim(), out squadId);

            if (squadData != null && bonusMapId < squadData.Count)
            {
                if (lookAtSquadId != null)
                {
                    var tileList = squadData[bonusMapId].GetTileList();

                    foreach (var tile in tileList)
                    {
                        if (Math.Abs(tile.Value) > Double.Epsilon)
                        {
                            var color01 = new Color01(1, 1 - tile.Value, 1 - tile.Value);
                            FillRect(color01.ToColor(), tile.CenterPosition.X, tile.CenterPosition.Y, tile.Size * 1, tile.Size * 1);

                            if (tile.Value > 0.9999)
                            {
                                FillRect(Color.YellowGreen, tile.CenterPosition.X, tile.CenterPosition.Y, tile.Size * 1, tile.Size * 1);
                            }

                            if (Math.Abs(tile.RealValue) > Double.Epsilon)
                            {
                                DrawText($"{tile.RealValue:f2}", 3, Brushes.Black, tile.CenterPosition.X, tile.CenterPosition.Y);
                            }
                        }
                    }
                }
            }

            if (squadData != null)
            {
                foreach (var rays in MyStrategy.BonusCalculator.PossibleRays)
                {
                    if (rays.Key == squadId)
                    {
                        var maxRay = rays.Value.OrderByDescending(r => r.Value).FirstOrDefault();
                        foreach (var ray in rays.Value)
                        {
                            var color01 = new Color01(1, 1 - ray.Value, 1 - ray.Value);
                            if (ray.Key == maxRay.Key)
                            {
                                FillCircle(Color.Green, ray.Key.X, ray.Key.Y, 3);
                            }
                            FillCircle(color01.ToColor(), ray.Key.X, ray.Key.Y, 1);
                        }
                    }
                }
            }


            foreach (var squad in MyStrategy.SquadCalculator.SquadList.Where(s => s.IsScout))
            {
                var scoutCenter = squad.SquadCenter;
                if (scoutCenter != null)
                {
                    DrawCircle(Color.DeepSkyBlue, scoutCenter.X, scoutCenter.Y, MyStrategy.Universe.Game.FighterVisionRange);
                }
            }

            #endregion


            #region Facilities

            foreach (var facility in MyStrategy.Universe.World.Facilities)
            {
                Color color = Color.Gray;
                if (facility.OwnerPlayerId == MyStrategy.Universe.Player.Id)
                {
                    color = Color.ForestGreen;
                }
                if (facility.OwnerPlayerId == MyStrategy.Universe.World.GetOpponentPlayer().Id)
                {
                    color = Color.OrangeRed;
                }

                var size = MyStrategy.Universe.Game.FacilityWidth;
                FillRect(color, facility.Left + size / 2, facility.Top + size / 2, size / 4, size / 4);
                DrawText($"{facility.CapturePoints:f0}", 7, Brushes.DarkSlateBlue, facility.Left + size / 2, facility.Top + size / 2);
            }


            #endregion

            #region UnitsDraw

            foreach (var unit in MyStrategy.Universe.MyUnits.GetEnumeration())
            {
                switch (unit.Type)
                {
                case VehicleType.Fighter:
                    DrawUnit(Color.Blue, unit, "F"); break;

                case VehicleType.Helicopter:
                    DrawUnit(Color.Brown, unit, "H"); break;

                case VehicleType.Tank:
                    DrawUnit(Color.Red, unit, "T"); break;

                case VehicleType.Arrv:
                    DrawUnit(Color.Green, unit, "A"); break;

                case VehicleType.Ifv:
                    DrawUnit(Color.Gray, unit, "I"); break;
                }
            }


            foreach (var unit in MyStrategy.Universe.OppUnits.GetEnumeration())
            {
                switch (unit.Type)
                {
                case VehicleType.Fighter:
                    DrawUnit(Color.DodgerBlue, unit, "F");
                    break;

                case VehicleType.Helicopter:
                    DrawUnit(Color.SandyBrown, unit, "H");
                    break;

                case VehicleType.Tank:
                    DrawUnit(Color.LightPink, unit, "T");
                    break;

                case VehicleType.Arrv:
                    DrawUnit(Color.LightGreen, unit, "A");
                    break;

                case VehicleType.Ifv:
                    DrawUnit(Color.LightGray, unit, "I");
                    break;
                }
            }

            #endregion

            #region Predictions

            var allRealUnits = MyStrategy.Universe.OppUnits.GetCombinedList(MyStrategy.Universe.MyUnits);

            foreach (var currectUnit in allRealUnits)
            {
                var expectedTickForNextUpdate = MyStrategy.Universe.World.TickIndex;
                if (currectUnit.PlayerId == MyStrategy.Universe.Player.Id)
                {
                    var correspondingSquad = MyStrategy.SquadCalculator.SquadList.GetSquadByUnit(currectUnit);
                    if (correspondingSquad == null)
                    {
                        continue;
                    }
                    expectedTickForNextUpdate = MyStrategy.Universe.World.TickIndex +
                                                correspondingSquad.ExpectedTicksToNextUpdate;
                }
                else
                {
                    // nearestMyUnit = MyStrategy.Universe.MyUnits.
                    // var correspondingSquad = MyStrategy.SquadCalculator.SquadList.GetSquadByUnit(nearestMyUnit);
                    // expectedTickForNextUpdate = MyStrategy.Universe.World.TickIndex + correspondingSquad.ExpectedTicksToNextUpdate;
                    expectedTickForNextUpdate = MyStrategy.Universe.World.TickIndex + 60;
                }


                var predictedState    = MyStrategy.Predictor.GetStateOnTick(expectedTickForNextUpdate);
                var allPredictedUnits = predictedState.OppUnits.GetCombinedList(predictedState.MyUnits);

                foreach (var predictedUnit in allPredictedUnits)
                {
                    if (predictedUnit.Id == currectUnit.Id)
                    {
                        var vectorLength = currectUnit.GetDistanceTo(predictedUnit);
                        if (vectorLength > 2)
                        {
                            DrawLine(Color.Gray, currectUnit.X, currectUnit.Y, predictedUnit.X, predictedUnit.Y, 1);
                        }
                    }
                }
            }


            #endregion

            #region MoveOrders

            foreach (var order in SquadCalculator.MoveOrders.OrderList)
            {
                var unit = MyStrategy.Universe.MyUnits.FirstOrDefault(u => u.Id.Equals(order.Key));
                //if (unit.GetDistanceTo(order.Value) > 200)
                //    MyStrategy.Universe.Print("Wrong move order in visual");
                if (unit != null)
                {
                    DrawLine(Color.LightGreen, unit.X, unit.Y, order.Value.X, order.Value.Y, 2);
                }
            }


            #endregion

            #region NukeStrike

            foreach (var player in MyStrategy.Universe.World.Players)
            {
                var isNukeRequested = player.NextNuclearStrikeTickIndex > 0;
                var isMe            = player.IsMe;
                var radius          = MyStrategy.Universe.Game.TacticalNuclearStrikeRadius;
                var scout           = MyStrategy.Universe.MyUnits.FirstOrDefault(u =>
                                                                                 u.Id == MyStrategy.SquadCalculator.NukeStrikeScoutId);

                foreach (var squad in MyStrategy.SquadCalculator.SquadList)
                {
                    if (squad.NukeMarkerCounter > 0)
                    {
                        DrawCircle(Color.DarkOliveGreen, MyStrategy.SquadCalculator.NukeStrikePosition.X,
                                   MyStrategy.SquadCalculator.NukeStrikePosition.Y, radius - 2, 2);
                        DrawCircle(Color.DarkOliveGreen, scout.X, scout.Y, 10, 2);
                    }
                }


                if (isNukeRequested)
                {
                    DrawCircle(isMe? Color.GreenYellow : Color.DeepPink, player.NextNuclearStrikeX, player.NextNuclearStrikeY, radius, 3);
                }

                var coolDownValue = player.RemainingNuclearStrikeCooldownTicks;
                DrawText($"{coolDownValue}", 8, Brushes.Black, isMe ? 500 : 600, 25);
            }

            #region Damage

            if (MyStrategy.Universe.World.TickIndex != 0)
            {
                var thisStepUnits     = MyStrategy.Predictor.WorldStateList[MyStrategy.Universe.World.TickIndex].MyUnits;
                var previousStepUnits =
                    MyStrategy.Predictor.WorldStateList[MyStrategy.Universe.World.TickIndex - 1].MyUnits;

                foreach (var thisStepUnit in thisStepUnits)
                {
                    foreach (var previousStepUnit in previousStepUnits)
                    {
                        if (thisStepUnit.Durability + Double.Epsilon < previousStepUnit.Durability)
                        {
                            DrawCircle(Color.Yellow, thisStepUnit.X, thisStepUnit.Y, 2.5, 2);
                        }
                    }
                }

                thisStepUnits     = MyStrategy.Predictor.WorldStateList[MyStrategy.Universe.World.TickIndex].OppUnits;
                previousStepUnits =
                    MyStrategy.Predictor.WorldStateList[MyStrategy.Universe.World.TickIndex - 1].OppUnits;

                foreach (var thisStepUnit in thisStepUnits)
                {
                    foreach (var previousStepUnit in previousStepUnits)
                    {
                        if (thisStepUnit.Durability + Double.Epsilon < previousStepUnit.Durability)
                        {
                            DrawCircle(Color.LightYellow, thisStepUnit.X, thisStepUnit.Y, 2.5, 2);
                        }
                    }
                }
            }


            #endregion

            #endregion

            #region SquadSelection

            var selectedSquad = MyStrategy.SquadCalculator.SquadList.FirstOrDefault(s => s.Id.ToString() == _form.lookAtTextBox.Text.Trim());
            if (selectedSquad != null && selectedSquad.Units.Count > 0)
            {
                var xMax = selectedSquad.Units.OrderByDescending(u => u.X).FirstOrDefault().X + 5;
                var xMin = selectedSquad.Units.OrderBy(u => u.X).FirstOrDefault().X - 5;
                var yMax = selectedSquad.Units.OrderByDescending(u => u.Y).FirstOrDefault().Y + 5;
                var yMin = selectedSquad.Units.OrderBy(u => u.Y).FirstOrDefault().Y - 5;
                DrawLine(Color.Aquamarine, xMin, yMin, xMax, yMin, 2);
                DrawLine(Color.Aquamarine, xMin, yMin, xMin, yMax, 2);
                DrawLine(Color.Aquamarine, xMax, yMax, xMax, yMin, 2);
                DrawLine(Color.Aquamarine, xMax, yMax, xMin, yMax, 2);
            }

            #endregion

            #region WorldSelection

            foreach (var selectedUnit in MyStrategy.Universe.GetSelectedUnits())
            {
                DrawCircle(Color.White, selectedUnit.X, selectedUnit.Y, 2.5);
            }


            #endregion

            ////

            #region Something

            //            foreach (var seg in RoadsHelper.Roads)
            //                DrawLine(Color.Khaki, seg.A.X, seg.A.Y, seg.B.X, seg.B.Y);

            //            if (_form.gradCheckBox.Checked)
            //            {
            //                var maxDanger = DangerPoints.Max(x => x.Item2);
            //                var minDanger = DangerPoints.Min(x => x.Item2);
            //
            //                if (maxDanger > Const.Eps)
            //                {
            //                    foreach (var t in DangerPoints)
            //                    {
            //                        var pt = t.Item1;
            //                        var danger = t.Item2;
            //                        var color =
            //                            (danger >= 0 ? _grad(BadColors, 1 - danger/maxDanger) : _grad(GoodColors, danger/minDanger))
            //                                .ToColor();
            //                        FillCircle(color, pt.X, pt.Y, 4);
            //                    }
            //                }
            //            }

            //            if (_form.renderCheckBox.Checked)
            //            {
            //                for (var i = 0; i <= MyStrategy.Universe.GridSize; i++)
            //                    for (var j = 0; j <= MyStrategy.Universe.GridSize; j++)
            //                        FillCircle(Color.Red, MyStrategy.Universe._points[i, j].X, MyStrategy.Universe._points[i, j].Y, 3);
            //            }
            #endregion

            #region Statuses

            // statuses
            //            foreach (var unit in MyStrategy.Universe.MyUnits)
            //            {
            //                if (unit.RemainingFrozen > 0)
            //                    FillCircle(Color.SkyBlue, unit.X, unit.Y, unit.Radius - 3);
            //                if (unit.IsBurning)
            //                    FillCircle(Color.Orange, unit.X, unit.Y, unit.Radius - 3);
            //            }

            #endregion

            #region Wizards
            // wizards
            //            foreach (var wizard in MyStrategy.Universe.Wizards)
            //            {
            //                var w = MyStrategy.Universe.World.Wizards.FirstOrDefault(x => x.Id == wizard.Id);
            //                var color = w.IsMe ? Color.Red : (wizard.Faction == MyStrategy.Universe.Self.Faction ? Color.Blue : Color.Gold);
            //
            //                DrawCircle(color, w.X, w.Y, wizard.Radius);
            //
            //                var d = 7;
            //                for (var i = 0; i < d; i++)
            //                    if (wizard.RemainingStaffCooldownTicks >= MyStrategy.Universe.Game.StaffCooldownTicks - d)
            //                        DrawCircle(color, w.X, w.Y, wizard.Radius - (d - i));
            //
            //                DrawText(w.Life + "", 15, Brushes.Red, wizard.X - 20, wizard.Y - 35);
            //                DrawText(w.Mana + "", 15, Brushes.Blue, wizard.X - 20, wizard.Y - 15);
            //                DrawText(w.Xp + "", 15, Brushes.Green, wizard.X - 20, wizard.Y + 5);
            //
            //                DrawPie(color, wizard.X, wizard.Y, MyStrategy.Universe.Game.StaffRange, -MyStrategy.Universe.Game.StaffSector / 2.0 + wizard.Angle, MyStrategy.Universe.Game.StaffSector / 2.0 + wizard.Angle);
            //                DrawPie(color, wizard.X, wizard.Y, wizard.CastRange, -MyStrategy.Universe.Game.StaffSector / 2.0 + wizard.Angle, MyStrategy.Universe.Game.StaffSector / 2.0 + wizard.Angle);
            //
            //
            //                var statusesStr = "";
            //                if (wizard.RemainingHastened > 0)
            //                    statusesStr += "H";
            //                if (wizard.RemainingEmpowered > 0)
            //                    statusesStr += "E";
            //                if (wizard.RemainingShielded > 0)
            //                    statusesStr += "S";
            //
            //                var skillsStr = "";
            //                for (var i = 0; i < 5; i++)
            //                    skillsStr += wizard.SkillsLearnedArr[i];
            //
            //                var skillsStr2 = "";
            //                for (var i = 0; i < 5; i++)
            //                    skillsStr2 += wizard.SkillsFactorsArr[i] + wizard.AurasFactorsArr[i];
            //
            //                DrawText(statusesStr, 20, Brushes.Coral, wizard.X + 30, wizard.Y - 40);
            //                DrawText(skillsStr, 15, Brushes.Black, wizard.X + 30, wizard.Y - 15);
            //                DrawText(skillsStr2, 15, Brushes.DeepSkyBlue, wizard.X + 30, wizard.Y + 5);
            //            }


            #endregion

            #region Minions
            // minions
            //            foreach (var minion in MyStrategy.Universe.Minions)
            //            {
            //                var color = minion.IsTeammate ? Color.Blue : (minion.Faction == Faction.Neutral ? Color.Fuchsia : Color.DarkOrange);
            //
            //                DrawCircle(color, minion.X, minion.Y, minion.Radius);
            //
            //                var to = Point.ByAngle(minion.Angle) * minion.Radius + minion;
            //                DrawLine(color, minion.X, minion.Y, to.X, to.Y, 2);
            //
            //                if (minion is AOrc)
            //                {
            //                    DrawCircle(Color.Black, minion.X, minion.Y, MyStrategy.Universe.Game.OrcWoodcutterAttackRange);
            //                }
            //
            //                DrawText(minion.Life + "", 15, Brushes.Red, minion.X - 10, minion.Y - 30);
            //            }



            #endregion

            #region Trees
            // trees
            //            foreach (var tree in TreesObserver.Trees)
            //            {
            //                FillCircle(Color.Chartreuse, tree.X, tree.Y, tree.Radius);
            //            }

            #endregion

            #region Buildings

            // buildings
            //            foreach (var building in BuildingsObserver.Buildings)
            //            {
            //                FillCircle(building.IsTeammate ? Color.Blue : Color.DarkOrange, building.X, building.Y, building.Radius);
            //                DrawText(building.Life + "", 15, Brushes.Red, building.X - 10, building.Y - 30);
            //                if (building.IsBesieded)
            //                    DrawText("rush", 13, Brushes.Black, building.X - 10, building.Y);
            //                if (building.IsOpponent)
            //                    DrawCircle(Color.Red, building.X, building.Y, building.CastRange);
            //            }

            #endregion

            #region Bonuses

            // bonuses
            //            foreach (var bonus in BonusesObserver.Bonuses)
            //            {
            //                var color = bonus.Type == BonusType.Empower
            //                    ? Color.Blue
            //                    : bonus.Type == BonusType.Haste
            //                        ? Color.Aquamarine
            //                        : Color.MidnightBlue;
            //                if (bonus.Exists)
            //                    FillCircle(color, bonus.X, bonus.Y, bonus.Radius);
            //                else
            //                    DrawCircle(color, bonus.X, bonus.Y, bonus.Radius);
            //            }
            //            if (MyStrategy.Universe.NextBonusWaypoint != null)
            //                FillCircle(Color.Red, MyStrategy.Universe.NextBonusWaypoint.X, MyStrategy.Universe.NextBonusWaypoint.Y, 10);

            #endregion

            #region MapRanges

            // map ranges
            DrawLine(Color.Black, 1, 1, 1, MyStrategy.Universe.World.Height - 1);
            DrawLine(Color.Black, 1, MyStrategy.Universe.World.Height - 1, MyStrategy.Universe.World.Height - 1, MyStrategy.Universe.World.Height - 1);
            DrawLine(Color.Black, MyStrategy.Universe.World.Height - 1, 1, MyStrategy.Universe.World.Height - 1, MyStrategy.Universe.World.Height - 1);
            DrawLine(Color.Black, MyStrategy.Universe.World.Height - 1, 1, 1, 1);

            #endregion

            #region MinionSpaws

            // minions spawns
//            foreach (var pt in MagicConst.MinionAppearencePoints)
//            {
//                FillCircle(Color.Khaki, pt.X, pt.Y, 20);
//                FillCircle(Color.Khaki, MyStrategy.Universe.World.Height - pt.X, MyStrategy.Universe.World.Height - pt.Y, 20);
//            }

            #endregion

            #region ProjectTiles

            // projectiles
//            foreach (var projectile in MyStrategy.Universe.World.Projectiles)
//            {
//                var color = projectile.Type == ProjectileType.MagicMissile
//                    ? Color.Blue
//                    : projectile.Type == ProjectileType.Dart
//                        ? Color.Black
//                        : projectile.Type == ProjectileType.FrostBolt
//                            ? Color.SkyBlue
//                            : Color.Gold;
//
//                FillCircle(color, projectile.X, projectile.Y, projectile.Radius);
//                if (Projectiles.ContainsKey(projectile.Id))
//                {
//                    var pts = Projectiles[projectile.Id];
//                    DrawLine(Color.BlueViolet, pts[0].X, pts[0].Y, pts[1].X, pts[1].Y, 3);
//                }
//            }

            #endregion


            foreach (var seg in SegmentsDrawQueue)
            {
                var   points = seg[0] as List <Point>;
                var   pen    = seg[1] as Pen;
                float width  = seg.Length > 2 ? Convert.ToSingle(seg[2]) : 0F;
                for (var i = 1; i < points.Count; i++)
                {
                    DrawLine(pen.Color, points[i].X, points[i].Y, points[i - 1].X, points[i - 1].Y, width);
                }
            }
        }
Пример #10
0
 public PointLight(Vector3 position, float range, Color01 lightColor)
 {
     this.position   = position;
     this.range      = range;
     this.lightColor = lightColor;
 }
 public DirectionalLight(Vector3 direction, Color01 color)
 {
     this.direction = direction;
     lightColor     = color;
 }
Пример #12
0
    /// <summary>
    /// 山寨版片元着色器,
    /// 根据一个顶点的各属性,计算当前顶点(屏幕空间下)的像素的颜色
    /// </summary>
    /// <param name="vertex"></param>
    /// <returns></returns>
    public Color01 FragmentShader(Vertex vertex)
    {
        // 基于半兰伯特光照模型的光照
        //return LightingWithLambert(vertex);

        // 从法线贴图中取出法线(切线空间下的)
        Color01 UndecryptedNormal = Texture.Tex2D(normalTexture, vertex.u, vertex.v);
        // 把法线从[0,1]区间变回到[-1,1]区间
        Vector3 normal = new Vector3(
            UndecryptedNormal.R * 2 - 1,
            UndecryptedNormal.G * 2 - 1,
            UndecryptedNormal.B * 2 - 1
            );

        // 获得世界坐标下的法线
        Vector3 worldNormal = vertex.mMatrix * vertex.normal;

        worldNormal.Normlize();
        // 获得世界坐标下的切线
        Vector3 worldTangent = vertex.mMatrix * vertex.tangent;

        worldTangent.Normlize();
        // 获得世界坐标下的副切线
        Vector3 worldBinormal = Vector3.Cross(worldNormal, worldTangent) * vertex.tangent.W;

        worldBinormal.Normlize();

        // 构建 切线-世界 变换矩阵
        Matrix4x4 TtoW = new Matrix4x4();

        TtoW.Identity();

        TtoW.value[0, 0] = worldTangent.X;
        TtoW.value[1, 0] = worldTangent.Y;
        TtoW.value[2, 0] = worldTangent.Z;

        TtoW.value[0, 1] = worldBinormal.X;
        TtoW.value[1, 1] = worldBinormal.Y;
        TtoW.value[2, 1] = worldBinormal.Z;

        TtoW.value[0, 2] = worldNormal.X;
        TtoW.value[1, 2] = worldNormal.Y;
        TtoW.value[2, 2] = worldNormal.Z;

        // 将切线空间的法线变为世界坐标
        normal = TtoW * normal;
        normal.Normlize();

        // 增大凹凸比例
        normal.X *= 3;
        normal.Y *= 3;
        normal.Z *= MathF.Sqrt(1 - MathF.Clamp01(normal.X * normal.X + normal.Y * normal.Y));

        Color01 albedo = Texture.Tex2D(texture2D, vertex.u, vertex.v);

        float radiance = Vector3.Dot(normal, DirectionLight) * 0.5f + 0.5f;

        Color01 diffuse = albedo * radiance;

        return(diffuse);
    }