2013-01-15 55 views
1

使用D3D10,我繪製了一個2D矩形,並希望用每秒應該改變幾次的紋理(位圖)來填充它(如顯示視頻)。如何在每個幀(D3D10)中更新像素着色器中的Texture2D?

我正在使用着色器效果,使用Texture2D變量,並嘗試更新ID3D10EffectShaderResourceVariable並重新繪製網格。

我的實際使用情況是通過從內存中複製位圖並使用UpdateSubresource。 但它沒有工作,所以我減少它來測試兩個DDS圖像之間的切換。 結果是,它按預期繪製第一幅圖像,但仍然繪製它而不是在兩幅圖像之間切換。

我是D3D的新手。你能否解釋一下這種方法能否奏效,或者提出正確的方法。

的着色效果:

Texture2D txDiffuse; 
SamplerState samLinear 
{ 
    Filter = MIN_MAG_MIP_LINEAR; 
    AddressU = Wrap; 
    AddressV = Wrap; 
}; 
struct VS_INPUT 
{ 
    float4 Pos : POSITION; 
    float2 Tex : TEXCOORD; 
}; 
struct PS_INPUT 
{ 
    float4 Pos : SV_POSITION; 
    float2 Tex : TEXCOORD0; 
}; 
PS_INPUT VS(VS_INPUT input) 
{ 
    PS_INPUT output = (PS_INPUT)0; 
    output.Pos = input.Pos; 
    output.Tex = input.Tex;  
    return output; 
} 
float4 PS(PS_INPUT input) : SV_Target 
{ 
    return txDiffuse.Sample(samLinear, input.Tex); 
} 
technique10 Render 
{ 
    pass P0 
    { 
     SetVertexShader(CompileShader(vs_4_0, VS())); 
     SetGeometryShader(NULL); 
     SetPixelShader(CompileShader(ps_4_0, PS())); 
    } 
} 

代碼(跳過許多地區):

ID3D10ShaderResourceView*   g_pTextureRV = NULL; 
ID3D10EffectShaderResourceVariable* g_pDiffuseVariable = NULL; 

D3DX10CreateEffectFromResource(gInstance, MAKEINTRESOURCE(IDR_RCDATA1), NULL, NULL, NULL, "fx_4_0", dwShaderFlags, 0, device, NULL, NULL, &g_pEffect, NULL, NULL); 

g_pTechnique = g_pEffect->GetTechniqueByName("Render"); 
g_pDiffuseVariable = g_pEffect->GetVariableByName("txDiffuse")->AsShaderResource(); 

// this part is called on Frame render: 

device->CreateRenderTargetView(backBuffer, NULL, &rtView); 
device->ClearRenderTargetView(rtView, ClearColor); 

if(g_pTextureRV != NULL) { 
    g_pTextureRV->Release(); 
    g_pTextureRV = NULL; 
} 

D3DX10CreateShaderResourceViewFromFile(device, pCurrentDDSFilePath, NULL, NULL, &g_pTextureRV, NULL); 
g_pDiffuseVariable->SetResource(g_pTextureRV); 

D3D10_TECHNIQUE_DESC techDesc; 
g_pTechnique->GetDesc(&techDesc); 
for(UINT p = 0; p < techDesc.Passes; ++p) 
{ 
    g_pTechnique->GetPassByIndex(p)->Apply(0); 
    direct2dDrawingContext->dev->Draw(6, 0); 
} 

// ... present the current back buffer 

回答

1

一個解決辦法,不一定是最好的,但一個不使用自定義着色器,如下(我寫在C#/ Managed DirectX中,但它應該很容易轉碼。)

Bitmap bmp; //the bitmap that you will use to update the texture 
Texture tex; //the texture that DirectX will render 

void Render() 
{ 
    //render some stuff 

    bmp = GetNextTextureFrame(); //whatever you do to update your bitmap 
    Surface s = tex.GetSurfaceLevel(0); 
    Graphics g = s.GetGraphics(); 
    //IntPtr hdc = g.GetHdc(); 
    //BitBlt(hdc, 0, 0, bmp.Width, bmp.Height, bmpHdc, 0, 0, 0xcc0020); 
    g.DrawImageUnscaled(bmp, 0, 0); 
    g.ReleaseHdc(hdc); 
    s.ReleaseGraphics(); 
    device.SetTexture(0, tex); 
    //now render your primitives 

    //render some more stuff 
    //present 
} 

註釋掉li nes是我真正做到的,使用帶有BitBlt的hBitmap和DC,因爲它比GDI +更快。很多人可能會告訴你,由於所有內存鎖定必須發生,上面的方法是不好的,他們可能是對的。但是我能夠以多個1920x1080紋理達到30fps,所以無論它是否合適,它都能正常工作。

相關問題