예제 #1
0
		// VplFile _vplFile;

		public void Initialize() {
			Logger.Info("Initializing voxel renderer");
			_isInit = true;

			_surface = new DrawingSurface(400, 400, PixelFormat.Format32bppArgb);
			if (!CreateContext()) {
				Logger.Error("No graphics context could not be initialized, voxel rendering will be unavailable");
				return;
			}

			Logger.Debug("GL context created");
			try {
				Logger.Debug("GL functions loaded");

				GL.Enable(EnableCap.DepthTest);
				GL.Enable(EnableCap.ColorMaterial);

				//_vplFile = VFS.Open<VplFile>("voxels.vpl"); 
				_canRender = SetupFramebuffer();
			}

			catch (Exception exc) {
				Logger.Error("Voxel rendering will not be available because an exception occurred while initializing OpenGL: {0}", exc.ToString());
			}
		}
예제 #2
0
        // VplFile _vplFile;

        public void Initialize()
        {
            Logger.Info("Initializing voxel renderer");
            _isInit = true;

            _surface = new DrawingSurface(400, 400, PixelFormat.Format32bppArgb);
            if (!CreateContext())
            {
                Logger.Error("No graphics context could not be initialized, voxel rendering will be unavailable");
                return;
            }

            Logger.Debug("GL context created");
            try {
                Logger.Debug("GL functions loaded");

                GL.Enable(EnableCap.DepthTest);
                GL.Enable(EnableCap.ColorMaterial);

                //_vplFile = VFS.Open<VplFile>("voxels.vpl");
                _canRender = SetupFramebuffer();
            }

            catch (Exception exc) {
                Logger.Error("Voxel rendering will not be available because an exception occurred while initializing OpenGL: {0}", exc.ToString());
            }
        }
예제 #3
0
		public override void Draw(GameObject obj, DrawingSurface ds, bool shadows = true) {
			if (obj == null || TsEntry == null) return;

			var tmpFile = TsEntry.GetTmpFile(obj as MapTile);
			if (tmpFile != null)
				TmpRenderer.Draw((MapTile)obj, tmpFile, ds);

			// todo: tile shadows (TS)
		}
예제 #4
0
		public override void Draw(GameObject obj, DrawingSurface ds, bool omitShadow = false) {
			if (TransLucency == 0)
				base.Draw(obj, ds, omitShadow);
			else {
				Logger.Debug("Drawing object {0} with {1}% translucency", obj, TransLucency);
				ShpRenderer.Draw(Shp, obj, this, Props, ds, TransLucency);
			}
			if (Props.HasShadow && !omitShadow)
				ShpRenderer.DrawShadow(obj, Shp, Props, ds);
		}
		public DebugDrawingSurfaceWindow(DrawingSurface ds, TileLayer tiles, Theater t, Map.Map map)
			: this() {
			_drawingSurface = ds;
			_tiles = tiles;
			_theater = t;
			_map = map;

			ds.Unlock();
			pictureBox1.Image = ds.Bitmap;
		}
예제 #6
0
		public override void Draw(GameObject obj, DrawingSurface ds, bool shadows = true) {
			Size onBridgeOffset = Size.Empty;
			if (obj is OwnableObject && (obj as OwnableObject).OnBridge)
				onBridgeOffset = new Size(0, -4 * TileHeight / 2);

			foreach (var drawable in SubDrawables) {
				drawable.Props.Offset += onBridgeOffset;
				drawable.Draw(obj, ds, shadows);
				drawable.Props.Offset -= onBridgeOffset;
			}
		}
        public DebugDrawingSurfaceWindow(DrawingSurface ds, TileLayer tiles, Theater t, Map.Map map)
            : this()
        {
            _drawingSurface = ds;
            _tiles          = tiles;
            _theater        = t;
            _map            = map;

            ds.Unlock();
            pictureBox1.Image = ds.Bitmap;
        }
예제 #8
0
        public DebugDrawingSurfaceWindow(DrawingSurface ds, TileLayer tiles, Theater t, Map.Map map)
            : this()
        {
            _drawingSurface = ds;
            _tiles          = tiles;
            _theater        = t;
            _map            = map;

            _cells = (_map.FullSize.Width * 2 - 1) * _map.FullSize.Height;

            ds.Unlock();
            pictureBox1.Image = ds.Bitmap;
        }
        public DebugDrawingSurfaceWindow(DrawingSurface ds, TileLayer tiles, Theater t, Map.Map map)
            : this()
        {
            _drawingSurface = ds;
            _tiles          = tiles;
            _theater        = t;
            _map            = map;

            _cells = (_map.FullSize.Width * 2 - 1) * _map.FullSize.Height;

            ds.Unlock();

            // map is pre-rendered bitmap, shadow/heightmap are rendered on demand
            canvasMap.Image = ds.Bitmap;
        }
