2011-04-23 10 views
3

글쎄, 문제는 간단합니다. WPF 비주얼에서 렌더링 된 것이 있습니다. DirectX Texture를 사용하고 싶습니다. 현재, 다음 코드를 사용하여 작업을 완료합니다.WPF 비주얼을 DirectX Texture (성능 현명한)로 가져 오는 빠른 코드

var bmp = new System.Windows.Media.Imaging.RenderTargetBitmap(bound.Width, bound.Height, 96, 96, System.Windows.Media.PixelFormats.Pbgra32); 
bmp.Render(drawingVisual); 
var encoder = new System.Windows.Media.Imaging.PngBitmapEncoder(); 
encoder.Frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create(bmp)); 
Texture texture = new Texture(dxDevice, bound.Width, bound.Height, 1, Usage.RenderTarget, Format.A8R8G8B8, Pool.Default); 
using (MemoryStream ms = new MemoryStream()) 
{ 
    encoder.Save(ms); 
    ms.Seek(0, SeekOrigin.Begin); 
    Surface privateSurface = texture.GetSurfaceLevel(0); 
    SurfaceLoader.FromStream(privateSurface, ms, Filter.None, Color.MediumAquamarine.ToArgb()); 
    ms.Close(); 
} 
return texture; // our prepared texture 

그러나 다소 천천히, 분명히 있습니다. 당신은 사람들이 그것을 더 빨리 만들 수있는 어떤 것을 제안 할 수 있습니까?

[편집] CopyPixels()을 사용하여 데이터를로드하려고 시도했지만 D3DXERR_INVALIDDATA 예외가 발생합니다.

RenderTargetBitmap bmp = GetBitmap(); 
// copy into a byte array 
int stride = bmp.PixelWidth * 4; 
byte[] data = new byte[bmp.PixelHeight * stride]; 
bmp.CopyPixels(data, stride, 0); 

// create texture 
using (MemoryStream ms = new MemoryStream(data)) 
{ 
    ms.Seek(0, SeekOrigin.Begin); 

    if (dxDevice != null) 
    { 
     // next line throws D3DXERR_INVALIDDATA exception 
     texture = TextureLoader.FromStream(dxDevice, ms); 
    } 
} 

[편집] 좋아, 그래서 여기에 내가 그것을 할 관리 방법은 다음과 같습니다.

RenderTargetBitmap bmp = GetBitmap(); 
// copy into a byte array 
int stride = bmp.PixelWidth * 4; 
byte[] data = new byte[bmp.PixelHeight * stride]; 
bmp.CopyPixels(data, stride, 0); 

// create texture 
Texture texture = new Texture(dxDevice, bound.Width, bound.Height, 1, Usage.SoftwareProcessing, Format.A8R8G8B8, Pool.Managed); 
Surface privateSurface = texture.GetSurfaceLevel(0); 
var graphicsStream = privateSurface.LockRectangle(LockFlags.None); 
graphicsStream.Write(data); 
privateSurface.UnlockRectangle(); 

답변

2

예. 여전히 RenderTargetBitmap을 사용할 수 있습니다. 그러나 PNG로 인코딩하고 Direct3D에서 읽는 대신 RenderTargetBitmap에서 CopyPixels을 호출 한 다음 픽셀을 텍스처에 직접 쓸 수 있습니다. 훨씬 빨라야합니다!

// render the visual, just like you did 
var bmp = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Default, null); 
bmp.Render(visual); 

// get the pixels 
var pixels = new int[width * height]; 
bmp.CopyPixels(pixels, 4 * width, 0); // each line consists of 4*width bytes. 

는 이제 사용하는 정확한 API에 따라 (SlimDX? 뭔가 다른?) 당신은 당신의 질감을 고정하고 텍스처에 pixels 배열에 데이터를 작성해야합니다.

+0

이것은 정확히 내가 알아 내려고하는 것입니다 .. 일부 코드는 도움이 될 것입니다 .. – Trainee4Life

+0

일부 코드로 업데이트되었습니다. 희망이 도움이됩니다. – Alex

+0

내 질문이 업데이트되었습니다. 내가 제안한 것을하려고했지만 D3DXERR_INVALIDDATA 예외가 발생합니다. 다른 건 당신이 제안하고 싶어? – Trainee4Life