예제 #1
0
		public void WorldLoaded(World w, WorldRenderer wr)
		{
			if (w.Type != WorldType.Editor)
				return;

			palette = wr.Palette(info.Palette);
		}
예제 #2
0
		public IRenderable WithPalette(PaletteReference newPalette)
		{
			return new VoxelRenderable(
				voxels, pos, zOffset, camera, scale,
				lightSource, lightAmbientColor, lightDiffuseColor,
				newPalette, normalsPalette, shadowPalette);
		}
예제 #3
0
        internal void Draw(WorldRenderer wr)
        {
            if (initializePalettes)
            {
                fogPalette = wr.Palette("fog");
                shroudPalette = wr.Palette("shroud");
                initializePalettes = false;
            }

            if (shroud != null && shroud.dirty)
            {
                shroud.dirty = false;
                for (int i = map.Bounds.Left; i < map.Bounds.Right; i++)
                    for (int j = map.Bounds.Top; j < map.Bounds.Bottom; j++)
                        sprites[i, j] = ChooseShroud(i, j);

                for (int i = map.Bounds.Left; i < map.Bounds.Right; i++)
                    for (int j = map.Bounds.Top; j < map.Bounds.Bottom; j++)
                        fogSprites[i, j] = ChooseFog(i, j);
            }

            var clipRect = Game.viewport.WorldBounds(wr.world);
            DrawShroud(wr, clipRect, sprites, shroudPalette);
            if (wr.world.WorldActor.HasTrait<Fog>())
                DrawShroud(wr, clipRect, fogSprites, fogPalette);
        }
예제 #4
0
        public TerrainSpriteLayer(World world, WorldRenderer wr, Sheet sheet, BlendMode blendMode, PaletteReference palette, bool restrictToBounds)
        {
            worldRenderer = wr;
            this.restrictToBounds = restrictToBounds;
            Sheet = sheet;
            BlendMode = blendMode;
            paletteIndex = palette.TextureIndex;

            map = world.Map;
            rowStride = 4 * map.MapSize.X;

            vertices = new Vertex[rowStride * map.MapSize.Y];
            vertexBuffer = Game.Renderer.Device.CreateVertexBuffer(vertices.Length);
            emptySprite = new Sprite(sheet, Rectangle.Empty, TextureChannel.Alpha);

            wr.PaletteInvalidated += () =>
            {
                paletteIndex = palette.TextureIndex;

                // Everything in the layer uses the same palette,
                // so we can fix the indices in one pass
                for (var i = 0; i < vertices.Length; i++)
                {
                    var v = vertices[i];
                    vertices[i] = new Vertex(v.X, v.Y, v.Z, v.U, v.V, paletteIndex, v.C);
                }

                for (var row = 0; row < map.MapSize.Y; row++)
                    dirtyRows.Add(row);
            };
        }
예제 #5
0
		public override void Draw()
		{
			var sprite = GetSprite();
			var palette = GetPalette();
			var scale = GetScale();

			if (sprite == null || palette == null)
				return;

			if (sprite != cachedSprite)
			{
				offset = 0.5f * (new float2(RenderBounds.Size) - sprite.Size);
				cachedSprite = sprite;
			}

			if (palette != cachedPalette)
			{
				pr = WorldRenderer.Palette(palette);
				cachedPalette = palette;
			}

			if (scale != cachedScale)
			{
				offset *= scale;
				cachedScale = scale;
			}

			var size = new float2(sprite.Size.X * scale, sprite.Size.Y * scale);
			Game.Renderer.SpriteRenderer.DrawSprite(sprite, RenderOrigin + offset, pr, size);
		}
예제 #6
0
		public SpriteActorPreview(Animation animation, WVec offset, int zOffset, PaletteReference pr, float scale)
		{
			this.animation = animation;
			this.offset = offset;
			this.zOffset = zOffset;
			this.pr = pr;
			this.scale = scale;
		}
예제 #7
0
		public override IEnumerable<IRenderable> RenderPreview(World world, ActorInfo building, PaletteReference pr)
		{
			var p = BaseBuildingPreview(world, building, pr);
			var anim = new Animation(world, RenderSprites.GetImage(building), () => 0);
			anim.PlayRepeating("idle-top");

			return p.Concat(anim.Render(WPos.Zero, WVec.Zero, 0, pr, Scale));
		}
예제 #8
0
		public IEnumerable<IRenderable> Render(Actor self, WorldRenderer wr, PaletteReference pal, float scale)
		{
			var center = self.CenterPosition;
			var offset = OffsetFunc != null ? OffsetFunc() : WVec.Zero;

			var z = (ZOffset != null) ? ZOffset(center + offset) : 0;
			return Animation.Render(center, offset, z, pal, scale);
		}
예제 #9
0
 public UISpriteRenderable(Sprite sprite, int2 screenPos, int zOffset, PaletteReference palette, float scale)
 {
     this.sprite = sprite;
     this.screenPos = screenPos;
     this.zOffset = zOffset;
     this.palette = palette;
     this.scale = scale;
 }
예제 #10
0
        public override IEnumerable<IActorPreview> RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p)
        {
            // Show a static frame instead of animating all of the fullness states
            var anim = new Animation(init.World, image, () => 0);
            anim.PlayFetchIndex(RenderSprites.NormalizeSequence(anim, init.GetDamageState(), Sequence), () => 0);

            yield return new SpriteActorPreview(anim, WVec.Zero, 0, p, rs.Scale);
        }
예제 #11
0
        public Renderable Image(Actor self, WorldRenderer wr, PaletteReference pal)
        {
            var p = self.CenterLocation;
            var loc = p.ToFloat2() - 0.5f * Animation.Image.size
                + (OffsetFunc != null ? OffsetFunc(wr) : float2.Zero);
            var r = new Renderable(Animation.Image, loc, pal, p.Y);

            return ZOffset != 0 ? r.WithZOffset(ZOffset) : r;
        }
예제 #12
0
 public SpriteRenderable(Sprite sprite, WPos pos, WVec offset, int zOffset, PaletteReference palette, float scale, bool isDecoration)
 {
     this.sprite = sprite;
     this.pos = pos;
     this.offset = offset;
     this.zOffset = zOffset;
     this.palette = palette;
     this.scale = scale;
     this.isDecoration = isDecoration;
 }