예제 #10
0
		private unsafe void BlitVoxelToSurface(DrawingSurface ds, DrawingSurface vxl_ds, GameObject obj, DrawProperties props) {
			Point d = new Point(obj.Tile.Dx * TileWidth / 2, (obj.Tile.Dy - obj.Tile.Z) * TileHeight / 2);
			d.Offset(props.GetOffset(obj));
			d.Offset(-vxl_ds.BitmapData.Width / 2, -vxl_ds.BitmapData.Height / 2);

			// rows inverted!
			var w_low = (byte*)ds.BitmapData.Scan0;
			byte* w_high = w_low + ds.BitmapData.Stride * ds.BitmapData.Height;
			var zBuffer = ds.GetZBuffer();
			var shadowBufVxl = vxl_ds.GetShadows();
			var shadowBuf = ds.GetShadows();
			// int rowsTouched = 0;

			// short firstRowTouched = short.MaxValue;
			for (int y = 0; y < vxl_ds.Height; y++) {
				byte* src_row = (byte*)vxl_ds.BitmapData.Scan0 + vxl_ds.BitmapData.Stride * (vxl_ds.Height - y - 1);
				byte* dst_row = ((byte*)ds.BitmapData.Scan0 + (d.Y + y) * ds.BitmapData.Stride + d.X * 3);
				int zIdx = (d.Y + y) * ds.Width + d.X;
				if (dst_row < w_low || dst_row >= w_high) continue;

				for (int x = 0; x < vxl_ds.Width; x++) {
					// only non-transparent pixels
					if (*(src_row + x * 4 + 3) > 0) {
						*(dst_row + x * 3) = *(src_row + x * 4);
						*(dst_row + x * 3 + 1) = *(src_row + x * 4 + 1);
						*(dst_row + x * 3 + 2) = *(src_row + x * 4 + 2);

						// if (y < firstRowTouched)
						// 	firstRowTouched = (short)y;

						short zBufVal = (short)((obj.Tile.Rx + obj.Tile.Ry + obj.Tile.Z) * TileHeight / 2);
						if (zBufVal >= zBuffer[zIdx])
							zBuffer[zIdx] = zBufVal;
					}
					// or shadows
					else if (shadowBufVxl[x + y * vxl_ds.Height]) {
						int shadIdx = (d.Y + y) * ds.Width + d.X + x;
						if (!shadowBuf[shadIdx]) {
							*(dst_row + x * 3) /= 2;
							*(dst_row + x * 3 + 1) /= 2;
							*(dst_row + x * 3 + 2) /= 2;
							shadowBuf[shadIdx] = true;
						}
					}
					zIdx++;
				}
			}
		}
예제 #11
0
		public void DrawPowerup(GameObject obj, Drawable powerup, int slot, DrawingSurface ds) {
			if (slot >= _powerupSlots.Count)
				throw new InvalidOperationException("Building does not have requested slot ");

			var powerupOffset = new Point(_powerupSlots[slot].X, _powerupSlots[slot].Y);
			powerup.Props.Offset.Offset(powerupOffset);
			powerup.Draw(obj, ds);
			// undo offset
			powerup.Props.Offset.Offset(-powerupOffset.X, -powerupOffset.Y);
		}
예제 #12
0
        unsafe public static void Draw(MapTile tile, TmpFile tmp, DrawingSurface ds)
        {
            tmp.Initialize();

            if (tile.SubTile >= tmp.Images.Count)
            {
                return;
            }
            TmpFile.TmpImage img = tmp.Images[tile.SubTile];
            var     zBuffer      = ds.GetZBuffer();
            var     heightBuffer = ds.GetHeightBuffer();
            Palette p            = tile.Palette;

            // calculate tile index -> pixel index
            Point offset = new Point(tile.Dx * tmp.BlockWidth / 2, (tile.Dy - tile.Z) * tmp.BlockHeight / 2);

            // make touched tiles (used for determining image cutoff)
            Point center         = offset + new Size(tmp.BlockWidth / 2, tmp.BlockHeight / 2);
            var   centerGridTile = tile.Layer.GetTileScreen(center, true, true);

            if (centerGridTile != null)
            {
                tile.Layer.GridTouched[centerGridTile.Dx, centerGridTile.Dy / 2]  |= TileLayer.TouchType.ByNormalData;
                tile.Layer.GridTouchedBy[centerGridTile.Dx, centerGridTile.Dy / 2] = tile;
            }

            Logger.Trace("Drawing TMP file {0} (subtile {1}) at ({2},{3})", tmp.FileName, tile.SubTile, offset.X, offset.Y);

            int stride = ds.BitmapData.Stride;

            int halfCx = tmp.BlockWidth / 2,
                halfCy = tmp.BlockHeight / 2;

            // writing bounds
            var   w_low  = (byte *)ds.BitmapData.Scan0;
            byte *w_high = (byte *)ds.BitmapData.Scan0 + stride * ds.BitmapData.Height;
            byte *w      = (byte *)ds.BitmapData.Scan0 + stride * offset.Y + (offset.X + halfCx - 2) * 3;

            int rIdx = 0, x, y = 0;
            int zIdx = offset.Y * ds.Width + offset.X + halfCx - 2;
            int cx   = 0;           // Amount of pixel to copy

            for (; y < halfCy; y++)
            {
                cx += 4;
                for (ushort c = 0; c < cx; c++)
                {
                    byte paletteValue = img.TileData[rIdx];

                    short zBufVal = (short)((tile.Rx + tile.Ry) * tmp.BlockHeight / 2 - (img.ZData != null ? img.ZData[rIdx] : 0));
                    if (paletteValue != 0 && w_low <= w && w < w_high && zBufVal >= zBuffer[zIdx])
                    {
                        *(w + 0)           = p.Colors[paletteValue].B;
                        *(w + 1)           = p.Colors[paletteValue].G;
                        *(w + 2)           = p.Colors[paletteValue].R;
                        zBuffer[zIdx]      = zBufVal;
                        heightBuffer[zIdx] = (short)(tile.Z * Drawable.TileHeight / 2);
                    }
                    w += 3;
                    zIdx++;
                    rIdx++;
                }
                w    += stride - 3 * (cx + 2);
                zIdx += ds.Width - (cx + 2);
            }

            w    += 12;
            zIdx += 4;
            for (; y < tmp.BlockHeight; y++)
            {
                cx -= 4;
                for (ushort c = 0; c < cx; c++)
                {
                    byte paletteValue = img.TileData[rIdx];

                    short zBufVal = (short)((tile.Rx + tile.Ry) * tmp.BlockHeight / 2 - (img.ZData != null ? img.ZData[rIdx] : 0));
                    if (paletteValue != 0 && w_low <= w && w < w_high && zBufVal >= zBuffer[zIdx])
                    {
                        *(w + 0)           = p.Colors[paletteValue].B;
                        *(w + 1)           = p.Colors[paletteValue].G;
                        *(w + 2)           = p.Colors[paletteValue].R;
                        zBuffer[zIdx]      = zBufVal;
                        heightBuffer[zIdx] = (short)(tile.Z * Drawable.TileHeight / 2);
                    }
                    w += 3;
                    zIdx++;
                    rIdx++;
                }
                w    += stride - 3 * (cx - 2);
                zIdx += ds.Width - (cx - 2);
            }

            if (!img.HasExtraData)
            {
                return;                                // we're done now
            }
            offset.X += img.ExtraX - img.X;
            offset.Y += img.ExtraY - img.Y;
            w         = w_low + stride * offset.Y + 3 * offset.X;
            zIdx      = offset.X + offset.Y * ds.Width;
            rIdx      = 0;

            // identify extra-data affected tiles for cutoff
            var extraScreenBounds = Rectangle.FromLTRB(
                Math.Max(0, offset.X), Math.Max(0, offset.Y),
                Math.Min(offset.X + img.ExtraWidth, ds.Width), Math.Min(offset.Y + img.ExtraHeight, ds.Height));

            for (int by = extraScreenBounds.Top; by < extraScreenBounds.Bottom; by += tmp.BlockHeight / 2)
            {
                for (int bx = extraScreenBounds.Left; bx < extraScreenBounds.Right; bx += tmp.BlockWidth / 2)
                {
                    var gridTileNoZ = tile.Layer.GetTileScreen(new Point(bx, by), true, true);
                    if (gridTileNoZ != null)
                    {
                        Logger.Trace("Tile at ({0},{1}) has extradata affecting ({2},{3})", tile.Dx, tile.Dy, gridTileNoZ.Dx,
                                     gridTileNoZ.Dy);
                        tile.Layer.GridTouched[gridTileNoZ.Dx, gridTileNoZ.Dy / 2]  |= TileLayer.TouchType.ByExtraData;
                        tile.Layer.GridTouchedBy[gridTileNoZ.Dx, gridTileNoZ.Dy / 2] = tile;
                    }
                }
            }

            // Extra graphics are just a square
            for (y = 0; y < img.ExtraHeight; y++)
            {
                for (x = 0; x < img.ExtraWidth; x++)
                {
                    // Checking per line is required because v needs to be checked every time
                    byte  paletteValue = img.ExtraData[rIdx];
                    short zBufVal      = (short)((tile.Rx + tile.Ry) * tmp.BlockHeight / 2 + (img.ExtraZData != null ? img.ExtraZData[rIdx] : 0));

                    if (paletteValue != 0 && w_low <= w && w < w_high && zBufVal >= zBuffer[zIdx])
                    {
                        *w++ = p.Colors[paletteValue].B;
                        *w++ = p.Colors[paletteValue].G;
                        *w++ = p.Colors[paletteValue].R;
                        zBuffer[zIdx]      = zBufVal;
                        heightBuffer[zIdx] = (short)(img.ExtraHeight - y + tile.Z * Drawable.TileHeight / 2);
                    }
                    else
                    {
                        w += 3;
                    }
                    zIdx++;
                    rIdx++;
                }
                w    += stride - img.ExtraWidth * 3;
                zIdx += ds.Width - img.ExtraWidth;
            }
        }
