Exemplo n.º 1
0
bool Texture2D::Create()
{
    Release();

    if (!graphics_ || !width_ || !height_)
        return false;

    if (graphics_->IsDeviceLost())
    {
        URHO3D_LOGWARNING("Texture creation while device is lost");
        return true;
    }

    if (multiSample_ > 1 && !autoResolve_)
    {
        URHO3D_LOGWARNING("Multisampled texture without autoresolve is not supported on Direct3D9");
        autoResolve_ = true;
    }

    GraphicsImpl* impl = graphics_->GetImpl();

    unsigned pool = usage_ > TEXTURE_STATIC ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED;
    unsigned d3dUsage = 0;

    switch (usage_)
    {
    case TEXTURE_DYNAMIC:
        d3dUsage |= D3DUSAGE_DYNAMIC;
        break;
    case TEXTURE_RENDERTARGET:
        d3dUsage |= D3DUSAGE_RENDERTARGET;
        if (requestedLevels_ != 1)
        {
            // Check mipmap autogeneration support
            if (impl->CheckFormatSupport((D3DFORMAT)format_, D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE))
            {
                requestedLevels_ = 0;
                d3dUsage |= D3DUSAGE_AUTOGENMIPMAP;
            }
            else
                requestedLevels_ = 1;
        }
        break;
    case TEXTURE_DEPTHSTENCIL:
        d3dUsage |= D3DUSAGE_DEPTHSTENCIL;
        // No mipmaps for depth-stencil textures
        requestedLevels_ = 1;
        break;
    default:
        break;
    }

    if (multiSample_ > 1)
    {
        // Fall back to non-multisampled if unsupported multisampling mode
        if (!impl->CheckMultiSampleSupport((D3DFORMAT)format_,  multiSample_))
        {
            multiSample_ = 1;
            autoResolve_ = false;
        }
    }

    IDirect3DDevice9* device = graphics_->GetImpl()->GetDevice();
    // If creating a depth-stencil texture, and it is not supported, create a depth-stencil surface instead
    // Multisampled surfaces need also to be created this way
    if (usage_ == TEXTURE_DEPTHSTENCIL && (multiSample_ > 1 || !graphics_->GetImpl()->CheckFormatSupport((D3DFORMAT)format_, 
        d3dUsage, D3DRTYPE_TEXTURE)))
    {
        HRESULT hr = device->CreateDepthStencilSurface(
            (UINT)width_,
            (UINT)height_,
            (D3DFORMAT)format_,
            (multiSample_ > 1) ? (D3DMULTISAMPLE_TYPE)multiSample_ : D3DMULTISAMPLE_NONE,
            0,
            FALSE,
            (IDirect3DSurface9**)&renderSurface_->surface_,
            nullptr);
        if (FAILED(hr))
        {
            URHO3D_LOGD3DERROR("Could not create depth-stencil surface", hr);
            URHO3D_SAFE_RELEASE(renderSurface_->surface_);
            return false;
        }

        levels_ = 1;
    }
    else
    {
        HRESULT hr = graphics_->GetImpl()->GetDevice()->CreateTexture(
            (UINT)width_,
            (UINT)height_,
            requestedLevels_,
            d3dUsage,
            (D3DFORMAT)format_,
            (D3DPOOL)pool,
            (IDirect3DTexture9**)&object_,
            nullptr);
        if (FAILED(hr))
        {
            URHO3D_LOGD3DERROR("Could not create texture", hr);
            URHO3D_SAFE_RELEASE(object_.ptr_);
            return false;
        }

        levels_ = ((IDirect3DTexture9*)object_.ptr_)->GetLevelCount();

        // Create the multisampled rendertarget for rendering to if necessary
        if (usage_ == TEXTURE_RENDERTARGET && multiSample_ > 1)
        {
            HRESULT hr = device->CreateRenderTarget(
                (UINT)width_,
                (UINT)height_,
                (D3DFORMAT)format_,
                (D3DMULTISAMPLE_TYPE)multiSample_,
                0,
                FALSE,
                (IDirect3DSurface9**)&renderSurface_->surface_,
                nullptr);
            if (FAILED(hr))
            {
                URHO3D_LOGD3DERROR("Could not create multisampled rendertarget surface", hr);
                URHO3D_SAFE_RELEASE(renderSurface_->surface_);
                return false;
            }
        }
        else if (usage_ >= TEXTURE_RENDERTARGET)
        {
            // Else use the texture surface directly for rendering
            hr = ((IDirect3DTexture9*)object_.ptr_)->GetSurfaceLevel(0, (IDirect3DSurface9**)&renderSurface_->surface_);
            if (FAILED(hr))
            {
                URHO3D_LOGD3DERROR("Could not get rendertarget surface", hr);
                URHO3D_SAFE_RELEASE(renderSurface_->surface_);
                return false;
            }
        }
    }

    return true;
}
Exemplo n.º 2
0
bool TextureCube::Create()
{
    Release();

    if (!graphics_ || !width_ || !height_)
        return false;

    if (graphics_->IsDeviceLost())
    {
        URHO3D_LOGWARNING("Texture creation while device is lost");
        return true;
    }

    GraphicsImpl* impl = graphics_->GetImpl();

    unsigned pool = usage_ > TEXTURE_STATIC ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED;
    unsigned d3dUsage = 0;

    switch (usage_)
    {
    case TEXTURE_DYNAMIC:
        d3dUsage |= D3DUSAGE_DYNAMIC;
        break;
    case TEXTURE_RENDERTARGET:
        d3dUsage |= D3DUSAGE_RENDERTARGET;
        if (requestedLevels_ != 1)
        {
            // Check mipmap autogeneration support
            if (impl->CheckFormatSupport((D3DFORMAT)format_, D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE))
            {
                requestedLevels_ = 0;
                d3dUsage |= D3DUSAGE_AUTOGENMIPMAP;
            }
            else
                requestedLevels_ = 1;
        }
        break;
    default:
        break;
    }

    if (multiSample_ > 1)
    {
        // Fall back to non-multisampled if unsupported multisampling mode
        GraphicsImpl* impl = graphics_->GetImpl();
        if (!impl->CheckMultiSampleSupport((D3DFORMAT)format_, multiSample_))
        {
            multiSample_ = 1;
            autoResolve_ = false;
        }
    }

    IDirect3DDevice9* device = graphics_->GetImpl()->GetDevice();
    HRESULT hr = device->CreateCubeTexture(
        (UINT)width_,
        requestedLevels_,
        d3dUsage,
        (D3DFORMAT)format_,
        (D3DPOOL)pool,
        (IDirect3DCubeTexture9**)&object_.ptr_,
        nullptr);
    if (FAILED(hr))
    {
        URHO3D_LOGD3DERROR("Could not create cube texture", hr);
        URHO3D_SAFE_RELEASE(object_.ptr_);
        return false;
    }

    levels_ = ((IDirect3DCubeTexture9*)object_.ptr_)->GetLevelCount();

    if (usage_ == TEXTURE_RENDERTARGET)
    {
        for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i)
        {
            if (multiSample_ > 1)
            {
                // Create the multisampled face rendertarget if necessary
                HRESULT hr = device->CreateRenderTarget(
                    (UINT)width_,
                    (UINT)height_,
                    (D3DFORMAT)format_,
                    (D3DMULTISAMPLE_TYPE)multiSample_,
                    0,
                    FALSE,
                    (IDirect3DSurface9**)&renderSurfaces_[i]->surface_,
                    nullptr);
                if (FAILED(hr))
                {
                    URHO3D_LOGD3DERROR("Could not create multisampled rendertarget surface", hr);
                    URHO3D_SAFE_RELEASE(renderSurfaces_[i]->surface_);
                    return false;
                }
            }
            else
            {
                hr = ((IDirect3DCubeTexture9*)object_.ptr_)->GetCubeMapSurface((D3DCUBEMAP_FACES)i, 0,
                    (IDirect3DSurface9**)&renderSurfaces_[i]->surface_);
                if (FAILED(hr))
                {
                    URHO3D_LOGD3DERROR("Could not get rendertarget surface", hr);
                    URHO3D_SAFE_RELEASE(renderSurfaces_[i]->surface_);
                    return false;
                }
            }
        }
    }

    return true;
}