예제 #13
0
		public IEnumerable<IRenderable> Render(WPos pos, WVec offset, int zOffset, PaletteReference palette, float scale)
		{
			var imageRenderable = new SpriteRenderable(Image, pos, offset, CurrentSequence.ZOffset + zOffset, palette, scale, IsDecoration);

			if (CurrentSequence.ShadowStart >= 0)
			{
				var shadow = CurrentSequence.GetShadow(CurrentFrame, facingFunc());
				var shadowRenderable = new SpriteRenderable(shadow, pos, offset, CurrentSequence.ShadowZOffset + zOffset, palette, scale, true);
				return new IRenderable[] { shadowRenderable, imageRenderable };
			}

			return new IRenderable[] { imageRenderable };
		}
예제 #14
0
        public TerrainSpriteLayer(World world, WorldRenderer wr, Sheet sheet, BlendMode blendMode, PaletteReference palette, bool restrictToBounds)
        {
            worldRenderer = wr;
            this.restrictToBounds = restrictToBounds;
            Sheet = sheet;
            BlendMode = blendMode;
            this.palette = palette;

            map = world.Map;
            rowStride = 6 * map.MapSize.X;

            vertices = new Vertex[rowStride * map.MapSize.Y];
            vertexBuffer = Game.Renderer.Device.CreateVertexBuffer(vertices.Length);
            emptySprite = new Sprite(sheet, Rectangle.Empty, TextureChannel.Alpha);

            wr.PaletteInvalidated += UpdatePaletteIndices;
        }
예제 #15
0
		public VoxelRenderable(
			IEnumerable<VoxelAnimation> voxels, WPos pos, int zOffset, WRot camera, float scale,
			WRot lightSource, float[] lightAmbientColor, float[] lightDiffuseColor,
			PaletteReference color, PaletteReference normals, PaletteReference shadow)
		{
			this.voxels = voxels;
			this.pos = pos;
			this.zOffset = zOffset;
			this.scale = scale;
			this.camera = camera;
			this.lightSource = lightSource;
			this.lightAmbientColor = lightAmbientColor;
			this.lightDiffuseColor = lightDiffuseColor;
			this.palette = color;
			this.normalsPalette = normals;
			this.shadowPalette = shadow;
		}
예제 #16
0
        public VoxelPreview(VoxelAnimation[] components, WVec offset, int zOffset, float scale, WAngle lightPitch, WAngle lightYaw, float[] lightAmbientColor, float[] lightDiffuseColor, WAngle cameraPitch,
			PaletteReference colorPalette, PaletteReference normalsPalette, PaletteReference shadowPalette)
        {
            this.components = components;
            this.scale = scale;
            this.lightAmbientColor = lightAmbientColor;
            this.lightDiffuseColor = lightDiffuseColor;

            lightSource = new WRot(WAngle.Zero, new WAngle(256) - lightPitch, lightYaw);
            camera = new WRot(WAngle.Zero, cameraPitch - new WAngle(256), new WAngle(256));

            this.colorPalette = colorPalette;
            this.normalsPalette = normalsPalette;
            this.shadowPalette = shadowPalette;

            this.offset = offset;
            this.zOffset = zOffset;
        }
예제 #17
0
        internal void Draw(WorldRenderer wr, Shroud shroud)
        {
            if (initializePalettes)
            {
                if (shroudInfo.Fog)
                    fogPalette = wr.Palette("fog");
                shroudPalette = wr.Palette("shroud");
                initializePalettes = false;
            }

            GenerateSprites(shroud);

            var clipRect = Game.viewport.WorldBounds(wr.world);

            // We draw the shroud when disabled to hide the sharp map edges
            DrawShroud(wr, clipRect, sprites, shroudPalette);

            if (shroudInfo.Fog)
                DrawShroud(wr, clipRect, fogSprites, fogPalette);
        }
예제 #18
0
		public override void Draw()
		{
			var sprite = GetSprite();
			var palette = GetPalette();

			if (sprite == null || palette == null)
				return;

			if (sprite != cachedSprite)
			{
				offset = 0.5f * (new float2(RenderBounds.Size) - sprite.size);
				cachedSprite = sprite;
			}

			if (palette != cachedPalette)
			{
				pr = worldRenderer.Palette(palette);
				cachedPalette = palette;
			}

			Game.Renderer.SpriteRenderer.DrawSprite(sprite, RenderOrigin + offset, pr);
		}
예제 #19
0
        public virtual IEnumerable<Renderable> Render(Actor self, WorldRenderer wr)
        {
            if (initializePalette)
            {
                palette = wr.Palette(PaletteName(self));
                initializePalette = false;
            }

            foreach (var a in anims.Values)
                if (a.DisableFunc == null || !a.DisableFunc())
                {
                    Renderable ret = a.Image(self, wr, palette);
                    if (Info.Scale != 1f)
                        ret = ret.WithScale(Info.Scale).WithPos(ret.Pos + 0.5f * ret.Sprite.size * (1 - Info.Scale));
                    yield return ret;
                }
        }
예제 #20
0
		public IRenderable WithPalette(PaletteReference newPalette) { return new RangeCircleRenderable(centerPosition, radius, zOffset, color, contrastColor); }
