Documentation

Rendering

This example shows and explain how rendering works in combination with the Wikitude SDK Native API. There are two methods of rendering available in the Wikitude Native SDK. We call them internal and external rendering. Internal means the rendering view (OpenGL ES, Metal) is setup by the Wikitude SDK and the SDK user can define custom rendering, that is executed by the Wikitude SDK. On the other hand external rendering means the SDK user sets up the rendering view on his own and integrates the Wikitude SDK into this rendering setup.

Rendering APIs

The Wikitude Native SDK for UWP currently supports Direct3D 11 API.

External Direct3D 11 Rendering

Most of the examples in the Wikitude Native SDK example application use external rendering, simply because it might be the preferred usage by developers. The example application comes with a simple Direct3D view (SwapChainPanel) and an also very simple renderer class (D3D11Renderer).

To activate external rendering you will need to create a ExternalRenderingSystem object with a IDirect3DDevice reference as the only parameter. The code to convert from a ID3D11Device pointer to a IDirect3DDevice reference is shown below :

IDXGIDevice* pDXGIDevice;
_renderer->deviceResources()->GetD3DDevice()->QueryInterface(__uuidof(IDXGIDevice), (void**)&pDXGIDevice);

ID3D11Device* pDevice;
pDXGIDevice->QueryInterface(__uuidof(ID3D11Device), (void**)&pDevice);

auto device = Direct3D11::CreateDirect3DDevice(pDXGIDevice);

Once we have a reference to a IDirect3DDevice reference, you can simply create a WikitudeNativeSDK with the ExternalRenderingSystem as the parameter.

auto device = Direct3D11::CreateDirect3DDevice(pDXGIDevice);
_renderingSystem = ref new ExternalRenderingSystem(device);
_sdk = ref new WikitudeNativeSDK(_renderingSystem);

To update the internal state of the SDK and draw the camera frame, the ExternalRenderingSystem class provides two methods update and draw that are called in the onUpdate and onRender event handlers in our example :

void ExternalRenderingPage::onUpdate() {
    if (_sdk && _sdk->isRunning()) {
        _renderingSystem->update();
    }
}
void ExternalRenderingPage::onRender() {
    if (_sdk && _sdk->isRunning()) {
        _renderingSystem->draw();
    }
    // ...
}

Internal Direct3D 11 Rendering

In case no Direct3D 11 rendering is already setup in the hosting Wikitude Native SDK application, the Wikitude Native SDK provides its own internal rendering code. To start the Wikitude Native SDK with internal rendering, you need to create the WikitudeNativeSDK with a InternalRenderingParameters parameter. InternalRenderingParameters takes a SwapChainPanel reference, where the rendering will happen, and a referance to an object implementing RenderExtension interface.

public ref class InternalRenderer sealed : public wikitude::sdk::uwp::RenderExtension {
    // ...
}
_sdk = ref new WikitudeNativeSDK(ref new InternalRenderingParameters(swapChainPanel, _internalRenderer));

RenderExtension::surfaceCreated will be called once the rendering code is initialized, passing IDirect3DDevice reference to setup our augmentation rendering.

void InternalRenderer::surfaceCreated(Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice ^device_)
{
    Microsoft::WRL::ComPtr<IDXGIDevice> dxgiDevice;
    HRESULT hr = GetDXGIInterface(device_, dxgiDevice.GetAddressOf());
    dxgiDevice.As(&_d3dDevice);
}

RenderExtension::update and RenderExtention::drawFrame will be called from the internal renderer to allow drawing augmentations on your own.

void InternalRenderer::drawFrame()
{
    if (_rectangle) {
        _rectangle->Render();
    }
}
void InternalRenderer::update()
{
    // Nothing to update in this example.
}