UPDATE: Since originally asking this question, I have changed my approach slightly. Rather than drawing using System.Drawing.Graphics
, I am hosting a WPF user control with an InkCanvas. That does everything I need it to do. The problem still is that I cannot get the background of the ElementHost to be transparent. I see the same black square I was seeing before.
ORIGINAL QUESTION: I have a C# WinForms application that renders a 3D scene using Ogre3D to a panel in the form using that panel's handle. I am trying to add the ability to draw on top of that scene (imagine Madden drawing over the TV screen) using C#'s System.Drawing.Graphics
.
I'm using the BufferedGraphics
class to do this. As a test, I'm trying to simply draw a rectangle on top of the 3D scene. Below is a snippet of the code I'm using to set everything up.
namespace TestApp
{
public partial class TestForm
{
private BufferedGraphics graphicsBuffer;
private BufferedGraphicsContext bufferContext = BufferedGraphicsManager.Current;
public TestForm()
{
InitializeComponent();
UpdateGraphicsBuffer();
}
private void UpdateGraphicsBuffer()
{
bufferContext.MaximumBuffer = new Size(panelRender.Width + 1, panelRender.Height + 1);
graphicsBuffer = bufferContext.Allocate(Graphics.FromHwnd(panelRender.Handle), new Rectangle(49, 49, 100, 100));
graphicsBuffer.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
}
private void TestForm_Load(object sender, EventArgs e)
{
graphicsBuffer.Graphics.DrawRectangle(new Pen(Color.Red), 50, 50, 50, 50);
}
}
}
I've left out a lot of the proprietary code (there is a call to graphicsBuffer.Render();
in part of that proprietary code) and renamed some stuff but hopefully what I have provided will give you the gist. Also, the 3D scene is also using panelRender.Handle
to draw into that panel, and the panelRender.BackColor
is black.
In a nutshell, what I am seeing is a chunk of my 3D scene missing (specifically a 100x100 chunk) with the 50x50 red rectangle drawn inside it, as pictured here:
Obviously I don't want to lose the scene that I'm trying to draw on top of. Right now, I'm at a loss as to why this is happening. Is what I'm trying to do just not possible? If any additional information/code is needed, I will be happy to provide it, if possible.
EDIT: To try and simplify matters, I created a really simple WinForms app that has a single panel and used the code above to recreate the issue. The code-behind for that is here:
using System.Drawing;
using System.Windows.Forms;
namespace DoubleBufferTest
{
public partial class Form1 : Form
{
private BufferedGraphics graphicsBuffer = null;
private BufferedGraphicsContext bufferContext = BufferedGraphicsManager.Current;
public Form1()
{
this.SetStyle(ControlStyles.SupportsTransparentBackColor | ControlStyles.UserPaint, true);
this.UpdateStyles();
InitializeComponent();
UpdateGraphicsBuffer();
}
private void UpdateGraphicsBuffer()
{
bufferContext.MaximumBuffer = new Size(panel1.Width + 1, panel1.Height + 1);
graphicsBuffer = bufferContext.Allocate(Graphics.FromHwnd(panel1.Handle), new Rectangle(10, 10, 50, 50));
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
graphicsBuffer.Graphics.DrawRectangle(new Pen(Color.Red, 3.0f), 20, 20, 10, 10);
graphicsBuffer.Render();
}
}
}
The panel's backcolor is set to transparent. Here is the result:
That black square corresponds to the graphics buffer that is getting allocated by the context. Why it always shows up as black is basically what is confusing me now...