2013-12-12 1 views
1

그래픽 컨트롤을 사용하여 그래픽 라이브러리를 만들려고합니다. 이 컨트롤을 사용하면 오버레이 컨트롤을 추가 할 수 있습니다. 컨트롤의 그래픽은 DirectX를 사용하며 라이브러리의 일부이며 오버레이 컨트롤은 그래픽 전문가가 아닌 라이브러리의 최종 사용자가 제공합니다. 따라서 안정성과 편리한 API가 가장 중요한 문제입니다.DirectX 내용의 오버레이 WinForms 컨트롤

기술적 인 이유로 DirectX로 컨트롤을 직접 표시해야하며 다른 프레임 워크를 WPF로 사용하여 DirectX 장면을 호스팅 할 수 없습니다 (자세한 내용은 이전 질문 참조 : Stereoscopic 3D on WPF).

내가 가장 문제가 문제가 있다고 생각 :

  • 투명성 (반 투명성 ...) 컨트롤 자체 지역 내에서.
  • 오버레이 컨트롤의 애니메이션 : 이것이 컨트롤 래스터 화 (예 : WPF)가 옵션이 아닌 이유입니다. 지금까지

내 시도 :

  1. 게시물의 많은 다음은 내가 WS_EX_TRANSPARENT를 사용하기로 결정 유사한 문제를 논의했다. Airspace issue이지만 오버레이 컨트롤의 투명 영역 아래에서 DirectX 콘텐츠를 볼 수 있다는 사실에 놀랐습니다. 그러나 창 크기를 조정할 때를 제외하고는 오버레이 컨트롤이 표시되지 않았습니다. 그러면 깜박이고 다시 사라집니다. 여기에 오버레이 컨트롤의 코드는 다음과 같습니다

    class GDIGraphicsControl : UserControl 
    { 
        private const int WS_EX_TRANSPARENT = 0x20; 
    
        protected override CreateParams CreateParams 
        { 
        get 
        { 
         CreateParams p = base.CreateParams; 
         p.ExStyle |= WS_EX_TRANSPARENT; 
         return p; 
        } 
        } 
    
        public GDIGraphicsControl() 
        { 
        this.Dock = DockStyle.Fill; 
        } 
    
        protected override void OnPaintBackground(PaintEventArgs e) 
        { 
        // Do nothing 
        } 
    
        protected override void OnPaint(PaintEventArgs e) 
        { 
        for (int i = 0; i < 10; ++i) 
        { 
         int alpha = 25 * i; 
         int yPos = 10 * i; 
         e.Graphics.FillRectangle(
         new SolidBrush(Color.FromArgb(alpha, Color.Green)), 
         5, 5 + yPos, 100, 10); 
        } 
        e.Graphics.FillEllipse(new SolidBrush(Color.Red), 110, 5, 100, 100); 
        } 
    } 
    
  2. 내가 일을 간단하게 만들려고 깜박이는 문제를 분석합니다. 우선 디버깅 목적으로 DirectX 대신 GDI 렌더링을 사용하려고했습니다. 필자는 DirectX 렌더링과 매우 흡사하게 구현했습니다. 특히 Form.SetStyle 및 Invalidate() 호출은 문제의 원인으로 생각되는 모든 OnPaint()에서 호출됩니다. GDI 전용 렌더링에도 문제가 있습니다.

    public partial class RenderingForm : Form 
    { 
        public RenderingForm() 
        { 
        InitializeComponent(); 
    
        ControlStyles styles = 
         ControlStyles.AllPaintingInWmPaint | 
         ControlStyles.OptimizedDoubleBuffer | 
         ControlStyles.ResizeRedraw | 
         ControlStyles.UserPaint | 
         ControlStyles.Opaque; 
        this.SetStyle(styles, true); 
    
        Button button = new Button() 
        { 
         Text = "Just a button", 
         Left = 5, 
         Top = 210, 
         Width = 200 
        }; 
    
        this.Controls.Add(button); 
        this.Controls.Add(new GDIGraphicsControl()); 
        } 
    
        protected override void OnPaintBackground(PaintEventArgs e) 
        { 
        // Do nothing 
        } 
    
        protected override void OnPaint(PaintEventArgs e) 
        { 
        e.Graphics.Clear(Color.Blue); 
    
        this.Invalidate(); 
    
        base.OnPaint(e); 
        } 
    } 
    
  3. 내가 더 투명성 (위의 코드에서 참조)를 사용하지 않을 때 문제가 존재하는지 확인하는 간단한 오버레이 버튼을 추가하려고 다음은 GDI 렌더링 부모 컨트롤 코드입니다. 버튼이 깜박이지 않지만, 버튼 대신에 컨트롤의 크기를 처음으로 조절할 때까지 화면에 가비지가 표시됩니다. 그러면 버튼이 올바르게 나타납니다.

  4. 하위 오버레이 컨트롤을 무효화하려했지만 효과가 없습니다. 부모의 OnPaint와 자식 OnPaint에서 메시지 펌프 렌더링 효과를 만들려고했는데 아무 효과가 없습니다. 부모 렌더링 컨트롤 에서처럼 컨트롤의 스타일을 설정해도 문제가 해결되지 않고 배경이 검정색으로 깜박입니다.

