问题
I'm using the Microsoft branch of the ANGLE project to have access to OpenGL in a Universal Windows application. Also I use the C++/WinRT binding to code as much in standard C++ as possible.
I started from one of the examples in the ANGLE project and tried to convert the C++/CX code to C++/WinRT code, but I fail to find a solution for the part where I create an EGL Surface:
mEGLSurface = eglCreateWindowSurface(mEGLDisplay, config, /*WHERE IS MY HWND?*/, NULL);
In the C++/CX they use the following code, but I must admit, I don't get how they get from the PropertySet with a CoreWindow to the EGLNativeWindowType (in this case HWND) and how to translate this to C++/WinRT code:
PropertySet^ surfaceCreationProperties = ref new PropertySet();
surfaceCreationProperties->Insert(ref new String(EGLNativeWindowTypeProperty), window);
mEglSurface = eglCreateWindowSurface(mEglDisplay, config, reinterpret_cast<IInspectable*>(surfaceCreationProperties), surfaceAttributes);
EDIT: When naively converting the code to C++/WinRT conventions, the reinterpret_cast gives an 'invalid cast' error (from IInspectable to EGLNativeWindowType).
EDIT: Just for completeness, the window
argument is a Windows::UI::Core::CoreWindow.
EDIT: Actually this answer to a similar question gives a lot of good info, I will investigate further.
EDIT: After reading the answer linked to in the previous edit and looking at the right places in the source code of ANGLE, I found out that my confusion is caused by an implementation detail specific to the Windows side of ANGLE. The function is not expecting an HWND handle in the traditional sense, but more like a dictionary of settings disguised as an HWND. Also the reinterpret_cast error is due to the fact that I tried to cast an object to a pointer, silly me..
回答1:
EGLNativeWindowType is defined as follows in ANGLE:
#if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP) /* Windows Desktop */
typedef HWND EGLNativeWindowType;
#else /* Windows Store */
#include <inspectable.h>
typedef IInspectable* EGLNativeWindowType;
#endif
So when using C++/WinRT types in a Universal Windows application, I must be careful not to mix those types with C++/CX types used by other code.
I was trying to cast the PropertySet pointer, that this implementation of the function expects when using UWP, to an winrt::Windows::Foundation::IInspectable pointer. This is not the C++/CX IInspectable type that the ANGLE implementation expects. So I had to directly cast to EGLNativeWindowType:
PropertySet surfaceProperties;
surfaceProperties.Insert(EGLNativeWindowTypeProperty, window);
EGLNativeWindowType win = reinterpret_cast<EGLNativeWindowType>(&surfaceProperties);
mEGLSurface = eglCreateWindowSurface(mEGLDisplay, config, win, surfaceAttributes);
This is one of the caveats when trying to use standard C++ in an UWP environment. See this answers on sharing C++/WinRT with C++/CX code:
https://stackoverflow.com/a/39775875/1891866
回答2:
There is also an issue with winrt' PropertySet
not being compatible with cx' PropertySet
.
This worked for me:
PropertySet surfaceCreationProperties;
surfaceCreationProperties.Insert(EGLNativeWindowTypeProperty, panel);
EGLNativeWindowType win = static_cast<EGLNativeWindowType>(winrt::get_abi(surfaceCreationProperties));
surface = eglCreateWindowSurface(mEglDisplay, mEglConfig, win, surfaceAttributes);
来源:https://stackoverflow.com/questions/46550182/how-to-create-eglsurface-using-c-winrt-and-angle