예제 #21
0
        public VoxelRenderProxy RenderAsync(
			WorldRenderer wr, IEnumerable<VoxelAnimation> voxels, WRot camera, float scale,
			float[] groundNormal, WRot lightSource, float[] lightAmbientColor, float[] lightDiffuseColor,
			PaletteReference color, PaletteReference normals, PaletteReference shadowPalette)
        {
            // Correct for inverted y-axis
            var scaleTransform = Util.ScaleMatrix(scale, scale, scale);

            // Correct for bogus light source definition
            var lightYaw = Util.MakeFloatMatrix(new WRot(WAngle.Zero, WAngle.Zero, -lightSource.Yaw).AsMatrix());
            var lightPitch = Util.MakeFloatMatrix(new WRot(WAngle.Zero, -lightSource.Pitch, WAngle.Zero).AsMatrix());
            var shadowTransform = Util.MatrixMultiply(lightPitch, lightYaw);

            var invShadowTransform = Util.MatrixInverse(shadowTransform);
            var cameraTransform = Util.MakeFloatMatrix(camera.AsMatrix());
            var invCameraTransform = Util.MatrixInverse(cameraTransform);
            if (invCameraTransform == null)
                throw new InvalidOperationException("Failed to invert the cameraTransform matrix during RenderAsync.");

            // Sprite rectangle
            var tl = new float2(float.MaxValue, float.MaxValue);
            var br = new float2(float.MinValue, float.MinValue);

            // Shadow sprite rectangle
            var stl = new float2(float.MaxValue, float.MaxValue);
            var sbr = new float2(float.MinValue, float.MinValue);

            foreach (var v in voxels)
            {
                // Convert screen offset back to world coords
                var offsetVec = Util.MatrixVectorMultiply(invCameraTransform, wr.ScreenVector(v.OffsetFunc()));
                var offsetTransform = Util.TranslationMatrix(offsetVec[0], offsetVec[1], offsetVec[2]);

                var worldTransform = v.RotationFunc().Aggregate(Util.IdentityMatrix(),
                    (x, y) => Util.MatrixMultiply(Util.MakeFloatMatrix(y.AsMatrix()), x));
                worldTransform = Util.MatrixMultiply(scaleTransform, worldTransform);
                worldTransform = Util.MatrixMultiply(offsetTransform, worldTransform);

                var bounds = v.Voxel.Bounds(v.FrameFunc());
                var worldBounds = Util.MatrixAABBMultiply(worldTransform, bounds);
                var screenBounds = Util.MatrixAABBMultiply(cameraTransform, worldBounds);
                var shadowBounds = Util.MatrixAABBMultiply(shadowTransform, worldBounds);

                // Aggregate bounds rects
                tl = float2.Min(tl, new float2(screenBounds[0], screenBounds[1]));
                br = float2.Max(br, new float2(screenBounds[3], screenBounds[4]));
                stl = float2.Min(stl, new float2(shadowBounds[0], shadowBounds[1]));
                sbr = float2.Max(sbr, new float2(shadowBounds[3], shadowBounds[4]));
            }

            // Inflate rects to ensure rendering is within bounds
            tl -= SpritePadding;
            br += SpritePadding;
            stl -= SpritePadding;
            sbr += SpritePadding;

            // Corners of the shadow quad, in shadow-space
            var corners = new float[][]
            {
                new[] { stl.X, stl.Y, 0, 1 },
                new[] { sbr.X, sbr.Y, 0, 1 },
                new[] { sbr.X, stl.Y, 0, 1 },
                new[] { stl.X, sbr.Y, 0, 1 }
            };

            var shadowScreenTransform = Util.MatrixMultiply(cameraTransform, invShadowTransform);
            var shadowGroundNormal = Util.MatrixVectorMultiply(shadowTransform, groundNormal);
            var screenCorners = new float3[4];
            for (var j = 0; j < 4; j++)
            {
                // Project to ground plane
                corners[j][2] = -(corners[j][1] * shadowGroundNormal[1] / shadowGroundNormal[2] +
                                  corners[j][0] * shadowGroundNormal[0] / shadowGroundNormal[2]);

                // Rotate to camera-space
                corners[j] = Util.MatrixVectorMultiply(shadowScreenTransform, corners[j]);
                screenCorners[j] = new float3(corners[j][0], corners[j][1], 0);
            }

            // Shadows are rendered at twice the resolution to reduce artifacts
            Size spriteSize, shadowSpriteSize;
            int2 spriteOffset, shadowSpriteOffset;
            CalculateSpriteGeometry(tl, br, 1, out spriteSize, out spriteOffset);
            CalculateSpriteGeometry(stl, sbr, 2, out shadowSpriteSize, out shadowSpriteOffset);

            var sprite = sheetBuilder.Allocate(spriteSize, 0, spriteOffset);
            var shadowSprite = sheetBuilder.Allocate(shadowSpriteSize, 0, shadowSpriteOffset);
            var sb = sprite.Bounds;
            var ssb = shadowSprite.Bounds;
            var spriteCenter = new float2(sb.Left + sb.Width / 2, sb.Top + sb.Height / 2);
            var shadowCenter = new float2(ssb.Left + ssb.Width / 2, ssb.Top + ssb.Height / 2);

            var translateMtx = Util.TranslationMatrix(spriteCenter.X - spriteOffset.X, renderer.SheetSize - (spriteCenter.Y - spriteOffset.Y), 0);
            var shadowTranslateMtx = Util.TranslationMatrix(shadowCenter.X - shadowSpriteOffset.X, renderer.SheetSize - (shadowCenter.Y - shadowSpriteOffset.Y), 0);
            var correctionTransform = Util.MatrixMultiply(translateMtx, FlipMtx);
            var shadowCorrectionTransform = Util.MatrixMultiply(shadowTranslateMtx, ShadowScaleFlipMtx);

            doRender.Add(Pair.New<Sheet, Action>(sprite.Sheet, () =>
            {
                foreach (var v in voxels)
                {
                    // Convert screen offset to world offset
                    var offsetVec = Util.MatrixVectorMultiply(invCameraTransform, wr.ScreenVector(v.OffsetFunc()));
                    var offsetTransform = Util.TranslationMatrix(offsetVec[0], offsetVec[1], offsetVec[2]);

                    var rotations = v.RotationFunc().Aggregate(Util.IdentityMatrix(),
                        (x, y) => Util.MatrixMultiply(Util.MakeFloatMatrix(y.AsMatrix()), x));
                    var worldTransform = Util.MatrixMultiply(scaleTransform, rotations);
                    worldTransform = Util.MatrixMultiply(offsetTransform, worldTransform);

                    var transform = Util.MatrixMultiply(cameraTransform, worldTransform);
                    transform = Util.MatrixMultiply(correctionTransform, transform);

                    var shadow = Util.MatrixMultiply(shadowTransform, worldTransform);
                    shadow = Util.MatrixMultiply(shadowCorrectionTransform, shadow);

                    var lightTransform = Util.MatrixMultiply(Util.MatrixInverse(rotations), invShadowTransform);

                    var frame = v.FrameFunc();
                    for (uint i = 0; i < v.Voxel.Limbs; i++)
                    {
                        var rd = v.Voxel.RenderData(i);
                        var t = v.Voxel.TransformationMatrix(i, frame);
                        var it = Util.MatrixInverse(t);
                        if (it == null)
                            throw new InvalidOperationException("Failed to invert the transformed matrix of frame {0} during RenderAsync.".F(i));

                        // Transform light vector from shadow -> world -> limb coords
                        var lightDirection = ExtractRotationVector(Util.MatrixMultiply(it, lightTransform));

                        Render(rd, Util.MatrixMultiply(transform, t), lightDirection,
                            lightAmbientColor, lightDiffuseColor, color.TextureMidIndex, normals.TextureMidIndex);

                        // Disable shadow normals by forcing zero diffuse and identity ambient light
                        if (v.ShowShadow)
                            Render(rd, Util.MatrixMultiply(shadow, t), lightDirection,
                                ShadowAmbient, ShadowDiffuse, shadowPalette.TextureMidIndex, normals.TextureMidIndex);
                    }
                }
            }));

            var screenLightVector = Util.MatrixVectorMultiply(invShadowTransform, ZVector);
            screenLightVector = Util.MatrixVectorMultiply(cameraTransform, screenLightVector);
            return new VoxelRenderProxy(sprite, shadowSprite, screenCorners, -screenLightVector[2] / screenLightVector[1]);
        }
