2013-01-15 5 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

하나의 솔루션, 반드시 최선을 다하지만 사용자 정의 쉐이더를 사용하지 않는 한, (I 다음 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는 GDI +보다 빠르기 때문에 실제로 BitBlt와 함께 hBitmap과 DC를 사용하여 실제로 수행 한 방법입니다. 많은 사람들이 아마도 위와 같은 것이 메모리를 잠그기 위해 나쁜 방법이라고 말할 것입니다. 왜냐하면 모든 메모리 잠금이 발생해야하기 때문입니다. 그리고 아마 맞을 것입니다. 그러나 여러 1920x1080 텍스처로 30fps를 달성 할 수 있었으므로 적합 여부에 관계없이 작동합니다.

관련 문제