2012-11-27 27 views
7

Tôi đang cố gắng thực hiện chọn màu bằng FBO. Tôi có FBO multisampled (fbo [0]) mà tôi sử dụng để render scene và tôi có FBO không ghép (Fbo [1]) mà tôi sử dụng để chọn màu.glReadPixels() đặt cờ GL_INVALID_OPERATION không có lý do

Vấn đề là: khi tôi cố gắng đọc dữ liệu pixel từ fbo [1] mọi thứ diễn ra tốt đẹp cho đến khi cuộc gọi glReadPixels đặt cờ GL_INVALID_OPERATION. Tôi đã kiểm tra hướng dẫn sử dụng và không thể tìm thấy lý do tại sao.

Code để tạo FBO:

glBindRenderbuffer(GL_RENDERBUFFER, rbo[0]); 
glRenderbufferStorageMultisample(GL_RENDERBUFFER, numSamples, GL_RGBA8, resolution[0], resolution[1]); 
glBindRenderbuffer(GL_RENDERBUFFER, rbo[1]); 
glRenderbufferStorageMultisample(GL_RENDERBUFFER, numSamples, GL_DEPTH24_STENCIL8, resolution[0], resolution[1]); 
glBindRenderbuffer(GL_RENDERBUFFER, rbo[2]); 
glRenderbufferStorage(GL_RENDERBUFFER, GL_R32UI, resolution[0], resolution[1]); 
glBindRenderbuffer(GL_RENDERBUFFER, rbo[3]); 
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, resolution[0], resolution[1]); 

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[1]); 
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo[3]); 
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo[2]); 
OGLChecker::checkFBO(GL_DRAW_FRAMEBUFFER); 
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[0]); 
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo[1]); 
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo[0]); 
OGLChecker::checkFBO(GL_DRAW_FRAMEBUFFER); 

kiểm tra tôi vẫn im lặng nên FBOs được hoàn thành. Tiếp theo mã hái

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[1]); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
// bla, bla, bla 
// do the rendering 
unsigned int result; 
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); 
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo[1]); 
int sb; 
glReadBuffer(GL_COLOR_ATTACHMENT0); 
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); 
glGetIntegerv(GL_SAMPLE_BUFFERS, &sb); 
// glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); 
OGLChecker::getGlError(); 
std::cerr << "Sample buffers " << sb << std::endl; 
glReadPixels(pos.x(), resolution.y() - pos.y(), 1, 1, GL_RED, GL_UNSIGNED_INT, &result); 
OGLChecker::getGlError(); 
return result; 

đầu ra:

Sample buffers 0 
OpenGL Error : Invalid Operation 

Sự thật thú vị mà nếu tôi bỏ ghi chú glBindFramebuffer (GL_READ_FRAMEBUFFER, 0); sau đó không có lỗi xảy ra và điểm ảnh được đọc từ màn hình (nhưng tôi không cần điều này).

Điều gì có thể xảy ra ở đây?

+0

Một thực tế thú vị khác. Nếu tôi thay đổi định dạng của RBO từ GL_R32UI để GL_R32F tất cả mọi thứ hoạt động tốt, ngoại trừ tôi muốn lưu trữ và đọc số nguyên và không mất chính xác về hội tụ giữa uint32 và phao. (BTW, đầu ra từ shader fragment là uvec4) –

+1

Vâng vấn đề là với định dạng của framebuffer. glReadBuffer() tạo ra lỗi chỉ khi tôi cố gắng đọc từ bộ đệm với các định dạng số nguyên (như GL_RGBA8I hoặc GL_RGBA8UI hoặc GL_R32UI). Không có vấn đề gì khi đọc từ GL_RGBA8 hoặc GL_R32F. Đó có thể là cách khắc phục sự cố nếu có ai đó gặp phải vấn đề đó. –

Trả lời

0

Cho rằng nó "cố định" nếu bạn bỏ ghi chú rằng dòng mã, tôi tự hỏi, nếu lái xe của bạn đang nói dối bạn về GL_SAMPLE_BUFFERS là 0. Từ http://www.opengl.org/sdk/docs/man/xhtml/glReadPixels.xml:

GL_INVALID_OPERATION is generated if GL_READ_FRAMEBUFFER_BINDING is non-zero, the read framebuffer is complete, and the value of GL_SAMPLE_BUFFERS for the read framebuffer is greater than zero. 
+0

Không gian lưu trữ RBO cho FBO được tạo ra với glRenderbufferStorage(). Whats lý do cho FBO này được multisampled là gì? –

+0

Tôi không biết. Nó chỉ là một lý thuyết cho các khả năng hạn chế cho "hoạt động không hợp lệ". –

0

Nếu bạn đang sử dụng trình điều khiển nhị phân của NVIDIA trên Linux và đã chuyển sang giao diện điều khiển ảo không đồ họa (ví dụ: CTRL + ALT + F1) thì mọi nỗ lực glReadPixels() sẽ trả về GL_INVALID_OPERATION (0x502).

Giải pháp: Chuyển về giao diện điều khiển đồ họa (thường CTRL +ALT +F7).

Các vấn đề liên quan