예제 #13
0
		public abstract void Draw(GameObject obj, DrawingSurface ds, bool shadow = true);
예제 #14
0
		unsafe public static void Draw(MapTile tile, TmpFile tmp, DrawingSurface ds) {
			tmp.Initialize();

			if (tile.SubTile >= tmp.Images.Count) return;
			TmpFile.TmpImage img = tmp.Images[tile.SubTile];
			var zBuffer = ds.GetZBuffer();
			var heightBuffer = ds.GetHeightBuffer();
			Palette p = tile.Palette;

			// calculate tile index -> pixel index
			Point offset = new Point(tile.Dx * tmp.BlockWidth / 2, (tile.Dy - tile.Z) * tmp.BlockHeight / 2);

			// make touched tiles (used for determining image cutoff)
			Point center = offset + new Size(tmp.BlockWidth / 2, tmp.BlockHeight / 2);
			var centerGridTile = tile.Layer.GetTileScreen(center, true, true);
			if (centerGridTile != null) {
				tile.Layer.GridTouched[centerGridTile.Dx, centerGridTile.Dy / 2] |= TileLayer.TouchType.ByNormalData;
				tile.Layer.GridTouchedBy[centerGridTile.Dx, centerGridTile.Dy / 2] = tile;
			}

			Logger.Trace("Drawing TMP file {0} (subtile {1}) at ({2},{3})", tmp.FileName, tile.SubTile, offset.X, offset.Y);

			int stride = ds.BitmapData.Stride;

			int halfCx = tmp.BlockWidth / 2,
				halfCy = tmp.BlockHeight / 2;

			// writing bounds
			var w_low = (byte*)ds.BitmapData.Scan0;
			byte* w_high = (byte*)ds.BitmapData.Scan0 + stride * ds.BitmapData.Height;
			byte* w = (byte*)ds.BitmapData.Scan0 + stride * offset.Y + (offset.X + halfCx - 2) * 3;

			int rIdx = 0, x, y = 0;
			int zIdx = offset.Y * ds.Width + offset.X + halfCx - 2;
			int cx = 0; // Amount of pixel to copy

			for (; y < halfCy; y++) {
				cx += 4;
				for (ushort c = 0; c < cx; c++) {
					byte paletteValue = img.TileData[rIdx];

					short zBufVal = (short)((tile.Rx + tile.Ry) * tmp.BlockHeight / 2 - (img.ZData != null ? img.ZData[rIdx] : 0));
					if (paletteValue != 0 && w_low <= w && w < w_high && zBufVal >= zBuffer[zIdx]) {
						*(w + 0) = p.Colors[paletteValue].B;
						*(w + 1) = p.Colors[paletteValue].G;
						*(w + 2) = p.Colors[paletteValue].R;
						zBuffer[zIdx] = zBufVal;
						heightBuffer[zIdx] = (short)(tile.Z * Drawable.TileHeight / 2);
					}
					w += 3;
					zIdx++;
					rIdx++;
				}
				w += stride - 3 * (cx + 2);
				zIdx += ds.Width - (cx + 2);
			}

			w += 12;
			zIdx += 4;
			for (; y < tmp.BlockHeight; y++) {
				cx -= 4;
				for (ushort c = 0; c < cx; c++) {
					byte paletteValue = img.TileData[rIdx];

					short zBufVal = (short)((tile.Rx + tile.Ry) * tmp.BlockHeight / 2 - (img.ZData != null ? img.ZData[rIdx] : 0));
					if (paletteValue != 0 && w_low <= w && w < w_high && zBufVal >= zBuffer[zIdx]) {
						*(w + 0) = p.Colors[paletteValue].B;
						*(w + 1) = p.Colors[paletteValue].G;
						*(w + 2) = p.Colors[paletteValue].R;
						zBuffer[zIdx] = zBufVal;
						heightBuffer[zIdx] = (short)(tile.Z * Drawable.TileHeight / 2);
					}
					w += 3;
					zIdx++;
					rIdx++;
				}
				w += stride - 3 * (cx - 2);
				zIdx += ds.Width - (cx - 2);
			}

			if (!img.HasExtraData) return; // we're done now

			offset.X += img.ExtraX - img.X;
			offset.Y += img.ExtraY - img.Y;
			w = w_low + stride * offset.Y + 3 * offset.X;
			zIdx = offset.X + offset.Y * ds.Width;
			rIdx = 0;

			// identify extra-data affected tiles for cutoff
			var extraScreenBounds = Rectangle.FromLTRB(
				Math.Max(0, offset.X), Math.Max(0, offset.Y),
				Math.Min(offset.X + img.ExtraWidth, ds.Width), Math.Min(offset.Y + img.ExtraHeight, ds.Height));

			for (int by = extraScreenBounds.Top; by < extraScreenBounds.Bottom; by += tmp.BlockHeight / 2) {
				for (int bx = extraScreenBounds.Left; bx < extraScreenBounds.Right; bx += tmp.BlockWidth / 2) {
					var gridTileNoZ = tile.Layer.GetTileScreen(new Point(bx, by), true, true);
					if (gridTileNoZ != null) {
						Logger.Trace("Tile at ({0},{1}) has extradata affecting ({2},{3})", tile.Dx, tile.Dy, gridTileNoZ.Dx,
							gridTileNoZ.Dy);
						tile.Layer.GridTouched[gridTileNoZ.Dx, gridTileNoZ.Dy / 2] |= TileLayer.TouchType.ByExtraData;
						tile.Layer.GridTouchedBy[gridTileNoZ.Dx, gridTileNoZ.Dy / 2] = tile;
					}
				}
			}

			// Extra graphics are just a square
			for (y = 0; y < img.ExtraHeight; y++) {
				for (x = 0; x < img.ExtraWidth; x++) {
					// Checking per line is required because v needs to be checked every time
					byte paletteValue = img.ExtraData[rIdx];
					short zBufVal = (short)((tile.Rx + tile.Ry) * tmp.BlockHeight / 2 + (img.ExtraZData != null ? img.ExtraZData[rIdx] : 0));

					if (paletteValue != 0 && w_low <= w && w < w_high && zBufVal >= zBuffer[zIdx]) {
						*w++ = p.Colors[paletteValue].B;
						*w++ = p.Colors[paletteValue].G;
						*w++ = p.Colors[paletteValue].R;
						zBuffer[zIdx] = zBufVal;
						heightBuffer[zIdx] = (short)(img.ExtraHeight - y + tile.Z * Drawable.TileHeight / 2);
					}
					else
						w += 3;
					zIdx++;
					rIdx++;
				}
				w += stride - img.ExtraWidth * 3;
				zIdx += ds.Width - img.ExtraWidth;
			}
		}
