Hosting OpenGL C++ Window in C# WPF

Trending 1 year ago

I americium pursuing this tutorial connected really to big Win32 OpenGL windows successful WPF. There is besides a Microsoft walkthrough connected really to Host a Win32 Control successful WPF that is useful aswell. The original task is from 2009 and uses managed C++ but doesn't really render. I person rebuilt nan programme utilizing nan aforesaid root codification (a fewer modifications owed to debugging) utilizing a C++ CLR Class Library. I usage nan compiled DLL successful C# WPF however, erstwhile I tally nan programme I get a blank model arsenic opposed to nan triangle successful nan tutorial.

I was wondering if personification could return a look astatine my programme and spot why thing is rendering.

What nan original programme renders:

enter image explanation here

What I americium getting:

enter image explanation here

Here is simply a link to nan root connected GitHub.

OpenGLCpp.h

#pragma once // Exclude seldom utilized parts of nan windows headers #define WIN32_LEAN_AND_MEAN #include <Windows.h> #include "Helper.h" #include "OpenGL.h" // To usage these, we must adhd immoderate references... // o PresentationFramework (for HwndHost) // * PresentationCore // * WindowsBase using namespace System; using namespace System::Windows; using namespace System::Windows::Interop; using namespace System::Windows::Input; using namespace System::Windows::Media; using namespace System::Runtime::InteropServices; namespace OpenGLCpp { LRESULT WINAPI MyMsgProc(HWND _hWnd, UINT _msg, WPARAM _wParam, LPARAM _lParam) { move (_msg) { // Make judge nan model gets attraction erstwhile it has to! lawsuit WM_IME_SETCONTEXT: // LOWORD(wParam) = 0 stands for deactivation, truthful don't set // attraction past (results successful a rather, err... 'greedy' window...) if (LOWORD(_wParam) > 0) SetFocus(_hWnd); return 0; default: return DefWindowProc(_hWnd, _msg, _wParam, _lParam); } } // // This people implements HwndHost // // We person to overwrite BuildWindowCore and DestroyWindowCore // // A very elemental illustration which creates a Win32 ListBox tin beryllium recovered successful nan MSDN: // http://msdn2.microsoft.com/en-us/library/aa970061.aspx // nationalist ref people OpenGLHwnd : nationalist HwndHost { public: OpenGLHwnd() : m_hRC(NULL), m_hDC(NULL), m_hWnd(NULL), m_hInstance(NULL), m_sWindowName(NULL), m_sClassName(NULL), m_fRotationAngle(0.0f) { } private: HGLRC m_hRC; HDC m_hDC; HWND m_hWnd; HINSTANCE m_hInstance; LPCWSTR m_sWindowName; LPCWSTR m_sClassName; float m_fRotationAngle; // DPI Scaling double m_dScaleX; double m_dScaleY; protected: /*virtual IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, bool% handled) override { switch( msg ) { lawsuit WM_IME_SETCONTEXT: if(LOWORD(wParam.ToInt32()) > 0) SetFocus(m_hWnd); handled = true; return System::IntPtr::Zero; } handled = false; return System::IntPtr::Zero; }*/ public: virtual void OnRenderSizeChanged(SizeChangedInfo^ sizeInfo) override { if (m_hDC == NULL || m_hRC == NULL) return; // Apply DPI correction // NOTE: sizeInfo->NewSize contains doubles, truthful we do nan multiplication before // converting to int. int iHeight = (int)(sizeInfo->NewSize.Height * m_dScaleY); int iWidth = (int)(sizeInfo->NewSize.Width * m_dScaleX); if (iWidth == 0 || iHeight == 0) return; wglMakeCurrent(m_hDC, m_hRC); glViewport(0, 0, iWidth, iHeight); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-1.0, 1.0, -1.0, 1.0, 1.0, 100.0); // gluPerspective( 67.5, ((double)(iWidth) / (double)(iHeight)), 1.0, 500.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } // // Communicating pinch this method will beryllium considerably much analyzable successful a real- // world application... // virtual void OnRender(System::Windows::Media::DrawingContext^ drawingContext) override { UNREF(drawingContext); if (m_hDC == NULL || m_hRC == NULL) return; wglMakeCurrent(m_hDC, m_hRC); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glTranslatef(0.0f, 0.0f, -2.6f); glRotatef(m_fRotationAngle, 0.0f, 1.0f, 0.0f); glBegin(GL_TRIANGLES); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 0.0f); glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(0.0f, 1.0f, 0.0f); glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(1.0f, -1.0f, 0.0f); glEnd(); glFlush(); SwapBuffers(m_hDC); // NOTE: This is nary longer wglSwapBuffers // For changeless rotation speed, and correct rotation speeds connected different machines, // we'd request a timer here. However, I don't want to bloat nan illustration code. m_fRotationAngle += 1.0; } virtual void DestroyWindowCore(HandleRef hwnd) override { if (NULL != m_hRC) { wglDeleteContext(m_hRC); m_hRC = NULL; } if (NULL != m_hWnd && NULL != m_hDC) { ReleaseDC(m_hWnd, m_hDC); m_hDC = NULL; } if (NULL != m_hWnd && m_hWnd == (HWND)hwnd.Handle.ToPointer()) { ::DestroyWindow(m_hWnd); m_hWnd = NULL; } UnregisterClass(m_sClassName, m_hInstance); } //Allowing Multiple Instances of nan Window bool RegisterWindowClass() { // // Create civilization WNDCLASS // WNDCLASS wndClass; if (GetClassInfo(m_hInstance, m_sClassName, &wndClass)) { // Class is already registered! return true; } wndClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Not providing a WNDPROC present results successful a clang connected my system: wndClass.lpfnWndProc = (WNDPROC)MyMsgProc; wndClass.cbClsExtra = 0; wndClass.cbWndExtra = 0; wndClass.hInstance = m_hInstance; wndClass.hIcon = LoadIcon(NULL, IDI_WINLOGO); wndClass.hCursor = LoadCursor(0, IDC_ARROW); wndClass.hbrBackground = 0; wndClass.lpszMenuName = 0; // No menu wndClass.lpszClassName = m_sClassName; // ... and registry it if (!RegisterClass(&wndClass)) { Helper::ErrorExit(L"RegisterWindowClass"); return false; } return true; } // // This is nan cardinal method to override // virtual HandleRef BuildWindowCore(HandleRef hwndParent) override { // Get HINSTANCE m_hInstance = (HINSTANCE)GetModuleHandle(NULL); m_sWindowName = L"OpenGL successful HwndHost"; m_sClassName = L"OGLClassHwnd"; if (RegisterWindowClass()) { // immoderate default size int iWidth = 2; int iHeight = 2; DWORD dwStyle = WS_CHILD | WS_VISIBLE; // Get nan genitor (WPF) Hwnd. This is important: Windows won't fto you create // nan Hwnd otherwise. HWND parentHwnd = (HWND)hwndParent.Handle.ToPointer(); m_hWnd = CreateWindowEx(0, m_sClassName, m_sWindowName, dwStyle, 0, // X Pos 0, // Y Pos iWidth, iHeight, parentHwnd, // Parent 0, // Menu m_hInstance, 0); // Param if (!m_hWnd) { Helper::ErrorExit(L"BuildWindowCore"); } m_hDC = GetDC(m_hWnd); if (!m_hDC) { Helper::ErrorExit(L"BuildWindowCore"); } // // Create PixelFormatDescriptor and take pixel format // uint PixelFormat; BYTE iAlphaBits = 0; BYTE iColorBits = 32; BYTE iDepthBits = 16; BYTE iAccumBits = 0; BYTE iStencilBits = 0; fixed PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), //size 1, //version PFD_DRAW_TO_WINDOW | //flags PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, //pixeltype iColorBits, 0, 0, 0, 0, 0, 0, //color bits ignored iAlphaBits, 0, //alpha displacement ignored iAccumBits, //accum. buffer 0, 0, 0, 0, //accum bits ignored iDepthBits, //depth buffer iStencilBits, //stencil buffer 0, //aux buffer PFD_MAIN_PLANE, //layer type 0, //reserved 0, 0, 0 //masks ignored }; PixelFormat = ChoosePixelFormat(m_hDC, &pfd); if (!PixelFormat) { Helper::ErrorExit(L"BuildWindowCore"); } if (!SetPixelFormat(m_hDC, PixelFormat, &pfd)) { Helper::ErrorExit(L"BuildWindowCore"); } m_hRC = wglCreateContext(m_hDC); if (!m_hRC) { Helper::ErrorExit(L"BuildWindowCore"); } if (!wglMakeCurrent(m_hDC, m_hRC)) { Helper::ErrorExit(L"BuildWindowCore"); } // // Get DPI accusation and shop scaling comparative to 96 DPI. // See http://msdn2.microsoft.com/en-us/library/ms969894.aspx // m_dScaleX = GetDeviceCaps(m_hDC, LOGPIXELSX) / 96.0; m_dScaleY = GetDeviceCaps(m_hDC, LOGPIXELSY) / 96.0; glEnable(GL_DEPTH_TEST); glDisable(GL_TEXTURE_2D); return HandleRef(this, IntPtr(m_hWnd)); } return HandleRef(nullptr, System::IntPtr::Zero); } }; }

