Example #1
0
void SkiaWindow::resizeImpl(const gfx::Size& size)
{
  bool gpu = instance()->gpuAcceleration();
  (void)gpu;

#if SK_SUPPORT_GPU
#if SK_ANGLE
  if (gpu && attachANGLE()) {
    m_backend = Backend::ANGLE;
  }
  else
#endif // SK_ANGLE
  if (gpu && attachGL()) {
    m_backend = Backend::GL;
  }
  else
#endif // SK_SUPPORT_GPU
  {
#if SK_SUPPORT_GPU
    detachGL();
#endif
    m_backend = Backend::NONE;
  }

#if SK_SUPPORT_GPU
  if (m_glCtx)
    createRenderTarget(size);
#endif

  m_display->resize(size);
}
Example #2
0
//-----------------------------------------------------------------------------
void D2DDrawContext::endDraw ()
{
	if (renderTarget)
	{
		if (currentClip.isEmpty () == false)
		{
			getRenderTarget ()->PopAxisAlignedClip ();
			currentClip = CRect ();
		}
		renderTarget->Flush ();
		HRESULT result = renderTarget->EndDraw ();
		if (result == D2DERR_RECREATE_TARGET)
		{
			releaseRenderTarget ();
			createRenderTarget ();
		}
		else
		{
			vstgui_assert (result == S_OK);
		}
		if (bitmap)
		{
			D2DBitmap* d2dBitmap = dynamic_cast<D2DBitmap*> (bitmap->getPlatformBitmap ());
			D2DBitmapCache::instance ()->removeBitmap (d2dBitmap);
		}
	}
}
Example #3
0
void OculusInterface::initOculus(float _devicePixelAspect)
{

  m_devicePixelAspect=_devicePixelAspect;
  std::cout<<"setting device aspect "<<m_devicePixelAspect<<"\n";
  m_hmd = ovrHmd_Create(0);
  if (!m_hmd)
  {
    std::cerr<<"Unable to create HMD: "<< ovrHmd_GetLastError(NULL)<<std::endl;
    std::cerr<<"Attempting to run without HMD\n";
    // If we didn't detect an Hmd, create a simulated one for debugging.
    m_hmd = ovrHmd_CreateDebug(ovrHmd_DK1);
    if (!m_hmd)
    {   // Failed Hmd creation.
      exit(EXIT_FAILURE);
    }
  }
  m_windowWidth=m_hmd->Resolution.w;
  m_windowHeight=m_hmd->Resolution.h;

  oculusDebug();
  // Start the sensor which provides the Rift’s pose and motion.
  ovrHmd_ConfigureTracking(m_hmd, ovrTrackingCap_Orientation | ovrTrackingCap_MagYawCorrection | ovrTrackingCap_Position, 0);
  // let's fill in some info about oculus
  m_eyeres[0] = ovrHmd_GetFovTextureSize(m_hmd, ovrEye_Left, m_hmd->DefaultEyeFov[0], 1.0);
  m_eyeres[1] = ovrHmd_GetFovTextureSize(m_hmd, ovrEye_Right, m_hmd->DefaultEyeFov[1],1.0);

	/* and create a single render target texture to encompass both eyes */
	//m_fbWidth = m_eyeres[0].w + m_eyeres[1].w;
	//m_fbHeight = m_eyeres[0].h > m_eyeres[1].h ? m_eyeres[0].h : m_eyeres[1].h;

	ovrSizei recommenedTex0Size = ovrHmd_GetFovTextureSize(m_hmd, ovrEye_Left,m_hmd->DefaultEyeFov[0], m_devicePixelAspect);
	ovrSizei recommenedTex1Size = ovrHmd_GetFovTextureSize(m_hmd, ovrEye_Right,m_hmd->DefaultEyeFov[1], m_devicePixelAspect);

	// Determine dimensions to fit into a single render target.
	ovrSizei renderTargetSize;
	m_fbWidth = recommenedTex0Size.w + recommenedTex1Size.w;
	m_fbHeight = std::max ( recommenedTex0Size.h, recommenedTex1Size.h );


	createRenderTarget();
	createOVRGLConfig();
	createOVRTextureBuffers();
	/* enable low-persistence display and dynamic prediction for lattency compensation */
	ovrHmd_SetEnabledCaps(m_hmd, ovrHmdCap_LowPersistence | ovrHmdCap_DynamicPrediction);

	/* configure SDK-rendering and enable chromatic abberation correction, vignetting, and
	 * timewrap, which shifts the image before drawing to counter any lattency between the call
	 * to ovrHmd_GetEyePose and ovrHmd_EndFrame.
	 */
	unsigned int dcaps = ovrDistortionCap_Chromatic | ovrDistortionCap_Vignette | ovrDistortionCap_TimeWarp |
		ovrDistortionCap_Overdrive;
	if(!ovrHmd_ConfigureRendering(m_hmd, &m_glcfg.Config, dcaps, m_hmd->DefaultEyeFov, m_eyeRdesc))
	{
		fprintf(stderr, "failed to configure distortion renderer\n");
	}


}
Example #4
0
 Texture* Texture::createScreenRenderTarget(bool willBeUsedInEffects)
 {
     auto pRet = createRenderTarget({OScreenW, OScreenH}, willBeUsedInEffects);
     if (pRet)
     {
         pRet->m_isScreenRenderTarget = true;
     }
     return pRet;
 }
