使用 C# 绘制 3D 渲染场景

Drawing over a 3D rendered scene using C#

更新:自从最初问这个问题后,我稍微改变了我的方法。我没有使用 System.Drawing.Graphics 进行绘图,而是使用 InkCanvas 托管 WPF 用户控件。这就是我需要它做的一切。问题仍然是我无法使 ElementHost 的背景透明。我看到了我之前看到的同一个黑色方块。

原始问题:我有一个 C# WinForms 应用程序,它使用 Ogre3D 将 3D 场景渲染到使用该面板句柄的表单中的面板。我正在尝试使用 C# System.Drawing.Graphics.

添加在该场景之上绘制的功能(想象一下 Madden 在电视屏幕上绘制)

我正在使用 BufferedGraphics class 来执行此操作。作为测试,我试图在 3D 场景的顶部简单地绘制一个矩形。下面是我用来设置所有内容的代码片段。

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);
        }
    }
}

我已经遗漏了很多专有代码(在该专有代码中有对 graphicsBuffer.Render(); 的调用)并重命名了一些内容,但希望我提供的内容能为您提供要点。此外,3D 场景也使用 panelRender.Handle 绘制到该面板中,panelRender.BackColor 为黑色。

简而言之,我看到的是我的 3D 场景中缺少一块(特别是 100x100 块),其中绘制了 50x50 红色矩形,如下图所示:

显然我不想失去我试图在其上绘制的场景。现在,我不知道为什么会这样。我想做的事情是不可能的吗?如果需要任何额外的 information/code,如果可能的话,我很乐意提供。

编辑: 为了尝试简化问题,我创建了一个非常简单的 WinForms 应用程序,它只有一个面板,并使用上面的代码重现了这个问题。 code-behind 在这里:

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();
        }
    }
}

面板的背景颜色设置为透明。这是结果:

那个黑色方块对应于上下文分配的图形缓冲区。为什么它总是显示为黑色基本上是我现在很困惑的问题...

感谢 @Ron Beyer for answering this for me in a 我发帖。

所以我使用 ElementHost 控件是正确的,但由于透明度问题,Ron 建议我尝试使用新的 WPF window,我可以将其覆盖在应用程序(link)。 WPF window 的背景设置为透明,因此在 InkCanvas 上绘图会产生所需的效果。