// This is a temporary function implementation, and it functionality needs to be implemented in a more generic way.
Texture* LoadTextureTga(RenderParams& rParams, int samplerMode, OVR::File* f, uint8_t alpha)
{
    OVR::CAPI::GL::Texture* pTexture = NULL;

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

    if (pRGBA)
    {
        pTexture = new OVR::CAPI::GL::Texture(&rParams, width, height);

        // SetSampleMode forces the use of mipmaps through GL_LINEAR_MIPMAP_LINEAR.
        pTexture->SetSampleMode(samplerMode); // Calls glBindTexture internally.

        // We are intentionally not using mipmaps. We need to use this because Texture::SetSampleMode unilaterally uses GL_LINEAR_MIPMAP_LINEAR.
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
        OVR_ASSERT(glGetError() == 0);

        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pRGBA);
        OVR_ASSERT(glGetError() == 0);

        // With OpenGL 4.2+ we can use this instead of glTexImage2D:
        // glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
        // glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pRGBA);

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

    return pTexture;
}
// 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;
}