示例#1
0
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;
}
示例#3
0
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;
}