使用C#绘制3D渲染场景 [英] Drawing over a 3D rendered scene using C#

查看:879
本文介绍了使用C#绘制3D渲染场景的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:自从最初提出这个问题以来,我已经稍微改变了我的方法.我使用InkCanvas托管WPF用户控件,而不是使用System.Drawing.Graphics进行绘制.那完成了我需要做的所有事情.问题仍然是我无法使ElementHost的背景透明.我看到的是以前看到的相同的黑色方块.

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.

原始问题:我有一个C#WinForms应用程序,该应用程序使用Ogre3D将3D场景渲染到使用该面板手柄的表单面板中.我正在尝试使用C#的System.Drawing.Graphics来添加在该场景顶部进行绘制的能力(想象在电视屏幕上进行Madden绘制).

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.

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

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

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

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.

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

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.

为了尝试简化问题,我创建了一个非常简单的WinForms应用程序,该应用程序具有一个面板,并使用上面的代码重新创建了问题.后面的代码在这里:

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...

推荐答案

感谢您 @Ron Beyer 不同的问题中为我回答这个问题我发布了.

因此,我使用ElementHost控件的方向正确,但是由于透明性问题,Ron建议我尝试使用一个新的WPF窗口,该窗口可以覆盖在应用程序顶部(

So I was on the right track with the ElementHost control, but because of the transparency issues, Ron suggested that I try using a new WPF window that I could overlay on top of the application (link). The WPF window's background is set to transparent, so drawing on the InkCanvas results in the desired effect.

这篇关于使用C#绘制3D渲染场景的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