2012-11-12 23 views
6

Tôi đang tìm cách đọc màu pixel tại điểm chuột. Trong OpenGL nó được thực hiện bằng cách gọi hàm "glReadPixels" sau khi vẽ cảnh (hoặc một phần của nó). Tôi muốn thực hiện một thói quen chọn màu đơn giản trong nền, để xác định một hình dạng/dòng trong không gian 3D.Một chức năng như "glReadPixels" trong DirectX/SharpDX

Vì vậy, có phương pháp/chức năng/đề xuất tương đương nào để thực hiện tương tự trong SharpDX (DirectX10/DirectX11) không?

Trả lời

8

này là hoàn toàn có thể với Direct3D11: chỉ cần làm theo các bước sau:

  • Sử dụng DeviceContext.CopySubResourceRegion để sao chép một phần từ kết cấu nguồn tới một kết cấu dàn (kích thước của vùng pixel bạn muốn readback, cùng định dạng, nhưng với ResourceUsage.Staging)
  • Lấy pixel từ kết cấu dàn này bằng Device.Map/UnMap.

Có rất nhiều cuộc thảo luận về chủ đề này trên mạng (ví dụ: "Reading one pixel from texture to CPU in DX11")

+0

Có phải cái gì đó giống như thế này có thể trong DX9 không? – jjxtra

1

Vì bạn đang sử dụng C#, đề xuất của tôi sẽ là sử dụng GDI +, vì không có chức năng như "glReadPixels" trong DX. GDI + cung cấp các phương pháp rất dễ đọc màu của một pixel ở con trỏ chuột của bạn. Tham khảo stackoverflow.com/questions/1483928.

Nếu GDI + không hoạt động, vì nó không phải là rất nhanh, bạn không thể bám vào đối tượng thông thường bằng cách sử dụng "Ray"? Bạn muốn xác định (tôi giả sử 3 chiều) hình dạng/dòng, điều này sẽ dễ dàng bằng cách sử dụng một tia (và kiểm tra giao lộ) để chọn chúng.

+0

[..] đối tượng chọn bằng cách sử dụng "Ray" [..] - đây là suy nghĩ của tôi, nhưng tôi nghĩ, nếu có bất kỳ chức năng nào như "ReadPixels", tôi có thể sử dụng nó - trong một số trường hợp, chọn màu có thể rất tốt, nhưng bạn nói đúng, vì nhu cầu của tôi, tia sáng sẽ làm công việc. Và, GDI + - tôi không nghĩ về điều này .. nhưng bạn nói đúng, sau khi dựng hình, tôi có thể đọc pixel từ điều khiển - bởi vì tôi chỉ đọc một pixel mỗi khung hình/cập nhật, tốc độ không quan trọng lắm . Cảm ơn câu trả lời của bạn :) – lunatix

+0

Vì vậy, tôi đã cố gắng thực hiện đề xuất GDI + (tôi muốn thử nó, và nó hoạt động tốt :)) nhưng có một vấn đề còn lại - tôi có một cửa sổ WPF với một WindowsFormsHost và một Panel trong nó, vẽ đến các bảng điều khiển thông qua DirectX.Nhưng tôi chỉ nhận được backcolor của bảng điều khiển, không whats thực sự trong đó =/Nếu tôi sử dụng cửa sổ máy tính để bàn, tôi nhận được màu sắc của tôi .. bất kỳ giải pháp cho điều này = /? – lunatix

+0

Vì vậy, tôi có một giải pháp - tôi chiếu tọa độ chuột vào không gian màn hình và sử dụng pixel "máy tính để bàn" - vì vậy, khi cửa sổ của tôi ở trên cùng, tôi nhận được pixel được yêu cầu. Giải pháp là Ok, nhưng tôi muốn sử dụng bảng điều khiển đầu ra "thực" .. – lunatix

2

Một lựa chọn khác là sử dụng một Shader tính toán nhỏ, như:

Texture2D<float4> TextureInput: register(t0); 
StructuredBuffer<float2> UVBuffer: register(t1); 
RWStructuredBuffer<float4> RWColorBuffer : register(u0); 

SamplerState Sampler : register(s0); 

[numthreads(1, 1, 1)] 
void CSGetPixels(uint3 DTid : SV_DispatchThreadID) 
{ 
float4 c = TextureInput.SampleLevel(Sampler , UVBuffer[DTid.x].xy, 0); 
RWColorBuffer [DTid.x] = c; 
} 

Nó cung cấp cho bạn có lợi thế hơn một chút "định dạng bất khả tri".

Quá trình sẽ diễn ra như sau.

  • Tạo bộ đệm có cấu trúc nhỏ cho UV (float2) (vị trí pixel/kích thước kết cấu, đừng quên lật trục Y). Sao chép vị trí pixel bạn muốn lấy mẫu vào bộ đệm này.
  • Tạo bộ đệm có thể ghi và bộ đệm dàn dựng (float4). Cần phải được tính cùng một yếu tố như bộ đệm uv của bạn.
  • Kết hợp tất cả và công văn
  • Sao chép bộ đệm có thể ghi vào dàn dựng.
  • Bản đồ và đọc dữ liệu float4 trong cpu

Xin lưu ý tôi bỏ qua thread group tối ưu hóa/kiểm tra trong tính toán đổ bóng cho đơn giản.

+0

Interresting và đẹp o_o Tôi sẽ kiểm tra này nếu tôi có thời gian cho :) Trên thực tế, tôi thực hiện một ray chọn nhịp với kiểm tra giao nhau :) – lunatix