예제 #22
0
 public IRenderable[] Render(WPos pos, PaletteReference palette)
 {
     return(Render(pos, WVec.Zero, 0, palette));
 }
예제 #23
0
 public SpriteRenderable(Sprite sprite, WPos pos, WVec offset, int zOffset, PaletteReference palette, float scale, bool isDecoration, bool ignoreWorldTint)
     : this(sprite, pos, offset, zOffset, palette, scale, float3.Ones, isDecoration, ignoreWorldTint)
 {
 }
예제 #24
0
파일: Animation.cs 프로젝트: wytsep/OpenRA
 public IEnumerable <IRenderable> Render(WPos pos, PaletteReference palette)
 {
     return(Render(pos, WVec.Zero, 0, palette, 1f));
 }
예제 #25
0
 public UISpriteRenderable(Sprite sprite, WPos effectiveWorldPos, int2 screenPos, int zOffset, PaletteReference palette, float scale)
 {
     this.sprite            = sprite;
     this.effectiveWorldPos = effectiveWorldPos;
     this.screenPos         = screenPos;
     this.zOffset           = zOffset;
     this.palette           = palette;
     this.scale             = scale;
 }
예제 #26
0
 public IRenderable WithPalette(PaletteReference newPalette)
 {
     return(new SpriteRenderable(sprite, pos, offset, zOffset, newPalette, scale, isDecoration));
 }
예제 #27
0
 public IRenderable WithPalette(PaletteReference newPalette)
 {
     return(new TargetLineRenderable(waypoints, color));
 }
예제 #28
0
 public IRenderable WithPalette(PaletteReference newPalette)
 {
     return(new UISpriteRenderable(sprite, screenPos, zOffset, newPalette, scale));
 }
예제 #29
0
 public IRenderable WithPalette(PaletteReference newPalette)
 {
     return(new TextRenderable(font, pos, zOffset, color, text));
 }
예제 #30
0
 public IRenderable WithPalette(PaletteReference newPalette)
 {
     return(new SpriteRenderable(sprite, pos, offset, zOffset, newPalette, scale, tint, isDecoration, ignoreWorldTint));
 }
예제 #31
0
 public IRenderable WithPalette(PaletteReference newPalette)
 {
     return new BeamRenderable(pos, zOffset, length, shape, width, color);
 }
