2009-04-19 36 views
7

Tôi có một đối tượng FBO với một tập tin đính kèm màu sắc và chiều sâu mà tôi render và sau đó đọc từ sử dụng glReadPixels() và tôi đang cố gắng thêm vào nó hỗ trợ multisampling.
Thay vì glRenderbufferStorage() Tôi đang gọi glRenderbufferStorageMultisampleEXT() cho cả tệp đính kèm màu và tệp đính kèm độ sâu. Đối tượng bộ đệm khung dường như đã được tạo thành công và được báo cáo là hoàn chỉnh.
Sau khi hiển thị, tôi đang cố đọc từ đó với glReadPixels(). Khi số lượng mẫu là 0, nghĩa là multisampling vô hiệu hóa nó hoạt động hoàn hảo và tôi nhận được hình ảnh tôi muốn. khi tôi đặt số lượng mẫu cho một thứ khác, giả sử 4, bộ đệm khung vẫn được tạo OK nhưng glReadPixels() không thành công với một INVALID_OPERATIONglReadPixels từ FBO thất bại với multisampling

Bất kỳ ai có ý tưởng gì có thể sai ở đây?

EDIT: Mã của glReadPixels:

glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, ptr); 

nơi điểm ptr đến một mảng rộng * uints chiều cao.

+0

Bạn có thể gửi dòng đầy đủ cho glReadPixels của bạn() gọi (định dạng, chủng loại, vv)? –

Trả lời

23

Tôi không nghĩ rằng bạn có thể đọc từ FBO nhiều trang với glReadPixels(). Bạn cần phải blit từ FBO multisampled đến một FBO bình thường, ràng buộc FBO bình thường, và sau đó đọc các điểm ảnh từ FBO bình thường.

Something như thế này:

// Bind the multisampled FBO for reading 
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, my_multisample_fbo); 
// Bind the normal FBO for drawing 
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, my_fbo); 
// Blit the multisampled FBO to the normal FBO 
glBlitFramebufferEXT(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST); 
//Bind the normal FBO for reading 
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, my_fbo); 
// Read the pixels! 
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); 
+0

"Tôi không nghĩ rằng bạn có thể đọc từ một multisampled" - Có bất kỳ tài liệu tham khảo cho điều đó? – shoosh

+2

Ở đây bạn đi (cuộn xuống dưới): http://www.opengl.org/wiki/GL_EXT_framebuffer_multisample –

+0

Cách khởi tạo 'my_fbo' thành blit? –

1

Bạn không thể đọc được đệm multisample trực tiếp với glReadPixels vì nó sẽ nâng cao một lỗi GL_INVALID_OPERATION. Bạn cần phải chuyển sang một bề mặt khác để GPU có thể thực hiện một mẫu. Bạn có thể đổ lỗi cho backbuffer, nhưng có vấn đề của "kiểm tra tàu chủ sở hữu pixel". Tốt nhất là làm một FBO khác. Giả sử bạn tạo một FBO khác và bây giờ bạn muốn blit. Điều này yêu cầu GL_EXT_framebuffer_blit. Thông thường, khi trình điều khiển của bạn hỗ trợ GL_EXT_framebuffer_multisample, nó cũng hỗ trợ GL_EXT_framebuffer_blit, ví dụ như dòng nVidia Geforce 8.

//Bind the MS FBO 
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, multisample_fboID); 
//Bind the standard FBO 
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fboID); 
//Let's say I want to copy the entire surface 
//Let's say I only want to copy the color buffer only 
//Let's say I don't need the GPU to do filtering since both surfaces have the same dimension 
glBlitFramebufferEXT(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST); 
//-------------------- 
//Bind the standard FBO for reading 
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboID); 
glReadPixels(0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, pixels); 

Nguồn: GL EXT framebuffer multisample