예제 #15
0
		public override void Draw(GameObject obj, DrawingSurface ds, bool shadow = true) {
			ShpRenderer.DrawAlpha(obj, Shp, Props, ds);
		}
예제 #16
0
		public override void Draw(GameObject obj, DrawingSurface ds, bool shadows = true) {
			if (InvisibleInGame)
				return;

			var drawList = new List<Drawable>();
			drawList.Add(_baseShp);

			if (obj is StructureObject && (obj as StructureObject).Health < 128) {
				drawList.AddRange(_animsDamaged);
				drawList.AddRange(_fires);
			}
			else
				drawList.AddRange(_anims);

			drawList.AddRange(SubDrawables); // bib
			/* order:
			ActiveAnims+Flat=yes
			BibShape
			ActiveAnims (+ZAdjust=0)
			Building
			ActiveAnims+ZAdjust=-32 */
			drawList = drawList.OrderBy(d => d.Flat ? -1 : 1).ThenBy(d => d.Props.SortIndex).ToList();

			foreach (var d in drawList)
				d.Draw(obj, ds, false);
			if (shadows)
				foreach (var d in drawList)
					d.DrawShadow(obj, ds);

			var strObj = obj as StructureObject;
			if (!strObj.Upgrade1.Equals("None", StringComparison.InvariantCultureIgnoreCase) && _powerupSlots.Count >= 1) {
				var powerup = OwnerCollection.GetDrawable(strObj.Upgrade1);
				DrawPowerup(obj, powerup, 0, ds);
			}

			if (!strObj.Upgrade2.Equals("None", StringComparison.InvariantCultureIgnoreCase) && _powerupSlots.Count >= 2) {
				var powerup = OwnerCollection.GetDrawable(strObj.Upgrade2);
				DrawPowerup(obj, powerup, 1, ds);
			}

			if (!strObj.Upgrade3.Equals("None", StringComparison.InvariantCultureIgnoreCase) && _powerupSlots.Count >= 3) {
				var powerup = OwnerCollection.GetDrawable(strObj.Upgrade3);
				DrawPowerup(obj, powerup, 2, ds);
			}
		}
예제 #17
0
		public virtual void DrawShadow(GameObject obj, DrawingSurface ds) { }
예제 #18
0
		internal void Draw(GameObject obj, DrawingSurface ds) {
			Logger.Trace("Drawing object {0} @ {1}", obj, obj.Tile);
			obj.Drawable.Draw(obj, ds);
		}