예제 #32
0
        public VoxelRenderProxy RenderAsync(WorldRenderer wr, IEnumerable <VoxelAnimation> voxels, WRot camera, float scale,
                                            float[] groundNormal, WRot lightSource, float[] lightAmbientColor, float[] lightDiffuseColor,
                                            PaletteReference color, PaletteReference normals, PaletteReference shadowPalette)
        {
            // Correct for inverted y-axis
            var scaleTransform = Util.ScaleMatrix(scale, scale, scale);

            // Correct for bogus light source definition
            var lightYaw        = Util.MakeFloatMatrix(new WRot(WAngle.Zero, WAngle.Zero, -lightSource.Yaw).AsMatrix());
            var lightPitch      = Util.MakeFloatMatrix(new WRot(WAngle.Zero, -lightSource.Pitch, WAngle.Zero).AsMatrix());
            var shadowTransform = Util.MatrixMultiply(lightPitch, lightYaw);

            var invShadowTransform = Util.MatrixInverse(shadowTransform);
            var cameraTransform    = Util.MakeFloatMatrix(camera.AsMatrix());
            var invCameraTransform = Util.MatrixInverse(cameraTransform);

            // Sprite rectangle
            var tl = new float2(float.MaxValue, float.MaxValue);
            var br = new float2(float.MinValue, float.MinValue);

            // Shadow sprite rectangle
            var stl = new float2(float.MaxValue, float.MaxValue);
            var sbr = new float2(float.MinValue, float.MinValue);

            foreach (var v in voxels)
            {
                // Convert screen offset back to world coords
                var offsetVec       = Util.MatrixVectorMultiply(invCameraTransform, wr.ScreenVector(v.OffsetFunc()));
                var offsetTransform = Util.TranslationMatrix(offsetVec[0], offsetVec[1], offsetVec[2]);

                var worldTransform = v.RotationFunc().Aggregate(Util.IdentityMatrix(),
                                                                (x, y) => Util.MatrixMultiply(Util.MakeFloatMatrix(y.AsMatrix()), x));
                worldTransform = Util.MatrixMultiply(scaleTransform, worldTransform);
                worldTransform = Util.MatrixMultiply(offsetTransform, worldTransform);

                var bounds       = v.Voxel.Bounds(v.FrameFunc());
                var worldBounds  = Util.MatrixAABBMultiply(worldTransform, bounds);
                var screenBounds = Util.MatrixAABBMultiply(cameraTransform, worldBounds);
                var shadowBounds = Util.MatrixAABBMultiply(shadowTransform, worldBounds);

                // Aggregate bounds rects
                tl  = float2.Min(tl, new float2(screenBounds[0], screenBounds[1]));
                br  = float2.Max(br, new float2(screenBounds[3], screenBounds[4]));
                stl = float2.Min(stl, new float2(shadowBounds[0], shadowBounds[1]));
                sbr = float2.Max(sbr, new float2(shadowBounds[3], shadowBounds[4]));
            }

            // Inflate rects to ensure rendering is within bounds
            tl  -= spritePadding;
            br  += spritePadding;
            stl -= spritePadding;
            sbr += spritePadding;

            // Corners of the shadow quad, in shadow-space
            var corners = new float[][]
            {
                new float[] { stl.X, stl.Y, 0, 1 },
                new float[] { sbr.X, sbr.Y, 0, 1 },
                new float[] { sbr.X, stl.Y, 0, 1 },
                new float[] { stl.X, sbr.Y, 0, 1 }
            };

            var shadowScreenTransform = Util.MatrixMultiply(cameraTransform, invShadowTransform);
            var shadowGroundNormal    = Util.MatrixVectorMultiply(shadowTransform, groundNormal);
            var screenCorners         = new float2[4];

            for (var j = 0; j < 4; j++)
            {
                // Project to ground plane
                corners[j][2] = -(corners[j][1] * shadowGroundNormal[1] / shadowGroundNormal[2] +
                                  corners[j][0] * shadowGroundNormal[0] / shadowGroundNormal[2]);

                // Rotate to camera-space
                corners[j]       = Util.MatrixVectorMultiply(shadowScreenTransform, corners[j]);
                screenCorners[j] = new float2(corners[j][0], corners[j][1]);
            }

            // Shadows are rendered at twice the resolution to reduce artefacts
            Size spriteSize, shadowSpriteSize;
            int2 spriteOffset, shadowSpriteOffset;

            CalculateSpriteGeometry(tl, br, 1, out spriteSize, out spriteOffset);
            CalculateSpriteGeometry(stl, sbr, 2, out shadowSpriteSize, out shadowSpriteOffset);

            var sprite       = sheetBuilder.Allocate(spriteSize, spriteOffset);
            var shadowSprite = sheetBuilder.Allocate(shadowSpriteSize, shadowSpriteOffset);
            var sb           = sprite.bounds;
            var ssb          = shadowSprite.bounds;
            var spriteCenter = new float2(sb.Left + sb.Width / 2, sb.Top + sb.Height / 2);
            var shadowCenter = new float2(ssb.Left + ssb.Width / 2, ssb.Top + ssb.Height / 2);

            var translateMtx              = Util.TranslationMatrix(spriteCenter.X - spriteOffset.X, Renderer.SheetSize - (spriteCenter.Y - spriteOffset.Y), 0);
            var shadowTranslateMtx        = Util.TranslationMatrix(shadowCenter.X - shadowSpriteOffset.X, Renderer.SheetSize - (shadowCenter.Y - shadowSpriteOffset.Y), 0);
            var correctionTransform       = Util.MatrixMultiply(translateMtx, flipMtx);
            var shadowCorrectionTransform = Util.MatrixMultiply(shadowTranslateMtx, shadowScaleFlipMtx);

            doRender.Add(Pair.New <Sheet, Action>(sprite.sheet, () =>
            {
                foreach (var v in voxels)
                {
                    // Convert screen offset to world offset
                    var offsetVec       = Util.MatrixVectorMultiply(invCameraTransform, wr.ScreenVector(v.OffsetFunc()));
                    var offsetTransform = Util.TranslationMatrix(offsetVec[0], offsetVec[1], offsetVec[2]);

                    var rotations = v.RotationFunc().Aggregate(Util.IdentityMatrix(),
                                                               (x, y) => Util.MatrixMultiply(Util.MakeFloatMatrix(y.AsMatrix()), x));
                    var worldTransform = Util.MatrixMultiply(scaleTransform, rotations);
                    worldTransform     = Util.MatrixMultiply(offsetTransform, worldTransform);

                    var transform = Util.MatrixMultiply(cameraTransform, worldTransform);
                    transform     = Util.MatrixMultiply(correctionTransform, transform);

                    var shadow = Util.MatrixMultiply(shadowTransform, worldTransform);
                    shadow     = Util.MatrixMultiply(shadowCorrectionTransform, shadow);

                    var lightTransform = Util.MatrixMultiply(Util.MatrixInverse(rotations), invShadowTransform);

                    var frame = v.FrameFunc();
                    for (uint i = 0; i < v.Voxel.Limbs; i++)
                    {
                        var rd = v.Voxel.RenderData(i);
                        var t  = v.Voxel.TransformationMatrix(i, frame);

                        // Transform light vector from shadow -> world -> limb coords
                        var lightDirection = ExtractRotationVector(Util.MatrixMultiply(Util.MatrixInverse(t), lightTransform));

                        Render(rd, Util.MatrixMultiply(transform, t), lightDirection,
                               lightAmbientColor, lightDiffuseColor, color.Index, normals.Index);

                        // Disable shadow normals by forcing zero diffuse and identity ambient light
                        Render(rd, Util.MatrixMultiply(shadow, t), lightDirection,
                               shadowAmbient, shadowDiffuse, shadowPalette.Index, normals.Index);
                    }
                }
            }));

            var screenLightVector = Util.MatrixVectorMultiply(invShadowTransform, zVector);

            screenLightVector = Util.MatrixVectorMultiply(cameraTransform, screenLightVector);
            return(new VoxelRenderProxy(sprite, shadowSprite, screenCorners, -screenLightVector[2] / screenLightVector[1]));
        }
