private void GameCanvas_Paint(object sender, PaintEventArgs e) { long sampleBefore = Utilities.PerformanceCounter.Current; BitmapBunch currentBunch = this.bitmapBunch; BitmapDefinition bitmapDefinition = currentBunch.GetNextRenderBitmap(); Bitmap bitmapToRender = bitmapDefinition == null ? null : bitmapDefinition.Bitmap; if (bitmapToRender == null) { bitmapToRender = currentBunch.GetBlackBitmap().Bitmap; } Rectangle destRect = new Rectangle(0, 0, this.Width, this.Height); Graphics g = e.Graphics; g.InterpolationMode = this.scalingMode; var crop = bitmapDefinition == null ? new BitmapCrop() : bitmapDefinition.Crop; Rectangle sourceRect = new Rectangle( crop.Left, crop.Top, currentBunch.BitmapWidth - crop.Left - crop.Right, currentBunch.BitmapHeight - crop.Top - crop.Bottom); g.DrawImage(bitmapToRender, destRect, sourceRect, GraphicsUnit.Pixel); // If we're taking longer than half of the scan time to draw, do a frame skip. if ((Utilities.PerformanceCounter.Current - sampleBefore) * 2 > scanDrawTime) { this.isGraphicsIntensive = true; this.frameSkip = 1; } else { this.isGraphicsIntensive = false; this.frameSkip = 0; } }
protected void Render() { /////////////////////////// // Update texture. BitmapBunch currentBunch = this.bitmapBunch; BitmapDefinition bitmapDefinition = currentBunch.GetNextRenderBitmap(); if (bitmapDefinition == null) { bitmapDefinition = currentBunch.GetBlackBitmap(); } Bitmap bitmapToRender = bitmapDefinition == null ? null : bitmapDefinition.Bitmap; Surface textureSurface = this.texture.GetSurfaceLevel(0); DataRectangle dataRect = textureSurface.LockRectangle(LockFlags.None); BitmapData bitmapData = bitmapToRender.LockBits(new Rectangle(0, 0, bitmapToRender.Width, bitmapToRender.Height), ImageLockMode.ReadOnly, bitmapToRender.PixelFormat); { DataStream stream = dataRect.Data; int stride = bitmapData.Stride; int bitDepth = bitmapData.Stride / bitmapData.Width; int sourceWidth = bitmapData.Width; IntPtr sourcePtr = bitmapData.Scan0; for (int y = 0; y < bitmapData.Height; y++) { stream.WriteRange(sourcePtr, stride); stream.WriteRange(this.blackRowPtr, 4); // This is okay, texture width always exceeds bitmap width by a lot stream.Position += ((textureWidth - sourceWidth) * bitDepth) - 4; sourcePtr += stride; } stream.WriteRange(this.blackRowPtr, (sourceWidth + 1) * 4); } bitmapToRender.UnlockBits(bitmapData); textureSurface.UnlockRectangle(); /////////////////////////// // Set up scaling algorithm. TextureFilter filter = this.ImageSmoothing ? TextureFilter.Linear : TextureFilter.Point; this.device.SetSamplerState(0, SamplerState.MinFilter, filter); this.device.SetSamplerState(0, SamplerState.MagFilter, filter); /////////////////////////// // Update drawing size dependent on cropping and resolution. int bitmapWidth = bitmapToRender.Width; int bitmapHeight = bitmapToRender.Height; float bottom = bitmapHeight / (float)textureHeight; float right = bitmapWidth / (float)textureWidth; var crop = bitmapDefinition == null ? new BitmapCrop() : bitmapDefinition.Crop; Size renderedSize = new Size(); renderedSize.Width = bitmapWidth - crop.Left - crop.Right; renderedSize.Height = bitmapHeight - crop.Top - crop.Bottom; if (this.BeforeRender != null) { this.BeforeRender(renderedSize); } float top = (crop.Top / (float)bitmapHeight) * bottom; float left = (crop.Left / (float)bitmapWidth) * right; right = right - (crop.Right / (float)bitmapWidth) * right; bottom = bottom - (crop.Bottom / (float)bitmapHeight) * bottom; var vertexStream = this.vertexBuffer.Lock(0, 0, LockFlags.None); vertexStream.WriteRange(new[] { new TexturedVertex(new Vector3(-1.0f, 1.0f, 0.0f), new Vector2(left + .0001f, top + .0001f)) , new TexturedVertex(new Vector3(1.0f, -1.0f, 0.0f), new Vector2(right + .0001f, bottom + .0001f)) , new TexturedVertex(new Vector3(-1.0f, -1.0f, 0.0f), new Vector2(left + .0001f, bottom + .0001f)) , new TexturedVertex(new Vector3(1.0f, -1.0f, 0.0f), new Vector2(right + .0001f, bottom + .0001f)) , new TexturedVertex(new Vector3(-1.0f, 1.0f, 0.0f), new Vector2(left + .0001f, top + .0001f)) , new TexturedVertex(new Vector3(1.0f, 1.0f, 0.0f), new Vector2(right + .0001f, top + .0001f)) }); vertexBuffer.Unlock(); ////////////////////// // Draw scene. this.device.Clear(ClearFlags.Target, colorBlack, 1f, 0); this.device.BeginScene(); this.device.SetTexture(0, this.texture); this.device.SetStreamSource(0, vertexBuffer, 0, Marshal.SizeOf(typeof(TexturedVertex))); this.device.VertexDeclaration = this.vertexDeclaration; this.device.DrawPrimitives(PrimitiveType.TriangleList, 0, 2); this.device.EndScene(); this.device.Present(); }