2015-05-28 5 views
0

ОБНОВЛЕНИЕ: с тех пор, как я задал этот вопрос, я немного изменил свой подход. Вместо того, чтобы рисовать с помощью System.Drawing.Graphics, я размещаю пользовательский элемент управления WPF с помощью InkCanvas. Это делает все, что мне нужно для этого. Проблема в том, что я не могу получить фон ElementHost прозрачным. Я вижу тот самый черный квадрат, который я видел раньше.Рисование 3D-сцены с использованием C#

ОРИГИНАЛЬНЫЙ ВОПРОС: У меня есть приложение C# WinForms, которое визуализирует 3D-сцену с использованием Ogre3D на панели в форме с использованием ручки этой панели. Я пытаюсь добавить способность рисовать поверх этой сцены (представьте, что Мэдден рисует экран телевизора), используя C# System.Drawing.Graphics.

Для этого используется класс BufferedGraphics. В качестве теста я пытаюсь просто нарисовать прямоугольник поверх 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 красным прямоугольником внутри него, как изображено здесь:

drawing problem

Очевидно, что я не хочу терять сцену, которую я пытаюсь нарисовать сверху. Сейчас я не понимаю, почему это происходит. Это то, что я пытаюсь сделать, просто невозможно? Если вам нужна дополнительная информация/код, я буду рад предоставить его, если это возможно.

EDIT: Чтобы попытаться упростить дело, я создал действительно простое приложение WinForms, которое имеет одну панель и использовало приведенный выше код для воссоздания проблемы. Код для этого здесь:

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

Цвет обратной стороны панели установлен на прозрачный. Вот результат:

Test app

Это черный квадрат соответствует графическому буферу, который становится выделенным из контекста. Почему это всегда проявляется как черное, в основном то, что меня сейчас путает ...

ответ

0

Благодарим вас за @Ron Beyer за ответ на этот вопрос для меня в different question.

Итак, я был на правильном пути с помощью элемента управления ElementHost, но из-за проблем с прозрачностью Рон предложил мне попробовать использовать новое окно WPF, которое я мог бы наложить поверх приложения (link). Фон фона WPF установлен на прозрачный, поэтому нарисовать InkCanvas дает желаемый эффект.

0

Что я думаю, вам следует использовать метод SetStyle, чтобы установить фон в прозрачный. Больше информации на https://msdn.microsoft.com/en-us/library/system.windows.forms.control.setstyle%28v=vs.110%29.aspx

+0

Я думаю, что вы должны также установить цвет фона элемента управления прозрачным, выполнив все это. this.BackColor = Color.Transparent; – BVintila

+0

Использование 'SetStyle()' не сработало для меня.Я добавил следующий код в конструктор моей формы в: 'this.SetStyle (ControlStyles.SupportsTransparentBackColor | ControlStyles.UserPaint, правда),' ' this.UpdateStyles();' Возможно, я использовал это неправильно? – WERUreo

+0

Извините, я пытался переформатировать мой комментарий и в итоге просто удалил его и снова начал. Я также попытался добавить строку, которую вы предлагаете, чтобы сделать BackColor прозрачным, но это тоже не сработало, что мне показалось странным, потому что в Designer задний цвет действительно прозрачен, нигде не видно никаких черных. Но когда я бегу, я все еще вижу красный прямоугольник внутри черного квадрата. – WERUreo