예제 #33
0
        public void AddCommand(int ShaderID, int CurrentFrame, int TotalFrames, int CurrentTime, int TotalTime, int2 iResolutionXY,
                               float3 TopLeftXYrect, float3 SpriteSize, Sprite SpriteUVCoords, PaletteReference PaletteIndex)
        {
            //рисуем в СисКоординат, где начало координат в ЛевомНижнемУглу
            //заполнение локального массива Verts
            //нужно 4 записи сделать, на каждый угол прямоугольника.
            var a = new float3(TopLeftXYrect.X, TopLeftXYrect.Y + SpriteSize.Y, TopLeftXYrect.Z);                //1
            var b = new float3(TopLeftXYrect.X + SpriteSize.X, TopLeftXYrect.Y + SpriteSize.Y, TopLeftXYrect.Z); //2
            var c = new float3(TopLeftXYrect.X, TopLeftXYrect.Y, TopLeftXYrect.Z + 0);                           //3
            var d = new float3(TopLeftXYrect.X + SpriteSize.X, TopLeftXYrect.Y, TopLeftXYrect.Z + 0);            //4

            float TextureStoreChannel = 0;
            int   TextureInputSlot    = 1;        // всегда 1 слот, так как пока поддержка только 1 текстурки будет.
            float palindex            = 0;

            if (SpriteUVCoords != null)
            {
                shtInputSlot1 = SpriteUVCoords.Sheet2D;
                this.SetTexture("Texture2D0", shtInputSlot1.AssignOrGetOrSetDataGLTexture());                 // заполняем текстуру0 для аргумента шейдера

                ni = 0;
                //Vertex mapping xyz,ShaderID,CurrentFrame,TotalFrames, iTime, TotalTime,iResolutionXY, TextureInputSlot , TextureStoreChannel,SpriteUVCoords

                //PaletteIndex.TextureIndex индекс в текстуре палитр


                if (SpriteUVCoords.Channel == TextureChannel.RGBA)
                {
                    TextureStoreChannel = 4f;                     // это потому что, выбор текстуры зависит от 0.0 чисел в шейдере в методе vec4 Sample()
                }
                else
                {
                    TextureStoreChannel = (byte)SpriteUVCoords.Channel;
                }
                TextureStoreChannel = SpriteUVCoords.TextureArrayIndex;
            }

            if (SpriteUVCoords == null)
            {
                SpriteUVCoords = new Sprite(new Sheet(SheetType.Indexed, new Size(0, 0)), new Rectangle(new int2(0, 0), new Size(0, 0)), 0);
            }
            if (PaletteIndex == null)
            {
                PaletteIndex = new PaletteReference("null", 0, null, new HardwarePalette());
                palindex     = PaletteIndex.TextureIndex;
            }



            Verts[nv]     = new Vertex2(a, ShaderID, CurrentFrame, TotalFrames, 0, 0, SpriteUVCoords.Size.X, SpriteUVCoords.Size.Y, TextureInputSlot, TextureStoreChannel, SpriteUVCoords.Left, SpriteUVCoords.Bottom, palindex, 0);
            Verts[nv + 1] = new Vertex2(b, ShaderID, CurrentFrame, TotalFrames, 0, 0, SpriteUVCoords.Size.X, SpriteUVCoords.Size.Y, TextureInputSlot, TextureStoreChannel, SpriteUVCoords.Right, SpriteUVCoords.Bottom, palindex, 0);
            Verts[nv + 2] = new Vertex2(c, ShaderID, CurrentFrame, TotalFrames, 0, 0, SpriteUVCoords.Size.X, SpriteUVCoords.Size.Y, TextureInputSlot, TextureStoreChannel, SpriteUVCoords.Left, SpriteUVCoords.Top, palindex, 0);
            Verts[nv + 3] = new Vertex2(d, ShaderID, CurrentFrame, TotalFrames, 0, 0, SpriteUVCoords.Size.X, SpriteUVCoords.Size.Y, TextureInputSlot, TextureStoreChannel, SpriteUVCoords.Right, SpriteUVCoords.Top, palindex, 0);
            nv           += 4;
        }
예제 #34
0
 public void OwnerChanged()
 {
     // Update the palette reference next time we draw
     if (IsPlayerPalette)
         PaletteReference = null;
 }
예제 #35
0
 public IRenderable[] Render(Actor actor, WPos pos, PaletteReference palette)
 {
     return(Render(actor, pos, WVec.Zero, 0, palette, 1f));
 }
예제 #36
0
 public void WorldLoaded(World w, WorldRenderer wr)
 {
     Palette = wr.Palette(Info.Palette);
 }
예제 #37
0
        public IRenderable[] RenderUI(WorldRenderer wr, int2 pos, WVec offset, int zOffset, PaletteReference palette, float scale)
        {
            var screenOffset    = (scale * wr.ScreenVectorComponents(offset)).XY.ToInt2();
            var imagePos        = pos + screenOffset - new int2((int)(scale * Image.Size.X / 2), (int)(scale * Image.Size.Y / 2));
            var imageRenderable = new UISpriteRenderable(Image, WPos.Zero + offset, imagePos, CurrentSequence.ZOffset + zOffset, palette, scale);

            if (CurrentSequence.ShadowStart >= 0)
            {
                var shadow           = CurrentSequence.GetShadow(CurrentFrame, facingFunc());
                var shadowPos        = pos - new int2((int)(scale * shadow.Size.X / 2), (int)(scale * shadow.Size.Y / 2));
                var shadowRenderable = new UISpriteRenderable(shadow, WPos.Zero + offset, shadowPos, CurrentSequence.ShadowZOffset + zOffset, palette, scale);
                return(new IRenderable[] { shadowRenderable, imageRenderable });
            }

            return(new IRenderable[] { imageRenderable });
        }