예제 #19
0
		public override void DrawShadow(GameObject obj, DrawingSurface ds) {
			if (InvisibleInGame || Shp == null) return;
			if (Props.HasShadow)
				ShpRenderer.DrawShadow(obj, Shp, Props, ds);
		}
예제 #20
0
        public unsafe void Draw(ShpFile shp, GameObject obj, Drawable dr, DrawProperties props, DrawingSurface ds, int transLucency = 0)
        {
            shp.Initialize();
            Palette p          = props.PaletteOverride ?? obj.Palette;
            int     frameIndex = props.FrameDecider(obj);

            if (obj.Drawable.IsActualWall)
            {
                frameIndex = ((StructureObject)obj).WallBuildingFrame;
            }
            frameIndex = DecideFrameIndex(frameIndex, shp.NumImages);
            if (frameIndex >= shp.Images.Count)
            {
                return;
            }

            var img     = shp.GetImage(frameIndex);
            var imgData = img.GetImageData();

            if (imgData == null || img.Width * img.Height != imgData.Length)
            {
                return;
            }

            Point offset = props.GetOffset(obj);

            offset.X += obj.Tile.Dx * _config.TileWidth / 2 - shp.Width / 2 + img.X;
            offset.Y += (obj.Tile.Dy - obj.Tile.Z) * _config.TileHeight / 2 - shp.Height / 2 + img.Y;
            Logger.Trace("Drawing SHP file {0} (Frame {1}) at ({2},{3})", shp.FileName, frameIndex, offset.X, offset.Y);

            int stride       = ds.BitmapData.Stride;
            var heightBuffer = ds.GetHeightBuffer();
            var zBuffer      = ds.GetZBuffer();

            var   w_low  = (byte *)ds.BitmapData.Scan0;
            byte *w_high = (byte *)ds.BitmapData.Scan0 + stride * ds.BitmapData.Height;
            byte *w      = (byte *)ds.BitmapData.Scan0 + offset.X * 3 + stride * offset.Y;

            // clip to 25-50-75-100
            transLucency = (transLucency / 25) * 25;
            float a = transLucency / 100f;
            float b = 1 - a;

            int   rIdx    = 0;                              // image pixel index
            int   zIdx    = offset.X + offset.Y * ds.Width; // z-buffer pixel index
            short hBufVal = (short)(obj.Tile.Z * _config.TileHeight / 2);
            short zOffset = (short)((obj.BottomTile.Rx + obj.BottomTile.Ry) * _config.TileHeight / 2 + props.ZAdjust);

            if (!dr.Flat)
            {
                hBufVal += shp.Height;
            }

            for (int y = 0; y < img.Height; y++)
            {
                if (offset.Y + y < 0)
                {
                    w    += stride;
                    rIdx += img.Width;
                    zIdx += ds.Width;
                    continue;                     // out of bounds
                }

                for (int x = 0; x < img.Width; x++)
                {
                    byte paletteValue = imgData[rIdx];

                    short zshapeOffset = obj is StructureObject ? (GetBuildingZ(x, y, shp, img, obj)) : (short)0;

                    if (paletteValue != 0)
                    {
                        short zBufVal = zOffset;
                        if (dr.Flat)
                        {
                            zBufVal += (short)(y - img.Height);
                        }
                        else if (dr.IsBuildingPart)
                        {
                            // nonflat building
                            zBufVal += zshapeOffset;
                        }
                        else
                        {
                            zBufVal += img.Height;
                        }

                        if (w_low <= w && w < w_high /*&& zBufVal >= zBuffer[zIdx]*/)
                        {
                            if (transLucency != 0)
                            {
                                *(w + 0) = (byte)(a * *(w + 0) + b * p.Colors[paletteValue].B);
                                *(w + 1) = (byte)(a * *(w + 1) + b * p.Colors[paletteValue].G);
                                *(w + 2) = (byte)(a * *(w + 2) + b * p.Colors[paletteValue].R);
                            }
                            else
                            {
                                *(w + 0) = p.Colors[paletteValue].B;
                                *(w + 1) = p.Colors[paletteValue].G;
                                *(w + 2) = p.Colors[paletteValue].R;

                                //var pal = Theater.Active.GetPalettes().UnitPalette.Colors;
                                //*(w + 0) = pal[zshapeOffset].R;
                                //*(w + 1) = pal[zshapeOffset].G;
                                //*(w + 2) = pal[zshapeOffset].B;
                            }
                            zBuffer[zIdx]      = zBufVal;
                            heightBuffer[zIdx] = hBufVal;
                        }
                    }
                    //else {
                    //	*(w + 0) = 0;
                    //	*(w + 1) = 0;
                    //	*(w + 2) = 255;
                    //}

                    // Up to the next pixel
                    rIdx++;
                    zIdx++;
                    w += 3;
                }
                w    += stride - 3 * img.Width;
                zIdx += ds.Width - img.Width;
            }
        }
