static uint[] decodeRgbIcon(byte[] payload, CSize size) { // https://devblogs.microsoft.com/oldnewthing/20101019-00/?p=12503 int totalPixels = size.cx * size.cy; int maskLineDwords = (size.cx + 31) / 32; int maskStrideBytes = maskLineDwords * 4; int bytesMask = size.cy * maskStrideBytes; int cbHeader = Marshal.SizeOf <BITMAPINFOHEADER>(); if (payload.Length != (totalPixels * 4) + bytesMask + cbHeader) { throw new ArgumentException("Size doesn't match"); } uint[] result = new uint[totalPixels]; // Copy the RGB values payload.AsSpan() .Slice(cbHeader, totalPixels * 4) .castSpan <uint>() .CopyTo(result.AsSpan()); // Apply the alpha mask, it's 1 bit / pixel. ReadOnlySpan <byte> mask = payload.AsSpan().Slice(cbHeader + totalPixels * 4); applyMask(result.AsSpan(), size, mask, maskStrideBytes); return(result); }
public void setWindowSize(CSize size) { // ConsoleLogger.logDebug( "sCursorPosition.setWindowSize: {0}", size ); positionMulX = 2.0 / size.cx; positionMulY = 2.0 / size.cy; updateSize(); }
internal static void applyMask(Span <uint> pixels, CSize size, ReadOnlySpan <byte> mask, int maskStrideBytes) { if (0 == (size.cx % 8)) { if (0 == (size.cx % 32)) { // No padding whatsoever int destOffset = 0; for (int i = 0; i < mask.Length; i++, destOffset += 8) { applyMask(pixels, destOffset, mask[i]); } } else { // There is padding, but it's whole count of bytes int maskBytesPerLine = size.cx / 8; int sourceOffset = 0; int destOffset = 0; for (int y = 0; y < size.cy; y++, sourceOffset += maskStrideBytes) { for (int x = 0; x < maskBytesPerLine; x++, destOffset += 8) { applyMask(pixels, destOffset, mask[sourceOffset + x]); } } } } else { // There is padding, and the last few pixels have less than 8 payload bits per line. throw new NotImplementedException("The library only supports cursors with width being a multiple of 8px"); } }
protected void drawText(string text, Font font, ref Rect rectangle, SolidColorData foreground, SolidColorData background) { getCurrentTransform(out Matrix3x2 tform, out float pixel); var transformedRect = tform.transformRectangle(ref rectangle); if (!DrawDevice.clipSpaceRectangle.intersects(ref transformedRect) || foreground.brushType == eBrushType.Null) { return; } flushIfNeeded(1); IntMatrix? intMtx; CPoint startingPoint = transformToPhysicalPixels(rectangle.topLeft, out intMtx); CSize size = (rectangle.size / pixel).roundToInt().asSize; CRect textRect = new CRect(startingPoint, size); eTextRendering trs = textRenderingStyle(intMtx); Order o = drawMeshes.addText(ref currentZ, text, font, ref textRect, foreground.paletteIndex, trs); bool opaqueBackground = background.brushType == eBrushType.Opaque; passFlags |= eRenderPassFlags.Transparent; calls.add(sDrawCall.drawText(o, ref tform, foreground.paletteIndex, background.paletteIndex, opaqueBackground, pixel, trs)); }
void switchToTrueFullScreen(iDiligentWindow window) { if (window.windowState == eShowWindow.TrueFullscreen) { // Already in true full screen mode. Switch to maximized borderless. window.moveWindow(eShowWindow.Fullscreen); return; } iGraphicsEngine graphicsEngine = Render.graphicsEngine; using (var gpuEnum = graphicsEngine.createGpuEnumerator()) using (var gpu = gpuEnum.openDefaultAdapter()) using (var connector = gpu.openDefaultConnector()) { var format = context.swapChainFormats.color; if (format == Diligent.Graphics.TextureFormat.Unknown) { throw new ApplicationException("The swap chain was not created"); } connector.setSurfaceFormat(format); // Debug code below // Console.WriteLine( "Following is available:\n{0}", string.Join( "\n", connector.getAllModes() ) ); // connector.enumModes(); CSize trueFullScreenRez = new CSize(1920, 1080); if (!connector.findVideoMode(out var mode, ref trueFullScreenRez)) { throw new ApplicationException("The default monitor doesn't support FullHD"); } window.fullScreen(connector, ref mode); } }
private void btnSave_Click(object sender, EventArgs e) { CSize oCSize = Getformdata(); CSizeBO oCSizeBO = new CSizeBO(); CResult oresult = new CResult(); if (validatedata()) { if (txtSizeid.Text.Trim() != string.Empty) { if (DialogResult.OK == MessageBox.Show("Are you wanted to upadte " + txtSIZECode.Text + " ?", "Confirmation!", MessageBoxButtons.OKCancel)) { oresult = oCSizeBO.Update(oCSize); } } else { if (!IsUpdateMode) { oresult = oCSizeBO.Create(oCSize); } } if (oresult.IsSuccess) { LoadSizeName(); ClearFormData(); } else { MessageBox.Show("Not Saved" + oresult.ErrMsg + ""); } } }
public static int find(MkvMediaFile file, TrackEntry track, CSize size) { ulong trackNum = track.trackNumber; int maxFound = 0; for (int i = 0; i < 166; i++) { Cluster firstCluster = file.segment.cluster[i].loadCluster(file.stream); int extraBytes = track.extraBytesCount(); int clusterMax = 0; foreach (var b in firstCluster.allBlobs()) { if (b.trackNumber != trackNum) { continue; } // Don't bother decoding NALUs. We don't need precise number, just a reasonable upper estimate. clusterMax = Math.Max(clusterMax, (int)b.length + extraBytes); } Console.WriteLine("{0}\t{1}", i, clusterMax); maxFound = Math.Max(maxFound, clusterMax); } return(maxFound); }
public CRect(CPoint topLeft, CSize size) { left = topLeft.x; top = topLeft.y; right = topLeft.x + size.cx; bottom = topLeft.y + size.cy; }
/// <summary>Create rectangle in units from size in pixels, the top left corner being [ 0, 0 ]</summary> public Rect fullRectUnits(CSize sizePixels) { Vector2 bottomRight = new Vector2(sizePixels.cx, sizePixels.cy); bottomRight *= mulUnits; return(new Rect(Vector2.Zero, bottomRight)); }
IBuffer getTextCBuffer() { if (null != m_staticCBufferForText) { return(m_staticCBufferForText); } ConstantsBufferText data = new ConstantsBufferText(); data.pixelSizeAndDpiScaling = pixelSizeAndDpiScaling; DrawDevice dev = (DrawDevice)context.drawDevice; CSize atlasSize = dev.fontTextures.grayscale.layerSize; data.textureAtlasSize.X = atlasSize.cx; data.textureAtlasSize.Y = atlasSize.cy; atlasSize = dev.fontTextures.cleartype.layerSize; data.textureAtlasSize.Z = atlasSize.cx; data.textureAtlasSize.W = atlasSize.cy; IBuffer ib; using (var device = context.renderContext.device) ib = device.CreateImmutableUniformBuffer(ref data, "Text cbuffer"); m_staticCBufferForText = ib; return(ib); }
protected override void render(ITextureView swapChainRgb, ITextureView swapChainDepthStencil) { iDrawDevice dev = context.drawDevice; Rect rect = new Rect(Vector2.Zero, dev.viewportSize); rect = rect.deflate(32, 32); using (var dc = dev.begin(swapChainRgb, swapChainDepthStencil, backgroundColor)) { Matrix3x2 imageRotation = rotationMatrix(dev.viewportSize, -0.11f); Matrix3x2 trans = Matrix3x2.CreateTranslation(0, -70); dc.transform.push(imageRotation * trans); dc.drawText("Hello World", comicSans.font, rect, black, background); dc.transform.pop(); // rect.top += dev.dpiScaling.mulUnits * comicSans.font.lineHeightPixels + 12; rect.top += dev.dpiScaling.mulUnits * comicSans.font.lineHeightPixels + 24; CSize lipsumSize = dc.measureText(lipsum, rect.width, defaultSerif.font); dc.fillRectangle(pixelsRectangle(dev, rect.topLeft, lipsumSize), white); dc.drawText(lipsum, defaultSerif.font, rect, black, white); return; CSize consoleSize = dc.measureConsoleText(lipsum, 80, 14); // Apparently, when FreeType measures fonts it allocates height on the top for diacritic combining characters. Vector2 paddingTopLeft = new Vector2(12, 2); Vector2 paddingBottomRight = new Vector2(12, 12); Vector2 size = consoleSize.asFloat * dev.dpiScaling.mulUnits; Rect consoleRect = new Rect(rect.topLeft, rect.topLeft + size + paddingTopLeft + paddingBottomRight); dc.fillRectangle(consoleRect, black); dc.drawConsoleText(lipsum, 80, 14, rect.topLeft + paddingTopLeft, green, black); } }
internal VideoTextureDesc(TextureFormat lumaFormat, TextureFormat chromaFormat, CSize lumaSize, CSize chromaSize) { this.lumaFormat = lumaFormat; this.chromaFormat = chromaFormat; this.lumaSize = lumaSize; this.chromaSize = chromaSize; }
public MappedOutput(int idx, int length, IntPtr ptr, int stride, CSize size) { bufferIndex = idx; mappedLength = length; mappedAddress = ptr; this.stride = stride; this.size = size; }
static Rect computeDefaultClipRectangle(CSize size) { float marginPixels = Math.Min(size.cx / 8, size.cy / 8); Vector2 sizeFloats = size.asFloat; Vector2 marginClipSpaceUnits = (2.0f * sizeFloats) / sizeFloats; return(new Rect(-Vector2.One - marginClipSpaceUnits, Vector2.One + marginClipSpaceUnits)); }
static byte[] decodeMonochromeIcon(byte[] payload, CSize size) { int totalPixels = size.cx * size.cy; int maskLineDwords = (size.cx + 31) / 32; int maskStrideBytes = maskLineDwords * 4; int bytesMask = size.cy * maskStrideBytes; int cbHeader = Marshal.SizeOf <BITMAPINFOHEADER>(); // 8 is the color table, immediately after the header if (payload.Length != cbHeader + (bytesMask * 2) + 8) { throw new ArgumentException("Size doesn't match"); } byte[] image = new byte[totalPixels]; Span <byte> palette = stackalloc byte[4]; { Span <uint> colorTable = stackalloc uint[2]; payload.AsSpan() .Slice(cbHeader, 8) .castSpan <uint>() .CopyTo(colorTable); ePalette pal = getPalette(colorTable); decodePalette(pal, palette); } ReadOnlySpan <byte> bits = payload.AsSpan() .Slice(cbHeader + 8, bytesMask); ReadOnlySpan <byte> mask = payload.AsSpan() .Slice(cbHeader + 8 + bytesMask, bytesMask); if (0 == (size.cx % 32)) { // No padding whatsoever decodeMonochrome(image.AsSpan(), bits, mask, palette, totalPixels); } else { // There is some padding Span <byte> imageSpan = image.AsSpan(); int maskBytesPerLine = (size.cx + 7) / 8; int destOffset = 0; int sourceOffset = 0; for (int y = 0; y < size.cy; y++, destOffset += size.cx, sourceOffset += maskStrideBytes) { Span <byte> destSpan = imageSpan.Slice(destOffset, size.cx); ReadOnlySpan <byte> lineBits = bits.Slice(sourceOffset, maskBytesPerLine); ReadOnlySpan <byte> lineMask = mask.Slice(sourceOffset, maskBytesPerLine); decodeMonochrome(destSpan, lineBits, lineMask, palette, size.cx); } } return(image); }
void onResized(CSize newSize, double dpi) { dpiScaling = new DpiScaling(dpi); d2dContext.dpiScaling = dpi; viewportSize = new Vector2((float)(newSize.cx / dpi), (float)(newSize.cy / dpi)); foreach (var sub in resized) { sub(viewportSize, dpi); } }
public AniBitmaps(Stream stream, AniFile.Frame[] frames, int formatIndex) { size = frames[0].images[formatIndex].size; int countFrames = frames.Length; pixelsPerFrame = size.cx * size.cy; data = new uint[pixelsPerFrame * countFrames]; Span <uint> destSpan = data.AsSpan(); int streamOffset = 0; int bihSize = Marshal.SizeOf <BITMAPINFOHEADER>(); for (int i = 0; i < frames.Length; i++) { AniFile.Payload src = frames[i].payloads[formatIndex]; stream.skip(src.offset - streamOffset); streamOffset = src.offset; BITMAPINFOHEADER header = stream.read <BITMAPINFOHEADER>(); streamOffset += bihSize; Debug.Assert(bihSize == header.biSize); if (header.biWidth != size.cx) { throw new ArgumentException("Size in BMP doesn't match"); } Span <uint> destFrame = destSpan.Slice(i * pixelsPerFrame, pixelsPerFrame); if (header.biCompression == BitmapCompressionMode.BI_RGB && header.biHeight == size.cy * 2) { decodeRgbIcon(stream, destFrame, ref streamOffset, ref header, src.size); } else { throw new NotImplementedException(); } } bool flipBgr = RuntimeEnvironment.operatingSystem != eOperatingSystem.Windows; GraphicsUtils.premultiplyAlpha(data, flipBgr); this.frames = new TextureSubResData[countFrames]; pinned = GCHandle.Alloc(data, GCHandleType.Pinned); IntPtr pointer = pinned.AddrOfPinnedObject(); for (int i = 0; i < countFrames; i++) { TextureSubResData srd = new TextureSubResData(); srd.pData = pointer + (i * pixelsPerFrame * 4); srd.Stride = size.cx * 4; srd.DepthStride = pixelsPerFrame * 4; this.frames[i] = srd; } }
void onResized(CSize newSize, double dpi) { dpiScaling = new DpiScaling(dpi); viewportSize = new Vector2((float)(newSize.cx / dpi), (float)(newSize.cy / dpi)); rootTransform.M11 = (float)(2.0 / viewportSize.X); rootTransform.M22 = (float)(-2.0 / viewportSize.Y); foreach (var sub in resized) { sub(viewportSize, dpi); } swapChain?.destroyTargets(); }
private CItem Getformdata() { CItem oitem = new CItem(); CItemType oItemType = (CItemType)ddlItemType.SelectedItem; CItemGroup oitemgroup = (CItemGroup)ddlGroupNAme.SelectedItem; CUOM oUOM = (CUOM)ddlUOM.SelectedItem; CSize oSize = (CSize)cmbItemSize.SelectedItem; oitem.Item_OID = txthiddenitemid.Text; oitem.Item_Branch = currentBranch.CompBrn_Code; oitem.Item_GroupID = oitemgroup.Catg_OID; oitem.Item_TypeID = oItemType.ITyp_OID; oitem.Item_UOMID = oUOM.UOM_OID; oitem.Item_Code = txtItemCode.Text.Trim(); if (cmbItemSize.SelectedItem != null && txtICode.Text != "") { oitem.Item_ItemName = txtItemName.Text + "-" + txtICode.Text + "-- " + oSize.Size_Name; } if (txtICode.Text != "") { oitem.Item_ItemName = txtItemName.Text + "-" + txtICode.Text; } else { oitem.Item_ItemName = txtItemName.Text; } //oitem.Item_ItemName = txtItemName.Text; oitem.Item_Pprice = float.Parse(txtpprice.Text); oitem.Remarks = txtRemarks.Text; oitem.Item_RQTY = float.Parse(txtRQTY.Text); oitem.Item_Sprice = float.Parse(txtSprice.Text); oitem.Creator = currentUser.User_OID; oitem.CreationDate = DateTime.Now; oitem.UpdateBy = currentUser.User_OID; oitem.UpdateDate = DateTime.Now; oitem.CreationDate = DateTime.Now.Date; if (chkIsActive.Checked) { oitem.IsActive = "Y"; } else { oitem.IsActive = "N"; } oitem.Item_Priority = int.Parse(nupdnItemPriority.Text.Trim()); oitem.ItemImage = this.ItemImage; return(oitem); }
public CResult Update(CSize oCSize) { oResult = new CResult(); conn = oConnManager.GetConnection(out s_DBError); if (conn != null) { SqlCommand cmd = new SqlCommand(); cmd.Connection = conn; cmd.Transaction = oConnManager.BeginTransaction(); try { cmd.CommandText = "sp_Size_Update"; cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.AddWithValue("@Size_OID", oCSize.Size_OID); cmd.Parameters.AddWithValue("@Size_Code", oCSize.Size_Code); cmd.Parameters.AddWithValue("@Size_Name", oCSize.Size_Name); cmd.Parameters.AddWithValue("@Size_Branch", oCSize.Size_Branch); cmd.Parameters.AddWithValue("@Creator", oCSize.Creator); cmd.Parameters.AddWithValue("@CreationDate", oCSize.CreationDate); cmd.Parameters.AddWithValue("@UpdateBy", oCSize.UpdateBy); cmd.Parameters.AddWithValue("@UpdateDate", oCSize.UpdateDate); cmd.Parameters.AddWithValue("@IsActive", oCSize.IsActive); cmd.Parameters.AddWithValue("@Remarks", oCSize.Remarks); cmd.ExecuteNonQuery(); oConnManager.Commit(); oResult.IsSuccess = true; } catch (SqlException e) { string sRollbackError = oConnManager.Rollback(); oResult.IsSuccess = false; oResult.ErrMsg = sRollbackError.Equals("") ? oConnManager.GetErrorMessage(e) : sRollbackError; } finally { oConnManager.Close(); } } else { oResult.IsSuccess = false; oResult.ErrMsg = s_DBError; } return(oResult); }
private void LLSIZEType_SelectedIndexChanged(object sender, EventArgs e) { if (LLSIZEType.SelectedIndex != -1) { if (LLSIZEType.Items.Count > 0) { CSize oCSize = (CSize)LLSIZEType.SelectedItem; txtSizeid.Text = oCSize.Size_OID.ToString(); txtSIZECode.Text = oCSize.Size_Code; txtSIZEName.Text = oCSize.Size_Name; txtRemarks.Text = oCSize.Remarks; FormControlMode(1); } } }
internal VideoSampleEntry(Mp4Reader reader, ref int bytesLeft) { var ss = reader.readStructure <Structures.VisualSampleEntry>(); bytesLeft -= Marshal.SizeOf <Structures.VisualSampleEntry>(); sizePixels = ss.size; pixelsPerInch = ss.resolution; framesPerSample = ss.frameCount; unsafe { byte *comp = ss.compressorname; compressorName = StringMarshal.copy(comp, 32); } }
public static ITextureView load(IRenderDevice device, byte[] payload, CSize size) { byte[] data = decodeMonochromeIcon(payload, size); TextureDesc desc = new TextureDesc(false); desc.Type = ResourceDimension.Tex2d; desc.Size = size; desc.Format = TextureFormat.R8Unorm; desc.Usage = Usage.Static; desc.BindFlags = BindFlags.ShaderResource; ITexture texture = device.CreateTexture(ref desc, data, size.cx, "Monochrome cursor"); return(texture.GetDefaultView(TextureViewType.ShaderResource)); }
public RenderBase(IRenderDevice device, CSize renderTargetSize, SwapChainFormats formats, Vector4 borderColor, sDecodedVideoSize videoSize) { this.videoSize = videoSize; // Create vertex buffer vertexBuffer = createVideoVertexBuffer(device, renderTargetSize, ref videoSize); // Create pipeline state var pso = new PipelineStateDesc(false); pso.GraphicsPipeline.DepthStencilDesc.DepthEnable = false; pso.GraphicsPipeline.PrimitiveTopology = PrimitiveTopology.TriangleList; pso.GraphicsPipeline.NumRenderTargets = 1; pso.GraphicsPipeline.setRTVFormat(0, formats.color); pso.GraphicsPipeline.DSVFormat = formats.depth; pso.ResourceLayout.DefaultVariableType = ShaderResourceVariableType.Static; var compiler = device.GetShaderFactory(); iStorageFolder assets = StorageFolder.embeddedResources(System.Reflection.Assembly.GetExecutingAssembly(), resourceFolder); using (var psf = device.CreatePipelineStateFactory()) { psf.setName("Video PSO"); setupVideoInputLayout(psf); using (var vs = compiler.compileHlslFile(assets, "VideoVS.hlsl", ShaderType.Vertex)) psf.graphicsVertexShader(vs); (string uvMin, string uvMax) = videoUvCroppedRect(ref videoSize); string colorString = Utils.printFloat4(borderColor); using (var ps = compilePixelShader(compiler, assets, uvMin, uvMax, colorString)) psf.graphicsPixelShader(ps); psf.layoutVariable(ShaderType.Pixel, ShaderResourceVariableType.Dynamic, varTexture); var sampler = new SamplerDesc(false) { MipFilter = FilterType.Point, }; psf.layoutStaticSampler(ShaderType.Pixel, ref sampler, varTexture); psf.apply(ref pso); pipelineState = device.CreatePipelineState(ref pso); } // Create resource binding and cache the variable, we gonna need both on every frame rendered binding = pipelineState.CreateShaderResourceBinding(true); textureVariable = binding.GetVariableByName(ShaderType.Pixel, varTexture); }
private CSize Getformdata() { CSize oSize = new CSize(); oSize.Size_OID = txtSizeid.Text.Trim(); oSize.Size_Branch = currentBranch.CompBrn_Code; oSize.Size_Code = txtSIZECode.Text.Trim(); oSize.Size_Name = txtSIZEName.Text.Trim(); oSize.Remarks = txtRemarks.Text.Trim(); oSize.CreationDate = DateTime.Now; oSize.Creator = currentUser.User_OID; oSize.UpdateBy = currentUser.User_OID; oSize.UpdateDate = DateTime.Now; oSize.IsActive = "Y"; return(oSize); }
/// <summary>Create and set fields to their defaults</summary> public TextureDesc(bool unused) { baseStruct = new DeviceObjectAttribs(true); Type = ResourceDimension.Undefined; Size = new CSize(0, 0); ArraySizeOrDepth = 1; Format = TextureFormat.Unknown; MipLevels = 1; SampleCount = 1; Usage = Usage.Default; BindFlags = BindFlags.None; CPUAccessFlags = CpuAccessFlags.None; MiscFlags = MiscTextureFlags.None; ClearValue = new OptimizedClearValue(true); CommandQueueMask = 1; }
/// <summary>Decode frames of the specified format index, and upload them to VRAM.</summary> public AnimatedCursorTexture load(IRenderDevice device, Stream stream, string name, int formatIndex = 0) { if (formatIndex < 0 || formatIndex >= formats.Length) { throw new ArgumentOutOfRangeException(); } iTextureArrayData data; switch (formats[formatIndex].format) { case eFormat.Bitmap: data = new AniBitmaps(stream, this.frames, formatIndex); break; default: throw new NotImplementedException(); } CSize size = formats[formatIndex].size; int frames = data.data.Length; ITexture textureArray; using ( data ) { TextureDesc desc = new TextureDesc(false); desc.Type = ResourceDimension.Tex2dArray; desc.Size = size; desc.ArraySizeOrDepth = (uint)frames; desc.Format = data.format; desc.Usage = Usage.Static; desc.BindFlags = BindFlags.ShaderResource; textureArray = device.CreateTexture(ref desc, data.data, (uint)frames, name); } ITextureView view = textureArray.GetDefaultView(TextureViewType.ShaderResource); double ticks = TimeSpan.TicksPerSecond; ticks /= 60; ticks *= header.JifRate; ticks = Math.Round(ticks); TimeSpan duration = TimeSpan.FromTicks((long)ticks); CPoint hotspot = this.frames[0].images[formatIndex].hotspot; return(new AnimatedCursorTexture(view, size, hotspot, frames, duration)); }
/// <summary>Cropped video rectangle in clip space units</summary> static RectD videoRectangle(CSize pxRenderTarget, ref sDecodedVideoSize videoSize) { CSize pxVideo = videoSize.cropRect.size; if (pxVideo.cx * pxRenderTarget.cy >= pxVideo.cy * pxRenderTarget.cx) { // scale X to fit, center vertically double h = mulDiv(pxVideo.cy, pxRenderTarget.cx, pxVideo.cx, pxRenderTarget.cy); return(new RectD(-1, -h, 1, h)); } else { // scale Y to fit, center horizontally double w = mulDiv(pxVideo.cx, pxRenderTarget.cy, pxVideo.cy, pxRenderTarget.cx); return(new RectD(-w, -1, w, 1)); } }
/// <summary>Create immutable VB with the full-screen triangle with cropping-included texture coordinates</summary> public static IBuffer createVideoVertexBuffer(IRenderDevice device, CSize renderTargetSize, ref sDecodedVideoSize videoSize) { Span <sVideoVertex> data = stackalloc sVideoVertex[3]; produceVertices(data, renderTargetSize, ref videoSize); BufferDesc desc = new BufferDesc(false) { uiSizeInBytes = 16 * 3, BindFlags = BindFlags.VertexBuffer, Usage = Usage.Static, }; ReadOnlySpan <sVideoVertex> readOnly = data; return(device.CreateBuffer(desc, readOnly, "Video VB")); }
static void encodeScreenshot(TextureFormat format, CSize size, MappedTextureSubresource mapped, string dest) { // Pick the right set of PNG options ePngOptions options; switch (format) { case TextureFormat.Rgba8Sint: case TextureFormat.Rgba8Snorm: case TextureFormat.Rgba8Typeless: case TextureFormat.Rgba8Unorm: options = ePngOptions.None; break; case TextureFormat.Rgba8UnormSrgb: options = ePngOptions.SrgbMetadata; break; case TextureFormat.Bgra8Typeless: case TextureFormat.Bgrx8Typeless: case TextureFormat.Bgra8Unorm: case TextureFormat.Bgrx8Unorm: options = ePngOptions.FlipChannels; break; case TextureFormat.Bgra8UnormSrgb: case TextureFormat.Bgrx8UnormSrgb: options = ePngOptions.FlipChannels | ePngOptions.SrgbMetadata; break; default: throw new ArgumentException($"{ format } textures can’t be PNG encoded. Do something else, e.g. DDS."); } // No idea why, but identical C# and C++ code produces good images on Windows and vertically flipped ones on Linux. // Need to pass a bit to encoder to distinguish. // Fortunately, LibPNG takes an array of row pointers and thus doesn't care about rows RAM layout, the implementation doesn't need to make copies. if (RuntimeEnvironment.runningLinux) { options |= ePngOptions.FlipRows; } // Finally, write the PNG using (var fs = File.Create(dest)) GraphicsUtils.encodeRgbaPng(size, mapped, options, fs); }