예제 #38
0
        public ModelRenderProxy RenderAsync(
            WorldRenderer wr, IEnumerable <ModelAnimation> models, WRot camera, float scale,
            float[] groundNormal, WRot lightSource, float[] lightAmbientColor, float[] lightDiffuseColor,
            PaletteReference color, PaletteReference normals, PaletteReference shadowPalette)
        {
            if (!isInFrame)
            {
                throw new InvalidOperationException("BeginFrame has not been called. You cannot render until a frame has been started.");
            }

            // Correct for inverted y-axis
            var scaleTransform = Util.ScaleMatrix(scale, scale, scale);

            // Correct for bogus light source definition
            var lightYaw        = Util.MakeFloatMatrix(new WRot(WAngle.Zero, WAngle.Zero, -lightSource.Yaw).AsMatrix());
            var lightPitch      = Util.MakeFloatMatrix(new WRot(WAngle.Zero, -lightSource.Pitch, WAngle.Zero).AsMatrix());
            var shadowTransform = Util.MatrixMultiply(lightPitch, lightYaw);

            var invShadowTransform = Util.MatrixInverse(shadowTransform);
            var cameraTransform    = Util.MakeFloatMatrix(camera.AsMatrix());
            var invCameraTransform = Util.MatrixInverse(cameraTransform);

            if (invCameraTransform == null)
            {
                throw new InvalidOperationException("Failed to invert the cameraTransform matrix during RenderAsync.");
            }

            // Sprite rectangle
            var tl = new float2(float.MaxValue, float.MaxValue);
            var br = new float2(float.MinValue, float.MinValue);

            // Shadow sprite rectangle
            var stl = new float2(float.MaxValue, float.MaxValue);
            var sbr = new float2(float.MinValue, float.MinValue);

            foreach (var m in models)
            {
                // Convert screen offset back to world coords
                var offsetVec       = Util.MatrixVectorMultiply(invCameraTransform, wr.ScreenVector(m.OffsetFunc()));
                var offsetTransform = Util.TranslationMatrix(offsetVec[0], offsetVec[1], offsetVec[2]);

                var worldTransform = m.RotationFunc().Aggregate(Util.IdentityMatrix(),
                                                                (x, y) => Util.MatrixMultiply(Util.MakeFloatMatrix(y.AsMatrix()), x));
                worldTransform = Util.MatrixMultiply(scaleTransform, worldTransform);
                worldTransform = Util.MatrixMultiply(offsetTransform, worldTransform);

                var bounds       = m.Model.Bounds(m.FrameFunc());
                var worldBounds  = Util.MatrixAABBMultiply(worldTransform, bounds);
                var screenBounds = Util.MatrixAABBMultiply(cameraTransform, worldBounds);
                var shadowBounds = Util.MatrixAABBMultiply(shadowTransform, worldBounds);

                // Aggregate bounds rects
                tl  = float2.Min(tl, new float2(screenBounds[0], screenBounds[1]));
                br  = float2.Max(br, new float2(screenBounds[3], screenBounds[4]));
                stl = float2.Min(stl, new float2(shadowBounds[0], shadowBounds[1]));
                sbr = float2.Max(sbr, new float2(shadowBounds[3], shadowBounds[4]));
            }

            // Inflate rects to ensure rendering is within bounds
            tl  -= SpritePadding;
            br  += SpritePadding;
            stl -= SpritePadding;
            sbr += SpritePadding;

            // Corners of the shadow quad, in shadow-space
            var corners = new float[][]
            {
                new[] { stl.X, stl.Y, 0, 1 },
                new[] { sbr.X, sbr.Y, 0, 1 },
                new[] { sbr.X, stl.Y, 0, 1 },
                new[] { stl.X, sbr.Y, 0, 1 }
            };

            var shadowScreenTransform = Util.MatrixMultiply(cameraTransform, invShadowTransform);
            var shadowGroundNormal    = Util.MatrixVectorMultiply(shadowTransform, groundNormal);
            var screenCorners         = new float3[4];

            for (var j = 0; j < 4; j++)
            {
                // Project to ground plane
                corners[j][2] = -(corners[j][1] * shadowGroundNormal[1] / shadowGroundNormal[2] +
                                  corners[j][0] * shadowGroundNormal[0] / shadowGroundNormal[2]);

                // Rotate to camera-space
                corners[j]       = Util.MatrixVectorMultiply(shadowScreenTransform, corners[j]);
                screenCorners[j] = new float3(corners[j][0], corners[j][1], 0);
            }

            // Shadows are rendered at twice the resolution to reduce artifacts
            Size spriteSize, shadowSpriteSize;
            int2 spriteOffset, shadowSpriteOffset;

            CalculateSpriteGeometry(tl, br, 1, out spriteSize, out spriteOffset);
            CalculateSpriteGeometry(stl, sbr, 2, out shadowSpriteSize, out shadowSpriteOffset);

            if (sheetBuilderForFrame == null)
            {
                sheetBuilderForFrame = new SheetBuilder(SheetType.BGRA, AllocateSheet);
            }

            var sprite       = sheetBuilderForFrame.Allocate(spriteSize, 0, spriteOffset);
            var shadowSprite = sheetBuilderForFrame.Allocate(shadowSpriteSize, 0, shadowSpriteOffset);
            var sb           = sprite.Bounds;
            var ssb          = shadowSprite.Bounds;
            var spriteCenter = new float2(sb.Left + sb.Width / 2, sb.Top + sb.Height / 2);
            var shadowCenter = new float2(ssb.Left + ssb.Width / 2, ssb.Top + ssb.Height / 2);

            var translateMtx              = Util.TranslationMatrix(spriteCenter.X - spriteOffset.X, renderer.SheetSize - (spriteCenter.Y - spriteOffset.Y), 0);
            var shadowTranslateMtx        = Util.TranslationMatrix(shadowCenter.X - shadowSpriteOffset.X, renderer.SheetSize - (shadowCenter.Y - shadowSpriteOffset.Y), 0);
            var correctionTransform       = Util.MatrixMultiply(translateMtx, FlipMtx);
            var shadowCorrectionTransform = Util.MatrixMultiply(shadowTranslateMtx, ShadowScaleFlipMtx);

            doRender.Add(Pair.New <Sheet, Action>(sprite.Sheet, () =>
            {
                foreach (var m in models)
                {
                    // Convert screen offset to world offset
                    var offsetVec       = Util.MatrixVectorMultiply(invCameraTransform, wr.ScreenVector(m.OffsetFunc()));
                    var offsetTransform = Util.TranslationMatrix(offsetVec[0], offsetVec[1], offsetVec[2]);

                    var rotations = m.RotationFunc().Aggregate(Util.IdentityMatrix(),
                                                               (x, y) => Util.MatrixMultiply(Util.MakeFloatMatrix(y.AsMatrix()), x));
                    var worldTransform = Util.MatrixMultiply(scaleTransform, rotations);
                    worldTransform     = Util.MatrixMultiply(offsetTransform, worldTransform);

                    var transform = Util.MatrixMultiply(cameraTransform, worldTransform);
                    transform     = Util.MatrixMultiply(correctionTransform, transform);

                    var shadow = Util.MatrixMultiply(shadowTransform, worldTransform);
                    shadow     = Util.MatrixMultiply(shadowCorrectionTransform, shadow);

                    var lightTransform = Util.MatrixMultiply(Util.MatrixInverse(rotations), invShadowTransform);

                    var frame = m.FrameFunc();
                    for (uint i = 0; i < m.Model.Sections; i++)
                    {
                        var rd = m.Model.RenderData(i);
                        var t  = m.Model.TransformationMatrix(i, frame);
                        var it = Util.MatrixInverse(t);
                        if (it == null)
                        {
                            throw new InvalidOperationException("Failed to invert the transformed matrix of frame {0} during RenderAsync.".F(i));
                        }

                        // Transform light vector from shadow -> world -> limb coords
                        var lightDirection = ExtractRotationVector(Util.MatrixMultiply(it, lightTransform));

                        Render(rd, wr.World.ModelCache, Util.MatrixMultiply(transform, t), lightDirection,
                               lightAmbientColor, lightDiffuseColor, color.TextureMidIndex, normals.TextureMidIndex);

                        // Disable shadow normals by forcing zero diffuse and identity ambient light
                        if (m.ShowShadow)
                        {
                            Render(rd, wr.World.ModelCache, Util.MatrixMultiply(shadow, t), lightDirection,
                                   ShadowAmbient, ShadowDiffuse, shadowPalette.TextureMidIndex, normals.TextureMidIndex);
                        }
                    }
                }
            }));

            var screenLightVector = Util.MatrixVectorMultiply(invShadowTransform, ZVector);

            screenLightVector = Util.MatrixVectorMultiply(cameraTransform, screenLightVector);
            return(new ModelRenderProxy(sprite, shadowSprite, screenCorners, -screenLightVector[2] / screenLightVector[1]));
        }