예제 #21
0
파일: Map.cs 프로젝트: dkeetonx/ccmaps-net
		public void Draw() {
			_drawingSurface = new DrawingSurface(FullSize.Width * TileWidth, FullSize.Height * TileHeight, PixelFormat.Format24bppRgb);
			
#if SORT
			Logger.Info("Sorting objects map");
			var sorter = new ObjectSorter(_theater, _tiles);
			var orderedObjs = sorter.GetOrderedObjects().ToList();

			double lastReported = 0.0;
			Logger.Info("Drawing map... 0%");
			for (int i = 0; i < orderedObjs.Count; i++) {
				var obj = orderedObjs[i];
				_theater.Draw(obj, _drawingSurface);
				double pct = 100.0 * i / orderedObjs.Count;
				if (pct > lastReported + 5) {
					Logger.Info("Drawing map... {0}%", Math.Round(pct, 0));
					lastReported = pct;
				}
			}
#else
			double lastReported = 0.0;
			for (int y = 0; y < FullSize.Height; y++) {
				Logger.Trace("Drawing tiles row {0}", y);
				for (int x = FullSize.Width * 2 - 2; x >= 0; x -= 2)
					_theater.Draw(_tiles.GetTile(x, y), _drawingSurface);
				for (int x = FullSize.Width * 2 - 3; x >= 0; x -= 2)
					_theater.Draw(_tiles.GetTile(x, y), _drawingSurface);

				double pct = 50.0 * y / FullSize.Height;
				if (pct > lastReported + 5) {
					Logger.Info("Drawing tiles... {0}%", Math.Round(pct, 0));
					lastReported = pct;
				}
			}
			Logger.Info("Tiles drawn");

			for (int y = 0; y < FullSize.Height; y++) {
				Logger.Trace("Drawing objects row {0}", y);
				for (int x = FullSize.Width * 2 - 2; x >= 0; x -= 2)
					foreach (GameObject o in GetObjectsAt(x, y))
						_theater.Draw(o, _drawingSurface);

				for (int x = FullSize.Width * 2 - 3; x >= 0; x -= 2)
					foreach (GameObject o in GetObjectsAt(x, y))
						_theater.Draw(o, _drawingSurface);

				double pct = 50 + 50.0 * y / FullSize.Height;
				if (pct > lastReported + 5) {
					Logger.Info("Drawing objects... {0}%", Math.Round(pct, 0));
					lastReported = pct;
				}
			}
#endif


#if DEBUG && FALSE
			// test that my bounds make some kind of sense
			_drawingSurface.Unlock();
			using (Graphics gfx = Graphics.FromImage(_drawingSurface.Bitmap)) {
				foreach (var obj in _tiles.SelectMany(t=>t.AllObjects))
					if (obj.Drawable != null)
						obj.Drawable.DrawBoundingBox(obj, gfx);
			}
#endif

			Logger.Info("Map drawing completed");
		}
예제 #22
0
		public override void Draw(GameObject obj, DrawingSurface ds, bool shadows = true) {
			if (Vxl == null || Hva == Stream.Null) return;
			DrawingSurface vxl_ds = VoxelRenderer.Render(Vxl, Hva, obj, Props);
			if (vxl_ds != null)
				BlitVoxelToSurface(ds, vxl_ds, obj, Props);
		}
예제 #23
0
        public unsafe void DrawShadow(GameObject obj, ShpFile shp, DrawProperties props, DrawingSurface ds)
        {
            shp.Initialize();
            int frameIndex = props.FrameDecider(obj);

            if (obj.Drawable.IsActualWall)
            {
                frameIndex = ((StructureObject)obj).WallBuildingFrame;
            }
            frameIndex  = DecideFrameIndex(frameIndex, shp.NumImages);
            frameIndex += shp.Images.Count / 2;             // latter half are shadow Images
            if (frameIndex >= shp.Images.Count)
            {
                return;
            }

            var img     = shp.GetImage(frameIndex);
            var imgData = img.GetImageData();

            if (imgData == null || img.Width * img.Height != imgData.Length)
            {
                return;
            }

            Point offset = props.GetShadowOffset(obj);

            offset.X += obj.Tile.Dx * _config.TileWidth / 2 - shp.Width / 2 + img.X;
            offset.Y += (obj.Tile.Dy - obj.Tile.Z) * _config.TileHeight / 2 - shp.Height / 2 + img.Y;
            Logger.Trace("Drawing SHP shadow {0} (frame {1}) at ({2},{3})", shp.FileName, frameIndex, offset.X, offset.Y);

            int stride       = ds.BitmapData.Stride;
            var shadows      = ds.GetShadows();
            var zBuffer      = ds.GetZBuffer();
            var heightBuffer = ds.GetHeightBuffer();

            var   w_low  = (byte *)ds.BitmapData.Scan0;
            byte *w_high = (byte *)ds.BitmapData.Scan0 + stride * ds.BitmapData.Height;

            byte *w          = (byte *)ds.BitmapData.Scan0 + offset.X * 3 + stride * offset.Y;
            int   zIdx       = offset.X + offset.Y * ds.Width;
            int   rIdx       = 0;
            short zOffset    = (short)((obj.Tile.Rx + obj.Tile.Ry) * _config.TileHeight / 2 - shp.Height / 2 + img.Y);
            int   castHeight = obj.Tile.Z * _config.TileHeight / 2;

            if (obj.Drawable != null && !obj.Drawable.Flat)
            {
                castHeight += shp.Height;
                castHeight += obj.Drawable.TileElevation * _config.TileHeight / 2;
            }

            for (int y = 0; y < img.Height; y++)
            {
                if (offset.Y + y < 0)
                {
                    w    += stride;
                    rIdx += img.Width;
                    zIdx += ds.Width;
                    continue;                     // out of bounds
                }

                short zBufVal = zOffset;
                if (obj.Drawable.Flat)
                {
                    zBufVal += (short)y;
                }
                else
                {
                    zBufVal += img.Height;
                }

                for (int x = 0; x < img.Width; x++)
                {
                    if (0 <= offset.X + x && offset.X + x < ds.Width && 0 <= y + offset.Y && y + offset.Y < ds.Height &&
                        imgData[rIdx] != 0 && !shadows[zIdx] &&
                        // zBufVal >= zBuffer[zIdx] &&
                        castHeight >= heightBuffer[zIdx])
                    {
                        *(w + 0)     /= 2;
                        *(w + 1)     /= 2;
                        *(w + 2)     /= 2;
                        shadows[zIdx] = true;
                    }
                    // Up to the next pixel
                    rIdx++;
                    zIdx++;
                    w += 3;
                }
                w    += stride - 3 * img.Width;                 // ... and if we're no more on the same row,
                zIdx += ds.Width - img.Width;
                // adjust the writing pointer accordingy
            }
        }