는 또한 WPF를 사용하여 몇 가지 시도를 수행하지만, 문제는 ... 하드 Airspace issue없이 지금 질문에 대한 지금

충분한 길이 : GDI 어떻게하는지

  1. 누군가가 설명 할 수 DirectX 그래픽 오버레이가 작동합니까? 특히 WinForms 투명도가 작동한다는 것은 자식 컨트롤이 부모의 장치 컨텍스트에서 렌더링된다는 것을 알고 있기 때문에 이해할 수 없습니다. DirectX에는 하드웨어 렌더링 컨텍스트가 있습니다. DirectX 텍스처가 소프트웨어에 다시 복사된다는 의미입니까?

  2. 왜 CreateParams를 재정 의하여 컨트롤이 깜박이고 방지 할 수 있습니까?

  3. 투명도 메서드는 무엇입니까 (CreateParams, BackColorTransparency = True, Control.SetStyle + OnPainBackground 재정의) 무엇이 성능 비용입니까? 기본 그래픽은 효율적으로 렌더링되지만 오버레이 성능은 신경 쓰지 않습니다 (경량 애니메이션 제외).

답변

1

저는이 분야에서 많은 연구를 수행했으며, 영공이 갈 길이라는 결론에 도달했습니다. 웹상의 수많은 프로젝트에서 소스를 수집하여 WPF와 XNA를 통합 할 수있는 단일 프로젝트에 넣었습니다. 나는 또한 순수한 DirectX 인이 버전을 만들었지 만, XNA 버전은 훨씬 더 간단하고 C#에 더 잘 맞습니다. 나는 여기에 모든 세부 사항을 게시 할 수있는 충분한 공간이 없지만 당신은 download the demo from my website 일 수 있으며 아마도 거기에서 어디로 가야할 지 알 수있을 것입니다. 행운을 빕니다!

+0

대단히 감사합니다. 사실 저는 이미 ElementHost를 사용하고 DirectX 내용 위에 WPF 컨트롤을 배치하고 BackColorTransparent = True로 설정하는 데 성공했습니다. 그러나 WinForms 컨트롤도 지원하고 싶습니다. WPF ElementHost (그리고 나는 당신의 소스에서 나온 Popup이라고 생각합니다)는 같은 계층 구조의 다른 오버레이 WinForms 컨트롤과 잘 작동하지 않습니다 (투명 영역에서도 WinForms 컨트롤을 숨 깁니다). 또한 투명 WinForms가 깜박이고 (예에서와 같이 WPF 컨트롤이없는 경우) 원본에서 WinForms 컨트롤을 처리하지 못합니다. – MaMazav

+0

DirectX를 통한 WinForms에 대한 예제가 있습니까? 또는 내 경험에 대한 나의 이해 질문에 대한 제안? – MaMazav