// switching colors private unsafe void BackgroundRadioButton_Checked(object sender, RoutedEventArgs e) { fixed (Color* colorptr = &BackgroundColor) { selectedcolor = colorptr; } UpdateControls(); }
/// <summary> /// Applies the specified image. /// </summary> /// <param name="image">The image.</param> /// <param name="targetLocation">The target location.</param> /// <returns>The image</returns> public unsafe Image Apply(Image image, Rectangle targetLocation = default(Rectangle)) { targetLocation = targetLocation == default(Rectangle) ? new Rectangle(0, 0, image.Width, image.Height) : targetLocation.Clamp(image); var tempPixels = new Color[image.Pixels.Length]; Array.Copy(image.Pixels, tempPixels, image.Pixels.Length); Parallel.For(targetLocation.Bottom, targetLocation.Top, y => { fixed(Color * Pointer = &image.Pixels[(y * image.Width) + targetLocation.Left]) { Color *OutputPointer = Pointer; for (int x = targetLocation.Left; x < targetLocation.Right; ++x) { var XValue = new Vector4(0, 0, 0, 0); var YValue = new Vector4(0, 0, 0, 0); float WeightX = 0; float WeightY = 0; int XCurrent = -Width >> 1; int YCurrent = -Height >> 1; int Start = 0; fixed(float *XMatrixPointer = &XMatrix[0]) { fixed(float *YMatrixPointer = &YMatrix[0]) { float *XMatrixValue = XMatrixPointer; float *YMatrixValue = YMatrixPointer; for (int MatrixIndex = 0; MatrixIndex < XMatrix.Length; ++MatrixIndex) { if (MatrixIndex % Width == 0 && MatrixIndex != 0) { ++YCurrent; XCurrent = 0; } if (XCurrent + x < image.Width && XCurrent + x >= 0 && YCurrent + y < image.Height && YCurrent + y >= 0) { if (*XMatrixValue != 0 || *YMatrixValue != 0) { Start = ((YCurrent + y) * image.Width) + (x + XCurrent); var TempPixel = tempPixels[Start]; XValue = XValue + new Vector4((*XMatrixValue * TempPixel.Red), (*XMatrixValue * TempPixel.Green), (*XMatrixValue * TempPixel.Blue), (*XMatrixValue * TempPixel.Alpha)); YValue = YValue + new Vector4((*YMatrixValue * TempPixel.Red), (*YMatrixValue * TempPixel.Green), (*YMatrixValue * TempPixel.Blue), (*YMatrixValue * TempPixel.Alpha)); WeightX += *XMatrixValue; WeightY += *YMatrixValue; } ++XMatrixValue; ++YMatrixValue; } ++XCurrent; } } } if (WeightX == 0) { WeightX = 1; } if (WeightY == 0) { WeightY = 1; } if (WeightX > 0 && WeightY > 0) { if (Absolute) { YValue = Vector4.Abs(YValue); XValue = Vector4.Abs(XValue); } XValue /= WeightX; YValue /= WeightY; var TempResult = Vector4.SquareRoot((XValue * XValue) + (YValue * YValue)); TempResult = Vector4.Clamp(TempResult, Vector4.Zero, new Vector4(255, 255, 255, 255)) / 255f; *OutputPointer = TempResult; ++OutputPointer; } else { ++OutputPointer; } } } }); return(image); }
/// <summary> /// Applies the filter to the specified image. /// </summary> /// <param name="image">The image.</param> /// <param name="targetLocation">The target location.</param> /// <returns>The image</returns> public unsafe Image Apply(Image image, Rectangle targetLocation = default(Rectangle)) { targetLocation = targetLocation == default(Rectangle) ? new Rectangle(0, 0, image.Width, image.Height) : targetLocation.Clamp(image); var Result = new Color[image.Pixels.Length]; Array.Copy(image.Pixels, Result, Result.Length); Parallel.For(targetLocation.Bottom, targetLocation.Top, y => { fixed(Color * Pointer = &image.Pixels[(y * image.Width) + targetLocation.Left]) { Color *SourcePointer = Pointer; for (int x = targetLocation.Left; x < targetLocation.Right; ++x) { uint[] RValues = { 0, 0, 0, 0 }; uint[] GValues = { 0, 0, 0, 0 }; uint[] BValues = { 0, 0, 0, 0 }; uint[] NumPixels = { 0, 0, 0, 0 }; uint[] MaxRValue = { 0, 0, 0, 0 }; uint[] MaxGValue = { 0, 0, 0, 0 }; uint[] MaxBValue = { 0, 0, 0, 0 }; uint[] MinRValue = { 255, 255, 255, 255 }; uint[] MinGValue = { 255, 255, 255, 255 }; uint[] MinBValue = { 255, 255, 255, 255 }; for (int i = 0; i < 4; ++i) { for (int x2 = ApetureMinX[i]; x2 < ApetureMaxX[i]; ++x2) { int TempX = x + x2; if (TempX >= 0 && TempX < image.Width) { for (int y2 = ApetureMinY[i]; y2 < ApetureMaxY[i]; ++y2) { int TempY = y + y2; if (TempY >= 0 && TempY < image.Height) { RValues[i] += image.Pixels[(TempY * image.Width) + TempX].Red; GValues[i] += image.Pixels[(TempY * image.Width) + TempX].Green; BValues[i] += image.Pixels[(TempY * image.Width) + TempX].Blue; if (image.Pixels[(TempY * image.Width) + TempX].Red > MaxRValue[i]) { MaxRValue[i] = image.Pixels[(TempY * image.Width) + TempX].Red; } else if (image.Pixels[(TempY * image.Width) + TempX].Red < MinRValue[i]) { MinRValue[i] = image.Pixels[(TempY * image.Width) + TempX].Red; } if (image.Pixels[(TempY * image.Width) + TempX].Green > MaxGValue[i]) { MaxGValue[i] = image.Pixels[(TempY * image.Width) + TempX].Green; } else if (image.Pixels[(TempY * image.Width) + TempX].Green < MinGValue[i]) { MinGValue[i] = image.Pixels[(TempY * image.Width) + TempX].Green; } if (image.Pixels[(TempY * image.Width) + TempX].Blue > MaxBValue[i]) { MaxBValue[i] = image.Pixels[(TempY * image.Width) + TempX].Blue; } else if (image.Pixels[(TempY * image.Width) + TempX].Blue < MinBValue[i]) { MinBValue[i] = image.Pixels[(TempY * image.Width) + TempX].Blue; } ++NumPixels[i]; } } } } } int j = 0; uint MinDifference = uint.MaxValue; for (int i = 0; i < 4; ++i) { uint CurrentDifference = (MaxRValue[i] - MinRValue[i]) + (MaxGValue[i] - MinGValue[i]) + (MaxBValue[i] - MinBValue[i]); if (CurrentDifference < MinDifference && NumPixels[i] > 0) { j = i; MinDifference = CurrentDifference; } } RValues[j] = RValues[j] / NumPixels[j]; GValues[j] = GValues[j] / NumPixels[j]; BValues[j] = BValues[j] / NumPixels[j]; Result[(y * image.Width) + x].Red = (byte)RValues[j]; Result[(y * image.Width) + x].Green = (byte)GValues[j]; Result[(y * image.Width) + x].Blue = (byte)BValues[j]; } } }); return(image.ReCreate(image.Width, image.Height, Result)); }
unsafe void WarpingAlgorithm.WarpImage(MarkerSet markerSet, Morphing.ImageData inputImage, Morphing.ImageData outputImage, bool startImage) { System.Diagnostics.Debug.Assert(markerSet != null && inputImage != null && outputImage != null); PointMarkerSet pointMarkerSet = markerSet as PointMarkerSet; System.Diagnostics.Debug.Assert(pointMarkerSet != null); // minor precomputation - movevector & interppos (for more mem consistency) WarpMarker[] markers; if (startImage) { markers = pointMarkerSet.Points.Select(x => new WarpMarker { CurrentPos = x.InterpolatedMarker, MoveVec = x.StartMarker - x.InterpolatedMarker }).ToArray(); } else { markers = pointMarkerSet.Points.Select(x => new WarpMarker { CurrentPos = x.InterpolatedMarker, MoveVec = x.EndMarker - x.InterpolatedMarker }).ToArray(); } double xStep = 1.0 / outputImage.Width; if (markers.Length == 0) { return; } Parallel.For(0, outputImage.Height, yi => { Color *outputDataPixel = outputImage.Data + yi * outputImage.Width; Color *lastOutputDataPixel = outputDataPixel + outputImage.Width; double y = (double)yi / outputImage.Height; for (double x = 0; outputDataPixel != lastOutputDataPixel; x += xStep, ++outputDataPixel) { Vector position = new Vector(x, y); Vector displacement = new Vector(0, 0); // fixed ptr won't work inside loop! // for(WarpMarker* pMarker = pMarkerFirst; pMarker != pMarkerEnd; ++pMarker) double weightSum = 0.0f; foreach (var marker in markers) { double distSq = (position - marker.CurrentPos).LengthSquared; double weight = Math.Exp(-distSq / POINT_WEIGHT);//1.0f / (1.0f + distSq / POINT_WEIGHT); // inverse quadratic! weightSum += weight; displacement += marker.MoveVec * weight; } displacement /= weightSum; position += displacement; position = position.ClampToImageArea(); *outputDataPixel = inputImage.Sample(position.X, position.Y); } }); }
public void Quantize(IColorQuantizer quantizer, int colorCount) { if (Disposed) { return; } int myWidth = Width; int myHeight = Height; Color *colors = GetColors(); quantizer.Prepare(this); bool usesAlpha = false; // weird stuff to make the quantizer work with alpha Color lastColor = new Color(255, 255, 255, 0); bool firstColorFound = false; for (int y = 0; y < myHeight; y++) { for (int x = 0; x < myWidth; x++) { int idx = x + y * myWidth; var col = *(colors + idx); if (col.A > 128) { col.A = 255; (*(colors + x + y * myWidth)) = col; if (!firstColorFound && usesAlpha) { for (int i = 0; i < idx; i++) { quantizer.AddColor(col, i % myWidth, Mathf.FloorToInt(i / myWidth)); } } firstColorFound = true; lastColor = col; quantizer.AddColor(col, x, y); } else { col = new Color(255, 255, 255, 0); (*(colors + x + y * myWidth)) = col; usesAlpha = true; if (firstColorFound) { quantizer.AddColor(lastColor, x, y); } } } } var palette = quantizer.GetPalette(colorCount); for (int y = 0; y < myHeight; y++) { for (int x = 0; x < myWidth; x++) { if ((*(colors + x + y * myWidth)).A == 255) { int index = quantizer.GetPaletteIndex(*(colors + x + y * myWidth), x, y); //Debug.Log(index); *(colors + x + y * myWidth) = palette[index]; } } } quantizer.Finish(); }
public unsafe void CreateTexture(int index, out Texture2D diffuseTexture, out Texture2D normalTexture) { diffuseTexture = null; normalTexture = null; if (!_fileIndex.FilesExist) { return; } int length, extra; bool patched; Stream stream = _fileIndex.Seek(index, out length, out extra, out patched); if (stream == null) { return; } int size = extra == 0 ? 64 : 128; int pixelCount = size * size; byte[] buffer = new byte[pixelCount * 2]; ushort[] pixels = new ushort[pixelCount]; Color[] colors = new Color[pixelCount]; stream.Read(buffer, 0, buffer.Length); Buffer.BlockCopy(buffer, 0, pixels, 0, pixelCount * 2); fixed(ushort *pPtr = pixels) fixed(Color * cPtr = colors) { ushort *pixelPtr = pPtr; Color * colorPtr = cPtr; int count = pixels.Length; for (int i = 0; i < count; i++) { colorPtr->R = (byte)((*pixelPtr & 0x1F) & multiplier); colorPtr->G = (byte)(((*pixelPtr >> 5) & 0x1F) & multiplier); colorPtr->B = (byte)(((*pixelPtr >> 10) & 0x1F) & multiplier); colorPtr->A = 255; colorPtr++; } } diffuseTexture = new Texture2D(GraphicsDeviceManager.Current.GraphicsDevice, size, size, false, SurfaceFormat.Color); diffuseTexture.SetData(colors); float[] heights = GenerateHeightFields(pixels, size); Vector3[] normals = GenerateNormalFields(heights, size, false); Color[] normalColors = new Color[heights.Length]; fixed(Vector3 *normal = normals) fixed(Color * color = normalColors) { Vector3 *nPtr = normal; Color * cPtr = color; int count = normalColors.Length; for (int i = 0; i < count; i++) { cPtr->R = (byte)(nPtr->X * 255); cPtr->G = (byte)(nPtr->Y * 255); cPtr->B = (byte)(nPtr->Z * 255); nPtr++; cPtr++; } } normalTexture = new Texture2D(GraphicsDeviceManager.Current.GraphicsDevice, size, size, false, SurfaceFormat.Color); normalTexture.SetData(normalColors); }
public unsafe static extern void RenderPixels(int width, int height, Color *pixels);
/// <summary> /// Applies the filter to the specified image. /// </summary> /// <param name="image">The image.</param> /// <param name="targetLocation">The target location.</param> /// <returns>The image</returns> public unsafe Image Apply(Image image, Rectangle targetLocation = default(Rectangle)) { targetLocation = targetLocation == default(Rectangle) ? new Rectangle(0, 0, image.Width, image.Height) : targetLocation.Clamp(image); var TempValues = new Color[image.Pixels.Length]; Array.Copy(image.Pixels, TempValues, TempValues.Length); int ApetureMin = -ApetureRadius; int ApetureMax = ApetureRadius; Parallel.For(targetLocation.Bottom, targetLocation.Top, y => { fixed(Color * TargetPointer = &image.Pixels[(y * image.Width) + targetLocation.Left]) { Color *TargetPointer2 = TargetPointer; for (int x = targetLocation.Left; x < targetLocation.Right; ++x) { byte RValue = byte.MaxValue; byte GValue = byte.MaxValue; byte BValue = byte.MaxValue; for (int y2 = ApetureMin; y2 < ApetureMax; ++y2) { int TempY = y + y2; int TempX = x + ApetureMin; if (TempY >= 0 && TempY < image.Height) { int Length = ApetureRadius * 2; if (TempX < 0) { Length += TempX; TempX = 0; } var Start = ((TempY * image.Width) + TempX); fixed(Color * ImagePointer = &TempValues[Start]) { Color *ImagePointer2 = ImagePointer; for (int x2 = 0; x2 < Length; ++x2) { if (TempX >= image.Width) { break; } var TempR = (*ImagePointer2).Red; var TempG = (*ImagePointer2).Green; var TempB = (*ImagePointer2).Blue; ++ImagePointer2; RValue = RValue < TempR ? RValue : TempR; GValue = GValue < TempG ? GValue : TempG; BValue = BValue < TempB ? BValue : TempB; ++TempX; } } } } (*TargetPointer2).Red = RValue; (*TargetPointer2).Green = GValue; (*TargetPointer2).Blue = BValue; ++TargetPointer2; } } }); return(image); }
unsafe void ThreadedCopy(uint *Frame, Color *Pixels, int Frame2D_width, int Frame2D_height, int FrameArray_Length, int PixelsArray_Length) { int PixelsDrawn = 0; int PixelsQueued = 0; bool Aborted = false; System.Action <int, int> CopyPixels = (PixelIndex, PixelCount) => { try { var rgba = new Color(); for (int p = PixelIndex; p < PixelIndex + PixelCount; p++) { var x = p % Frame2D_width; var y = p / Frame2D_width; if (Flip) { y = Frame2D_height - 1 - y; } var FrameIndex = x + (y * Frame2D_width); var rgba32 = Frame [FrameIndex]; var a = (rgba32 >> 24) & 0xff; var r = (rgba32 >> 16) & 0xff; var g = (rgba32 >> 8) & 0xff; var b = (rgba32 >> 0) & 0xff; if (ForceOpaque) { a = 255; } rgba.r = r / 255.0f; rgba.g = g / 255.0f; rgba.b = b / 255.0f; rgba.a = a / 255.0f; Pixels [p] = rgba; } } catch { Aborted = true; } Interlocked.Add(ref PixelsDrawn, PixelCount); }; var TotalPixels = Mathf.Min(PixelCountClip, Mathf.Min(FrameArray_Length, PixelsArray_Length)); int ThreadCount = TotalPixels / WritePixelsPerThread; for (int t = 0; t < ThreadCount + 1; t++) { int FirstPixel = WritePixelsPerThread * t; int PixelsToDraw = WritePixelsPerThread; if (FirstPixel + PixelsToDraw > TotalPixels) { PixelsToDraw = TotalPixels - FirstPixel; } PixelsQueued += PixelsToDraw; if (PixelsToDraw > 0) { ThreadPool.QueueUserWorkItem((x) => { CopyPixels(FirstPixel, PixelsToDraw); }); } } while (PixelsDrawn < PixelsQueued && !Aborted) { //Debug.Log ("Waiting for " + (PixelsQueued - PixelsDrawn) + " pixels to draw"); Thread.Sleep(1); } }
public override unsafe void Draw() { List <MyPhysics.HitInfo> .Enumerator enumerator2; base.Draw(); foreach (MyCubeBlock block in this.m_grid.BlocksForDraw) { if (MyRenderProxy.VisibleObjectsRead.Contains(block.Render.RenderObjectIDs[0])) { block.Render.Draw(); } } if ((MyCubeGrid.ShowCenterOfMass && (!this.IsStatic && (base.Container.Entity.Physics != null))) && base.Container.Entity.Physics.HasRigidBody) { MatrixD worldMatrix = base.Container.Entity.Physics.GetWorldMatrix(); Vector3D centerOfMassWorld = base.Container.Entity.Physics.CenterOfMassWorld; Vector3D position = MySector.MainCamera.Position; float num = Vector3.Distance((Vector3)position, (Vector3)centerOfMassWorld); bool flag = false; if (num < 30f) { flag = true; } else if (num < 200f) { flag = true; MyPhysics.CastRay(position, centerOfMassWorld, m_tmpHitList, 0x10); using (enumerator2 = m_tmpHitList.GetEnumerator()) { while (enumerator2.MoveNext()) { if (!ReferenceEquals(enumerator2.Current.HkHitInfo.GetHitEntity(), this)) { flag = false; break; } } } m_tmpHitList.Clear(); } if (flag) { float num2 = MathHelper.Lerp((float)1f, (float)9f, (float)(num / 200f)); MyStringId id = ID_WEAPON_LASER_IGNORE_DEPTH; Vector4 color = Color.Yellow.ToVector4(); float thickness = 0.02f * num2; MySimpleObjectDraw.DrawLine(centerOfMassWorld - ((worldMatrix.Up * 0.5) * num2), centerOfMassWorld + ((worldMatrix.Up * 0.5) * num2), new MyStringId?(id), ref color, thickness, MyBillboard.BlendTypeEnum.AdditiveTop); MySimpleObjectDraw.DrawLine(centerOfMassWorld - ((worldMatrix.Forward * 0.5) * num2), centerOfMassWorld + ((worldMatrix.Forward * 0.5) * num2), new MyStringId?(id), ref color, thickness, MyBillboard.BlendTypeEnum.AdditiveTop); MySimpleObjectDraw.DrawLine(centerOfMassWorld - ((worldMatrix.Right * 0.5) * num2), centerOfMassWorld + ((worldMatrix.Right * 0.5) * num2), new MyStringId?(id), ref color, thickness, MyBillboard.BlendTypeEnum.AdditiveTop); MyTransparentGeometry.AddBillboardOriented(ID_RED_DOT_IGNORE_DEPTH, Color.White.ToVector4(), centerOfMassWorld, MySector.MainCamera.LeftVector, MySector.MainCamera.UpVector, 0.1f * num2, MyBillboard.BlendTypeEnum.AdditiveTop, -1, 0f); } } if (MyCubeGrid.ShowGridPivot) { MatrixD worldMatrix = base.Container.Entity.WorldMatrix; Vector3D translation = worldMatrix.Translation; Vector3D position = MySector.MainCamera.Position; float num4 = Vector3.Distance((Vector3)position, (Vector3)translation); bool flag2 = false; if (num4 < 30f) { flag2 = true; } else if (num4 < 200f) { flag2 = true; MyPhysics.CastRay(position, translation, m_tmpHitList, 0x10); using (enumerator2 = m_tmpHitList.GetEnumerator()) { while (enumerator2.MoveNext()) { if (!ReferenceEquals(enumerator2.Current.HkHitInfo.GetHitEntity(), this)) { flag2 = false; break; } } } m_tmpHitList.Clear(); } if (flag2) { float num5 = MathHelper.Lerp((float)1f, (float)9f, (float)(num4 / 200f)); MyStringId id2 = ID_WEAPON_LASER_IGNORE_DEPTH; float thickness = 0.02f * num5; Vector4 color = Color.Green.ToVector4(); MySimpleObjectDraw.DrawLine(translation, translation + ((worldMatrix.Up * 0.5) * num5), new MyStringId?(id2), ref color, thickness, MyBillboard.BlendTypeEnum.Standard); color = Color.Blue.ToVector4(); MySimpleObjectDraw.DrawLine(translation, translation + ((worldMatrix.Forward * 0.5) * num5), new MyStringId?(id2), ref color, thickness, MyBillboard.BlendTypeEnum.Standard); color = Color.Red.ToVector4(); MySimpleObjectDraw.DrawLine(translation, translation + ((worldMatrix.Right * 0.5) * num5), new MyStringId?(id2), ref color, thickness, MyBillboard.BlendTypeEnum.Standard); MyTransparentGeometry.AddBillboardOriented(ID_RED_DOT_IGNORE_DEPTH, Color.White.ToVector4(), translation, MySector.MainCamera.LeftVector, MySector.MainCamera.UpVector, 0.1f * num5, MyBillboard.BlendTypeEnum.Standard, -1, 0f); MyRenderProxy.DebugDrawAxis(worldMatrix, 0.5f, false, false, false); } } if (!MyCubeGrid.ShowStructuralIntegrity) { if ((this.m_grid.StructuralIntegrity != null) && this.m_grid.StructuralIntegrity.EnabledOnlyForDraw) { this.m_grid.CloseStructuralIntegrity(); } } else if (this.m_grid.StructuralIntegrity != null) { this.m_grid.StructuralIntegrity.Draw(); } else if (MyFakes.ENABLE_STRUCTURAL_INTEGRITY) { this.m_grid.CreateStructuralIntegrity(); if (this.m_grid.StructuralIntegrity != null) { this.m_grid.StructuralIntegrity.EnabledOnlyForDraw = true; } } if (MyFakes.ENABLE_ATMOSPHERIC_ENTRYEFFECT) { this.DrawAtmosphericEntryEffect(); } if (this.m_grid.MarkedAsTrash) { BoundingBoxD localAABB = this.m_grid.PositionComp.LocalAABB; Vector3D * vectordPtr1 = (Vector3D *)ref localAABB.Max; vectordPtr1[0] += 0.2f; Vector3D *vectordPtr2 = (Vector3D *)ref localAABB.Min; vectordPtr2[0] -= 0.20000000298023224; MatrixD worldMatrix = this.m_grid.PositionComp.WorldMatrix; Color red = Color.Red; red.A = (byte)(((100.0 * (Math.Sin((double)(((float)this.m_grid.TrashHighlightCounter) / 10f)) + 1.0)) / 2.0) + 100.0); red.R = (byte)(((200.0 * (Math.Sin((double)(((float)this.m_grid.TrashHighlightCounter) / 10f)) + 1.0)) / 2.0) + 50.0); Color * colorPtr1 = (Color *)ref red; MyStringId?faceMaterial = null; faceMaterial = null; MySimpleObjectDraw.DrawTransparentBox(ref worldMatrix, ref localAABB, ref (Color) ref colorPtr1, ref red, MySimpleObjectRasterizer.SolidAndWireframe, 1, 0.008f, faceMaterial, faceMaterial, false, -1, MyBillboard.BlendTypeEnum.LDR, 1f, null); } }
private unsafe Color[] Sample(Image image, double xScale, double yScale, int oldWidth, int oldHeight) { Filter.Precompute(image.Width, image.Height, Width, Height); var targetLocation = new Rectangle(0, 0, image.Width, image.Height); var Output = new Color[Width * Height]; var TransformationMatrix = GetMatrix(image, targetLocation); double TempWidth = Width < 0 ? image.Width : Width; double TempHeight = Height < 0 ? image.Width : Height; double XScale = TempWidth / image.Width; double YScale = TempHeight / image.Height; var YRadius = YScale < 1f ? (Filter.FilterRadius / YScale) : Filter.FilterRadius; var XRadius = XScale < 1f ? (Filter.FilterRadius / XScale) : Filter.FilterRadius; Parallel.For(0, Height, y => { fixed(Color * OutputPointer = &Output[y * Width]) { Color *OutputPointer2 = OutputPointer; for (int x = 0; x < Width; ++x) { var Values = new Vector4(0, 0, 0, 0); float Weight = 0; var rotated = Vector2.Transform(new Vector2(x, y), TransformationMatrix); var rotatedY = (int)rotated.Y; var rotatedX = (int)rotated.X; var Left = (int)(rotatedX - XRadius); var Right = (int)(rotatedX + XRadius); var Top = (int)(rotatedY - YRadius); var Bottom = (int)(rotatedY + YRadius); if (Top < 0) { Top = 0; } if (Bottom >= image.Height) { Bottom = image.Height - 1; } if (Left < 0) { Left = 0; } if (Right >= image.Width) { Right = image.Width - 1; } for (int i = Top, YCount = 0; i <= Bottom; ++i, ++YCount) { fixed(Color * PixelPointer = &image.Pixels[i * image.Width]) { Color *PixelPointer2 = PixelPointer + Left; for (int j = Left, XCount = 0; j <= Right; ++j, ++XCount) { var TempYWeight = Filter.YWeights[rotatedY].Values[YCount]; var TempXWeight = Filter.XWeights[rotatedX].Values[XCount]; var TempWeight = TempYWeight * TempXWeight; if (YRadius == 0 && XRadius == 0) { TempWeight = 1; } if (TempWeight == 0) { ++PixelPointer2; continue; } Values.X = Values.X + ((*PixelPointer2).Red * (float)TempWeight); Values.Y = Values.Y + ((*PixelPointer2).Green * (float)TempWeight); Values.Z = Values.Z + ((*PixelPointer2).Blue * (float)TempWeight); Values.W = Values.W + ((*PixelPointer2).Alpha * (float)TempWeight); ++PixelPointer2; Weight += (float)TempWeight; } } } if (Weight == 0) { Weight = 1; } if (Weight > 0) { Values = Vector4.Clamp(Values, Vector4.Zero, new Vector4(255, 255, 255, 255)); (*OutputPointer2).Red = (byte)Values.X; (*OutputPointer2).Green = (byte)Values.Y; (*OutputPointer2).Blue = (byte)Values.Z; (*OutputPointer2).Alpha = (byte)Values.W; ++OutputPointer2; } else { ++OutputPointer2; } } } }); return(Output); }
/// <summary> /// GIF文件写入器 /// </summary> /// <param name="filename">文件名称</param> /// <param name="width">素数宽度</param> /// <param name="height">素数高度</param> /// <param name="globalColors">全局颜色列表</param> /// <param name="backgroundColorIndex">背景颜色在全局颜色列表中的索引,如果没有全局颜色列表,该值没有意义</param> /// <param name="log">日志处理</param> public unsafe FileWriter(string filename, short width, short height, Color[] globalColors = null, byte backgroundColorIndex = 0, ILog log = null) { this.log = log ?? AutoCSer.Log.Pub.Log; if (width <= 0) { throw new IndexOutOfRangeException("width[" + width.toString() + "] <= 0"); } if (height <= 0) { throw new IndexOutOfRangeException("height[" + height.toString() + "] <= 0"); } if (string.IsNullOrEmpty(filename)) { throw new ArgumentNullException("filename is null or empty"); } fileStream = new FileStream(filename, FileMode.CreateNew, FileAccess.Write, FileShare.None, 1, FileOptions.WriteThrough); Width = width; Height = height; globalColorCount = globalColors.length(); int pixel = 0; if (globalColorCount != 0) { if (globalColorCount < 256) { pixel = ((uint)globalColorCount).bits() - 1; if (globalColorCount != (1 << pixel)) { ++pixel; } } else { globalColorCount = 256; pixel = 7; } pixel |= 0x80; } fixed(byte *bufferFixed = fileBuffer) { *(ulong *)bufferFixed = fileVersion | ((ulong)width << 48); *(uint *)(bufferFixed + 8) = (uint)(int)height | (globalColorCount == 0 ? 0 : ((uint)pixel << 16)) | (7 << (16 + 4)) | (backgroundColorIndex >= globalColorCount ? 0 : ((uint)backgroundColorIndex << 24)); bufferIndex = 13; if (globalColorCount != 0) { byte *currentBuffer = bufferFixed + 13; fixed(Color *colorFixed = globalColors) { for (Color *currentColor = colorFixed, colorEnd = colorFixed + globalColorCount; currentColor != colorEnd; ++currentColor) { Color color = *currentColor; * currentBuffer++ = color.Red; * currentBuffer++ = color.Green; * currentBuffer++ = color.Blue; } } bufferIndex += 3 << (pixel ^ 0x80); } } colors = new Color[(int)Width * Height]; colorCounts = new int[colors.Length]; colorIndexs = DictionaryCreator <Color> .Create <int>(); }
/// <summary> /// 添加图片 /// </summary> /// <param name="bitmap">位图</param> /// <param name="leftOffset">X方向偏移量</param> /// <param name="topOffset">Y方向偏移量</param> /// <param name="width">图象宽度</param> /// <param name="height">图象高度</param> /// <param name="bitmapLeftOffset">位图剪切X方向偏移量</param> /// <param name="bitmapTopOffset">位图剪切Y方向偏移量</param> /// <param name="isInterlace">图象数据是否连续方式排列,否则使用顺序排列</param> /// <param name="maxPixel">最大色彩深度</param> /// <returns>图片是否添加成功</returns> internal unsafe bool addImage(BitmapData bitmap, int bitmapLeftOffset, int bitmapTopOffset , int leftOffset, int topOffset, int width, int height, bool isInterlace, byte maxPixel) { if (fileBuffer == null) { return(false); fixed(Color *colorFixed = colors) fixed(int *colorCountFixed = colorCounts) { byte * bitmapFixed = (byte *)bitmap.Scan0, currentBitmap = bitmapFixed + bitmap.Stride * (bitmapTopOffset - 1) + (bitmapLeftOffset + width) * 3; Color *currentColor = colorFixed; int bitMapSpace = bitmap.Stride - (width << 1) - width; colorIndexs.Clear(); for (int colorIndex, row = height; row != 0; --row) { currentBitmap += bitMapSpace; for (int col = width; col != 0; --col) { Color color = new Color { Green = *currentBitmap++, Blue = *currentBitmap++, Red = *currentBitmap++ }; if (colorIndexs.TryGetValue(color, out colorIndex)) { ++colorCountFixed[colorIndex]; } else { colorIndexs.Add(color, colorIndex = (int)(currentColor - colorFixed)); colorCountFixed[colorIndex] = 1; } *currentColor++ = color; } } int pixel = ((uint)colorIndexs.Count).bits() - 1; if ((1 << pixel) != colorIndexs.Count) { ++pixel; } if (pixel > maxPixel) { pixel = maxPixel; } else if (pixel < 2) { pixel = 2; } int maxColorCount = 1 << pixel; fixed(byte *bufferFixed = fileBuffer) { byte *currentBuffer = bufferFixed + bufferIndex; *currentBuffer = 0x2c; *(short *)(currentBuffer + 1) = (short)leftOffset; *(short *)(currentBuffer + 3) = (short)topOffset; *(short *)(currentBuffer + 5) = (short)width; *(short *)(currentBuffer + 7) = (short)height; *(currentBuffer + 9) = (byte)(0x80 + (isInterlace ? 0x40 : 0) + (pixel - 1)); if (!checkBuffer(bufferFixed, 10)) { return(false); } } if (colorIndexs.Count <= maxColorCount) { fixed(byte *bufferFixed = fileBuffer) { int *currentColorCount = colorCountFixed; foreach (Color colorKey in colorIndexs.Keys) { *currentColorCount++ = colorKey.Value; } Color color = new Color(); int currentColorIndex = 0; byte *currentBuffer = bufferFixed + bufferIndex; while (currentColorCount != colorCountFixed) { color.Value = *--currentColorCount; *currentBuffer++ = color.Red; *currentBuffer++ = color.Blue; *currentBuffer++ = color.Green; colorIndexs[color] = currentColorIndex++; } *(bufferFixed + bufferIndex + (maxColorCount << 1) + maxColorCount) = (byte)pixel; if (!checkBuffer(bufferFixed, (maxColorCount << 1) + maxColorCount + 1)) { return(false); } } } else { int indexCount = colorIndexs.Count; UnmanagedPool pool = UnmanagedPool.GetDefaultPool(indexCount * sizeof(IntSortIndex)); Pointer.Size sizeBuffer = pool.GetSize(indexCount * (sizeof(IntSortIndex) + sizeof(int))); int * buffer = sizeBuffer.Int; try { IntSortIndex *indexFixed = (IntSortIndex *)(buffer + indexCount), currentSortIndex = indexFixed; foreach (KeyValuePair <Color, int> colorIndex in colorIndexs) { int color0 = colorIndex.Key.Value; int color3 = ((color0 >> 3) & 0x111111) * 0x1020400; int color2 = ((color0 >> 2) & 0x111111) * 0x1020400; int color1 = ((color0 >> 1) & 0x111111) * 0x1020400; color0 = (color0 & 0x111111) * 0x1020400; (*currentSortIndex++).Set((color3 & 0x70000000) | ((color2 >> 4) & 0x7000000) | ((color1 >> 8) & 0x700000) | ((color0 >> 12) & 0x70000) | ((color3 >> 12) & 0x7000) | ((color2 >> 16) & 0x700) | ((color1 >> 20) & 0x70) | ((color0 >> 24) & 7), colorIndex.Value); } AutoCSer.Algorithm.FixedArrayQuickSort.sort(indexFixed, indexFixed + indexCount - 1); int *currentSortArray; if (maxColorCount != 2) { currentSortArray = buffer; for (int currentColorCode, lastColorCode = (*--currentSortIndex).Value; currentSortIndex != indexFixed; lastColorCode = currentColorCode) { currentColorCode = (*--currentSortIndex).Value; *currentSortArray++ = lastColorCode - currentColorCode; } currentSortArray = buffer + (maxColorCount >> 1) - 2; new AutoCSer.Algorithm.FixedArrayQuickRangeSort.IntRangeSorterDesc { SkipCount = currentSortArray, GetEndIndex = currentSortArray }.Sort(buffer, buffer + indexCount - 2); int minColorDifference = *currentSortArray, minColorDifferenceCount = 1; while (currentSortArray != buffer) { if (*--currentSortArray == minColorDifference) { ++minColorDifferenceCount; } } currentSortIndex = indexFixed + indexCount; int maxCountIndex = (*--currentSortIndex).Index, maxCount = *(colorCountFixed + maxCountIndex); for (int currentColorCode, lastColorCode = (*currentSortIndex).Value; currentSortIndex != indexFixed; lastColorCode = currentColorCode) { currentColorCode = (*--currentSortIndex).Value; int colorDifference = lastColorCode - currentColorCode; if (colorDifference >= minColorDifference) { if (colorDifference == minColorDifference && --minColorDifferenceCount == 0) { ++minColorDifference; } *(colorCountFixed + maxCountIndex) = int.MaxValue; maxCount = *(colorCountFixed + (maxCountIndex = (*currentSortIndex).Index)); } else { int countIndex = (*currentSortIndex).Index, count = *(colorCountFixed + countIndex); if (count > maxCount) { maxCountIndex = countIndex; maxCount = count; } } } *(colorCountFixed + maxCountIndex) = int.MaxValue; } for (currentSortArray = buffer + indexCount, currentSortIndex = indexFixed; currentSortArray != buffer; *(--currentSortArray) = *(colorCountFixed + (*currentSortIndex++).Index)) { ; } currentSortArray = buffer + maxColorCount - 1; new AutoCSer.Algorithm.FixedArrayQuickRangeSort.IntRangeSorterDesc { SkipCount = currentSortArray, GetEndIndex = currentSortArray }.Sort(buffer, buffer + indexCount - 1); int minColorCount = *currentSortArray, minColorCounts = 1; while (currentSortArray != buffer) { if (*--currentSortArray == minColorCount) { ++minColorCounts; } } fixed(byte *fileBufferFixed = fileBuffer) { byte * currentBuffer = fileBufferFixed + bufferIndex; IntSortIndex *lastSortIndex = indexFixed, endSortIndex = indexFixed + indexCount; while (*(colorCountFixed + (*lastSortIndex).Index) < minColorCount) { colorIndexs[*(colorFixed + (*lastSortIndex++).Index)] = 0; } if (*(colorCountFixed + (*lastSortIndex).Index) == minColorCount && --minColorCounts == 0) { ++minColorCount; } Color outputColor = *(colorFixed + (*lastSortIndex).Index); *currentBuffer++ = outputColor.Red; *currentBuffer++ = outputColor.Blue; *currentBuffer++ = outputColor.Green; colorIndexs[outputColor] = 0; for (--maxColorCount; *(colorCountFixed + (*--endSortIndex).Index) < minColorCount; colorIndexs[*(colorFixed + (*endSortIndex).Index)] = maxColorCount) { ; } if (*(colorCountFixed + (*endSortIndex).Index) == minColorCount && --minColorCounts == 0) { ++minColorCount; } colorIndexs[*(colorFixed + (*endSortIndex).Index)] = maxColorCount++; int currentColorIndex = 0; for (int *lastColorCount = colorCountFixed + (*endSortIndex).Index; lastSortIndex != endSortIndex;) { for (*lastColorCount = 0; *(colorCountFixed + (*++lastSortIndex).Index) >= minColorCount; colorIndexs[outputColor] = ++currentColorIndex) { if (*(colorCountFixed + (*lastSortIndex).Index) == minColorCount && --minColorCounts == 0) { ++minColorCount; } outputColor = *(colorFixed + (*lastSortIndex).Index); *currentBuffer++ = outputColor.Red; *currentBuffer++ = outputColor.Blue; *currentBuffer++ = outputColor.Green; } if (lastSortIndex == endSortIndex) { break; } *lastColorCount = int.MaxValue; IntSortIndex *nextSortIndex = lastSortIndex; while (*(colorCountFixed + (*++nextSortIndex).Index) < minColorCount) { ; } for (int lastColorCode = (*(lastSortIndex - 1)).Value, nextColorCode = (*nextSortIndex).Value; lastSortIndex != nextSortIndex; ++lastSortIndex) { colorIndexs[*(colorFixed + (*lastSortIndex).Index)] = (*lastSortIndex).Value - lastColorCode <= nextColorCode - (*lastSortIndex).Value ? currentColorIndex : (currentColorIndex + 1); } if (lastSortIndex != endSortIndex) { if (*(colorCountFixed + (*lastSortIndex).Index) == minColorCount && --minColorCounts == 0) { ++minColorCount; } outputColor = *(colorFixed + (*lastSortIndex).Index); *currentBuffer++ = outputColor.Red; *currentBuffer++ = outputColor.Blue; *currentBuffer++ = outputColor.Green; colorIndexs[outputColor] = ++currentColorIndex; } } outputColor = *(colorFixed + (*lastSortIndex).Index); *currentBuffer++ = outputColor.Red; *currentBuffer++ = outputColor.Blue; *currentBuffer++ = outputColor.Green; *currentBuffer = (byte)pixel; if (!checkBuffer(fileBufferFixed, (maxColorCount << 1) + maxColorCount + 1)) { return(false); } } } finally { pool.Push(ref sizeBuffer); } } byte *colorIndexFixed = (byte *)colorCountFixed; if (isInterlace) { Color *colorEnd = colorFixed + width * height; int inputSpace = (width << 3) - width; for (Color *inputColor = colorFixed; inputColor < colorEnd; inputColor += inputSpace) { for (Color *inputEnd = inputColor + width; inputColor != inputEnd; *colorIndexFixed++ = (byte)colorIndexs[*inputColor++]) { ; } } for (Color *inputColor = colorFixed + (width << 2); inputColor < colorEnd; inputColor += inputSpace) { for (Color *inputEnd = inputColor + width; inputColor != inputEnd; *colorIndexFixed++ = (byte)colorIndexs[*inputColor++]) { ; } } inputSpace -= width << 2; for (Color *inputColor = colorFixed + (width << 1); inputColor < colorEnd; inputColor += inputSpace) { for (Color *inputEnd = inputColor + width; inputColor != inputEnd; *colorIndexFixed++ = (byte)colorIndexs[*inputColor++]) { ; } } for (Color *inputColor = colorFixed + width; inputColor < colorEnd; inputColor += width) { for (Color *inputEnd = inputColor + width; inputColor != inputEnd; *colorIndexFixed++ = (byte)colorIndexs[*inputColor++]) { ; } } } else { for (Color *inputColor = colorFixed, inputEnd = colorFixed + width * height; inputColor != inputEnd; *colorIndexFixed++ = (byte)colorIndexs[*inputColor++]) { ; } } return(lzwEncode((byte *)colorCountFixed, colorIndexFixed, pixel)); } }
public void Dispose() { System.Runtime.InteropServices.Marshal.FreeHGlobal((IntPtr)Data); Data = null; }
public unsafe static extern void RenderText(int scrW, int scrH, int width, int height, Color *pixels);
public static extern void GlTexImage2D(uint target, int level, uint internalformat, int width, int height, int border, uint format, uint type, Color *pixels);
/// <summary> /// Applies the specified image. /// </summary> /// <param name="image">The image.</param> /// <param name="targetLocation">The target location.</param> /// <returns>The image</returns> public unsafe Image Apply(Image image, Rectangle targetLocation = default(Rectangle)) { targetLocation = targetLocation == default(Rectangle) ? new Rectangle(0, 0, image.Width, image.Height) : targetLocation.Clamp(image); var tempPixels = new Color[image.Pixels.Length]; Array.Copy(image.Pixels, tempPixels, image.Pixels.Length); Parallel.For(targetLocation.Bottom, targetLocation.Top, y => { fixed(Color * Pointer = &image.Pixels[(y * image.Width) + targetLocation.Left]) { Color *OutputPointer = Pointer; for (int x = targetLocation.Left; x < targetLocation.Right; ++x) { var Values = new Vector4(0, 0, 0, 0); float Weight = 0; int XCurrent = -Width >> 1; int YCurrent = -Height >> 1; int Start = 0; fixed(float *MatrixPointer = &Matrix[0]) { float *MatrixValue = MatrixPointer; for (int MatrixIndex = 0; MatrixIndex < Matrix.Length; ++MatrixIndex) { if (MatrixIndex % Width == 0 && MatrixIndex != 0) { ++YCurrent; XCurrent = 0; } if (XCurrent + x < image.Width && XCurrent + x >= 0 && YCurrent + y < image.Height && YCurrent + y >= 0) { if (*MatrixValue != 0) { Start = ((YCurrent + y) * image.Width) + (x + XCurrent); var TempPixel = tempPixels[Start]; Values += new Vector4(*MatrixValue * TempPixel.Red, *MatrixValue * TempPixel.Green, *MatrixValue * TempPixel.Blue, TempPixel.Alpha); Weight += *MatrixValue; } ++MatrixValue; } ++XCurrent; } } if (Weight == 0) { Weight = 1; } if (Weight > 0) { if (Absolute) { Values = Vector4.Abs(Values); } Values /= Weight; Values = new Vector4(Values.X + Offset, Values.Y + Offset, Values.Z + Offset, 1); Values = Vector4.Clamp(Values, Vector4.Zero, new Vector4(255, 255, 255, 255)); (*OutputPointer).Red = (byte)Values.X; (*OutputPointer).Green = (byte)Values.Y; (*OutputPointer).Blue = (byte)Values.Z; ++OutputPointer; } else { ++OutputPointer; } } } }); return(image); }
public static extern void GlTexSubImage2D(uint target, int level, int xoffset, int yoffset, int width, int height, uint format, uint type, Color *pixels);
private unsafe void InternalPrepareDraw(Rectangle drawArea) { Rectangle rectangle = new Rectangle(drawArea.X - 2, drawArea.Y - 2, drawArea.Width + 4, drawArea.Height + 4); _drawArea = drawArea; if (_cache.Length < rectangle.Width * rectangle.Height + 1) { _cache = new LiquidCache[rectangle.Width * rectangle.Height + 1]; } if (_drawCache.Length < drawArea.Width * drawArea.Height + 1) { _drawCache = new LiquidDrawCache[drawArea.Width * drawArea.Height + 1]; } if (_waveMask.Length < drawArea.Width * drawArea.Height) { _waveMask = new Color[drawArea.Width * drawArea.Height]; } Tile tile = null; fixed(LiquidCache *ptr = &_cache[1]) { LiquidCache *ptr2 = ptr; int num = rectangle.Height * 2 + 2; ptr2 = ptr; for (int i = rectangle.X; i < rectangle.X + rectangle.Width; i++) { for (int j = rectangle.Y; j < rectangle.Y + rectangle.Height; j++) { tile = Tiles[i, j]; if (tile == null) { tile = new Tile(); } ptr2->LiquidLevel = (float)(int)tile.liquid / 255f; ptr2->IsHalfBrick = (tile.halfBrick() && ptr2[-1].HasLiquid && !TileID.Sets.Platforms[tile.type]); ptr2->IsSolid = WorldGen.SolidOrSlopedTile(tile); ptr2->HasLiquid = (tile.liquid != 0); ptr2->VisibleLiquidLevel = 0f; ptr2->HasWall = (tile.wall != 0); ptr2->Type = tile.liquidType(); if (ptr2->IsHalfBrick && !ptr2->HasLiquid) { ptr2->Type = ptr2[-1].Type; } ptr2++; } } ptr2 = ptr; float num2 = 0f; ptr2 += num; for (int k = 2; k < rectangle.Width - 2; k++) { for (int l = 2; l < rectangle.Height - 2; l++) { num2 = 0f; if (ptr2->IsHalfBrick && ptr2[-1].HasLiquid) { num2 = 1f; } else if (!ptr2->HasLiquid) { LiquidCache liquidCache = ptr2[-1]; LiquidCache liquidCache2 = ptr2[1]; LiquidCache liquidCache3 = ptr2[-rectangle.Height]; LiquidCache liquidCache4 = ptr2[rectangle.Height]; if (liquidCache.HasLiquid && liquidCache2.HasLiquid && liquidCache.Type == liquidCache2.Type && !liquidCache.IsSolid && !liquidCache2.IsSolid) { num2 = liquidCache.LiquidLevel + liquidCache2.LiquidLevel; ptr2->Type = liquidCache.Type; } if (liquidCache3.HasLiquid && liquidCache4.HasLiquid && liquidCache3.Type == liquidCache4.Type && !liquidCache3.IsSolid && !liquidCache4.IsSolid) { num2 = Math.Max(num2, liquidCache3.LiquidLevel + liquidCache4.LiquidLevel); ptr2->Type = liquidCache3.Type; } num2 *= 0.5f; } else { num2 = ptr2->LiquidLevel; } ptr2->VisibleLiquidLevel = num2; ptr2->HasVisibleLiquid = (num2 != 0f); ptr2++; } ptr2 += 4; } ptr2 = ptr; for (int m = 0; m < rectangle.Width; m++) { for (int n = 0; n < rectangle.Height - 10; n++) { if (ptr2->HasVisibleLiquid && (!ptr2->IsSolid || ptr2->IsHalfBrick)) { ptr2->Opacity = 1f; ptr2->VisibleType = ptr2->Type; float num3 = 1f / (float)(WATERFALL_LENGTH[ptr2->Type] + 1); float num4 = 1f; for (int num5 = 1; num5 <= WATERFALL_LENGTH[ptr2->Type]; num5++) { num4 -= num3; if (ptr2[num5].IsSolid) { break; } ptr2[num5].VisibleLiquidLevel = Math.Max(ptr2[num5].VisibleLiquidLevel, ptr2->VisibleLiquidLevel * num4); ptr2[num5].Opacity = num4; ptr2[num5].VisibleType = ptr2->Type; } } if (ptr2->IsSolid && !ptr2->IsHalfBrick) { ptr2->VisibleLiquidLevel = 1f; ptr2->HasVisibleLiquid = false; } else { ptr2->HasVisibleLiquid = (ptr2->VisibleLiquidLevel != 0f); } ptr2++; } ptr2 += 10; } ptr2 = ptr; ptr2 += num; for (int num6 = 2; num6 < rectangle.Width - 2; num6++) { for (int num7 = 2; num7 < rectangle.Height - 2; num7++) { if (!ptr2->HasVisibleLiquid) { ptr2->HasLeftEdge = false; ptr2->HasTopEdge = false; ptr2->HasRightEdge = false; ptr2->HasBottomEdge = false; } else { LiquidCache liquidCache = ptr2[-1]; LiquidCache liquidCache2 = ptr2[1]; LiquidCache liquidCache3 = ptr2[-rectangle.Height]; LiquidCache liquidCache4 = ptr2[rectangle.Height]; float num8 = 0f; float num9 = 1f; float num10 = 0f; float num11 = 1f; float visibleLiquidLevel = ptr2->VisibleLiquidLevel; if (!liquidCache.HasVisibleLiquid) { num10 += liquidCache2.VisibleLiquidLevel * (1f - visibleLiquidLevel); } if (!liquidCache2.HasVisibleLiquid && !liquidCache2.IsSolid && !liquidCache2.IsHalfBrick) { num11 -= liquidCache.VisibleLiquidLevel * (1f - visibleLiquidLevel); } if (!liquidCache3.HasVisibleLiquid && !liquidCache3.IsSolid && !liquidCache3.IsHalfBrick) { num8 += liquidCache4.VisibleLiquidLevel * (1f - visibleLiquidLevel); } if (!liquidCache4.HasVisibleLiquid && !liquidCache4.IsSolid && !liquidCache4.IsHalfBrick) { num9 -= liquidCache3.VisibleLiquidLevel * (1f - visibleLiquidLevel); } ptr2->LeftWall = num8; ptr2->RightWall = num9; ptr2->BottomWall = num11; ptr2->TopWall = num10; Point zero = Point.Zero; ptr2->HasTopEdge = ((!liquidCache.HasVisibleLiquid && !liquidCache.IsSolid) || num10 != 0f); ptr2->HasBottomEdge = ((!liquidCache2.HasVisibleLiquid && !liquidCache2.IsSolid) || num11 != 1f); ptr2->HasLeftEdge = ((!liquidCache3.HasVisibleLiquid && !liquidCache3.IsSolid) || num8 != 0f); ptr2->HasRightEdge = ((!liquidCache4.HasVisibleLiquid && !liquidCache4.IsSolid) || num9 != 1f); if (!ptr2->HasLeftEdge) { if (ptr2->HasRightEdge) { zero.X += 32; } else { zero.X += 16; } } if (ptr2->HasLeftEdge && ptr2->HasRightEdge) { zero.X = 16; zero.Y += 32; if (ptr2->HasTopEdge) { zero.Y = 16; } } else if (!ptr2->HasTopEdge) { if (!ptr2->HasLeftEdge && !ptr2->HasRightEdge) { zero.Y += 48; } else { zero.Y += 16; } } if (zero.Y == 16 && (ptr2->HasLeftEdge ^ ptr2->HasRightEdge) && (num7 + rectangle.Y) % 2 == 0) { zero.Y += 16; } ptr2->FrameOffset = zero; } ptr2++; } ptr2 += 4; } ptr2 = ptr; ptr2 += num; for (int num12 = 2; num12 < rectangle.Width - 2; num12++) { for (int num13 = 2; num13 < rectangle.Height - 2; num13++) { if (ptr2->HasVisibleLiquid) { LiquidCache liquidCache = ptr2[-1]; LiquidCache liquidCache2 = ptr2[1]; LiquidCache liquidCache3 = ptr2[-rectangle.Height]; LiquidCache liquidCache4 = ptr2[rectangle.Height]; ptr2->VisibleLeftWall = ptr2->LeftWall; ptr2->VisibleRightWall = ptr2->RightWall; ptr2->VisibleTopWall = ptr2->TopWall; ptr2->VisibleBottomWall = ptr2->BottomWall; if (liquidCache.HasVisibleLiquid && liquidCache2.HasVisibleLiquid) { if (ptr2->HasLeftEdge) { ptr2->VisibleLeftWall = (ptr2->LeftWall * 2f + liquidCache.LeftWall + liquidCache2.LeftWall) * 0.25f; } if (ptr2->HasRightEdge) { ptr2->VisibleRightWall = (ptr2->RightWall * 2f + liquidCache.RightWall + liquidCache2.RightWall) * 0.25f; } } if (liquidCache3.HasVisibleLiquid && liquidCache4.HasVisibleLiquid) { if (ptr2->HasTopEdge) { ptr2->VisibleTopWall = (ptr2->TopWall * 2f + liquidCache3.TopWall + liquidCache4.TopWall) * 0.25f; } if (ptr2->HasBottomEdge) { ptr2->VisibleBottomWall = (ptr2->BottomWall * 2f + liquidCache3.BottomWall + liquidCache4.BottomWall) * 0.25f; } } } ptr2++; } ptr2 += 4; } ptr2 = ptr; ptr2 += num; for (int num14 = 2; num14 < rectangle.Width - 2; num14++) { for (int num15 = 2; num15 < rectangle.Height - 2; num15++) { if (ptr2->HasLiquid) { LiquidCache liquidCache = ptr2[-1]; LiquidCache liquidCache2 = ptr2[1]; LiquidCache liquidCache3 = ptr2[-rectangle.Height]; LiquidCache liquidCache4 = ptr2[rectangle.Height]; if (ptr2->HasTopEdge && !ptr2->HasBottomEdge && (ptr2->HasLeftEdge ^ ptr2->HasRightEdge)) { if (ptr2->HasRightEdge) { ptr2->VisibleRightWall = liquidCache2.VisibleRightWall; ptr2->VisibleTopWall = liquidCache3.VisibleTopWall; } else { ptr2->VisibleLeftWall = liquidCache2.VisibleLeftWall; ptr2->VisibleTopWall = liquidCache4.VisibleTopWall; } } else if (liquidCache2.FrameOffset.X == 16 && liquidCache2.FrameOffset.Y == 32) { if (ptr2->VisibleLeftWall > 0.5f) { ptr2->VisibleLeftWall = 0f; ptr2->FrameOffset = new Point(0, 0); } else if (ptr2->VisibleRightWall < 0.5f) { ptr2->VisibleRightWall = 1f; ptr2->FrameOffset = new Point(32, 0); } } } ptr2++; } ptr2 += 4; } ptr2 = ptr; ptr2 += num; for (int num16 = 2; num16 < rectangle.Width - 2; num16++) { for (int num17 = 2; num17 < rectangle.Height - 2; num17++) { if (ptr2->HasLiquid) { LiquidCache liquidCache = ptr2[-1]; LiquidCache liquidCache2 = ptr2[1]; LiquidCache liquidCache3 = ptr2[-rectangle.Height]; LiquidCache liquidCache4 = ptr2[rectangle.Height]; if (!ptr2->HasBottomEdge && !ptr2->HasLeftEdge && !ptr2->HasTopEdge && !ptr2->HasRightEdge) { if (liquidCache3.HasTopEdge && liquidCache.HasLeftEdge) { ptr2->FrameOffset.X = Math.Max(4, (int)(16f - liquidCache.VisibleLeftWall * 16f)) - 4; ptr2->FrameOffset.Y = 48 + Math.Max(4, (int)(16f - liquidCache3.VisibleTopWall * 16f)) - 4; ptr2->VisibleLeftWall = 0f; ptr2->VisibleTopWall = 0f; ptr2->VisibleRightWall = 1f; ptr2->VisibleBottomWall = 1f; } else if (liquidCache4.HasTopEdge && liquidCache.HasRightEdge) { ptr2->FrameOffset.X = 32 - Math.Min(16, (int)(liquidCache.VisibleRightWall * 16f) - 4); ptr2->FrameOffset.Y = 48 + Math.Max(4, (int)(16f - liquidCache4.VisibleTopWall * 16f)) - 4; ptr2->VisibleLeftWall = 0f; ptr2->VisibleTopWall = 0f; ptr2->VisibleRightWall = 1f; ptr2->VisibleBottomWall = 1f; } } } ptr2++; } ptr2 += 4; } ptr2 = ptr; ptr2 += num; fixed(LiquidDrawCache *ptr3 = &_drawCache[0]) { fixed(Color *ptr5 = &_waveMask[0]) { LiquidDrawCache *ptr4 = ptr3; Color * ptr6 = ptr5; for (int num18 = 2; num18 < rectangle.Width - 2; num18++) { for (int num19 = 2; num19 < rectangle.Height - 2; num19++) { if (ptr2->HasVisibleLiquid) { float num20 = Math.Min(0.75f, ptr2->VisibleLeftWall); float num21 = Math.Max(0.25f, ptr2->VisibleRightWall); float num22 = Math.Min(0.75f, ptr2->VisibleTopWall); float num23 = Math.Max(0.25f, ptr2->VisibleBottomWall); if (ptr2->IsHalfBrick && ptr2->IsSolid && num23 > 0.5f) { num23 = 0.5f; } ptr4->IsVisible = (ptr2->HasWall || !ptr2->IsHalfBrick || !ptr2->HasLiquid || !(ptr2->LiquidLevel < 1f)); ptr4->SourceRectangle = new Rectangle((int)(16f - num21 * 16f) + ptr2->FrameOffset.X, (int)(16f - num23 * 16f) + ptr2->FrameOffset.Y, (int)Math.Ceiling((num21 - num20) * 16f), (int)Math.Ceiling((num23 - num22) * 16f)); ptr4->IsSurfaceLiquid = (ptr2->FrameOffset.X == 16 && ptr2->FrameOffset.Y == 0 && (double)(num19 + rectangle.Y) > Main.worldSurface - 40.0); ptr4->Opacity = ptr2->Opacity; ptr4->LiquidOffset = new Vector2((float)Math.Floor(num20 * 16f), (float)Math.Floor(num22 * 16f)); ptr4->Type = ptr2->VisibleType; ptr4->HasWall = ptr2->HasWall; byte b = WAVE_MASK_STRENGTH[ptr2->VisibleType]; byte g = ptr6->R = (byte)(b >> 1); ptr6->G = g; ptr6->B = VISCOSITY_MASK[ptr2->VisibleType]; ptr6->A = b; LiquidCache *ptr7 = ptr2 - 1; if (num19 != 2 && !ptr7->HasVisibleLiquid && !ptr7->IsSolid && !ptr7->IsHalfBrick) { *(ptr6 - 1) = *ptr6; } } else { ptr4->IsVisible = false; int num24 = (!ptr2->IsSolid && !ptr2->IsHalfBrick) ? 4 : 3; byte b3 = WAVE_MASK_STRENGTH[num24]; byte g2 = ptr6->R = (byte)(b3 >> 1); ptr6->G = g2; ptr6->B = VISCOSITY_MASK[num24]; ptr6->A = b3; } ptr2++; ptr4++; ptr6++; } ptr2 += 4; } } } ptr2 = ptr; for (int num25 = rectangle.X; num25 < rectangle.X + rectangle.Width; num25++) { for (int num26 = rectangle.Y; num26 < rectangle.Y + rectangle.Height; num26++) { if (ptr2->VisibleType == 1 && ptr2->HasVisibleLiquid && Dust.lavaBubbles < 200) { if (_random.Next(700) == 0) { Dust.NewDust(new Vector2(num25 * 16, num26 * 16), 16, 16, 35, 0f, 0f, 0, Color.White); } if (_random.Next(350) == 0) { int num27 = Dust.NewDust(new Vector2(num25 * 16, num26 * 16), 16, 8, 35, 0f, 0f, 50, Color.White, 1.5f); Main.dust[num27].velocity *= 0.8f; Main.dust[num27].velocity.X *= 2f; Main.dust[num27].velocity.Y -= (float)_random.Next(1, 7) * 0.1f; if (_random.Next(10) == 0) { Main.dust[num27].velocity.Y *= _random.Next(2, 5); } Main.dust[num27].noGravity = true; } } ptr2++; } } } if (this.WaveFilters != null) { this.WaveFilters(_waveMask, GetCachedDrawArea()); } }
unsafe static extern void sfImage_UpdatePixels(IntPtr This, Color *Pixels, IntRect Rectangle);
public void ResampleAndCrop(ResamplingFilters filter, CropMode mode, int newWidth, int newHeight) { if (Disposed) { return; } // fit int w = newWidth; int h = newHeight; if (mode == CropMode.Fit) { float factor1 = ((float)w / (float)h); float factor2 = ((float)Width / (float)Height); if (factor1 > factor2) { h = newHeight; w = (int)((((float)h) / ((float)Height)) * Width); } else { w = newWidth; h = (int)((((float)w) / ((float)Width)) * Height); } } else if (mode == CropMode.Cover) { float factor1 = ((float)w / (float)h); float factor2 = ((float)Width / (float)Height); if (factor1 > factor2) { w = newWidth; h = (int)((((float)w) / ((float)Width)) * Height); } else { h = newHeight; w = (int)((((float)h) / ((float)Height)) * Width); } } this.Resample(filter, w, h); Color *myPointer = (Color *)Bytes.ToPointer(); var copy = Marshal.AllocHGlobal(w * h * PixelSize); Color *copyPointer = (Color *)copy.ToPointer(); Buffer.MemoryCopy(myPointer, copyPointer, w * h * PixelSize, w * h * PixelSize); this.InternalResize(newWidth, newHeight); myPointer = (Color *)Bytes.ToPointer(); int ox = (newWidth - w) / 2; int oy = (newHeight - h) / 2; for (int y = 0; y < newHeight; y++) { for (int x = 0; x < newWidth; x++) { if (x >= ox && x < ox + w && y >= oy && y < oy + h) { *(myPointer + x + y * newWidth) = *(copyPointer + (x - ox) + (y - oy) * w); } else { *(myPointer + x + y * newWidth) = new Color(0, 0, 0, 0); } } } }
private unsafe void InternalPrepareDraw(Rectangle drawArea) { ReplacementLiquidRenderer.LiquidCache height; ReplacementLiquidRenderer.LiquidCache liquidCache; ReplacementLiquidRenderer.LiquidCache height1; ReplacementLiquidRenderer.LiquidCache liquidCache1; bool flag; Rectangle rectangle = new Rectangle(drawArea.X - 2, drawArea.Y - 2, drawArea.Width + 4, drawArea.Height + 4); this._drawArea = drawArea; Tile tile = null; fixed(ReplacementLiquidRenderer.LiquidCache *liquidCachePointer = &this._cache[1]) { ReplacementLiquidRenderer.LiquidCache *type = liquidCachePointer; int num = rectangle.Height * 2 + 2; type = liquidCachePointer; for (int i = rectangle.X; i < rectangle.X + rectangle.Width; i++) { for (int j = rectangle.Y; j < rectangle.Y + rectangle.Height; j++) { tile = this._tiles[i, j] ?? new Tile(); (*type).LiquidLevel = (float)tile.liquid / 255f; (*type).IsHalfBrick = (!tile.halfBrick() ? false : (*(type - 1)).HasLiquid); (*type).IsSolid = (!WorldGen.SolidOrSlopedTile(tile) ? false : !(*type).IsHalfBrick); (*type).HasLiquid = tile.liquid != 0; (*type).VisibleLiquidLevel = 0f; (*type).HasWall = tile.wall != 0; (*type).Type = tile.liquidType(); if ((*type).IsHalfBrick && !(*type).HasLiquid) { (*type).Type = (*(type - 1)).Type; } type = type + 1; } } type = liquidCachePointer; float liquidLevel = 0f; type = type + num; for (int k = 2; k < rectangle.Width - 2; k++) { for (int l = 2; l < rectangle.Height - 2; l++) { liquidLevel = 0f; if ((*type).IsHalfBrick && (*(type - 1)).HasLiquid) { liquidLevel = 1f; } else if ((*type).HasLiquid) { liquidLevel = (*type).LiquidLevel; } else { height = *(type + -rectangle.Height); liquidCache = *(type + rectangle.Height); height1 = *(type - 1); liquidCache1 = *(type + 1); if (height.HasLiquid && liquidCache.HasLiquid && height.Type == liquidCache.Type) { liquidLevel = height.LiquidLevel + liquidCache.LiquidLevel; (*type).Type = height.Type; } if (height1.HasLiquid && liquidCache1.HasLiquid && height1.Type == liquidCache1.Type) { liquidLevel = Math.Max(liquidLevel, height1.LiquidLevel + liquidCache1.LiquidLevel); (*type).Type = height1.Type; } liquidLevel = liquidLevel * 0.5f; } (*type).VisibleLiquidLevel = liquidLevel; (*type).HasVisibleLiquid = liquidLevel != 0f; type = type + 1; } type = type + 4; } type = liquidCachePointer; for (int m = 0; m < rectangle.Width; m++) { for (int n = 0; n < rectangle.Height - 10; n++) { if ((*type).HasVisibleLiquid && !(*type).IsSolid) { (*type).Opacity = 1f; (*type).VisibleType = (*type).Type; float wATERFALLLENGTH = 1f / (float)(ReplacementLiquidRenderer.WATERFALL_LENGTH[(*type).Type] + 1); float single = 1f; for (int o = 1; o <= ReplacementLiquidRenderer.WATERFALL_LENGTH[(*type).Type]; o++) { single = single - wATERFALLLENGTH; if ((*(type + o)).IsSolid) { break; } (*(type + o)).VisibleLiquidLevel = Math.Max((*(type + o)).VisibleLiquidLevel, (*type).VisibleLiquidLevel * single); (*(type + o)).Opacity = single; (*(type + o)).VisibleType = (*type).Type; } } if (!(*type).IsSolid) { (*type).HasVisibleLiquid = (*type).VisibleLiquidLevel != 0f; } else { (*type).VisibleLiquidLevel = 1f; (*type).HasVisibleLiquid = false; } type = type + 1; } type = type + 10; } type = liquidCachePointer; type = type + num; for (int p = 2; p < rectangle.Width - 2; p++) { for (int q = 2; q < rectangle.Height - 2; q++) { if (!(*type).HasVisibleLiquid || (*type).IsSolid) { (*type).HasLeftEdge = false; (*type).HasTopEdge = false; (*type).HasRightEdge = false; (*type).HasBottomEdge = false; } else { height = *(type - 1); liquidCache = *(type + 1); height1 = *(type + -rectangle.Height); liquidCache1 = *(type + rectangle.Height); float visibleLiquidLevel = 0f; float visibleLiquidLevel1 = 1f; float single1 = 0f; float visibleLiquidLevel2 = 1f; float single2 = (*type).VisibleLiquidLevel; if (!height.HasVisibleLiquid) { single1 = single1 + liquidCache.VisibleLiquidLevel * (1f - single2); } if (!liquidCache.HasVisibleLiquid && !liquidCache.IsSolid && !liquidCache.IsHalfBrick) { visibleLiquidLevel2 = visibleLiquidLevel2 - height.VisibleLiquidLevel * (1f - single2); } if (!height1.HasVisibleLiquid && !height1.IsSolid && !height1.IsHalfBrick) { visibleLiquidLevel = visibleLiquidLevel + liquidCache1.VisibleLiquidLevel * (1f - single2); } if (!liquidCache1.HasVisibleLiquid && !liquidCache1.IsSolid && !liquidCache1.IsHalfBrick) { visibleLiquidLevel1 = visibleLiquidLevel1 - height1.VisibleLiquidLevel * (1f - single2); } (*type).LeftWall = visibleLiquidLevel; (*type).RightWall = visibleLiquidLevel1; (*type).BottomWall = visibleLiquidLevel2; (*type).TopWall = single1; Point zero = Point.Zero; (*type).HasTopEdge = (height.HasVisibleLiquid || height.IsSolid ? single1 != 0f : true); (*type).HasBottomEdge = (liquidCache.HasVisibleLiquid || liquidCache.IsSolid ? visibleLiquidLevel2 != 1f : true); (*type).HasLeftEdge = (height1.HasVisibleLiquid || height1.IsSolid ? visibleLiquidLevel != 0f : true); (*type).HasRightEdge = (liquidCache1.HasVisibleLiquid || liquidCache1.IsSolid ? visibleLiquidLevel1 != 1f : true); if (!(*type).HasLeftEdge) { if (!(*type).HasRightEdge) { zero.X = zero.X + 16; } else { zero.X = zero.X + 32; } } if ((*type).HasLeftEdge && (*type).HasRightEdge) { zero.X = 16; zero.Y = zero.Y + 32; if ((*type).HasTopEdge) { zero.Y = 16; } } else if (!(*type).HasTopEdge) { if ((*type).HasLeftEdge || (*type).HasRightEdge) { zero.Y = zero.Y + 16; } else { zero.Y = zero.Y + 48; } } if (zero.Y == 16 && (*type).HasLeftEdge ^ (*type).HasRightEdge && q + rectangle.Y % 2 == 0) { zero.Y = zero.Y + 16; } (*type).FrameOffset = zero; } type = type + 1; } type = type + 4; } type = liquidCachePointer; type = type + num; for (int r = 2; r < rectangle.Width - 2; r++) { for (int s = 2; s < rectangle.Height - 2; s++) { if ((*type).HasVisibleLiquid) { height = *(type - 1); liquidCache = *(type + 1); height1 = *(type + -rectangle.Height); liquidCache1 = *(type + rectangle.Height); (*type).VisibleLeftWall = (*type).LeftWall; (*type).VisibleRightWall = (*type).RightWall; (*type).VisibleTopWall = (*type).TopWall; (*type).VisibleBottomWall = (*type).BottomWall; if (height.HasVisibleLiquid && liquidCache.HasVisibleLiquid) { if ((*type).HasLeftEdge) { (*type).VisibleLeftWall = ((*type).LeftWall * 2f + height.LeftWall + liquidCache.LeftWall) * 0.25f; } if ((*type).HasRightEdge) { (*type).VisibleRightWall = ((*type).RightWall * 2f + height.RightWall + liquidCache.RightWall) * 0.25f; } } if (height1.HasVisibleLiquid && liquidCache1.HasVisibleLiquid) { if ((*type).HasTopEdge) { (*type).VisibleTopWall = ((*type).TopWall * 2f + height1.TopWall + liquidCache1.TopWall) * 0.25f; } if ((*type).HasBottomEdge) { (*type).VisibleBottomWall = ((*type).BottomWall * 2f + height1.BottomWall + liquidCache1.BottomWall) * 0.25f; } } } type = type + 1; } type = type + 4; } type = liquidCachePointer; type = type + num; for (int t = 2; t < rectangle.Width - 2; t++) { for (int u = 2; u < rectangle.Height - 2; u++) { if ((*type).HasLiquid) { height = *(type - 1); liquidCache = *(type); height1 = *(type + -rectangle.Height); liquidCache1 = *(type + rectangle.Height); if ((*type).HasTopEdge && !(*type).HasBottomEdge && (*type).HasLeftEdge ^ (*type).HasRightEdge) { if (!(*type).HasRightEdge) { (*type).VisibleLeftWall = liquidCache.VisibleLeftWall; (*type).VisibleTopWall = liquidCache1.VisibleTopWall; } else { (*type).VisibleRightWall = liquidCache.VisibleRightWall; (*type).VisibleTopWall = height1.VisibleTopWall; } } else if (liquidCache.FrameOffset.X == 16 && liquidCache.FrameOffset.Y == 32) { if ((*type).VisibleLeftWall > 0.5f) { (*type).VisibleLeftWall = 0f; (*type).FrameOffset = new Point(0, 0); } else if ((*type).VisibleRightWall < 0.5f) { (*type).VisibleRightWall = 1f; (*type).FrameOffset = new Point(32, 0); } } } type = type + 1; } type = type + 4; } type = liquidCachePointer; type = type + num; for (int v = 2; v < rectangle.Width - 2; v++) { for (int w = 2; w < rectangle.Height - 2; w++) { if ((*type).HasLiquid) { height = *(type - 1); liquidCache = *(type); height1 = *(type + -rectangle.Height); liquidCache1 = *(type + rectangle.Height); if (!(*type).HasBottomEdge && !(*type).HasLeftEdge && !(*type).HasTopEdge && !(*type).HasRightEdge) { if (height1.HasTopEdge && height.HasLeftEdge) { (*type).FrameOffset.X = Math.Max(4, (int)(16f - height.VisibleLeftWall * 16f)) - 4; (*type).FrameOffset.Y = 48 + Math.Max(4, (int)(16f - height1.VisibleTopWall * 16f)) - 4; (*type).VisibleLeftWall = 0f; (*type).VisibleTopWall = 0f; (*type).VisibleRightWall = 1f; (*type).VisibleBottomWall = 1f; } else if (liquidCache1.HasTopEdge && height.HasRightEdge) { (*type).FrameOffset.X = 32 - Math.Min(16, (int)(height.VisibleRightWall * 16f) - 4); (*type).FrameOffset.Y = 48 + Math.Max(4, (int)(16f - liquidCache1.VisibleTopWall * 16f)) - 4; (*type).VisibleLeftWall = 0f; (*type).VisibleTopWall = 0f; (*type).VisibleRightWall = 1f; (*type).VisibleBottomWall = 1f; } } } type = type + 1; } type = type + 4; } type = liquidCachePointer; type = type + num; fixed(ReplacementLiquidRenderer.LiquidDrawCache *liquidDrawCachePointer = &this._drawCache[0]) { fixed(Color *colorPointer = &this._waveMask[0]) { ReplacementLiquidRenderer.LiquidDrawCache *opacity = liquidDrawCachePointer; Color *vISCOSITYMASK = colorPointer; for (int x = 2; x < rectangle.Width - 2; x++) { Color *colorPointer1 = vISCOSITYMASK; for (int y = 2; y < rectangle.Height - 2; y++) { if (!(*type).HasVisibleLiquid) { (*opacity).IsVisible = false; int num1 = ((*type).IsSolid || (*type).IsHalfBrick ? 3 : 4); byte wAVEMASKSTRENGTH = ReplacementLiquidRenderer.WAVE_MASK_STRENGTH[num1]; byte num2 = (byte)(wAVEMASKSTRENGTH >> 1); (*vISCOSITYMASK).R = num2; (*vISCOSITYMASK).G = num2; (*vISCOSITYMASK).B = ReplacementLiquidRenderer.VISCOSITY_MASK[num1]; (*vISCOSITYMASK).A = wAVEMASKSTRENGTH; } else { float single3 = Math.Min(0.75f, (*type).VisibleLeftWall); float single4 = Math.Max(0.25f, (*type).VisibleRightWall); float single5 = Math.Min(0.75f, (*type).VisibleTopWall); float single6 = Math.Max(0.25f, (*type).VisibleBottomWall); if ((*type).IsHalfBrick && single6 > 0.5f) { single6 = 0.5f; } ReplacementLiquidRenderer.LiquidDrawCache *liquidDrawCachePointer1 = opacity; if ((*type).HasWall) { flag = true; } else { flag = (!(*type).IsHalfBrick ? true : !(*type).HasLiquid); } (*liquidDrawCachePointer1).IsVisible = flag; (*opacity).SourceRectangle = new Rectangle((int)(16f - single4 * 16f) + (*type).FrameOffset.X, (int)(16f - single6 * 16f) + (*type).FrameOffset.Y, (int)Math.Ceiling((double)((single4 - single3) * 16f)), (int)Math.Ceiling((double)((single6 - single5) * 16f))); (*opacity).IsSurfaceLiquid = ((*type).FrameOffset.X != 16 || (*type).FrameOffset.Y != 0 ? false : (double)(y + rectangle.Y) > Main.worldSurface - 40); (*opacity).Opacity = (*type).Opacity; (*opacity).LiquidOffset = new Vector2((float)Math.Floor((double)(single3 * 16f)), (float)Math.Floor((double)(single5 * 16f))); (*opacity).Type = (*type).VisibleType; (*opacity).HasWall = (*type).HasWall; byte wAVEMASKSTRENGTH1 = ReplacementLiquidRenderer.WAVE_MASK_STRENGTH[(*type).VisibleType]; byte num3 = (byte)(wAVEMASKSTRENGTH1 >> 1); (*vISCOSITYMASK).R = num3; (*vISCOSITYMASK).G = num3; (*vISCOSITYMASK).B = ReplacementLiquidRenderer.VISCOSITY_MASK[(*type).VisibleType]; (*vISCOSITYMASK).A = wAVEMASKSTRENGTH1; ReplacementLiquidRenderer.LiquidCache *liquidCachePointer1 = type - 1; if (y != 2 && !(*liquidCachePointer1).HasVisibleLiquid && !(*liquidCachePointer1).IsSolid && !(*liquidCachePointer1).IsHalfBrick) { if (vISCOSITYMASK - 200 < colorPointer) { System.Diagnostics.Debugger.Launch(); } *(vISCOSITYMASK - 200) = *vISCOSITYMASK; } } type = type + 1; opacity = opacity + 1; vISCOSITYMASK = vISCOSITYMASK + 200; } type = type + 4; vISCOSITYMASK = colorPointer1 + 1; } } } type = liquidCachePointer; for (int a = rectangle.X; a < rectangle.X + rectangle.Width; a++) { for (int b = rectangle.Y; b < rectangle.Y + rectangle.Height; b++) { if ((*type).VisibleType == 1 && (*type).HasVisibleLiquid && Dust.lavaBubbles < 200) { if (this._random.Next(700) == 0) { Dust.NewDust(new Vector2((float)(a * 16), (float)(b * 16)), 16, 16, 35, 0f, 0f, 0, Color.White, 1f); } if (this._random.Next(350) == 0) { int num4 = Dust.NewDust(new Vector2((float)(a * 16), (float)(b * 16)), 16, 8, 35, 0f, 0f, 50, Color.White, 1.5f); Dust dust = Main.dust[num4]; dust.velocity = dust.velocity * 0.8f; Main.dust[num4].velocity.X = Main.dust[num4].velocity.X * 2f; Main.dust[num4].velocity.Y = Main.dust[num4].velocity.Y - (float)this._random.Next(1, 7) * 0.1f; if (this._random.Next(10) == 0) { Main.dust[num4].velocity.Y = Main.dust[num4].velocity.Y * (float)this._random.Next(2, 5); } Main.dust[num4].noGravity = true; } } type = type + 1; } } } if (this.ViscosityFilters != null) { this.ViscosityFilters(this._waveMask, this.GetCachedDrawArea()); } }
public static extern int SDL_SetPaletteColors( Palette palette, /*const*/ Color *colors, int firstcolor, int ncolors );
/// <summary> /// Applies the filter to the specified image. /// </summary> /// <param name="image">The image.</param> /// <param name="targetLocation">The target location.</param> /// <returns>The image</returns> public unsafe Image Apply(Image image, Numerics.Rectangle targetLocation = default(Numerics.Rectangle)) { targetLocation = targetLocation == default(Numerics.Rectangle) ? new Numerics.Rectangle(0, 0, image.Width, image.Height) : targetLocation.Clamp(image); var PointSize2 = PointSize * 2; var Copy = new Color[image.Pixels.Length]; Array.Copy(image.Pixels, Copy, Copy.Length); var EllipseDrawer = new Ellipse(Color.AliceBlue, true, PointSize, PointSize, new Vector2(0, 0)); for (int y = targetLocation.Bottom; y < targetLocation.Top; y += PointSize2) { var MinY = (y - PointSize).Clamp(targetLocation.Bottom, targetLocation.Top - 1); var MaxY = (y + PointSize).Clamp(targetLocation.Bottom, targetLocation.Top - 1); fixed(Color *TargetPointer = &Copy[(y * image.Width) + targetLocation.Left]) { Color *TargetPointer2 = TargetPointer; for (int x = targetLocation.Left; x < targetLocation.Right; x += PointSize2) { uint RValue = 0; uint GValue = 0; uint BValue = 0; var MinX = (x - PointSize).Clamp(targetLocation.Left, targetLocation.Right - 1); var MaxX = (x + PointSize).Clamp(targetLocation.Left, targetLocation.Right - 1); int NumberPixels = 0; for (int x2 = MinX; x2 < MaxX; ++x2) { for (int y2 = MinY; y2 < MaxY; ++y2) { var Offset = ((y * image.Width) + x); RValue += Copy[Offset].Red; GValue += Copy[Offset].Green; BValue += Copy[Offset].Blue; ++NumberPixels; } } RValue /= (uint)NumberPixels; GValue /= (uint)NumberPixels; BValue /= (uint)NumberPixels; EllipseDrawer.Center = new Vector2(x, y); EllipseDrawer.Color = new Color((byte)RValue, (byte)GValue, (byte)BValue); EllipseDrawer.Apply(image, targetLocation); } } } for (int y = targetLocation.Bottom + PointSize; y < targetLocation.Top; y += PointSize2) { var MinY = (y - PointSize).Clamp(targetLocation.Bottom, targetLocation.Top - 1); var MaxY = (y + PointSize).Clamp(targetLocation.Bottom, targetLocation.Top - 1); fixed(Color *TargetPointer = &Copy[(y *image.Width) + targetLocation.Left]) { Color *TargetPointer2 = TargetPointer; for (int x = targetLocation.Left + PointSize; x < targetLocation.Right; x += PointSize2) { uint RValue = 0; uint GValue = 0; uint BValue = 0; var MinX = (x - PointSize).Clamp(targetLocation.Left, targetLocation.Right - 1); var MaxX = (x + PointSize).Clamp(targetLocation.Left, targetLocation.Right - 1); int NumberPixels = 0; for (int x2 = MinX; x2 < MaxX; ++x2) { for (int y2 = MinY; y2 < MaxY; ++y2) { var Offset = ((y * image.Width) + x); RValue += Copy[Offset].Red; GValue += Copy[Offset].Green; BValue += Copy[Offset].Blue; ++NumberPixels; } } RValue /= (uint)NumberPixels; GValue /= (uint)NumberPixels; BValue /= (uint)NumberPixels; EllipseDrawer.Center = new Vector2(x, y); EllipseDrawer.Color = new Color((byte)RValue, (byte)GValue, (byte)BValue); EllipseDrawer.Apply(image, targetLocation); } } } for (int y = targetLocation.Bottom; y < targetLocation.Top; y += PointSize2) { var TempY = y + new Random(y).Next(-PointSize, PointSize); var MinY = (TempY - PointSize).Clamp(targetLocation.Bottom, targetLocation.Top - 1); var MaxY = (TempY + PointSize).Clamp(targetLocation.Bottom, targetLocation.Top - 1); fixed(Color *TargetPointer = &Copy[(y *image.Width) + targetLocation.Left]) { Color *TargetPointer2 = TargetPointer; for (int x = targetLocation.Left + PointSize; x < targetLocation.Right; x += PointSize2) { uint RValue = 0; uint GValue = 0; uint BValue = 0; var TempX = x + new Random(x).Next(-PointSize, PointSize); var MinX = (TempX - PointSize).Clamp(targetLocation.Left, targetLocation.Right - 1); var MaxX = (TempX + PointSize).Clamp(targetLocation.Left, targetLocation.Right - 1); int NumberPixels = 0; for (int x2 = MinX; x2 < MaxX; ++x2) { for (int y2 = MinY; y2 < MaxY; ++y2) { var Offset = ((y * image.Width) + x); RValue += Copy[Offset].Red; GValue += Copy[Offset].Green; BValue += Copy[Offset].Blue; ++NumberPixels; } } RValue /= (uint)NumberPixels; GValue /= (uint)NumberPixels; BValue /= (uint)NumberPixels; EllipseDrawer.Center = new Vector2(TempX, TempY); EllipseDrawer.Color = new Color((byte)RValue, (byte)GValue, (byte)BValue); EllipseDrawer.Apply(image, targetLocation); } } } return(image); }
public static ColorVertexes Create(int nx, int ny, int nz, float radius, float minValue, float maxValue) { int points = nx * ny * nz; ColorVertexes colorVertexes = new ColorVertexes(points); Random random = new Random(); Random colorRandom = new Random(); float xmin = 0, xmax = 0, ymin = 0, ymax = 0, zmin = 0, zmax = 0; bool isInit = false; unsafe { for (long i = 0; i < colorVertexes.Size; i++) { float x = minValue + ((float)random.NextDouble()) * maxValue; float y = minValue + ((float)random.NextDouble()) * maxValue; float z = minValue + ((float)random.NextDouble()) * maxValue; if (!isInit) { xmin = x; xmax = x; ymin = y; ymax = y; zmin = z; zmax = z; isInit = true; } if (x < xmin) { xmin = x; } if (x > xmax) { xmax = x; } if (y < ymin) { ymin = y; } if (y > ymax) { ymax = y; } if (z < zmin) { zmin = z; } if (z > zmax) { zmax = z; } Vertex *centers = colorVertexes.Centers; centers[i].X = x; centers[i].Y = y; centers[i].Z = z; Color *colors = colorVertexes.Colors; colors[i].red = (byte)colorRandom.Next(0, 256); colors[i].green = (byte)colorRandom.Next(0, 256); colors[i].blue = (byte)colorRandom.Next(0, 256); } Vertex location = new Vertex(xmin, ymin, zmin); Size3D size; size.x = (xmax - xmin); size.y = (ymax - ymin); size.z = (zmax - zmin); Rect3D rect = new Rect3D(location, size); colorVertexes.Bounds = rect; } return(colorVertexes); }
/// <summary> /// Applies the filter to the specified image. /// </summary> /// <param name="image">The image.</param> /// <param name="targetLocation">The target location.</param> /// <returns>The image</returns> public unsafe Image Apply(Image image, Rectangle targetLocation = default(Rectangle)) { targetLocation = targetLocation == default(Rectangle) ? new Rectangle(0, 0, image.Width, image.Height) : targetLocation.Clamp(image); var TempValues = new Color[image.Pixels.Length]; Array.Copy(image.Pixels, TempValues, TempValues.Length); int ApetureMin = -ApetureRadius; int ApetureMax = ApetureRadius; Parallel.For(targetLocation.Bottom, targetLocation.Top, y => { fixed(Color * TargetPointer = &TempValues[(y * image.Width) + targetLocation.Left]) { Color *TargetPointer2 = TargetPointer; for (int x = targetLocation.Left; x < targetLocation.Right; ++x) { uint RValue = 0; uint GValue = 0; uint BValue = 0; int NumPixels = 0; for (int x2 = ApetureMin; x2 < ApetureMax; ++x2) { int TempX1 = x + x2; int TempX2 = x - x2; if (TempX1 >= targetLocation.Left && TempX1 < targetLocation.Right && TempX2 >= targetLocation.Left && TempX2 < targetLocation.Right) { for (int y2 = ApetureMin; y2 < ApetureMax; ++y2) { int TempY1 = y + y2; int TempY2 = y - y2; if (TempY1 >= targetLocation.Bottom && TempY1 < targetLocation.Top && TempY2 >= targetLocation.Bottom && TempY2 < targetLocation.Top) { var TempValue1 = image.Pixels[(y * image.Width) + x]; var TempValue2 = image.Pixels[(TempY1 * image.Width) + TempX1]; var TempValue3 = image.Pixels[(TempY2 * image.Width) + TempX2]; if (Distance.Euclidean(TempValue1, TempValue2) < Distance.Euclidean(TempValue1, TempValue3)) { RValue += TempValue2.Red; GValue += TempValue2.Green; BValue += TempValue2.Blue; } else { RValue += TempValue3.Red; GValue += TempValue3.Green; BValue += TempValue3.Blue; } ++NumPixels; } } } } TempValues[(y * image.Width) + x].Red = (byte)(RValue / NumPixels); TempValues[(y * image.Width) + x].Green = (byte)(GValue / NumPixels); TempValues[(y * image.Width) + x].Blue = (byte)(BValue / NumPixels); TempValues[(y * image.Width) + x].Alpha = image.Pixels[(y * image.Width) + x].Alpha; } } }); return(image.ReCreate(image.Width, image.Height, TempValues)); }
/// <summary> /// Applies the filter to the specified image. /// </summary> /// <param name="image">The image.</param> /// <param name="targetLocation">The target location.</param> /// <returns>The image</returns> public unsafe Image Apply(Image image, Rectangle targetLocation = default(Rectangle)) { Filter.Precompute(image.Width, image.Height, Width, Height); targetLocation = targetLocation == default(Rectangle) ? new Rectangle(0, 0, image.Width, image.Height) : targetLocation.Clamp(image); var Copy = new Color[image.Pixels.Length]; Array.Copy(image.Pixels, Copy, Copy.Length); TransformationMatrix = GetMatrix(image, targetLocation); double TempWidth = Width < 0 ? image.Width : Width; double TempHeight = Height < 0 ? image.Width : Height; double XScale = TempWidth / image.Width; double YScale = TempHeight / image.Height; YRadius = YScale < 1f ? (Filter.FilterRadius / YScale) : Filter.FilterRadius; XRadius = XScale < 1f ? (Filter.FilterRadius / XScale) : Filter.FilterRadius; Parallel.For(targetLocation.Bottom, targetLocation.Top, y => { fixed(Color * OutputPointer = &image.Pixels[(y * image.Width) + targetLocation.Left]) { Color *OutputPointer2 = OutputPointer; for (int x = targetLocation.Left; x < targetLocation.Right; ++x) { var Values = new Vector4(0, 0, 0, 0); float Weight = 0; var rotated = Vector2.Transform(new Vector2(x, y), TransformationMatrix); var rotatedY = (int)rotated.Y; var rotatedX = (int)rotated.X; if (rotatedY >= image.Height || rotatedY < 0 || rotatedX >= image.Width || rotatedX < 0) { (*OutputPointer2).Red = 0; (*OutputPointer2).Green = 0; (*OutputPointer2).Blue = 0; (*OutputPointer2).Alpha = 255; ++OutputPointer2; continue; } var Left = (int)(rotatedX - XRadius); var Right = (int)(rotatedX + XRadius); var Top = (int)(rotatedY - YRadius); var Bottom = (int)(rotatedY + YRadius); if (Top < 0) { Top = 0; } if (Bottom >= image.Height) { Bottom = image.Height - 1; } if (Left < 0) { Left = 0; } if (Right >= image.Width) { Right = image.Width - 1; } for (int i = Top, YCount = 0; i <= Bottom; ++i, ++YCount) { fixed(Color * PixelPointer = &Copy[i * image.Width]) { Color *PixelPointer2 = PixelPointer + Left; for (int j = Left, XCount = 0; j <= Right; ++j, ++XCount) { var TempYWeight = Filter.YWeights[rotatedY].Values[YCount]; var TempXWeight = Filter.XWeights[rotatedX].Values[XCount]; var TempWeight = TempYWeight * TempXWeight; if (YRadius == 0 && XRadius == 0) { TempWeight = 1; } if (TempWeight == 0) { ++PixelPointer2; continue; } Values.X = Values.X + ((*PixelPointer2).Red * (float)TempWeight); Values.Y = Values.Y + ((*PixelPointer2).Green * (float)TempWeight); Values.Z = Values.Z + ((*PixelPointer2).Blue * (float)TempWeight); Values.W = Values.W + ((*PixelPointer2).Alpha * (float)TempWeight); ++PixelPointer2; Weight += (float)TempWeight; } } } if (Weight == 0) { Weight = 1; } if (Weight > 0) { Values = Vector4.Clamp(Values, Vector4.Zero, new Vector4(255, 255, 255, 255)); (*OutputPointer2).Red = (byte)Values.X; (*OutputPointer2).Green = (byte)Values.Y; (*OutputPointer2).Blue = (byte)Values.Z; (*OutputPointer2).Alpha = (byte)Values.W; ++OutputPointer2; } else { ++OutputPointer2; } } } }); return(image); }
public static unsafe void Paint() { Vector2 shapeCoord = new Vector2(); float num = P3D_Helper.Reciprocal(P3D_Brush.canvasW * P3D_Brush.detailScale.x); float num2 = P3D_Helper.Reciprocal(P3D_Brush.canvasH * P3D_Brush.detailScale.y); Color * colorPtr1 = &P3D_Brush.color; colorPtr1->a *= P3D_Brush.opacity; if ((P3D_Brush.shape != null) && (P3D_Brush.shape.format != TextureFormat.Alpha8)) { int xMin = P3D_Brush.rect.XMin; while (xMin < P3D_Brush.rect.XMax) { int yMin = P3D_Brush.rect.YMin; while (true) { if (yMin >= P3D_Brush.rect.YMax) { xMin++; break; } if (P3D_Brush.IsInsideShape(P3D_Brush.inverse, xMin, yMin, ref shapeCoord)) { Vector3 a = ColorToNormalXY(P3D_Brush.canvas.GetPixel(xMin, yMin)); Vector3 vector4 = ColorToNormalXY(P3D_Brush.shape.GetPixelBilinear(shapeCoord.x, shapeCoord.y)); if (P3D_Brush.detail != null) { vector4 = CombineNormalsXY(vector4, ColorToNormalXY(P3D_Brush.SampleRepeat(P3D_Brush.detail, num * xMin, num2 * yMin))); } P3D_Brush.canvas.SetPixel(xMin, yMin, NormalToColor(Vector3.Normalize(ComputeZ(CombineNormalsXY(a, vector4, P3D_Brush.opacity))))); } yMin++; } } } else { int xMin = P3D_Brush.rect.XMin; while (xMin < P3D_Brush.rect.XMax) { int yMin = P3D_Brush.rect.YMin; while (true) { if (yMin >= P3D_Brush.rect.YMax) { xMin++; break; } if (P3D_Brush.IsInsideShape(P3D_Brush.inverse, xMin, yMin, ref shapeCoord)) { Vector3 a = ColorToNormalXY(P3D_Brush.canvas.GetPixel(xMin, yMin)); Vector2 direction = P3D_Brush.direction; float opacity = P3D_Brush.opacity; if (P3D_Brush.shape != null) { opacity *= P3D_Brush.shape.GetPixelBilinear(shapeCoord.x, shapeCoord.y).a; } if (P3D_Brush.detail != null) { Vector3 b = ColorToNormalXY(P3D_Brush.SampleRepeat(P3D_Brush.detail, num * xMin, num2 * yMin)); direction = CombineNormalsXY((Vector3)direction, b); } P3D_Brush.canvas.SetPixel(xMin, yMin, NormalToColor(Vector3.Normalize(ComputeZ(CombineNormalsXY(a, direction, opacity))))); } yMin++; } } } }
private unsafe void InternalPrepareDraw(Rectangle drawArea) { Rectangle rectangle = new Rectangle(drawArea.X - 2, drawArea.Y - 2, drawArea.Width + 4, drawArea.Height + 4); this._drawArea = drawArea; fixed(LiquidRenderer.LiquidCache *liquidCachePtr1 = &this._cache[1]) { int num1 = rectangle.Height * 2 + 2; LiquidRenderer.LiquidCache *liquidCachePtr2 = liquidCachePtr1; for (int x = rectangle.X; x < rectangle.X + rectangle.Width; ++x) { for (int y = rectangle.Y; y < rectangle.Y + rectangle.Height; ++y) { Tile tile = this._tiles[x, y] ?? new Tile(); liquidCachePtr2->LiquidLevel = (float)tile.liquid / (float)byte.MaxValue; liquidCachePtr2->IsHalfBrick = tile.halfBrick() && liquidCachePtr2[-1].HasLiquid; liquidCachePtr2->IsSolid = WorldGen.SolidOrSlopedTile(tile) && !liquidCachePtr2->IsHalfBrick; liquidCachePtr2->HasLiquid = (int)tile.liquid != 0; liquidCachePtr2->VisibleLiquidLevel = 0.0f; liquidCachePtr2->HasWall = (int)tile.wall != 0; liquidCachePtr2->Type = tile.liquidType(); if (liquidCachePtr2->IsHalfBrick && !liquidCachePtr2->HasLiquid) { liquidCachePtr2->Type = liquidCachePtr2[-1].Type; } ++liquidCachePtr2; } } LiquidRenderer.LiquidCache *liquidCachePtr3 = liquidCachePtr1 + num1; LiquidRenderer.LiquidCache liquidCache1; LiquidRenderer.LiquidCache liquidCache2; LiquidRenderer.LiquidCache liquidCache3; LiquidRenderer.LiquidCache liquidCache4; for (int index1 = 2; index1 < rectangle.Width - 2; ++index1) { for (int index2 = 2; index2 < rectangle.Height - 2; ++index2) { float val1 = 0.0f; float num2; if (liquidCachePtr3->IsHalfBrick && liquidCachePtr3[-1].HasLiquid) { num2 = 1f; } else if (!liquidCachePtr3->HasLiquid) { liquidCache1 = liquidCachePtr3[-rectangle.Height]; liquidCache2 = liquidCachePtr3[rectangle.Height]; liquidCache3 = liquidCachePtr3[-1]; liquidCache4 = liquidCachePtr3[1]; if (liquidCache1.HasLiquid && liquidCache2.HasLiquid && (int)liquidCache1.Type == (int)liquidCache2.Type) { val1 = liquidCache1.LiquidLevel + liquidCache2.LiquidLevel; liquidCachePtr3->Type = liquidCache1.Type; } if (liquidCache3.HasLiquid && liquidCache4.HasLiquid && (int)liquidCache3.Type == (int)liquidCache4.Type) { val1 = Math.Max(val1, liquidCache3.LiquidLevel + liquidCache4.LiquidLevel); liquidCachePtr3->Type = liquidCache3.Type; } num2 = val1 * 0.5f; } else { num2 = liquidCachePtr3->LiquidLevel; } liquidCachePtr3->VisibleLiquidLevel = num2; liquidCachePtr3->HasVisibleLiquid = (double)num2 != 0.0; ++liquidCachePtr3; } liquidCachePtr3 += 4; } LiquidRenderer.LiquidCache *liquidCachePtr4 = liquidCachePtr1; for (int index1 = 0; index1 < rectangle.Width; ++index1) { for (int index2 = 0; index2 < rectangle.Height - 10; ++index2) { if (liquidCachePtr4->HasVisibleLiquid && !liquidCachePtr4->IsSolid) { liquidCachePtr4->Opacity = 1f; liquidCachePtr4->VisibleType = liquidCachePtr4->Type; float num2 = 1f / (float)(LiquidRenderer.WATERFALL_LENGTH[(int)liquidCachePtr4->Type] + 1); float num3 = 1f; for (int index3 = 1; index3 <= LiquidRenderer.WATERFALL_LENGTH[(int)liquidCachePtr4->Type]; ++index3) { num3 -= num2; if (!liquidCachePtr4[index3].IsSolid) { liquidCachePtr4[index3].VisibleLiquidLevel = Math.Max(liquidCachePtr4[index3].VisibleLiquidLevel, liquidCachePtr4->VisibleLiquidLevel * num3); liquidCachePtr4[index3].Opacity = num3; liquidCachePtr4[index3].VisibleType = liquidCachePtr4->Type; } else { break; } } } if (liquidCachePtr4->IsSolid) { liquidCachePtr4->VisibleLiquidLevel = 1f; liquidCachePtr4->HasVisibleLiquid = false; } else { liquidCachePtr4->HasVisibleLiquid = (double)liquidCachePtr4->VisibleLiquidLevel != 0.0; } ++liquidCachePtr4; } liquidCachePtr4 += 10; } LiquidRenderer.LiquidCache *liquidCachePtr5 = liquidCachePtr1 + num1; for (int index1 = 2; index1 < rectangle.Width - 2; ++index1) { for (int index2 = 2; index2 < rectangle.Height - 2; ++index2) { if (liquidCachePtr5->HasVisibleLiquid && !liquidCachePtr5->IsSolid) { liquidCache1 = liquidCachePtr5[-1]; liquidCache2 = liquidCachePtr5[1]; liquidCache3 = liquidCachePtr5[-rectangle.Height]; liquidCache4 = liquidCachePtr5[rectangle.Height]; float num2 = 0.0f; float num3 = 1f; float num4 = 0.0f; float num5 = 1f; float visibleLiquidLevel = liquidCachePtr5->VisibleLiquidLevel; if (!liquidCache1.HasVisibleLiquid) { num4 += liquidCache2.VisibleLiquidLevel * (1f - visibleLiquidLevel); } if (!liquidCache2.HasVisibleLiquid && !liquidCache2.IsSolid && !liquidCache2.IsHalfBrick) { num5 -= liquidCache1.VisibleLiquidLevel * (1f - visibleLiquidLevel); } if (!liquidCache3.HasVisibleLiquid && !liquidCache3.IsSolid && !liquidCache3.IsHalfBrick) { num2 += liquidCache4.VisibleLiquidLevel * (1f - visibleLiquidLevel); } if (!liquidCache4.HasVisibleLiquid && !liquidCache4.IsSolid && !liquidCache4.IsHalfBrick) { num3 -= liquidCache3.VisibleLiquidLevel * (1f - visibleLiquidLevel); } liquidCachePtr5->LeftWall = num2; liquidCachePtr5->RightWall = num3; liquidCachePtr5->BottomWall = num5; liquidCachePtr5->TopWall = num4; Point zero = Point.Zero; liquidCachePtr5->HasTopEdge = !liquidCache1.HasVisibleLiquid && !liquidCache1.IsSolid || (double)num4 != 0.0; liquidCachePtr5->HasBottomEdge = !liquidCache2.HasVisibleLiquid && !liquidCache2.IsSolid || (double)num5 != 1.0; liquidCachePtr5->HasLeftEdge = !liquidCache3.HasVisibleLiquid && !liquidCache3.IsSolid || (double)num2 != 0.0; liquidCachePtr5->HasRightEdge = !liquidCache4.HasVisibleLiquid && !liquidCache4.IsSolid || (double)num3 != 1.0; if (!liquidCachePtr5->HasLeftEdge) { if (liquidCachePtr5->HasRightEdge) { zero.X += 32; } else { zero.X += 16; } } if (liquidCachePtr5->HasLeftEdge && liquidCachePtr5->HasRightEdge) { zero.X = 16; zero.Y += 32; if (liquidCachePtr5->HasTopEdge) { zero.Y = 16; } } else if (!liquidCachePtr5->HasTopEdge) { if (!liquidCachePtr5->HasLeftEdge && !liquidCachePtr5->HasRightEdge) { zero.Y += 48; } else { zero.Y += 16; } } if (zero.Y == 16 && liquidCachePtr5->HasLeftEdge ^ liquidCachePtr5->HasRightEdge && (index2 + rectangle.Y) % 2 == 0) { zero.Y += 16; } liquidCachePtr5->FrameOffset = zero; } else { liquidCachePtr5->HasLeftEdge = false; liquidCachePtr5->HasTopEdge = false; liquidCachePtr5->HasRightEdge = false; liquidCachePtr5->HasBottomEdge = false; } ++liquidCachePtr5; } liquidCachePtr5 += 4; } LiquidRenderer.LiquidCache *liquidCachePtr6 = liquidCachePtr1 + num1; for (int index1 = 2; index1 < rectangle.Width - 2; ++index1) { for (int index2 = 2; index2 < rectangle.Height - 2; ++index2) { if (liquidCachePtr6->HasVisibleLiquid) { liquidCache1 = liquidCachePtr6[-1]; liquidCache2 = liquidCachePtr6[1]; liquidCache3 = liquidCachePtr6[-rectangle.Height]; liquidCache4 = liquidCachePtr6[rectangle.Height]; liquidCachePtr6->VisibleLeftWall = liquidCachePtr6->LeftWall; liquidCachePtr6->VisibleRightWall = liquidCachePtr6->RightWall; liquidCachePtr6->VisibleTopWall = liquidCachePtr6->TopWall; liquidCachePtr6->VisibleBottomWall = liquidCachePtr6->BottomWall; if (liquidCache1.HasVisibleLiquid && liquidCache2.HasVisibleLiquid) { if (liquidCachePtr6->HasLeftEdge) { liquidCachePtr6->VisibleLeftWall = (float)(((double)liquidCachePtr6->LeftWall * 2.0 + (double)liquidCache1.LeftWall + (double)liquidCache2.LeftWall) * 0.25); } if (liquidCachePtr6->HasRightEdge) { liquidCachePtr6->VisibleRightWall = (float)(((double)liquidCachePtr6->RightWall * 2.0 + (double)liquidCache1.RightWall + (double)liquidCache2.RightWall) * 0.25); } } if (liquidCache3.HasVisibleLiquid && liquidCache4.HasVisibleLiquid) { if (liquidCachePtr6->HasTopEdge) { liquidCachePtr6->VisibleTopWall = (float)(((double)liquidCachePtr6->TopWall * 2.0 + (double)liquidCache3.TopWall + (double)liquidCache4.TopWall) * 0.25); } if (liquidCachePtr6->HasBottomEdge) { liquidCachePtr6->VisibleBottomWall = (float)(((double)liquidCachePtr6->BottomWall * 2.0 + (double)liquidCache3.BottomWall + (double)liquidCache4.BottomWall) * 0.25); } } } ++liquidCachePtr6; } liquidCachePtr6 += 4; } LiquidRenderer.LiquidCache *liquidCachePtr7 = liquidCachePtr1 + num1; for (int index1 = 2; index1 < rectangle.Width - 2; ++index1) { for (int index2 = 2; index2 < rectangle.Height - 2; ++index2) { if (liquidCachePtr7->HasLiquid) { liquidCache1 = liquidCachePtr7[-1]; liquidCache2 = liquidCachePtr7[1]; liquidCache3 = liquidCachePtr7[-rectangle.Height]; liquidCache4 = liquidCachePtr7[rectangle.Height]; if (liquidCachePtr7->HasTopEdge && !liquidCachePtr7->HasBottomEdge && liquidCachePtr7->HasLeftEdge ^ liquidCachePtr7->HasRightEdge) { if (liquidCachePtr7->HasRightEdge) { liquidCachePtr7->VisibleRightWall = liquidCache2.VisibleRightWall; liquidCachePtr7->VisibleTopWall = liquidCache3.VisibleTopWall; } else { liquidCachePtr7->VisibleLeftWall = liquidCache2.VisibleLeftWall; liquidCachePtr7->VisibleTopWall = liquidCache4.VisibleTopWall; } } else if (liquidCache2.FrameOffset.X == 16 && liquidCache2.FrameOffset.Y == 32) { if ((double)liquidCachePtr7->VisibleLeftWall > 0.5) { liquidCachePtr7->VisibleLeftWall = 0.0f; liquidCachePtr7->FrameOffset = new Point(0, 0); } else if ((double)liquidCachePtr7->VisibleRightWall < 0.5) { liquidCachePtr7->VisibleRightWall = 1f; liquidCachePtr7->FrameOffset = new Point(32, 0); } } } ++liquidCachePtr7; } liquidCachePtr7 += 4; } LiquidRenderer.LiquidCache *liquidCachePtr8 = liquidCachePtr1 + num1; for (int index1 = 2; index1 < rectangle.Width - 2; ++index1) { for (int index2 = 2; index2 < rectangle.Height - 2; ++index2) { if (liquidCachePtr8->HasLiquid) { liquidCache1 = liquidCachePtr8[-1]; liquidCache2 = liquidCachePtr8[1]; liquidCache3 = liquidCachePtr8[-rectangle.Height]; liquidCache4 = liquidCachePtr8[rectangle.Height]; if (!liquidCachePtr8->HasBottomEdge && !liquidCachePtr8->HasLeftEdge && (!liquidCachePtr8->HasTopEdge && !liquidCachePtr8->HasRightEdge)) { if (liquidCache3.HasTopEdge && liquidCache1.HasLeftEdge) { liquidCachePtr8->FrameOffset.X = Math.Max(4, (int)(16.0 - (double)liquidCache1.VisibleLeftWall * 16.0)) - 4; liquidCachePtr8->FrameOffset.Y = 48 + Math.Max(4, (int)(16.0 - (double)liquidCache3.VisibleTopWall * 16.0)) - 4; liquidCachePtr8->VisibleLeftWall = 0.0f; liquidCachePtr8->VisibleTopWall = 0.0f; liquidCachePtr8->VisibleRightWall = 1f; liquidCachePtr8->VisibleBottomWall = 1f; } else if (liquidCache4.HasTopEdge && liquidCache1.HasRightEdge) { liquidCachePtr8->FrameOffset.X = 32 - Math.Min(16, (int)((double)liquidCache1.VisibleRightWall * 16.0) - 4); liquidCachePtr8->FrameOffset.Y = 48 + Math.Max(4, (int)(16.0 - (double)liquidCache4.VisibleTopWall * 16.0)) - 4; liquidCachePtr8->VisibleLeftWall = 0.0f; liquidCachePtr8->VisibleTopWall = 0.0f; liquidCachePtr8->VisibleRightWall = 1f; liquidCachePtr8->VisibleBottomWall = 1f; } } } ++liquidCachePtr8; } liquidCachePtr8 += 4; } LiquidRenderer.LiquidCache *liquidCachePtr9 = liquidCachePtr1 + num1; fixed(LiquidRenderer.LiquidDrawCache *liquidDrawCachePtr1 = &this._drawCache[0]) fixed(Color * colorPtr1 = &this._waveMask[0]) { LiquidRenderer.LiquidDrawCache *liquidDrawCachePtr2 = liquidDrawCachePtr1; Color *colorPtr2 = colorPtr1; for (int index1 = 2; index1 < rectangle.Width - 2; ++index1) { Color *colorPtr3 = colorPtr2; for (int index2 = 2; index2 < rectangle.Height - 2; ++index2) { if (liquidCachePtr9->HasVisibleLiquid) { float num2 = Math.Min(0.75f, liquidCachePtr9->VisibleLeftWall); float num3 = Math.Max(0.25f, liquidCachePtr9->VisibleRightWall); float num4 = Math.Min(0.75f, liquidCachePtr9->VisibleTopWall); float num5 = Math.Max(0.25f, liquidCachePtr9->VisibleBottomWall); if (liquidCachePtr9->IsHalfBrick && (double)num5 > 0.5) { num5 = 0.5f; } liquidDrawCachePtr2->IsVisible = liquidCachePtr9->HasWall || (!liquidCachePtr9->IsHalfBrick || !liquidCachePtr9->HasLiquid); liquidDrawCachePtr2->SourceRectangle = new Rectangle((int)(16.0 - (double)num3 * 16.0) + liquidCachePtr9->FrameOffset.X, (int)(16.0 - (double)num5 * 16.0) + liquidCachePtr9->FrameOffset.Y, (int)Math.Ceiling(((double)num3 - (double)num2) * 16.0), (int)Math.Ceiling(((double)num5 - (double)num4) * 16.0)); liquidDrawCachePtr2->IsSurfaceLiquid = liquidCachePtr9->FrameOffset.X == 16 && liquidCachePtr9->FrameOffset.Y == 0 && (double)(index2 + rectangle.Y) > Main.worldSurface - 40.0; liquidDrawCachePtr2->Opacity = liquidCachePtr9->Opacity; liquidDrawCachePtr2->LiquidOffset = new Vector2((float)Math.Floor((double)num2 * 16.0), (float)Math.Floor((double)num4 * 16.0)); liquidDrawCachePtr2->Type = liquidCachePtr9->VisibleType; liquidDrawCachePtr2->HasWall = liquidCachePtr9->HasWall; byte num6 = LiquidRenderer.WAVE_MASK_STRENGTH[(int)liquidCachePtr9->VisibleType]; byte num7 = (byte)((uint)num6 >> 1); colorPtr2->R = num7; colorPtr2->G = num7; colorPtr2->B = LiquidRenderer.VISCOSITY_MASK[(int)liquidCachePtr9->VisibleType]; colorPtr2->A = num6; LiquidRenderer.LiquidCache *liquidCachePtr10 = liquidCachePtr9 - 1; if (index2 != 2 && !liquidCachePtr10->HasVisibleLiquid && (!liquidCachePtr10->IsSolid && !liquidCachePtr10->IsHalfBrick)) { *(colorPtr2 - 200) = *colorPtr2; } } else { liquidDrawCachePtr2->IsVisible = false; int index3 = liquidCachePtr9->IsSolid || liquidCachePtr9->IsHalfBrick ? 3 : 4; byte num2 = LiquidRenderer.WAVE_MASK_STRENGTH[index3]; byte num3 = (byte)((uint)num2 >> 1); colorPtr2->R = num3; colorPtr2->G = num3; colorPtr2->B = LiquidRenderer.VISCOSITY_MASK[index3]; colorPtr2->A = num2; } ++liquidCachePtr9; ++liquidDrawCachePtr2; colorPtr2 += 200; } liquidCachePtr9 += 4; colorPtr2 = colorPtr3 + 1; } } LiquidRenderer.LiquidCache *liquidCachePtr11 = liquidCachePtr1; for (int x = rectangle.X; x < rectangle.X + rectangle.Width; ++x) { for (int y = rectangle.Y; y < rectangle.Y + rectangle.Height; ++y) { if ((int)liquidCachePtr11->VisibleType == 1 && liquidCachePtr11->HasVisibleLiquid && Dust.lavaBubbles < 200) { if (this._random.Next(700) == 0) { Dust.NewDust(new Vector2((float)(x * 16), (float)(y * 16)), 16, 16, 35, 0.0f, 0.0f, 0, Color.White, 1f); } if (this._random.Next(350) == 0) { int index = Dust.NewDust(new Vector2((float)(x * 16), (float)(y * 16)), 16, 8, 35, 0.0f, 0.0f, 50, Color.White, 1.5f); Main.dust[index].velocity *= 0.8f; Main.dust[index].velocity.X *= 2f; Main.dust[index].velocity.Y -= (float)this._random.Next(1, 7) * 0.1f; if (this._random.Next(10) == 0) { Main.dust[index].velocity.Y *= (float)this._random.Next(2, 5); } Main.dust[index].noGravity = true; } } ++liquidCachePtr11; } } } if (this.ViscosityFilters == null) { return; } this.ViscosityFilters(this._waveMask, this.GetCachedDrawArea()); }
public unsafe void LoadTextureData(Texture2D _texture, string _name = "") { _textureName = _name; Image img = Raylib.GetTextureData(_texture); //load into an image IntPtr mapPixelsData = Raylib.LoadImageColors(img); //get image data IntPtr Color *mapPixels = (Color *)mapPixelsData.ToPointer(); //IntPtr points to Color data // // Find color DATA going thru width of the texture // ImageData = new Color[img.height * img.width]; for (int x = 0; x < img.width; x++) { for (int y = 0; y < img.height; y++) { ImageData[y * img.width + x] = mapPixels[y * img.width + x]; } } Raylib.UnloadImage(img); // Unload image from RAM float darkness = 1.0f; // // arrange the Data to be in 2d coordinants [x,y] // _textureData = new List <Color[, ]>(); for (int d = 0; d <= DARKNESSLEVLES; d++) { Color[,] ShadeOfDarkData = new Color[img.width, img.height]; for (int x = 0; x < img.width; x++) { for (int y = 0; y < img.height; y++) { var index = x + (img.width * y); //find pixel going across the texture image Color pixel = ImageData[index]; Color tmpPixel = new Color(); // // pack the color bytes into int, shift the bits to get dark color // int tmp = (Byte)pixel.a << 24 | (Byte)(pixel.b / darkness) << 16 | (Byte)(pixel.g / darkness) << 8 | (Byte)(pixel.r / darkness); // // unpack the int back to bytes to update the Color values (with darkness) // var bytes = BitConverter.GetBytes(tmp); tmpPixel.r = bytes[0]; tmpPixel.g = bytes[1]; tmpPixel.b = bytes[2]; tmpPixel.a = bytes[3]; ShadeOfDarkData[x, y] = tmpPixel; } } // // add a shade of dark data // _textureData.Add(ShadeOfDarkData); darkness += 0.0f + (d * 0.0125f) + (d * d * 0.00025f); //change darkness } }
public unsafe static int Main() { // Initialization //-------------------------------------------------------------------------------------- const int screenWidth = 800; const int screenHeight = 450; InitWindow(screenWidth, screenHeight, "raylib [models] example - first person maze"); // Define the camera to look into our 3d world Camera3D camera = new Camera3D(new Vector3(0.2f, 0.4f, 0.2f), new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f), 45.0f, CameraType.CAMERA_PERSPECTIVE); Image imMap = LoadImage("resources/cubicmap.png"); // Load cubicmap image (RAM) Texture2D cubicmap = LoadTextureFromImage(imMap); // Convert image to texture to display (VRAM) Mesh mesh = GenMeshCubicmap(imMap, new Vector3(1.0f, 1.0f, 1.0f)); Model model = LoadModelFromMesh(mesh); // NOTE: By default each cube is mapped to one part of texture atlas Texture2D texture = LoadTexture("resources/cubicmap_atlas.png"); // Load map texture // Set map diffuse texture Utils.SetMaterialTexture(ref model, 0, MAP_ALBEDO, ref texture); // Get map image data to be used for collision detection IntPtr mapPixelsData = GetImageData(imMap); UnloadImage(imMap); // Unload image from RAM Vector3 mapPosition = new Vector3(-16.0f, 0.0f, -8.0f); // Set model position Vector3 playerPosition = camera.position; // Set player position SetCameraMode(camera, CAMERA_FIRST_PERSON); // Set camera mode SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- // Main game loop while (!WindowShouldClose()) // Detect window close button or ESC key { // Update //---------------------------------------------------------------------------------- Vector3 oldCamPos = camera.position; // Store old camera position UpdateCamera(ref camera); // Update camera // Check player collision (we simplify to 2D collision detection) Vector2 playerPos = new Vector2(camera.position.X, camera.position.Z); float playerRadius = 0.1f; // Collision radius (player is modelled as a cilinder for collision) int playerCellX = (int)(playerPos.X - mapPosition.X + 0.5f); int playerCellY = (int)(playerPos.Y - mapPosition.Z + 0.5f); // Out-of-limits security check if (playerCellX < 0) { playerCellX = 0; } else if (playerCellX >= cubicmap.width) { playerCellX = cubicmap.width - 1; } if (playerCellY < 0) { playerCellY = 0; } else if (playerCellY >= cubicmap.height) { playerCellY = cubicmap.height - 1; } // Check map collisions using image data and player position // TODO: Improvement: Just check player surrounding cells for collision for (int y = 0; y < cubicmap.height; y++) { for (int x = 0; x < cubicmap.width; x++) { Color *mapPixels = (Color *)mapPixelsData.ToPointer(); if ((mapPixels[y * cubicmap.width + x].r == 255) && // Collision: white pixel, only check R channel (CheckCollisionCircleRec(playerPos, playerRadius, new Rectangle(mapPosition.X - 0.5f + x * 1.0f, mapPosition.Z - 0.5f + y * 1.0f, 1.0f, 1.0f)))) { // Collision detected, reset camera position camera.position = oldCamPos; } } } //---------------------------------------------------------------------------------- // Draw //---------------------------------------------------------------------------------- BeginDrawing(); ClearBackground(RAYWHITE); BeginMode3D(camera); DrawModel(model, mapPosition, 1.0f, WHITE); // Draw maze map // DrawCubeV(playerPosition, new Vector3( 0.2f, 0.4f, 0.2f ), RED); // Draw player EndMode3D(); DrawTextureEx(cubicmap, new Vector2(GetScreenWidth() - cubicmap.width * 4 - 20, 20), 0.0f, 4.0f, WHITE); DrawRectangleLines(GetScreenWidth() - cubicmap.width * 4 - 20, 20, cubicmap.width * 4, cubicmap.height * 4, GREEN); // Draw player position radar DrawRectangle(GetScreenWidth() - cubicmap.width * 4 - 20 + playerCellX * 4, 20 + playerCellY * 4, 4, 4, RED); DrawFPS(10, 10); EndDrawing(); //---------------------------------------------------------------------------------- } // De-Initialization //-------------------------------------------------------------------------------------- UnloadTexture(cubicmap); // Unload cubicmap texture UnloadTexture(texture); // Unload map texture UnloadModel(model); // Unload map model CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- return(0); }
public ImageData(int width, int height) { Stride = width * sizeof(Color); BufferSize = Stride * height; Data = (Color*)System.Runtime.InteropServices.Marshal.AllocHGlobal(BufferSize); Width = width; Height = height; widthSub1 = width - 1; heightSub1 = height - 1; lastValidAdress = Data + BufferSize - 1; }