예제 #24
0
		unsafe public static void Draw(ShpFile shp, GameObject obj, Drawable dr, DrawProperties props, DrawingSurface ds, int transLucency = 0) {
			shp.Initialize();

			int frameIndex = props.FrameDecider(obj);
			Palette p = props.PaletteOverride ?? obj.Palette;

			frameIndex = DecideFrameIndex(frameIndex, shp.NumImages);
			if (frameIndex >= shp.Images.Count)
				return;

			var img = shp.GetImage(frameIndex);
			var imgData = img.GetImageData();
			if (imgData == null || img.Width * img.Height != imgData.Length)
				return;

			Point offset = props.GetOffset(obj);
			offset.X += obj.Tile.Dx * Drawable.TileWidth / 2 - shp.Width / 2 + img.X;
			offset.Y += (obj.Tile.Dy - obj.Tile.Z) * Drawable.TileHeight / 2 - shp.Height / 2 + img.Y;
			Logger.Trace("Drawing SHP file {0} (Frame {1}) at ({2},{3})", shp.FileName, frameIndex, offset.X, offset.Y);

			int stride = ds.BitmapData.Stride;
			var heightBuffer = ds.GetHeightBuffer();
			var zBuffer = ds.GetZBuffer();

			var w_low = (byte*)ds.BitmapData.Scan0;
			byte* w_high = (byte*)ds.BitmapData.Scan0 + stride * ds.BitmapData.Height;
			byte* w = (byte*)ds.BitmapData.Scan0 + offset.X * 3 + stride * offset.Y;

			// clip to 25-50-75-100
			transLucency = (transLucency / 25) * 25;
			float a = transLucency / 100f;
			float b = 1 - a;

			int rIdx = 0; // image pixel index
			int zIdx = offset.X + offset.Y * ds.Width; // z-buffer pixel index
			short hBufVal = (short)(obj.Tile.Z * Drawable.TileHeight / 2);
			short zOffset = (short)((obj.BottomTile.Rx + obj.BottomTile.Ry) * Drawable.TileHeight / 2);

			if (!dr.Flat)
				hBufVal += shp.Height;

			for (int y = 0; y < img.Height; y++) {
				if (offset.Y + y < 0) {
					w += stride;
					rIdx += img.Width;
					zIdx += ds.Width;
					continue; // out of bounds
				}

				for (int x = 0; x < img.Width; x++) {
					byte paletteValue = imgData[rIdx];

					short zshapeOffset = obj is StructureObject ? (GetBuildingZ(x, y, shp, img, obj)) : (short)0;
					
					if (paletteValue != 0) {
						short zBufVal = zOffset;
						if (dr.Flat)
							zBufVal += (short)(y - img.Height);
						else if (dr.IsBuildingPart) {
							// nonflat building
							zBufVal += zshapeOffset;
						}
						else
							zBufVal += img.Height;

						if (w_low <= w && w < w_high  /*&& zBufVal >= zBuffer[zIdx]*/) {
							if (transLucency != 0) {
								*(w + 0) = (byte)(a * *(w + 0) + b * p.Colors[paletteValue].B);
								*(w + 1) = (byte)(a * *(w + 1) + b * p.Colors[paletteValue].G);
								*(w + 2) = (byte)(a * *(w + 2) + b * p.Colors[paletteValue].R);
							}
							else {
								*(w + 0) = p.Colors[paletteValue].B;
								*(w + 1) = p.Colors[paletteValue].G;
								*(w + 2) = p.Colors[paletteValue].R;

								//var pal = Theater.Active.GetPalettes().UnitPalette.Colors;
								//*(w + 0) = pal[zshapeOffset].R;
								//*(w + 1) = pal[zshapeOffset].G;
								//*(w + 2) = pal[zshapeOffset].B;
							}
							zBuffer[zIdx] = zBufVal;
							heightBuffer[zIdx] = hBufVal;
						}
					}
					//else {
					//	*(w + 0) = 0;
					//	*(w + 1) = 0;
					//	*(w + 2) = 255;
					//}

					// Up to the next pixel
					rIdx++;
					zIdx++;
					w += 3;
				}
				w += stride - 3 * img.Width;
				zIdx += ds.Width - img.Width;
			}
		}
예제 #25
0
		unsafe public static void DrawAlpha(GameObject obj, ShpFile shp, DrawProperties props, DrawingSurface ds) {
			shp.Initialize();

			// Change originally implemented by Starkku: Ares supports multiframe AlphaImages, based on frame count 
			// the direction the unit it facing.
			int frameIndex = props.FrameDecider(obj);

			var img = shp.GetImage(frameIndex);
			var imgData = img.GetImageData();
			var c_px = (uint)(img.Width * img.Height);
			if (c_px <= 0 || img.Width < 0 || img.Height < 0 || frameIndex > shp.NumImages)
				return;

			Point offset = props.GetOffset(obj);
			offset.X += obj.Tile.Dx * Drawable.TileWidth / 2;
			offset.Y += (obj.Tile.Dy - obj.Tile.Z) * Drawable.TileHeight / 2;
			Logger.Trace("Drawing AlphaImage SHP file {0} (frame {1}) at ({2},{3})", shp.FileName, frameIndex, offset.X, offset.Y);

			int stride = ds.BitmapData.Stride;
			var w_low = (byte*)ds.BitmapData.Scan0;
			byte* w_high = (byte*)ds.BitmapData.Scan0 + stride * ds.BitmapData.Height;

			int dx = offset.X + Drawable.TileWidth / 2 - shp.Width / 2 + img.X,
				dy = offset.Y - shp.Height / 2 + img.Y;
			byte* w = (byte*)ds.BitmapData.Scan0 + dx * 3 + stride * dy;
			short zOffset = (short)((obj.Tile.Rx + obj.Tile.Ry) * Drawable.TileHeight / 2 - shp.Height / 2 + img.Y);
			int rIdx = 0;

			for (int y = 0; y < img.Height; y++) {
				for (int x = 0; x < img.Width; x++) {
					if (imgData[rIdx] != 0 && w_low <= w && w < w_high) {
						float mult = imgData[rIdx] / 127.0f;
						*(w + 0) = limit(mult, *(w + 0));
						*(w + 1) = limit(mult, *(w + 1));
						*(w + 2) = limit(mult, *(w + 2));
					}
					// Up to the next pixel
					rIdx++;
					w += 3;
				}
				w += stride - 3 * img.Width;	// ... and if we're no more on the same row,
				// adjust the writing pointer accordingy
			}
		}