예제 #39
0
 public void Update(CPos cell, ISpriteSequence sequence, PaletteReference palette, int frame)
 {
     Update(cell, sequence.GetSprite(frame), palette, sequence.Scale, sequence.GetAlpha(frame), sequence.IgnoreWorldTint);
 }
예제 #40
0
 public IRenderable WithPalette(PaletteReference newPalette)
 {
     return(new ContrailRenderable(world, (WPos[])trail.Clone(), next, length, skip, color, zOffset));
 }
예제 #41
0
 public void Update(MPos uv, Sprite sprite, PaletteReference palette, in float3 pos, float scale, float alpha, bool ignoreTint)
예제 #42
0
 public void DrawSprite(Sprite s, float3 location, PaletteReference pal, float3 size)
 {
     DrawSprite(s, location, pal.TextureIndex, size);
 }
예제 #43
0
 /* get around unverifiability */
 IEnumerable<IRenderable> BaseBuildingPreview(World world, ActorInfo building, PaletteReference pr)
 {
     return base.RenderPreview(world, building, pr);
 }
예제 #44
0
 public void DrawSpriteWithTint(Sprite s, float3 location, PaletteReference pal, float3 size, float3 tint)
 {
     DrawSpriteWithTint(s, location, pal.TextureIndex, size, tint);
 }
예제 #45
0
 public IRenderable WithPalette(PaletteReference newPalette)
 {
     return(new VoxelRenderable(voxels, pos, zOffset, camera, scale,
                                lightSource, lightAmbientColor, lightDiffuseColor,
                                newPalette, normalsPalette, shadowPalette));
 }
예제 #46
0
 public void DrawSprite(Sprite s, float2 location, PaletteReference pal, float2 size)
 {
     DrawSprite(s, location, pal.Index, size);
 }
예제 #47
0
        public virtual IEnumerable<Renderable> RenderPreview(ActorInfo building, PaletteReference pr)
        {
            var anim = new Animation(RenderSimple.GetImage(building), () => 0);
            anim.PlayRepeating("idle");

            yield return new Renderable(anim.Image, 0.5f * anim.Image.size * (1 - Scale), pr, 0, Scale);
        }
예제 #48
0
 public IPalettedRenderable WithPalette(PaletteReference newPalette)
 {
     return(new SpriteRenderable(sprite, pos, offset, zOffset, newPalette, scale, alpha, tint, tintModifiers, isDecoration));
 }
예제 #49
0
 public IRenderable WithPalette(PaletteReference newPalette)
 {
     return new UISpriteRenderable(sprite, screenPos, zOffset, newPalette, scale);
 }
예제 #50
0
        public TerrainSpriteLayer(World world, WorldRenderer wr, Sheet sheet, BlendMode blendMode, PaletteReference palette, bool restrictToBounds)
        {
            worldRenderer         = wr;
            this.restrictToBounds = restrictToBounds;
            Sheet        = sheet;
            BlendMode    = blendMode;
            this.palette = palette;

            map       = world.Map;
            rowStride = 6 * map.MapSize.X;

            vertices     = new Vertex[rowStride * map.MapSize.Y];
            vertexBuffer = Game.Renderer.Context.CreateVertexBuffer(vertices.Length);
            emptySprite  = new Sprite(sheet, Rectangle.Empty, TextureChannel.Alpha);

            wr.PaletteInvalidated += UpdatePaletteIndices;
        }
예제 #51
0
 public void CachePalette(WorldRenderer wr, Player owner)
 {
     PaletteReference = wr.Palette(IsPlayerPalette ? Palette + owner.InternalName : Palette);
 }
예제 #52
0
 public IRenderable WithPalette(PaletteReference newPalette)
 {
     return(this);
 }
예제 #53
0
 public IRenderable WithPalette(PaletteReference newPalette)
 {
     return new TeslaZapRenderable(pos, zOffset, length, image, brightZaps, dimZaps, palette);
 }
예제 #54
0
 public IRenderable WithPalette(PaletteReference newPalette)
 {
     return(new BeamRenderable(pos, zOffset, length, width, color));
 }
예제 #55
0
        public UISpriteRenderable(Sprite sprite, WPos effectiveWorldPos, int2 screenPos, int zOffset, PaletteReference palette, float scale = 1f, float alpha = 1f)
        {
            this.sprite            = sprite;
            this.effectiveWorldPos = effectiveWorldPos;
            this.screenPos         = screenPos;
            this.zOffset           = zOffset;
            this.palette           = palette;
            this.scale             = scale;
            this.alpha             = alpha;

            // PERF: Remove useless palette assignments for RGBA sprites
            // HACK: This is working around the fact that palettes are defined on traits rather than sequences
            // and can be removed once this has been fixed
            if (sprite.Channel == TextureChannel.RGBA && !(palette?.HasColorShift ?? false))
            {
                this.palette = null;
            }
        }
예제 #56
0
 public IPalettedRenderable WithPalette(PaletteReference newPalette)
 {
     return(new UISpriteRenderable(sprite, effectiveWorldPos, screenPos, zOffset, newPalette, scale, alpha));
 }
예제 #57
0
 public IRenderable WithPalette(PaletteReference newPalette)
 {
     return this;
 }
예제 #58
0
파일: Sprite.cs 프로젝트: epicelite/OpenRA
 public void DrawAt(float2 location, PaletteReference pal, float2 size)
 {
     Game.Renderer.WorldSpriteRenderer.DrawSprite(this, location, pal, size);
 }