2012-05-03 31 views
5

Trong ứng dụng của tôi, tôi chụp những bức ảnh của nội dung của một QGLWidget cho hai mục đích:Làm thế nào để có đáng tin cậy QGLWidget chụp

  • Không vẽ lại cảnh mọi lúc khi chỉ có một thay đổi lớp phủ, sử dụng một pixmap cache thay vì
  • Lat người dùng chụp ảnh màn hình của các ô cụ thể (cảnh 3D)

Điều đầu tiên tôi đã thử là grabFrameBuffer(). Nó là tự nhiên để sử dụng chức năng này như cho các ứng dụng đầu tiên, những gì hiện đang hiển thị trong widget là chính xác những gì tôi muốn cache. VẤN ĐỀ: Trên một số phần cứng (ví dụ: đồ họa tích hợp Intel, Mac OS X với đồ họa GeForce), hình ảnh thu được không chứa nội dung màn hình hiện tại, nhưng nội dung trước đó. Vì vậy, nếu cảnh sẽ được rút ra hai lần, trên màn hình bạn thấy bản vẽ thứ hai, trong hình ảnh bạn nhìn thấy bản vẽ đầu tiên (mà phải là nội dung của backbuffer?).

Điều thứ hai tôi đã thử là renderToPixmap(). Điều này hiển thị bằng cách sử dụng paintGL(), nhưng không sử dụng paint(). Tôi có tất cả nội dung của mình ở paint(), vì tôi sử dụng chức năng vẽ của Qt và chỉ một đoạn nhỏ của mã sử dụng GL gốc (beginNativePainting(), endNativePainting()).

Tôi cũng đã thử khả năng chụp nhanh QWidget thông thường (QPixmap :: fromWidget(), hoặc nó được gọi), nhưng có bộ đệm khung GL là màu đen.

Bất kỳ ý tưởng nào về cách giải quyết vấn đề và có được mô tả đáng tin cậy về cảnh hiện đang được vẽ?

Trả lời

2

Làm thế nào để có đáng tin cậy chụp QGLWidget

Render cảnh hiện tại để framebuffer, lưu dữ liệu từ bộ đệm khung để nộp. Hoặc lấy backbuffer hiện tại sau khi glFlush. Bất cứ điều gì khác có thể bao gồm hiện vật hoặc cảnh không đầy đủ.

+0

Tôi đã kết thúc làm việc với FBO. – ypnos

1

Kết quả của QGLWidget::grabFrameBuffer(), giống như mọi cuộc gọi OpenGL khác, tùy thuộc vào trình điều khiển video. Qt chỉ đơn thuần chuyển tiếp cuộc gọi của bạn đến trình điều khiển và lấy hình ảnh nó trả về, nhưng nội dung của hình ảnh không nằm dưới sự kiểm soát của Qt. Ngoài việc đảm bảo bạn đã cài đặt trình điều khiển mới nhất cho card màn hình của mình, bạn không thể làm gì ngoài việc báo cáo lỗi cho nhà sản xuất card màn hình và cầu nguyện.

0

Tôi sử dụng paintGL();glFlush(); trước khi sử dụng grabFrameBuffer(). PaintGL giúp vẽ khung hình hiện tại một lần nữa trước khi lấy bộ đệm khung, tạo bản sao chính xác của những gì hiện đang hiển thị.

2

Dường như QGLWidget :: grabFrameBuffer() gọi nội bộ glReadPixels() từ OpenGL. Trên cấu hình double-bufferd chế độ ban đầu đọc bộ đệm sau (GL_BACK), chuyển đổi với trình gọi OpenGL glReadBuffer (GL_FRONT) sang bộ đệm trước trước khi sử dụng QGLWidget :: grabFrameBuffer() hiển thị hình ảnh trên màn hình.

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