locked
Transparent Texture with WicImagingFactory

    Question

  • Since I convert my program to windows 7 to the new windows 8 application, I've loose transparency. All display correctly but transparency. Working well with D3DX::CreateTextureFromFile (old direct sdk)

    HRESULT CRXMaterial::InitializeShader(CRXDirect3D* pDirect3D, wchar_t* VertexShader, wchar_t* PixelShader, wchar_t* TextureFileName, wchar_t* DataBaseName)
    {
    	HRESULT hr = S_OK;
    	m_pDirect3D = pDirect3D;
    	//m_player->Initialize(m_pDirect3D->GetD3DDevice(), DXGI_FORMAT_B8G8R8A8_UNORM);
    
    	ID3D11Texture2D* m_pTexture = (ID3D11Texture2D*)CreateTextureFromMemory(TextureFileName, DataBaseName);
    	
    	CreateShaderRessourceView(m_pTexture);
    	CreateShaderEffect(VertexShader, PixelShader, DataBaseName);
    
    	return S_OK;
    }
    
    //***************************************************************************
    // Output         : ID3D11Texture2D*
    // Class name     : CRXMaterial
    // Function name  : CreateEmptyTexture
    // Description    : Create a empty texture
    //***************************************************************************
    ID3D11Texture2D* CRXMaterial::CreateEmptyTexture()
    {
    	CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_R8G8B8A8_UNORM, 1920, 1080, 1, 1, D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET);
    	ID3D11Texture2D* pRenderTarget = NULL;
    	m_pDirect3D->GetD3DDevice()->CreateTexture2D(&desc, NULL, &pRenderTarget);
    
    	return pRenderTarget;
    }
    
    //***************************************************************************
    // Output         : ID3D11Resource*
    // Class name     : CRXMaterial
    // Function name  : CreateTextureFromMemory
    // Description    : Create a texture from memory
    // Input          : wchar_t* TextureFileName
    // Input          : wchar_t* DataBaseName
    //***************************************************************************
    ID3D11Resource* CRXMaterial::CreateTextureFromMemory(wchar_t* TextureFileName, wchar_t* DataBaseName)
    {
    	CRXDatabase* Db = new CRXDatabase(DataBaseName);
    	CRXDBNode* DbNode = Db->GetElementFromDB(TextureFileName, DataBaseName);
    
    	ID3D11Resource* pTextureRes = NULL;
    	if (!DbNode) return pTextureRes;
    	
    	if (DbNode->m_Label->Find(L".dds") != -1)
    		CreateDDSTextureFromMemory(m_pDirect3D->GetD3DDevice(), DbNode->m_File, DbNode->m_FileSize, &pTextureRes, &m_pTextureView);
    	else
    	{
    		IWICStream* stream;
    		ThrowIfFailed(m_pDirect3D->GetWicImagingFactory()->CreateStream(&stream));
    		ThrowIfFailed(stream->InitializeFromMemory(DbNode->m_File, DbNode->m_FileSize));
    
    		IWICBitmapDecoder* bitmapDecoder;
    		ThrowIfFailed(m_pDirect3D->GetWicImagingFactory()->CreateDecoderFromStream(stream, nullptr, WICDecodeMetadataCacheOnDemand, &bitmapDecoder));
    		
    		IWICBitmapFrameDecode* bitmapFrame;
    		ThrowIfFailed(bitmapDecoder->GetFrame(0, &bitmapFrame));
    
    		IWICFormatConverter* formatConverter;
    		ThrowIfFailed(m_pDirect3D->GetWicImagingFactory()->CreateFormatConverter(&formatConverter));
    		ThrowIfFailed(formatConverter->Initialize(bitmapFrame, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, nullptr, 0.0, WICBitmapPaletteTypeCustom));
    		
    		uint32 width;
    		uint32 height;
    		ThrowIfFailed(bitmapFrame->GetSize(&width, &height));
    
    		byte* bitmapPixels(new byte[width * height * 4]);
    		ThrowIfFailed(formatConverter->CopyPixels(nullptr, width * 4, width * height * 4, bitmapPixels));
    		
    		D3D11_SUBRESOURCE_DATA initialData;
    		ZeroMemory(&initialData, sizeof(initialData));
    		initialData.pSysMem = bitmapPixels;
    		initialData.SysMemPitch = width * 4;
    		initialData.SysMemSlicePitch = 0;
    
    		CD3D11_TEXTURE2D_DESC textureDesc(DXGI_FORMAT_B8G8R8A8_UNORM, width, height, 1, 1);
    
    		ID3D11Texture2D* pRenderTarget = NULL;
    		ThrowIfFailed(m_pDirect3D->GetD3DDevice()->CreateTexture2D(&textureDesc, &initialData, &pRenderTarget));
    
    		CD3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc(pRenderTarget, D3D11_SRV_DIMENSION_TEXTURE2D);
    
    		ThrowIfFailed(m_pDirect3D->GetD3DDevice()->CreateShaderResourceView(pRenderTarget, &shaderResourceViewDesc, &m_pTextureView));
    		pTextureRes = pRenderTarget;
    	}
    
    	delete DbNode;
    	return pTextureRes;
    }
    
    //***************************************************************************
    // Class name     : CRXMaterial
    // Function name  : CreateShaderRessourceView
    // Description    : Creer les ressoureces material
    // Input          : ID3D11Texture2D* pRenderTarget
    //***************************************************************************
    void CRXMaterial::CreateShaderRessourceView(ID3D11Texture2D* pRenderTarget)
    {
    	CD3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
    	D3D11_RESOURCE_DIMENSION Type;
    	pRenderTarget->GetType(&Type);
    
    	if (Type == D3D11_RESOURCE_DIMENSION_TEXTURE2D)
    	{
    		D3D11_TEXTURE2D_DESC Texture2DDesc;
    		ID3D11Texture2D* pTexture2D = (ID3D11Texture2D*)pRenderTarget;
    
    		pTexture2D->GetDesc(&Texture2DDesc);
    
    		srvDesc.Format = Texture2DDesc.Format;
    		srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
    		srvDesc.Texture2D.MipLevels = Texture2DDesc.MipLevels;
    		srvDesc.Texture2D.MostDetailedMip = 0;
    
    		TextureWidth = Texture2DDesc.Width;
    		TextureHeight = Texture2DDesc.Height;
    	}
    
    	m_pDirect3D->GetD3DDevice()->CreateShaderResourceView(pRenderTarget, &srvDesc, &m_pTextureView);
    
    	D3D11_SAMPLER_DESC samplerDescription;
        ZeroMemory(&samplerDescription, sizeof(D3D11_SAMPLER_DESC));
        samplerDescription.Filter = D3D11_FILTER_ANISOTROPIC;
        samplerDescription.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
        samplerDescription.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
        samplerDescription.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
        samplerDescription.MipLODBias = 0.0f;
        samplerDescription.MaxAnisotropy = 4;
        samplerDescription.ComparisonFunc = D3D11_COMPARISON_NEVER;
        samplerDescription.BorderColor[0] = 0.0f;
        samplerDescription.BorderColor[1] = 0.0f;
        samplerDescription.BorderColor[2] = 0.0f;
        samplerDescription.BorderColor[3] = 0.0f;
        samplerDescription.MinLOD = 0;
        samplerDescription.MaxLOD = D3D11_FLOAT32_MAX;
    
        ThrowIfFailed(m_pDirect3D->GetD3DDevice()->CreateSamplerState(&samplerDescription, &m_pSamplerState));
    }
    
    //***************************************************************************
    // Output         : HRESULT
    // Class name     : CRXMaterial
    // Function name  : CreateShaderEffect
    // Description    : Create a shader effect
    // Input          : wchar_t* VertexShader
    // Input          : wchar_t* PixelShader
    // Input          : wchar_t* DataBaseName
    //***************************************************************************
    HRESULT CRXMaterial::CreateShaderEffect(wchar_t* VertexShader, wchar_t* PixelShader, wchar_t* DataBaseName)
    {
    	CRXDatabase* Db = new CRXDatabase(DataBaseName);
    	CRXDBNode* DbNode = Db->GetElementFromDB(L"Shaders\\Vertex.cso", DataBaseName);
    	if (!DbNode) return E_FAIL;
    
    	D3D11_INPUT_ELEMENT_DESC vertexDesc[] =
    	{		
    		{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    		{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    		{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    		{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }
    	};
    
    	ThrowIfFailed(m_pDirect3D->GetD3DDevice()->CreateVertexShader(DbNode->m_File, DbNode->m_FileSize, nullptr, &m_pVertexShader));
    	ThrowIfFailed(m_pDirect3D->GetD3DDevice()->CreateInputLayout(vertexDesc, ARRAYSIZE(vertexDesc), DbNode->m_File, DbNode->m_FileSize, &m_pInputLayout));
    	
    	DbNode = Db->GetElementFromDB(L"Shaders\\Pixel.cso", DataBaseName);
    	if (!DbNode) return E_FAIL;
    
    	ThrowIfFailed(m_pDirect3D->GetD3DDevice()->CreatePixelShader(DbNode->m_File, DbNode->m_FileSize, nullptr, &m_pPixelShader));
    
    	CD3D11_BUFFER_DESC constantBufferDesc(sizeof(ConstantBufferData), D3D11_BIND_CONSTANT_BUFFER);
    	ThrowIfFailed(m_pDirect3D->GetD3DDevice()->CreateBuffer(&constantBufferDesc, nullptr, &m_pConstantBuffer));
    
    	return S_OK;
    }
    Pixel.hlsl
    Texture2D SimpleTexture : register(t0);
    SamplerState SimpleSampler : register(s0);
    
    // Données de couleur par pixel transmises via le nuanceur de pixels.
    struct PixelShaderInput
    {
    	float4 pos : SV_POSITION;
    	float3 normal : NORMAL;
    	float2 tex : TEXCOORD0;
    	float4 color : COLOR0;
    };
    
    // Fonction de transmission directe pour les données de couleur (interpolé).
    float4 main(PixelShaderInput input) : SV_TARGET
    {
    	float3 lightDirection = normalize(float3(1, -1, 0));
    	return SimpleTexture.Sample(SimpleSampler, input.tex) * (0.8f * saturate(dot(input.normal , -lightDirection)) + 0.2f);
    }

    Vertex.hlsl

    // Une mémoire tampon constante qui stocke les trois matrices colonne-major de base pour composer la géométrie.
    cbuffer ConstantBuffer : register(b0)
    {
    	matrix Model;
    	matrix View;
    	matrix Projection;
    };
    
    struct VertexShaderInput
    {
    	float3 pos : POSITION;
    	float3 normal : NORMAL;
    	float2 tex : TEXCOORD0;
    	float4 color : COLOR0;
    };
    
    struct PixelShaderInput
    {
    	float4 pos : SV_POSITION;
    	float3 normal : NORMAL;
    	float2 tex : TEXCOORD0;
    	float4 color : COLOR0;
    };
    
    PixelShaderInput main(VertexShaderInput input)
    {
    	PixelShaderInput output;
    	float4 pos = float4(input.pos, 1.0f);
    
    	// Transformer la position vertex en un espace projeté.
    	pos = mul(pos, Model);
    	pos = mul(pos, View);
    	pos = mul(pos, Projection);
    	output.pos = pos;
    
    	// Transmettre la couleur sans aucune modification.
    	output.color = input.color;
    	output.tex = input.tex;
    	output.normal = mul(float4(input.normal , 1.0f), Model).xyz;
    
    	return output;
    }
    



    Sunday, November 23, 2014 7:18 AM

All replies

  • I'll ask one of our DirectX gurus to help here.

    Matt Small - Microsoft Escalation Engineer - Forum Moderator
    If my reply answers your question, please mark this post as answered.

    NOTE: If I ask for code, please provide something that I can drop directly into a project and run (including XAML), or an actual application project. I'm trying to help a lot of people, so I don't have time to figure out weird snippets with undefined objects and unknown namespaces.

    Monday, November 24, 2014 8:16 PM
    Moderator
  • The WIC loader in the Windows Store apps sample is extremely simple and forces all files to convert to a specific format. You should look at the WICTextureLoader in the DirectX Tool Kit which is much more robust.

    The other thing to note is that the WIC code above forces the conversion to premultiplied alpha which requires specific blend configuration to work as you'd expect vs. 'straight-alpha' which is likely what you were using with the legacy D3DX library. WICTextureLoader supports both.


    Monday, November 24, 2014 8:35 PM
  • Thanks for reply.

    After Comparing and Reintegrate all the stuff with WICTextureLoader from DirectX Tool Kit, I still have the same result. Image was showed without transparency.  My Own function was derived from Windows dev center that show up 4 easy step (I didn't remember the link, but look like this in more detail)

    • Load Texture
    • CreateTexture2D
    • CreateShaderResourceView
    • CreateShaderEffect

    By logic CreateTextureFromWIC replace the first three steps, I've also try to tweak CreateTextureFromWICEx in diffrent way. Because the first three step was similar, does the problem can come from CreateShaderEffect or HLSL file???


    I've also read the premultiplied alpha article, but it's seem take XNA and C# in consideration but I'm using C++/DirectX 11.2/IFrameworkView Based compatible X64,X86,ARM. Article that talk about code vs math but...

    Does native DirectX C++ version have RenderState equivalent?

    For the math version what is the best way to process?

    1. Directly on the 2D Texture (Map/UnMap tricks)
    2. By the shader file .HLSL/.CSO (Pixel or Vertex?)

    Wednesday, November 26, 2014 6:24 AM