예제 #1
0
        /// <summary>
        /// Pre-Draw
        /// </summary>
        /// <param name="device"></param>
        public override void PreDraw(GraphicsDevice device)
        {
            base.PreDraw(device);
            if (HasInit == false)
            {
                return;
            }
            BoundView();
            State._2D.PreciseZoom = State.PreciseZoom;
            State.OutsideColor    = Blueprint.OutsideColor;
            FSO.Common.Rendering.Framework.GameScreen.ClearColor = new Color(new Color(0x72, 0x72, 0x72).ToVector4() * State.OutsideColor.ToVector4());
            foreach (var sub in Blueprint.SubWorlds)
            {
                sub.PreDraw(device, State);
            }
            State.UpdateInterpolation();
            if (Blueprint != null)
            {
                foreach (var ent in Blueprint.Objects)
                {
                    ent.Update(null, State);
                }
            }

            //For all the tiles in the dirty list, re-render them
            //PPXDepthEngine.SetPPXTarget(null, null, true);
            State.PrepareLighting();
            State._2D.Begin(this.State.Camera);
            _2DWorld.PreDraw(device, State);
            device.SetRenderTarget(null);
            State._2D.End();

            State._3D.Begin(device);
            _3DWorld.PreDraw(device, State);
            State._3D.End();

            if (UseBackbuffer)
            {
                PPXDepthEngine.SetPPXTarget(null, null, true);
                InternalDraw(device);
                device.SetRenderTarget(null);
            }

            return;
        }
예제 #2
0
        /// <summary>
        /// Pre-Draw
        /// </summary>
        /// <param name="device"></param>
        public override void PreDraw(GraphicsDevice device)
        {
            //bound the scroll so we can't see gray space.
            float boundfactor = 0.5f;

            switch (State.Zoom)
            {
            case WorldZoom.Near:
                boundfactor = 1.20f; break;

            case WorldZoom.Medium:
                boundfactor = 1.05f; break;
            }
            boundfactor *= Blueprint?.Width ?? 64;
            var off  = 0.5f * (Blueprint?.Width ?? 64);
            var tile = State.CenterTile;

            tile = new Vector2(Math.Min(boundfactor + off, Math.Max(off - boundfactor, tile.X)), Math.Min(boundfactor + off, Math.Max(off - boundfactor, tile.Y)));
            if (tile != State.CenterTile)
            {
                State.CenterTile = tile;
            }

            base.PreDraw(device);
            if (HasInit == false)
            {
                return;
            }
            State._2D.PreciseZoom = State.PreciseZoom;
            State.OutsideColor    = Blueprint.OutsideColor;
            foreach (var sub in Blueprint.SubWorlds)
            {
                sub.PreDraw(device, State);
            }
            if (Blueprint != null)
            {
                foreach (var ent in Blueprint.Objects)
                {
                    ent.Update(null, State);
                }
            }

            //For all the tiles in the dirty list, re-render them
            //PPXDepthEngine.SetPPXTarget(null, null, true);
            State.PrepareLighting();
            State._2D.Begin(this.State.Camera);
            _2DWorld.PreDraw(device, State);
            device.SetRenderTarget(null);
            State._2D.End();

            State._3D.Begin(device);
            _3DWorld.PreDraw(device, State);
            State._3D.End();

            if (UseBackbuffer)
            {
                PPXDepthEngine.SetPPXTarget(null, null, true);
                InternalDraw(device);
                device.SetRenderTarget(null);
            }

            return;
        }