예제 #26
0
		unsafe public static void DrawShadow(GameObject obj, ShpFile shp, DrawProperties props, DrawingSurface ds) {
			int frameIndex = props.FrameDecider(obj);
			frameIndex = DecideFrameIndex(frameIndex, shp.NumImages);
			frameIndex += shp.Images.Count / 2; // latter half are shadow Images
			if (frameIndex >= shp.Images.Count)
				return;

			var img = shp.GetImage(frameIndex);
			var imgData = img.GetImageData();
			if (imgData == null || img.Width * img.Height != imgData.Length)
				return;

			Point offset = props.GetShadowOffset(obj);
			offset.X += obj.Tile.Dx * Drawable.TileWidth / 2 - shp.Width / 2 + img.X;
			offset.Y += (obj.Tile.Dy - obj.Tile.Z) * Drawable.TileHeight / 2 - shp.Height / 2 + img.Y;
			Logger.Trace("Drawing SHP shadow {0} (frame {1}) at ({2},{3})", shp.FileName, frameIndex, offset.X, offset.Y);

			int stride = ds.BitmapData.Stride;
			var shadows = ds.GetShadows();
			var zBuffer = ds.GetZBuffer();
			var heightBuffer = ds.GetHeightBuffer();

			var w_low = (byte*)ds.BitmapData.Scan0;
			byte* w_high = (byte*)ds.BitmapData.Scan0 + stride * ds.BitmapData.Height;

			byte* w = (byte*)ds.BitmapData.Scan0 + offset.X * 3 + stride * offset.Y;
			int zIdx = offset.X + offset.Y * ds.Width;
			int rIdx = 0;
			short zOffset = (short)((obj.Tile.Rx + obj.Tile.Ry) * Drawable.TileHeight / 2 - shp.Height / 2 + img.Y);
			int castHeight = obj.Tile.Z * Drawable.TileHeight / 2;
			if (obj.Drawable != null && !obj.Drawable.Flat) {
				castHeight += shp.Height;
				castHeight += obj.Drawable.TileElevation * Drawable.TileHeight / 2;
			}

			for (int y = 0; y < img.Height; y++) {
				if (offset.Y + y < 0) {
					w += stride;
					rIdx += img.Width;
					zIdx += ds.Width;
					continue; // out of bounds
				}

				short zBufVal = zOffset;
				if (obj.Drawable.Flat)
					zBufVal += (short)y;
				else
					zBufVal += img.Height;

				for (int x = 0; x < img.Width; x++) {
					if (w_low <= w && w < w_high && imgData[rIdx] != 0 && !shadows[zIdx] 
						//&& zBufVal >= zBuffer[zIdx] 
						&& castHeight >= heightBuffer[zIdx]
						) {
						*(w + 0) /= 2;
						*(w + 1) /= 2;
						*(w + 2) /= 2;
						shadows[zIdx] = true;
					}
					// Up to the next pixel
					rIdx++;
					zIdx++;
					w += 3;
				}
				w += stride - 3 * img.Width;	// ... and if we're no more on the same row,
				zIdx += ds.Width - img.Width;
				// adjust the writing pointer accordingy
			}
		}
예제 #27
0
        public unsafe void DrawAlpha(GameObject obj, ShpFile shp, DrawProperties props, DrawingSurface ds)
        {
            shp.Initialize();

            // Ares supports multiframe AlphaImages, based on frame count and the direction the unit it facing.
            int frameIndex = props.FrameDecider(obj);

            var img     = shp.GetImage(frameIndex);
            var imgData = img.GetImageData();
            var c_px    = (uint)(img.Width * img.Height);

            if (c_px <= 0 || img.Width < 0 || img.Height < 0 || frameIndex > shp.NumImages)
            {
                return;
            }

            Point offset = props.GetOffset(obj);

            offset.X += obj.Tile.Dx * _config.TileWidth / 2;
            offset.Y += (obj.Tile.Dy - obj.Tile.Z) * _config.TileHeight / 2;
            Logger.Trace("Drawing AlphaImage SHP file {0} (frame {1}) at ({2},{3})", shp.FileName, frameIndex, offset.X, offset.Y);

            int   stride = ds.BitmapData.Stride;
            var   w_low  = (byte *)ds.BitmapData.Scan0;
            byte *w_high = (byte *)ds.BitmapData.Scan0 + stride * ds.BitmapData.Height;

            int dx        = offset.X + _config.TileWidth / 2 - shp.Width / 2 + img.X,
                dy        = offset.Y - shp.Height / 2 + img.Y;
            byte *w       = (byte *)ds.BitmapData.Scan0 + dx * 3 + stride * dy;
            short zOffset = (short)((obj.Tile.Rx + obj.Tile.Ry) * _config.TileHeight / 2 - shp.Height / 2 + img.Y + props.ZAdjust);
            int   rIdx    = 0;

            for (int y = 0; y < img.Height; y++)
            {
                for (int x = 0; x < img.Width; x++)
                {
                    if (imgData[rIdx] != 0 && w_low <= w && w < w_high)
                    {
                        float mult = imgData[rIdx] / 127.0f;
                        *(w + 0) = limit(mult, *(w + 0));
                        *(w + 1) = limit(mult, *(w + 1));
                        *(w + 2) = limit(mult, *(w + 2));
                    }
                    // Up to the next pixel
                    rIdx++;
                    w += 3;
                }
                w += stride - 3 * img.Width;                    // ... and if we're no more on the same row,
                // adjust the writing pointer accordingly
            }
        }
예제 #28
0
		public override void Draw(GameObject obj, DrawingSurface ds, bool shadow = true) {
			if (InvisibleInGame || Shp == null) return;
			ShpRenderer.Draw(Shp, obj, this, Props, ds);
			if (Props.HasShadow && shadow)
				ShpRenderer.DrawShadow(obj, Shp, Props, ds);
		}