Example #5
0
//-----------------------------------------------------------------------------
D2DDrawContext::D2DDrawContext (HWND window, const CRect& drawSurface)
    : COffscreenContext (drawSurface)
    , window (window)
    , renderTarget (0)
    , fillBrush (0)
    , strokeBrush (0)
    , fontBrush (0)
    , strokeStyle (0)
{
    createRenderTarget ();
}
Example #6
0
//-----------------------------------------------------------------------------
D2DDrawContext::D2DDrawContext (D2DBitmap* inBitmap)
    : COffscreenContext (new CBitmap (inBitmap))
    , window (0)
    , renderTarget (0)
    , fillBrush (0)
    , strokeBrush (0)
    , fontBrush (0)
    , strokeStyle (0)
{
    createRenderTarget ();
    bitmap->forget ();
}
Example #7
0
//! rendertarget constructor
CD3D9Texture::CD3D9Texture(CD3D9Driver* driver, core::dimension2d<s32> size, const char* name)
: ITexture(name), Image(0), Texture(0), RTTSurface(0), Driver(driver),
	TextureSize(size), ImageSize(size), Pitch(0),
	HasMipMaps(false), HardwareMipMaps(false), IsRenderTarget(true)
{
	#ifdef _DEBUG
	setDebugName("CD3D9Texture");
	#endif

	Device=driver->getExposedVideoData().D3D9.D3DDev9;
	if (Device)
		Device->AddRef();

	createRenderTarget();
}
Example #8
0
//! rendertarget constructor
CD3D9Texture::CD3D9Texture(CD3D9Driver* driver, const core::dimension2d<u32>& size,
						   const io::path& name, const ECOLOR_FORMAT format)
: ITexture(name), Texture(0), RTTSurface(0), Driver(driver), DepthSurface(0),
	TextureSize(size), ImageSize(size), Pitch(0), ColorFormat(ECF_UNKNOWN),
	HasMipMaps(false), HardwareMipMaps(false), IsRenderTarget(true)
{
	#ifdef _DEBUG
	setDebugName("CD3D9Texture");
	#endif

	Device=driver->getExposedVideoData().D3D9.D3DDev9;
	if (Device)
		Device->AddRef();

	createRenderTarget(format);
}
Example #9
0
//-----------------------------------------------------------------------------
void D2DDrawContext::endDraw ()
{
    if (renderTarget)
    {
        renderTarget->Flush ();
        HRESULT result = renderTarget->EndDraw ();
        if (result == D2DERR_RECREATE_TARGET)
        {
            releaseRenderTarget ();
            createRenderTarget ();
        }
        if (bitmap)
        {
            D2DBitmap* d2dBitmap = dynamic_cast<D2DBitmap*> (bitmap->getPlatformBitmap ());
            D2DBitmapCache::instance ()->removeBitmap (d2dBitmap);
        }
    }
}
Example #10
0
	void installHooks()
	{
		auto dd7(DDraw::Repository::getDirectDraw());
		CompatPtr<IDirectDraw> dd;
		CALL_ORIG_PROC(DirectDrawCreate, nullptr, &dd.getRef(), nullptr);
		if (!dd || !dd7 || FAILED(dd->SetCooperativeLevel(dd, nullptr, DDSCL_NORMAL)))
		{
			Compat::Log() << "Failed to hook Direct3d interfaces";
			return;
		}

		CompatPtr<IDirectDrawSurface7> renderTarget7(createRenderTarget(*dd7));
		if (renderTarget7)
		{
			CompatPtr<IDirectDrawSurface4> renderTarget4(renderTarget7);
			hookDirect3d(*dd, *renderTarget4);
			hookDirect3d7(*dd7, *renderTarget7);
		}
	}