예제 #3
0
        /// <summary>
        /// Prep work before screen is painted
        /// </summary>
        /// <param name="gd"></param>
        /// <param name="state"></param>
        public virtual void PreDraw(GraphicsDevice gd, WorldState state)
        {
            //var oht = state.BaseHeight;
            //state.BaseHeight = 0;
            var pxOffset = -state.WorldSpace.GetScreenOffset();
            //state.BaseHeight = oht;
            var damage = Blueprint.Damage;
            var _2d    = state._2D;

            /**
             * Tasks:
             *  If zoom or rotation has changed, redraw all static layers
             *  If scroll has changed, redraw static layer if the scroll is outwith the buffered region
             *  If architecture has changed, redraw appropriate static layer
             *  If there is a new object in the static layer, redraw the static layer
             *  If an objects in the static layer has changed, redraw the static layer and move the object to the dynamic layer
             *  If wall visibility has changed, redraw wall layer (should think about how this works with breakthrough wall mode
             */

            var im = state.ThisFrameImmediate;
            var redrawStaticObjects = im;
            var redrawFloor         = im;
            var redrawWall          = im;

            var recacheWalls   = false;
            var recacheCutaway = false;
            var recacheFloors  = false;
            var recacheTerrain = false;
            var recacheObjects = false;
            var drawImmediate  = false;

            var lightChangeType = 0;

            if (TicksSinceLight++ > 60 * 4)
            {
                damage.Add(new BlueprintDamage(BlueprintDamageType.OUTDOORS_LIGHTING_CHANGED));
            }

            WorldObjectRenderInfo info = null;

            foreach (var item in damage)
            {
                switch (item.Type)
                {
                case BlueprintDamageType.ROTATE:
                case BlueprintDamageType.ZOOM:
                case BlueprintDamageType.LEVEL_CHANGED:
                    recacheObjects = true;
                    recacheWalls   = true;
                    recacheFloors  = true;
                    //recacheTerrain = true;
                    break;

                case BlueprintDamageType.SCROLL:
                    if (StaticObjects == null || StaticObjects.PxOffset != GetScrollIncrement(pxOffset, state))
                    {
                        redrawFloor         = true;
                        redrawWall          = true;
                        redrawStaticObjects = true;
                    }
                    break;

                case BlueprintDamageType.PRECISE_ZOOM:
                    drawImmediate = true;
                    redrawFloor   = redrawWall = redrawStaticObjects = true;
                    break;

                case BlueprintDamageType.LIGHTING_CHANGED:
                    if (lightChangeType >= 2)
                    {
                        break;
                    }
                    var room = (ushort)item.TileX;
                    redrawFloor         = true;
                    redrawWall          = true;
                    redrawStaticObjects = true;

                    state.Light?.InvalidateRoom(room);
                    Blueprint.GenerateRoomLights();
                    state.OutsideColor   = Blueprint.RoomColors[1];
                    state._3D.RoomLights = Blueprint.RoomColors;
                    state.OutsidePx.SetData(new Color[] { new Color(Blueprint.OutsideColor, (Blueprint.OutsideColor.R + Blueprint.OutsideColor.G + Blueprint.OutsideColor.B) / (255 * 3f)) });
                    if (state.AmbientLight != null)
                    {
                        state.AmbientLight.SetData(Blueprint.RoomColors);
                    }
                    TicksSinceLight = 0;
                    break;

                case BlueprintDamageType.OUTDOORS_LIGHTING_CHANGED:
                    if (lightChangeType >= 1)
                    {
                        break;
                    }
                    lightChangeType     = 1;
                    redrawFloor         = true;
                    redrawWall          = true;
                    redrawStaticObjects = true;

                    Blueprint.GenerateRoomLights();
                    state.OutsideColor   = Blueprint.RoomColors[1];
                    state._3D.RoomLights = Blueprint.RoomColors;
                    state.OutsidePx.SetData(new Color[] { new Color(Blueprint.OutsideColor, (Blueprint.OutsideColor.R + Blueprint.OutsideColor.G + Blueprint.OutsideColor.B) / (255 * 3f)) });
                    if (state.AmbientLight != null)
                    {
                        state.AmbientLight.SetData(Blueprint.RoomColors);
                    }
                    state.Light?.InvalidateOutdoors();

                    TicksSinceLight = 0;
                    break;

                case BlueprintDamageType.OBJECT_MOVE:
                    /** Redraw if its in static layer **/
                    info = GetRenderInfo(item.Component);
                    if (info.Layer == WorldObjectRenderLayer.STATIC)
                    {
                        recacheObjects = true;
                        info.Layer     = WorldObjectRenderLayer.DYNAMIC;
                    }
                    if (item.Component is ObjectComponent)
                    {
                        ((ObjectComponent)item.Component).DynamicCounter = 0;
                    }
                    break;

                case BlueprintDamageType.OBJECT_GRAPHIC_CHANGE:
                    /** Redraw if its in static layer **/
                    info = GetRenderInfo(item.Component);
                    if (info.Layer == WorldObjectRenderLayer.STATIC)
                    {
                        recacheObjects = true;
                        info.Layer     = WorldObjectRenderLayer.DYNAMIC;
                    }
                    if (item.Component is ObjectComponent)
                    {
                        ((ObjectComponent)item.Component).DynamicCounter = 0;
                    }
                    break;

                case BlueprintDamageType.OBJECT_RETURN_TO_STATIC:
                    info = GetRenderInfo(item.Component);
                    if (info.Layer == WorldObjectRenderLayer.DYNAMIC)
                    {
                        recacheObjects = true;
                        info.Layer     = WorldObjectRenderLayer.STATIC;
                    }
                    break;

                case BlueprintDamageType.WALL_CUT_CHANGED:
                    recacheCutaway = true;
                    break;

                case BlueprintDamageType.ROOF_STYLE_CHANGED:
                    Blueprint.RoofComp.StyleDirty = true;
                    break;

                case BlueprintDamageType.ROOM_CHANGED:
                    for (sbyte i = 0; i < Blueprint.RoomMap.Length; i++)
                    {
                        state.Rooms.SetRoomMap(i, Blueprint.RoomMap[i]);
                    }
                    if (state.Light != null)
                    {
                        if (lightChangeType < 2)
                        {
                            lightChangeType = 2;
                            state.Light.InvalidateAll();
                        }
                    }
                    Blueprint.RoofComp.ShapeDirty = true;
                    break;

                case BlueprintDamageType.FLOOR_CHANGED:
                case BlueprintDamageType.WALL_CHANGED:
                    //recacheTerrain = true;
                    recacheFloors = true;
                    recacheWalls  = true;
                    Blueprint.RoofComp.ShapeDirty = true;
                    break;
                }
            }
            if (recacheFloors || recacheTerrain)
            {
                redrawFloor = true;
            }
            if (recacheWalls || recacheCutaway)
            {
                redrawWall = true;
            }
            if (recacheObjects)
            {
                redrawStaticObjects = true;
            }
            damage.Clear();

            //scroll buffer loads in increments of SCROLL_BUFFER
            var newOff    = GetScrollIncrement(pxOffset, state);
            var oldCenter = state.CenterTile;

            state.CenterTile += state.WorldSpace.GetTileFromScreen(newOff - pxOffset); //offset the scroll to the position of the scroll buffer.
            var tileOffset = state.CenterTile;

            pxOffset = newOff;

            if (recacheTerrain)
            {
                Blueprint.Terrain.RegenTerrain(gd, state, Blueprint);
            }

            if (recacheWalls)
            {
                Blueprint.WCRC?.Generate(gd, state, false);
            }
            else if (recacheCutaway)
            {
                Blueprint.WCRC?.Generate(gd, state, true);
            }

            state.Light?.ParseInvalidated((sbyte)(state.Level + ((state.DrawRoofs) ? 1 : 0)), state);

            if (recacheWalls || recacheCutaway)
            {
                _2d.Pause();
                _2d.Resume(); //clear the sprite buffer before we begin drawing what we're going to cache
                Blueprint.WallComp.Draw(gd, state);
                ClearDrawBuffer(StaticWallCache);
                state.PrepareLighting();
                _2d.End(StaticWallCache, true);
            }

            if (recacheFloors)
            {
                _2d.Pause();
                _2d.Resume(); //clear the sprite buffer before we begin drawing what we're going to cache
                //Blueprint.FloorComp.Draw(gd, state);
                Blueprint.FloorGeom.FullReset(gd, state.BuildMode > 1);
                ClearDrawBuffer(StaticFloorCache);
                _2d.End(StaticFloorCache, true);
            }

            if (recacheObjects)
            {
                _2d.Pause();
                _2d.Resume();

                foreach (var obj in Blueprint.Objects)
                {
                    if (obj.Level > state.Level)
                    {
                        continue;
                    }
                    var renderInfo = GetRenderInfo(obj);
                    if (renderInfo.Layer == WorldObjectRenderLayer.STATIC)
                    {
                        var tilePosition = obj.Position;
                        _2d.OffsetPixel(state.WorldSpace.GetScreenFromTile(tilePosition));
                        _2d.OffsetTile(tilePosition);
                        _2d.SetObjID(obj.ObjectID);
                        obj.Draw(gd, state);
                    }
                }
                ClearDrawBuffer(StaticObjectsCache);
                _2d.End(StaticObjectsCache, true);
            }

            if (!drawImmediate)
            {
                state.PrepareLighting();

                if (redrawStaticObjects || redrawFloor || redrawWall)
                {
                    /** Draw static objects to a texture **/
                    Promise <Texture2D> bufferTexture = null;
                    Promise <Texture2D> depthTexture  = null;
                    using (var buffer = state._2D.WithBuffer(BUFFER_STATIC, ref bufferTexture, BUFFER_STATIC_DEPTH, ref depthTexture))
                    {
                        while (buffer.NextPass())
                        {
                            DrawFloorBuf(gd, state, pxOffset);
                            DrawWallBuf(gd, state, pxOffset);
                            DrawObjBuf(gd, state, pxOffset);
                        }
                    }
                    StaticObjects = new ScrollBuffer(bufferTexture.Get(), depthTexture.Get(), newOff, new Vector3(tileOffset, 0));
                }
            }
            //state._2D.PreciseZoom = state.PreciseZoom;
            state.CenterTile = oldCenter; //revert to our real scroll position

            state.ThisFrameImmediate = drawImmediate;
        }