void HSWDisplay::LoadGraphics()
{
    // As of this writing, we don't yet have an abstraction for Textures, Buffers, and Shaders like we do for D3D11, D3D11, and OpenGL.
    #if defined(OVR_BUILD_DEBUG)
        if(!pTexture)
            pTexture = *LoadTextureTga(RenderParams, "C:\\TestPath\\TestFile.tga", 255);
    #endif

    if(!pTexture)
    {
        D3DCAPS9 caps;
        RenderParams.Device->GetDeviceCaps(&caps);

        if(caps.TextureCaps & (D3DPTEXTURECAPS_SQUAREONLY | D3DPTEXTURECAPS_POW2))
            { HSWDISPLAY_LOG(("[HSWDisplay D3D9] Square textures allowed only.")); }

        size_t textureSize;
        const uint8_t* TextureData = GetDefaultTexture(textureSize);
        pTexture = *LoadTextureTga(RenderParams, TextureData, (int)textureSize, 255);
        OVR_ASSERT(pTexture);
    }

    if(!pVB)
    {
        HRESULT hResult = RenderParams.Device->CreateVertexBuffer(4 * sizeof(HASWVertex), NULL, HASWVertexD3D9Format, D3DPOOL_MANAGED, &pVB.GetRawRef(), NULL);

        if(FAILED(hResult))
            { HSWDISPLAY_LOG(("[HSWDisplay D3D9] CreateVertexBuffer failed. %d (%x)", hResult, hResult)); }
        else
        {
            void* pVerticesVoid;
            hResult = pVB->Lock(0, 0, (void**)&pVerticesVoid, 0);

            if(FAILED(hResult))
                { HSWDISPLAY_LOG(("[HSWDisplay D3D9] Lock failed. %d (%x)", hResult, hResult)); }
            else
            {
                HASWVertex* pVertices = reinterpret_cast<HASWVertex*>(pVerticesVoid);

                const bool  flip   = ((RenderState.DistortionCaps & ovrDistortionCap_FlipInput) != 0);
                const float left   = -1.0f;
                const float top    = -1.1f;
                const float right  = +1.0f;
                const float bottom = +0.9f;

                pVertices[0] = HASWVertex(left,  top,    0.f, Color(255, 255, 255, 255), 0.f, flip ? 1.f : 0.f); // To do: Make this branchless 
                pVertices[1] = HASWVertex(left,  bottom, 0.f, Color(255, 255, 255, 255), 0.f, flip ? 0.f : 1.f);
                pVertices[2] = HASWVertex(right, top,    0.f, Color(255, 255, 255, 255), 1.f, flip ? 1.f : 0.f); 
                pVertices[3] = HASWVertex(right, bottom, 0.f, Color(255, 255, 255, 255), 1.f, flip ? 0.f : 1.f);

                pVB->Unlock();
            }
        }
    }
}
Example #2
0
bool HSWDisplay::Dismiss()
{
    #if HSWDISPLAY_DEBUGGING
        if(GetKeyState(VK_SCROLL) & 0x0001) // If the scroll lock key is toggled on...
            return false;                   // Make it so that the display doesn't dismiss, so we can debug this.
    #endif

    // If dismissal is not requested yet, mark it as such.
    bool newlyRequested = false;

    if(!DismissRequested)
    {
        DismissRequested = true;
        newlyRequested = true;
    }

    // If displayed and time has elapsed, do the dismissal.
    OVR_ASSERT(DismissibleTime <= (ovr_GetTimeInSeconds() + HSWDISPLAY_FIRST_DISMISSAL_TIME)); // Make sure the dismissal time is sane.
    if (Displayed && (ovr_GetTimeInSeconds() >= DismissibleTime))
    {
        DismissInternal();
        Displayed = false;
        DismissRequested = false;
        SDKRendered = false;
        return true;
    }

    if(newlyRequested)
        { HSWDISPLAY_LOG(("[HSWDisplay] Dismiss(): Not permitted yet. Queued for timeout in %.1f seconds.", DismissibleTime - ovr_GetTimeInSeconds())); }

    return false; // Cannot dismiss yet.
}
Example #3
0
void HSWDisplay::Display()
{
    HSWDISPLAY_LOG(("[HSWDisplay] Display()"));

    DisplayInternal();

    HMDNewlyMounted = false;
    Displayed = true;
    SDKRendered = RenderEnabled;
    StartTime = ovr_GetTimeInSeconds();

    const time_t lastDisplayedTime = HSWDisplay::GetCurrentProfileLastHSWTime();
    DismissibleTime = StartTime + ((lastDisplayedTime == HSWDisplayTimeNever) ? HSWDISPLAY_FIRST_DISMISSAL_TIME : HSWDISPLAY_REGULAR_DISMISSAL_TIME);

    SetCurrentProfileLastHSWTime(time(NULL));
}
void HSWDisplay::DismissInternal()
{
    HSWDISPLAY_LOG(("[HSWDisplay GL] DismissInternal()"));
    UnloadGraphicsRequested = true; // We don't directly call UnloadGraphics here because this may be executed within a different thread.
}
void HSWDisplay::DisplayInternal()
{
    HSWDISPLAY_LOG(("[HSWDisplay GL] DisplayInternal()"));
    // We may want to call LoadGraphics here instead of within Render.
}
// This is a temporary function implementation, and it functionality needs to be implemented in a more generic way.
IDirect3DTexture9* LoadTextureTga(HSWRenderParams& rParams, OVR::File* f, uint8_t alpha)
{
    IDirect3DTexture9* pTexture = NULL;

    int width, height;
    const uint8_t* pRGBA = LoadTextureTgaData(f, alpha, width, height);

    if (pRGBA)
    {
        // We don't have access to D3DX9 and so we currently have to do this manually instead of calling a D3DX9 utility function.
        Ptr<IDirect3DTexture9> pTextureSysmem;
        HRESULT hResult = rParams.Device->CreateTexture((UINT)width, (UINT)height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &pTextureSysmem.GetRawRef(), NULL);

        if(FAILED(hResult))
            { HSWDISPLAY_LOG(("CreateTexture(D3DPOOL_SYSTEMMEM) failed. %d (%x)", hResult, hResult)); }
        else
        {
            // Lock the texture so we can write this frame's texel data
            D3DLOCKED_RECT lock;
            hResult = pTextureSysmem->LockRect(0, &lock, NULL, D3DLOCK_NOSYSLOCK | D3DLOCK_NO_DIRTY_UPDATE);
            if(FAILED(hResult))
                { HSWDISPLAY_LOG(("LockRect failed. %d (%x)", hResult, hResult)); }
            else
            {
                // Four bytes per pixel. Pitch bytes per row (will be >= w * 4).
                uint8_t*       pRow = (uint8_t*)lock.pBits;
                const uint8_t* pSource = pRGBA;

                for(int y = 0; y < height; y++, pRow += lock.Pitch, pSource += (width * 4))
                {
                    uint8_t* pDest = pRow;

                    for(int x = 0, xEnd = width * 4; x < xEnd; x += 4)
                    {
                        pDest[x + 0] = pSource[x + 2];
                        pDest[x + 1] = pSource[x + 1];
                        pDest[x + 2] = pSource[x + 0];
                        pDest[x + 3] = pSource[x + 3];
                    }
                }

                pTextureSysmem->UnlockRect(0);

                hResult = rParams.Device->CreateTexture((UINT)width, (UINT)height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pTexture, NULL);
                if(FAILED(hResult))
                    { HSWDISPLAY_LOG(("CreateTexture(D3DPOOL_DEFAULT) failed. %d (%x)", hResult, hResult)); }
                else
                {
                    hResult = rParams.Device->UpdateTexture(pTextureSysmem, pTexture);
                    if(FAILED(hResult))
                    {
                        HSWDISPLAY_LOG(("UpdateTexture failed. %d (%x)", hResult, hResult));
                        pTexture->Release();
                        pTexture = NULL;
                    }
                }
            }
        }

        OVR_FREE(const_cast<uint8_t*>(pRGBA));
    }

    return pTexture;
}
void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture)
{
    if(RenderEnabled && eyeTexture)
    {
        // Note: The D3D9 implementation below is entirely fixed-function and isn't yet using shaders.
        // For the time being this is sufficient, but future designs will likely necessitate moving
        // to a system that uses programmable shaders.

        // We need to render to the eyeTexture with the texture viewport.
        // Setup rendering to the texture.
        ovrD3D9Texture* eyeTextureD3D9 = const_cast<ovrD3D9Texture*>(reinterpret_cast<const ovrD3D9Texture*>(eyeTexture));
        OVR_ASSERT(eyeTextureD3D9->Texture.Header.API == ovrRenderAPI_D3D9);


        // Save previous state.
        // To do: Merge this saved state with that done by DistortionRenderer::GraphicsState::Save(), and put them in a shared location.
        DWORD fvfSaved;
        RenderParams.Device->GetFVF(&fvfSaved);

        Ptr<IDirect3DVertexBuffer9> pVBDSaved;
        UINT vbOffsetSaved;
        UINT vbStrideSaved;
        RenderParams.Device->GetStreamSource(0, &pVBDSaved.GetRawRef(), &vbOffsetSaved, &vbStrideSaved);

        Ptr<IDirect3DBaseTexture9> pTexture0Saved;
        RenderParams.Device->GetTexture(0, &pTexture0Saved.GetRawRef());
        Ptr<IDirect3DBaseTexture9> pTexture1Saved;
        RenderParams.Device->GetTexture(1, &pTexture1Saved.GetRawRef());

        D3DMATRIX worldMatrixSaved, viewMatrixSaved, projectionMatrixSaved, texture0MatrixSaved;
        RenderParams.Device->GetTransform(D3DTS_WORLD, &worldMatrixSaved);
        RenderParams.Device->GetTransform(D3DTS_VIEW, &viewMatrixSaved);
        RenderParams.Device->GetTransform(D3DTS_PROJECTION, &projectionMatrixSaved);
        RenderParams.Device->GetTransform(D3DTS_TEXTURE0, &texture0MatrixSaved);

        Ptr<IDirect3DVertexShader9> pVertexShaderSaved;
        RenderParams.Device->GetVertexShader(&pVertexShaderSaved.GetRawRef());

        Ptr<IDirect3DPixelShader9> pPixelShaderSaved;
        RenderParams.Device->GetPixelShader(&pPixelShaderSaved.GetRawRef());

        D3DVIEWPORT9 viewportSaved;
        RenderParams.Device->GetViewport(&viewportSaved);

        Ptr<IDirect3DSurface9> pRenderTargetSaved;
        RenderParams.Device->GetRenderTarget(0, &pRenderTargetSaved.GetRawRef());


        // Load the graphics if not loaded already.
        if(!pTexture)
            LoadGraphics();

        // Calculate ortho projection.
        GetOrthoProjection(RenderState, OrthoProjection);

        HRESULT hResult = RenderParams.Device->BeginScene();
        if(FAILED(hResult))
            { HSWDISPLAY_LOG(("[HSWDisplay D3D9] BeginScene failed. %d (%x)", hResult, hResult)); }

        Ptr<IDirect3DSurface9> pDestSurface;
        hResult = eyeTextureD3D9->D3D9.pTexture->GetSurfaceLevel(0, &pDestSurface.GetRawRef());
        if(FAILED(hResult))
            { HSWDISPLAY_LOG(("[HSWDisplay D3D9] GetSurfaceLevel failed. %d (%x)", hResult, hResult)); }

        hResult = RenderParams.Device->SetRenderTarget(0, pDestSurface);
        if(FAILED(hResult))
            { HSWDISPLAY_LOG(("[HSWDisplay D3D9] SetRenderTarget failed. %d (%x)", hResult, hResult)); }

        D3DVIEWPORT9 D3DViewport;
        D3DViewport.X        = eyeTextureD3D9->Texture.Header.RenderViewport.Pos.x;
        D3DViewport.Y        = eyeTextureD3D9->Texture.Header.RenderViewport.Pos.y;    
        D3DViewport.Width    = eyeTextureD3D9->Texture.Header.RenderViewport.Size.w;
        D3DViewport.Height   = eyeTextureD3D9->Texture.Header.RenderViewport.Size.h;
        D3DViewport.MinZ     = 0;
        D3DViewport.MaxZ     = 1;
        hResult = RenderParams.Device->SetViewport(&D3DViewport);
        if(FAILED(hResult))
            { HSWDISPLAY_LOG(("[HSWDisplay D3D9] SetViewport failed. %d (%x)", hResult, hResult)); }

        hResult = RenderParams.Device->SetTexture(0, pTexture);
        if(FAILED(hResult))
            { HSWDISPLAY_LOG(("[HSWDisplay D3D9] SetTexture failed. %d (%x)", hResult, hResult)); }

        RenderParams.Device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
        RenderParams.Device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
        RenderParams.Device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);

        RenderParams.Device->SetVertexShader(NULL);
        RenderParams.Device->SetPixelShader(NULL);

        hResult = RenderParams.Device->SetStreamSource(0, pVB, 0, sizeof(HASWVertex));
        if(FAILED(hResult))
            { HSWDISPLAY_LOG(("[HSWDisplay D3D9] SetStreamSource failed. %d (%x)", hResult, hResult)); }

        RenderParams.Device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
        RenderParams.Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
		RenderParams.Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
        RenderParams.Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
		RenderParams.Device->SetRenderState(D3DRS_LIGHTING, FALSE);
        RenderParams.Device->SetRenderState(D3DRS_ZENABLE, FALSE);
        RenderParams.Device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
        RenderParams.Device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
        RenderParams.Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
        RenderParams.Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

        const float scale  = HSWDISPLAY_SCALE * ((RenderState.OurHMDInfo.HmdType == HmdType_DK1) ? 0.70f : 1.f);
        Matrix4f identityMatrix = Matrix4f::Identity();
        Vector3f translation = OrthoProjection[eye].GetTranslation();
        Matrix4f orthoStereoMatrix(
            scale, 0, 0, 0,
            0, scale / 2, 0, 0,
            0, 0, HSWDISPLAY_DISTANCE, 0,
            translation.x, translation.y, translation.z, 1
            );
        RenderParams.Device->SetTransform(D3DTS_WORLD,      reinterpret_cast<const D3DMATRIX*>(&identityMatrix));
        RenderParams.Device->SetTransform(D3DTS_VIEW,       reinterpret_cast<const D3DMATRIX*>(&identityMatrix));
        RenderParams.Device->SetTransform(D3DTS_PROJECTION, reinterpret_cast<const D3DMATRIX*>(&orthoStereoMatrix));
        RenderParams.Device->SetTransform(D3DTS_TEXTURE0,   reinterpret_cast<const D3DMATRIX*>(&identityMatrix));

        hResult = RenderParams.Device->SetFVF(HASWVertexD3D9Format);
        if(FAILED(hResult))
            { HSWDISPLAY_LOG(("[HSWDisplay D3D9] SetFVF failed. %d (%x)", hResult, hResult)); }

        hResult = RenderParams.Device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
        if(FAILED(hResult))
            { HSWDISPLAY_LOG(("[HSWDisplay D3D9] DrawPrimitive failed. %d (%x)", hResult, hResult)); }

        hResult = RenderParams.Device->EndScene();
        if(FAILED(hResult))
            { HSWDISPLAY_LOG(("[HSWDisplay D3D9] EndScene failed. %d (%x)", hResult, hResult)); }


        // Restore previous state.
        RenderParams.Device->SetRenderTarget(0, pRenderTargetSaved);
        RenderParams.Device->SetViewport(&viewportSaved);
        RenderParams.Device->SetPixelShader(pPixelShaderSaved);
        RenderParams.Device->SetVertexShader(pVertexShaderSaved);
        RenderParams.Device->SetTransform(D3DTS_TEXTURE0, &texture0MatrixSaved);
        RenderParams.Device->SetTransform(D3DTS_PROJECTION, &projectionMatrixSaved);
        RenderParams.Device->SetTransform(D3DTS_VIEW, &viewMatrixSaved);
        RenderParams.Device->SetTransform(D3DTS_WORLD, &worldMatrixSaved);
        RenderParams.Device->SetTexture(0, pTexture0Saved);
        RenderParams.Device->SetTexture(1, pTexture1Saved);
        RenderParams.Device->SetStreamSource(0, pVBDSaved, vbOffsetSaved, vbStrideSaved);
        RenderParams.Device->SetFVF(fvfSaved);
    }
}
void HSWDisplay::DismissInternal()
{
    HSWDISPLAY_LOG(("[HSWDisplay D3D9] DismissInternal()"));
    UnloadGraphics();
}