Example #11
0
TextureID Renderer::addRenderDepth(const int width, const int height, const FORMAT format, bool lockToScreenSize){
	Texture texture;

	texture.textureKind = TEXKIND_2D;
	texture.isRenderTarget = true;
	texture.rtLockScreenSize = lockToScreenSize;
	texture.noLinearFilter = false;//((flags & TEX_NOLINEARFILTER) != 0);
	texture.clampS = true;
	texture.clampT = true;
	texture.levelOfAnisotropy = 1;
	texture.width  = width;
	texture.height = height;
	texture.depth  = 1;
	texture.format = format;
	texture.mipmapped = false;
	
	if (createRenderTarget(texture)){
		return insertTexture(texture);
	} else {
		return TEXTURE_NONE;
	}
}
Example #12
0
TextureID Renderer::addRenderCubemap(const int size, const FORMAT format, bool mipmapped){
	Texture texture;

	texture.textureKind = TEXKIND_CUBEMAP;
	texture.isRenderTarget = true;
	texture.rtLockScreenSize = false;
	texture.noLinearFilter = false;//((flags & TEX_NOLINEARFILTER) != 0);
	texture.clampS = true;
	texture.clampT = true;
	texture.levelOfAnisotropy = 1;
	texture.width  = size;
	texture.height = size;
	texture.depth  = 1;
	texture.format = format;
	texture.mipmapped = mipmapped;
	
	if (createRenderTarget(texture)){
		return insertTexture(texture);
	} else {
		return TEXTURE_NONE;
	}
}
Example #13
0
void QgsOffscreen3DEngine::createFrameGraph()
{
  // Firstly, create the offscreen surface. This will take the place
  // of a QWindow, allowing us to render our scene without one.
  mOffscreenSurface = new QOffscreenSurface();
  mOffscreenSurface->setFormat( QSurfaceFormat::defaultFormat() );
  mOffscreenSurface->create();

  // Hook it up to the frame graph.
  mSurfaceSelector = new Qt3DRender::QRenderSurfaceSelector( mRenderSettings );
  mSurfaceSelector->setSurface( mOffscreenSurface );
  mSurfaceSelector->setExternalRenderTargetSize( mSize );

  // Create a texture to render into. This acts as the buffer that
  // holds the rendered image.
  mRenderTargetSelector = new Qt3DRender::QRenderTargetSelector( mSurfaceSelector );
  createRenderTarget();
  // the target selector also sets itself as the parent of mTextureTarget
  mRenderTargetSelector->setTarget( mTextureTarget );

  // Create a node used for clearing the required buffers.
  mClearBuffers = new Qt3DRender::QClearBuffers( mRenderTargetSelector );
  mClearBuffers->setClearColor( QColor( 100, 100, 100, 255 ) );
  mClearBuffers->setBuffers( Qt3DRender::QClearBuffers::ColorDepthBuffer );

  // Create a viewport node. The viewport here just covers the entire render area.
  mViewport = new Qt3DRender::QViewport( mRenderTargetSelector );
  mViewport->setNormalizedRect( QRectF( 0.0, 0.0, 1.0, 1.0 ) );

  // Create a camera selector node, and tell it to use the camera we've ben given.
  mCameraSelector = new Qt3DRender::QCameraSelector( mViewport );
  mCameraSelector->setCamera( mCamera );

  // Add a render capture node to the frame graph.
  // This is set as the next child of the render target selector node,
  // so that the capture will be taken from the specified render target
  // once all other rendering operations have taken place.
  mRenderCapture = new Qt3DRender::QRenderCapture( mRenderTargetSelector );
}
Renderer::Renderer(Window& window) {
	createDevice(window);
	createRenderTarget();
}
Example #15
0
void egResize()
{
    if (!pBoundDevice) return;
    if (pBoundDevice->pRenderTargetView) pBoundDevice->pRenderTargetView->lpVtbl->Release(pBoundDevice->pRenderTargetView);

    // Delete buffers
    pBoundDevice->pSwapChain->lpVtbl->ResizeBuffers(pBoundDevice->pSwapChain, 0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
    for (uint32_t i = 0; i < 4; ++i)
    {
        SEGRenderTarget2D *pRenderTarget = pBoundDevice->gBuffer + i;
        destroyRenderTarget(pRenderTarget);
    }
    for (uint32_t i = 0; i < 8; ++i)
    {
        for (uint32_t k = 0; k < 2; ++k)
        {
            SEGRenderTarget2D *pRenderTarget = &pBoundDevice->blurBuffers[i][k];
            destroyRenderTarget(pRenderTarget);
        }
    }
    destroyRenderTarget(&pBoundDevice->accumulationBuffer);

    ID3D11Texture2D        *pBackBuffer;
    ID3D11Resource         *pBackBufferRes;

    // Create render target
    pBoundDevice->pSwapChain->lpVtbl->GetBuffer(pBoundDevice->pSwapChain, 0, &IID_ID3D11Texture2D, (void**)&pBackBuffer);
    pBoundDevice->pSwapChain->lpVtbl->GetBuffer(pBoundDevice->pSwapChain, 0, &IID_ID3D11Resource, (void**)&pBackBufferRes);
    pBoundDevice->pDevice->lpVtbl->CreateRenderTargetView(pBoundDevice->pDevice, pBackBufferRes, NULL, &pBoundDevice->pRenderTargetView);
    pBackBuffer->lpVtbl->GetDesc(pBackBuffer, &pBoundDevice->backBufferDesc);
    pBackBufferRes->lpVtbl->Release(pBackBufferRes);
    pBackBuffer->lpVtbl->Release(pBackBuffer);

    // Recreate buffers
    // Create our G-Buffer
    createRenderTarget(pBoundDevice->gBuffer + G_DIFFUSE,
                       pBoundDevice->backBufferDesc.Width, pBoundDevice->backBufferDesc.Height,
                       DXGI_FORMAT_R8G8B8A8_UNORM);
    createRenderTarget(pBoundDevice->gBuffer + G_DEPTH,
                       pBoundDevice->backBufferDesc.Width, pBoundDevice->backBufferDesc.Height,
                       DXGI_FORMAT_R32_FLOAT);
    createRenderTarget(pBoundDevice->gBuffer + G_NORMAL,
                       pBoundDevice->backBufferDesc.Width, pBoundDevice->backBufferDesc.Height,
                       DXGI_FORMAT_R8G8B8A8_UNORM);
    createRenderTarget(pBoundDevice->gBuffer + G_MATERIAL,
                       pBoundDevice->backBufferDesc.Width, pBoundDevice->backBufferDesc.Height,
                       DXGI_FORMAT_R8G8B8A8_UNORM);

    // Accumulation buffer. This is an HDR texture
    createRenderTarget(&pBoundDevice->accumulationBuffer,
                       pBoundDevice->backBufferDesc.Width, pBoundDevice->backBufferDesc.Height,
                       DXGI_FORMAT_R16G16B16A16_FLOAT); // DXGI_FORMAT_R11G11B10_FLOAT

    // Create blur buffers
    for (int i = 0; i < 8; ++i)
    {
        UINT divider = (UINT)pow(2, (double)i);
        for (int k = 0; k < 2; ++k)
        {
            UINT w = pBoundDevice->backBufferDesc.Width / divider;
            UINT h = pBoundDevice->backBufferDesc.Height / divider;
            createRenderTarget(&pBoundDevice->blurBuffers[i][k],
                               w, h,
                               DXGI_FORMAT_R8G8B8A8_UNORM);
        }
    }
}
Example #16
0
EGDevice egCreateDevice(HWND windowHandle)
{
    if (pBoundDevice)
    {
        if (pBoundDevice->bIsInBatch) return 0;
    }

    EGDevice                ret = 0;
    DXGI_SWAP_CHAIN_DESC    swapChainDesc;
    HRESULT                 result;
    ID3D11Texture2D        *pBackBuffer;
    ID3D11Resource         *pBackBufferRes;
    ID3D11Texture2D        *pDepthStencilBuffer;

    // Set as currently bound device
    devices = realloc(devices, sizeof(SEGDevice) * (deviceCount + 1));
    memset(devices + deviceCount, 0, sizeof(SEGDevice));
    pBoundDevice = devices + deviceCount;
    ++deviceCount;
    ret = deviceCount;

    // Define our swap chain
    memset(&swapChainDesc, 0, sizeof(swapChainDesc));
    swapChainDesc.BufferCount = 1;
    swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    swapChainDesc.OutputWindow = windowHandle;
    swapChainDesc.SampleDesc.Count = 1;
    swapChainDesc.Windowed = TRUE;

    // Create the swap chain, device and device context
    result = D3D11CreateDeviceAndSwapChain(
        NULL, D3D_DRIVER_TYPE_HARDWARE, NULL,
#if _DEBUG
        D3D11_CREATE_DEVICE_DEBUG,
#else /* _DEBUG */
        0,
#endif /* _DEBUG */
        NULL, 0, D3D11_SDK_VERSION,
        &swapChainDesc, &pBoundDevice->pSwapChain,
        &pBoundDevice->pDevice, NULL, &pBoundDevice->pDeviceContext);
    if (result != S_OK)
    {
        setError("Failed D3D11CreateDeviceAndSwapChain");
        egDestroyDevice(&ret);
        return 0;
    }

    // Create render target
    result = pBoundDevice->pSwapChain->lpVtbl->GetBuffer(pBoundDevice->pSwapChain, 0, &IID_ID3D11Texture2D, (void**)&pBackBuffer);
    if (result != S_OK)
    {
        setError("Failed IDXGISwapChain GetBuffer IID_ID3D11Texture2D");
        egDestroyDevice(&ret);
        return 0;
    }
    result = pBoundDevice->pSwapChain->lpVtbl->GetBuffer(pBoundDevice->pSwapChain, 0, &IID_ID3D11Resource, (void**)&pBackBufferRes);
    if (result != S_OK)
    {
        setError("Failed IDXGISwapChain GetBuffer IID_ID3D11Resource");
        egDestroyDevice(&ret);
        return 0;
    }
    result = pBoundDevice->pDevice->lpVtbl->CreateRenderTargetView(pBoundDevice->pDevice, pBackBufferRes, NULL, &pBoundDevice->pRenderTargetView);
    if (result != S_OK)
    {
        setError("Failed CreateRenderTargetView");
        egDestroyDevice(&ret);
        return 0;
    }
    pBackBuffer->lpVtbl->GetDesc(pBackBuffer, &pBoundDevice->backBufferDesc);
    pBackBufferRes->lpVtbl->Release(pBackBufferRes);
    pBackBuffer->lpVtbl->Release(pBackBuffer);

    // Set up the description of the depth buffer.
    D3D11_TEXTURE2D_DESC depthBufferDesc = {0};
    depthBufferDesc.Width = pBoundDevice->backBufferDesc.Width;
    depthBufferDesc.Height = pBoundDevice->backBufferDesc.Height;
    depthBufferDesc.MipLevels = 1;
    depthBufferDesc.ArraySize = 1;
    depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
    depthBufferDesc.SampleDesc.Count = 1;
    depthBufferDesc.SampleDesc.Quality = 0;
    depthBufferDesc.Usage = D3D11_USAGE_DEFAULT;
    depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
    depthBufferDesc.CPUAccessFlags = 0;
    depthBufferDesc.MiscFlags = 0;

    // Create the texture for the depth buffer using the filled out description.
    result = pBoundDevice->pDevice->lpVtbl->CreateTexture2D(pBoundDevice->pDevice, &depthBufferDesc, NULL, &pDepthStencilBuffer);
    if (result != S_OK)
    {
        setError("Failed DepthStencil CreateTexture2D");
        egDestroyDevice(&ret);
        return 0;
    }

    // Initailze the depth stencil view.
    D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc = {0};
    depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
    depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
    depthStencilViewDesc.Texture2D.MipSlice = 0;

    // Create the depth stencil view.
    result = pDepthStencilBuffer->lpVtbl->QueryInterface(pDepthStencilBuffer, &IID_ID3D11Resource, (void**)&pBackBufferRes);
    if (result != S_OK)
    {
        setError("Failed DepthStencil ID3D11Texture2D QueryInterface IID_ID3D11Resource");
        egDestroyDevice(&ret);
        return 0;
    }
    result = pBoundDevice->pDevice->lpVtbl->CreateDepthStencilView(pBoundDevice->pDevice, pBackBufferRes, &depthStencilViewDesc, &pBoundDevice->pDepthStencilView);
    if (result != S_OK)
    {
        setError("Failed CreateDepthStencilView");
        egDestroyDevice(&ret);
        return 0;
    }
    pBackBufferRes->lpVtbl->Release(pBackBufferRes);
    pDepthStencilBuffer->lpVtbl->Release(pDepthStencilBuffer);

    // Compile vertex shaders and related input layouts
    {
        ID3DBlob *pCompiled;
        CREATE_VS(g_vs, &pBoundDevice->pVS, pCompiled);
        D3D11_INPUT_ELEMENT_DESC layout[6] = {
            {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
            {"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
            {"TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0},
            {"BINORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 36, D3D11_INPUT_PER_VERTEX_DATA, 0},
            {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 48, D3D11_INPUT_PER_VERTEX_DATA, 0},
            {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 56, D3D11_INPUT_PER_VERTEX_DATA, 0}
        };
        result = pBoundDevice->pDevice->lpVtbl->CreateInputLayout(pBoundDevice->pDevice, layout, 6, pCompiled->lpVtbl->GetBufferPointer(pCompiled), pCompiled->lpVtbl->GetBufferSize(pCompiled), &pBoundDevice->pInputLayout);
        if (result != S_OK)
        {
            setError("Failed CreateInputLayout");
            egDestroyDevice(&ret);
            return 0;
        }
        pCompiled->lpVtbl->Release(pCompiled);
    }
    {
        ID3DBlob *pCompiled;
        CREATE_VS(g_vsPassThrough, &pBoundDevice->pVSPassThrough, pCompiled);
        D3D11_INPUT_ELEMENT_DESC layout[3] = {
            {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
            {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 48, D3D11_INPUT_PER_VERTEX_DATA, 0},
            {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 56, D3D11_INPUT_PER_VERTEX_DATA, 0}
        };
        result = pBoundDevice->pDevice->lpVtbl->CreateInputLayout(pBoundDevice->pDevice, layout, 3, pCompiled->lpVtbl->GetBufferPointer(pCompiled), pCompiled->lpVtbl->GetBufferSize(pCompiled), &pBoundDevice->pInputLayoutPassThrough);
        if (result != S_OK)
        {
            setError("Failed CreateInputLayout PassThrough");
            egDestroyDevice(&ret);
            return 0;
        }
        pCompiled->lpVtbl->Release(pCompiled);
    }

    // Pixel shaders
    for (int i = 0; i < 18; ++i)
    {
        CREATE_PS(g_pses[i], &(pBoundDevice->pPSes[i]));
    }
    pBoundDevice->pActivePS = pBoundDevice->pPSes[0];
    CREATE_PS(g_psPassThrough, &pBoundDevice->pPSPassThrough);
    CREATE_PS(g_psLDR, &pBoundDevice->pPSLDR);
    CREATE_PS(g_psAmbient, &pBoundDevice->pPSAmbient);
    CREATE_PS(g_psOmni, &pBoundDevice->pPSOmni);
    CREATE_PS(g_psBlurH, &pBoundDevice->pPSBlurH);
    CREATE_PS(g_psBlurV, &pBoundDevice->pPSBlurV);
    for (int i = 0; i < 2; ++i)
    {
        CREATE_PS(g_psPostProcess[i], &(pBoundDevice->pPSPostProcess[i]));
    }

    // Create uniforms
    {
        D3D11_BUFFER_DESC cbDesc = {64, D3D11_USAGE_DYNAMIC, D3D11_BIND_CONSTANT_BUFFER, D3D11_CPU_ACCESS_WRITE, 0, 0};
        result = pBoundDevice->pDevice->lpVtbl->CreateBuffer(pBoundDevice->pDevice, &cbDesc, NULL, &pBoundDevice->pCBViewProj);
        if (result != S_OK)
        {
            setError("Failed CreateBuffer CBViewProj");
            egDestroyDevice(&ret);
            return 0;
        }
        result = pBoundDevice->pDevice->lpVtbl->CreateBuffer(pBoundDevice->pDevice, &cbDesc, NULL, &pBoundDevice->pCBModel);
        if (result != S_OK)
        {
            setError("Failed CreateBuffer CBModel");
            egDestroyDevice(&ret);
            return 0;
        }
        result = pBoundDevice->pDevice->lpVtbl->CreateBuffer(pBoundDevice->pDevice, &cbDesc, NULL, &pBoundDevice->pCBInvViewProj);
        if (result != S_OK)
        {
            setError("Failed CreateBuffer CBInvViewProj");
            egDestroyDevice(&ret);
            return 0;
        }
    }
    {
        D3D11_BUFFER_DESC cbDesc = {sizeof(SEGOmni), D3D11_USAGE_DYNAMIC, D3D11_BIND_CONSTANT_BUFFER, D3D11_CPU_ACCESS_WRITE, 0, 0};
        result = pBoundDevice->pDevice->lpVtbl->CreateBuffer(pBoundDevice->pDevice, &cbDesc, NULL, &pBoundDevice->pCBOmni);
        if (result != S_OK)
        {
            setError("Failed CreateBuffer CBInvViewProj");
            egDestroyDevice(&ret);
            return 0;
        }
    }
    {
        D3D11_BUFFER_DESC cbDesc = {sizeof(float) * 4, D3D11_USAGE_DYNAMIC, D3D11_BIND_CONSTANT_BUFFER, D3D11_CPU_ACCESS_WRITE, 0, 0};
        float initialRef[4] = {.5f, 4.f, 0, 0};
        D3D11_SUBRESOURCE_DATA initialData = {initialRef, 0, 0};
        result = pBoundDevice->pDevice->lpVtbl->CreateBuffer(pBoundDevice->pDevice, &cbDesc, &initialData, &pBoundDevice->pCBAlphaTestRef);
        if (result != S_OK)
        {
            setError("Failed CreateBuffer CBAlphaTestRef");
            egDestroyDevice(&ret);
            return 0;
        }
        pBoundDevice->pDeviceContext->lpVtbl->PSSetConstantBuffers(pBoundDevice->pDeviceContext, 2, 1, &pBoundDevice->pCBAlphaTestRef);
    }
    {
        D3D11_BUFFER_DESC cbDesc = {sizeof(float) * 4, D3D11_USAGE_DYNAMIC, D3D11_BIND_CONSTANT_BUFFER, D3D11_CPU_ACCESS_WRITE, 0, 0};
        result = pBoundDevice->pDevice->lpVtbl->CreateBuffer(pBoundDevice->pDevice, &cbDesc, NULL, &pBoundDevice->pCBBlurSpread);
        if (result != S_OK)
        {
            setError("Failed CreateBuffer CBBlurSpread");
            egDestroyDevice(&ret);
            return 0;
        }
    }

    // Create our geometry batch vertex buffer that will be used to batch everything
    D3D11_BUFFER_DESC vertexBufferDesc;
    vertexBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
    vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    vertexBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
    vertexBufferDesc.MiscFlags = 0;
    vertexBufferDesc.StructureByteStride = 0;
    pBoundDevice->pCurrentBatchVertices = (SEGVertex *)malloc(sizeof(SEGVertex) * MAX_VERTEX_COUNT);
    for (UINT i = 0; i < VERTEX_BUFFER_COUNT; ++i)
    {
        UINT vertCount = (UINT)pow(2, 8 + (double)i);
        vertexBufferDesc.ByteWidth = vertCount * sizeof(SEGVertex);
        result = pBoundDevice->pDevice->lpVtbl->CreateBuffer(pBoundDevice->pDevice, &vertexBufferDesc, NULL, &pBoundDevice->pVertexBuffers[i]);
        if (result != S_OK)
        {
            setError("Failed CreateBuffer VertexBuffer");
            egDestroyDevice(&ret);
            return 0;
        }
        result = pBoundDevice->pVertexBuffers[i]->lpVtbl->QueryInterface(pBoundDevice->pVertexBuffers[i], &IID_ID3D11Resource, &pBoundDevice->pVertexBufferResources[i]);
        if (result != S_OK)
        {
            setError("Failed VertexBuffer ID3D11Buffer QueryInterface -> IID_ID3D11Resource");
            egDestroyDevice(&ret);
            return 0;
        }
    }

    // Create default textures
    {
        uint8_t pixel[4] = {255, 255, 255, 255};
        texture2DFromData(pBoundDevice->pDefaultTextureMaps + DIFFUSE_MAP, pixel, 1, 1, FALSE);
        if (!pBoundDevice->pDefaultTextureMaps[DIFFUSE_MAP].pTexture)
        {
            egDestroyDevice(&ret);
            return 0;
        }
    }
    {
        uint8_t pixel[4] = {128, 128, 255, 255};
        texture2DFromData(pBoundDevice->pDefaultTextureMaps + NORMAL_MAP, pixel, 1, 1, FALSE);
        if (!pBoundDevice->pDefaultTextureMaps[NORMAL_MAP].pTexture)
        {
            egDestroyDevice(&ret);
            return 0;
        }
    }
    {
        uint8_t pixel[4] = {0, 1, 0, 0};
        texture2DFromData(pBoundDevice->pDefaultTextureMaps + MATERIAL_MAP, pixel, 1, 1, FALSE);
        if (!pBoundDevice->pDefaultTextureMaps[MATERIAL_MAP].pTexture)
        {
            egDestroyDevice(&ret);
            return 0;
        }
    }
    {
        uint8_t pixel[4] = {0, 0, 0, 0};
        texture2DFromData(&pBoundDevice->transparentBlackTexture, pixel, 1, 1, FALSE);
        if (!pBoundDevice->transparentBlackTexture.pTexture)
        {
            egDestroyDevice(&ret);
            return 0;
        }
    }

    // Create our G-Buffer
    result = createRenderTarget(pBoundDevice->gBuffer + G_DIFFUSE,
                                pBoundDevice->backBufferDesc.Width, pBoundDevice->backBufferDesc.Height,
                                DXGI_FORMAT_R8G8B8A8_UNORM);
    if (result != S_OK)
    {
        egDestroyDevice(&ret);
        return 0;
    }
    result = createRenderTarget(pBoundDevice->gBuffer + G_DEPTH,
                                pBoundDevice->backBufferDesc.Width, pBoundDevice->backBufferDesc.Height,
                                DXGI_FORMAT_R32_FLOAT);
    if (result != S_OK)
    {
        egDestroyDevice(&ret);
        return 0;
    }
    result = createRenderTarget(pBoundDevice->gBuffer + G_NORMAL,
                                pBoundDevice->backBufferDesc.Width, pBoundDevice->backBufferDesc.Height,
                                DXGI_FORMAT_R8G8B8A8_UNORM);
    if (result != S_OK)
    {
        egDestroyDevice(&ret);
        return 0;
    }
    result = createRenderTarget(pBoundDevice->gBuffer + G_MATERIAL,
                                pBoundDevice->backBufferDesc.Width, pBoundDevice->backBufferDesc.Height,
                                DXGI_FORMAT_R8G8B8A8_UNORM);
    if (result != S_OK)
    {
        egDestroyDevice(&ret);
        return 0;
    }

    // Accumulation buffer. This is an HDR texture
    result = createRenderTarget(&pBoundDevice->accumulationBuffer,
                                pBoundDevice->backBufferDesc.Width, pBoundDevice->backBufferDesc.Height,
                                DXGI_FORMAT_R16G16B16A16_FLOAT); // DXGI_FORMAT_R11G11B10_FLOAT
    if (result != S_OK)
    {
        egDestroyDevice(&ret);
        return 0;
    }

    // Create blur buffers
    for (int i = 0; i < 8; ++i)
    {
        UINT divider = (UINT)pow(2, (double)i);
        for (int k = 0; k < 2; ++k)
        {
            UINT w = pBoundDevice->backBufferDesc.Width / divider;
            UINT h = pBoundDevice->backBufferDesc.Height / divider;
            result = createRenderTarget(&pBoundDevice->blurBuffers[i][k],
                                        w, h,
                                        DXGI_FORMAT_R8G8B8A8_UNORM);
            if (result != S_OK)
            {
                egDestroyDevice(&ret);
                return 0;
            }
        }
    }

    resetState();

    // Create some internal states
    {
        egDisable(EG_ALL);
        egEnable(EG_BLEND);
        egBlendFunc(EG_ONE, EG_ONE);
        pBoundDevice->passStates[EG_AMBIENT_PASS] = egCreateState();
        pBoundDevice->passStates[EG_OMNI_PASS] = egCreateState();

        SEGState *pState = pBoundDevice->states + (pBoundDevice->passStates[EG_AMBIENT_PASS] - 1);
        pState->ignoreBits = STATE_ALPHA_TEST | STATE_VIGNETTE;
        pState = pBoundDevice->states + (pBoundDevice->passStates[EG_OMNI_PASS] - 1);
        pState->ignoreBits = STATE_ALPHA_TEST | STATE_VIGNETTE;
    }
    {
        egDisable(EG_ALL);
        egFilter(EG_FILTER_MIN_MAG_LINEAR_MIP_POINT);
        SEGState *pState = pBoundDevice->stateStack + pBoundDevice->statesStackCount;
        pState->samplerState.desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
        pState->samplerState.desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
        pState->samplerState.desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
        pState->samplerState.desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
        pState->samplerState.desc.MaxLOD = D3D11_FLOAT32_MAX;
        pBoundDevice->passStates[EG_POST_PROCESS_PASS] = egCreateState();
        pState = pBoundDevice->states + (pBoundDevice->passStates[EG_POST_PROCESS_PASS] - 1);
        pState->ignoreBits = STATE_ALPHA_TEST | STATE_VIGNETTE;
    }

    resetState();

    return ret;
}