void MGEhud::setTexture(hud_id hud, const char *texture) { Element *e = &elements[hud]; if(e->texture) e->texture->Release(); IDirect3DTexture9 *tex = BSALoadTexture(device, texture); if(tex) { D3DSURFACE_DESC desc; tex->GetLevelDesc(0, &desc); e->w = desc.Width; e->h = desc.Height; e->texture = tex; // As the BSA cache cannot reload a texture after it is released, (it returns a pointer to the released texture) // we have to add a loose reference to keep the texture in memory and avoid a crash tex->AddRef(); e->textureFilename = texture; } else { LOG::logline("LoadHUDTexture : Cannot load texture %s", texture); e->texture = 0; e->textureFilename.clear(); } }
// Presents a video frame. HRESULT D3DPresentEngine::PresentSample(IMFSample* pSample, LONGLONG llTarget) { HRESULT hr = S_OK; IMFMediaBuffer* pBuffer = NULL; IDirect3DTexture9* pTexture = NULL; if (pSample) { // Get the buffer from the sample. hr = pSample->GetBufferByIndex(0, &pBuffer); if (SUCCEEDED(hr)) { // Get the surface from the buffer. IDirect3DSurface9* pSurface = NULL; hr = MFGetService(pBuffer, MR_BUFFER_SERVICE, __uuidof(IDirect3DSurface9), (void**)&pSurface); if (SUCCEEDED(hr)) { // Get the texture from the buffer. pSurface->GetContainer(IID_IDirect3DTexture9, (void**)&pTexture); } } if (hr == D3DERR_DEVICELOST || hr == D3DERR_DEVICENOTRESET || hr == D3DERR_DEVICEHUNG) { // We failed because the device was lost. // This case is ignored. The Reset(Ex) method must be called from the thread that created the device. // The presenter will detect the state when it calls CheckDeviceState() on the next sample. hr = S_OK; } } else if (m_pTextureRepaint) { // Redraw from the last surface. pTexture = m_pTextureRepaint; pTexture->AddRef(); } hr = m_EVRCallback->PresentSurface(m_Width, m_Height, m_ArX, m_ArY, (DWORD)&pTexture); // Return reference, so C# side can modify the pointer after Dispose() to avoid duplicated releasing. SAFE_RELEASE(pTexture); SAFE_RELEASE(pBuffer); return hr; }
bool Surface::swap() { if (mSwapChain) { IDirect3DTexture9 *flipTexture = mFlipTexture; flipTexture->AddRef(); IDirect3DSurface9 *renderTarget = mRenderTarget; renderTarget->AddRef(); EGLint oldWidth = mWidth; EGLint oldHeight = mHeight; checkForWindowResize(); IDirect3DDevice9 *device = mDisplay->getDevice(); IDirect3DSurface9 *textureSurface; flipTexture->GetSurfaceLevel(0, &textureSurface); mDisplay->endScene(); device->StretchRect(renderTarget, NULL, textureSurface, NULL, D3DTEXF_NONE); renderTarget->Release(); applyFlipState(device); device->SetTexture(0, flipTexture); float xscale = (float)mWidth / oldWidth; float yscale = (float)mHeight / oldHeight; // Render the texture upside down into the back buffer // Texcoords are chosen to pin a potentially resized image into the upper-left corner without scaling. float quad[4][6] = {{ 0 - 0.5f, 0 - 0.5f, 0.0f, 1.0f, 0.0f, 1.0f }, {mWidth - 0.5f, 0 - 0.5f, 0.0f, 1.0f, xscale, 1.0f }, {mWidth - 0.5f, mHeight - 0.5f, 0.0f, 1.0f, xscale, 1.0f-yscale}, { 0 - 0.5f, mHeight - 0.5f, 0.0f, 1.0f, 0.0f, 1.0f-yscale}}; // x, y, z, rhw, u, v mDisplay->startScene(); device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, quad, 6 * sizeof(float)); flipTexture->Release(); textureSurface->Release(); restoreState(device); mDisplay->endScene(); HRESULT result = mSwapChain->Present(NULL, NULL, NULL, NULL, mDisplay->getPresentInterval()); if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DRIVERINTERNALERROR) { return error(EGL_BAD_ALLOC, false); } if (result == D3DERR_DEVICELOST) { return error(EGL_CONTEXT_LOST, false); } ASSERT(SUCCEEDED(result)); } return true; }