OpenGLHWND.xaml.cs

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; using System.Windows.Interop; //HwndHost using OpenGLCpp; namespace OpenGLinWPF { /// <summary> /// Interaction logic for OpenGLHWND.xaml /// </summary> nationalist partial people OpenGLHWND : Window { nationalist OpenGLHWND() { InitializeComponent(); } backstage System.Windows.Threading.DispatcherTimer updateTimer = caller System.Windows.Threading.DispatcherTimer(); nationalist override void BeginInit() { updateTimer.Interval = caller TimeSpan(160000); updateTimer.Tick += caller EventHandler(updateTimer_Tick); updateTimer.Start(); base.BeginInit(); } protected override void OnClosing(System.ComponentModel.CancelEventArgs e) { base.OnClosing(e); if (!e.Cancel) { if (null != updateTimer) { updateTimer.Stop(); updateTimer = null; } } } backstage void updateTimer_Tick(object sender, EventArgs e) { if (null != hwndPlaceholder && null != hwndPlaceholder.Child) { hwndPlaceholder.Child.InvalidateVisual(); } } backstage void Window_Loaded(object sender, RoutedEventArgs e) { // Create our OpenGL Hwnd 'control'... HwndHost big = caller OpenGLCpp.OpenGLHwnd(); // ... and connect it to nan placeholder control: hwndPlaceholder.Child = host; } } }
More
close