2013-08-20 49 views
7

Tôi đang thực hiện tải lên kết cấu nhiều (60 hình ảnh VGA một giây) và nó chặn luồng UI của tôi. Từ the Qt 5.1 QGLWidget manual page (nhấn mạnh mỏ):QGLWidget trong chuỗi khác? Tài liệu tham khảo là gì?

Tải lên kết cấu trong chuỗi. Thực hiện tải lên kết cấu trong một chuỗi có thể rất hữu ích cho các ứng dụng xử lý một lượng lớn hình ảnh cần được hiển thị, ví dụ như ứng dụng thư viện ảnh. Điều này được hỗ trợ trong Qt thông qua API bindTexture() hiện có. Một cách đơn giản để làm điều này là tạo hai chia sẻ QGLWidgets. Một được tạo hiện tại trong luồng GUI chính, trong khi cái kia được tạo hiện tại trong chuỗi tải lên kết cấu. Tiện ích trong chuỗi tải lên không bao giờ được hiển thị, nó chỉ được sử dụng để chia sẻ họa tiết với chuỗi chính. Đối với mỗi kết cấu bị ràng buộc qua bindTexture(), hãy thông báo cho luồng chính để nó có thể bắt đầu sử dụng kết cấu.

Cái gì? Làm thế nào để một lớp QWidget như QGLWidget được chuyển sang một luồng? Cố gắng thực hiện kết quả như sau:

QObject::moveToThread: Widgets cannot be moved to a new thread 

Tôi không hiểu tài liệu đang đề xuất gì tôi triển khai để di chuyển, ví dụ: bindTexture() thực hiện trong chuỗi giao diện người dùng.

này cũng được đề cập ở đây: Qt4/Opengl bindTexture in separated thread

Không có mã đăng ở đó mặc dù.

Trả lời

3

Tôi phải nói rằng tôi không nhớ chính xác cách tôi đã làm điều này, dù sao tôi không nghĩ rằng QGLWidget phải được chuyển sang một chủ đề khác, và trên thực tế đó không phải là những gì tài liệu nói. Nó nói để làm cho nó hiện tại: QGLWidget::makeCurrent(). Điều đó sẽ làm cho bối cảnh OpenGL của dòng QGLWidget đó trong luồng mới.

Tuy nhiên, tôi muốn thử với lớp học QGLContext. Bạn có thể khởi tạo một QGLContext và sau đó gọi QGLContext :: create() để chia sẻ với một trong QGLWidget. Với QGLContext bạn có thể ràng buộc các kết cấu.

+0

Đúng. Thông tin thêm [tại đây] (http://blog.qt.digia.com/blog/2011/06/03/threaded-opengl-in-4-8/). Ngoài ra, trong Qt 5, bạn thực sự nên sử dụng các lớp QOpenGL *, không phải lớp QGL *, nếu có thể. – peppe

6

Ít trễ câu trả lời nhưng tiện ích con cần phải được chuyển sang chuỗi mới theo chuỗi đã tạo chúng. Trong trường hợp của bạn, chẳng hạn như:

QGLWidget *glWidget=new QGLWidget(); 
QThread *newThread=new QThread(); 

glWidget->doneCurrent(); 
glWidget->context()->moveToThread(newThread); 

Ở đây tôi chỉ chuyển ngữ cảnh openGL sang chuỗi mới, điều này yêu cầu một số ghi đè trong QGLWidget bị phát hiện và bỏ qua. Bạn sẽ cần phải tạo một lớp dẫn xuất mới từ QGLWidget và ghi đè lên những điều sau đây.

virtual void glInit(); 
virtual void glDraw(); 

virtual void initializeGL(); 
virtual void resizeGL(int width, int height); 
virtual void paintGL(); 

Điều này sẽ dừng luồng UI chuẩn khỏi cố gắng làm cho ngữ cảnh OpenGL hiện tại trong chuỗi giao diện người dùng. Một khi bạn ghi đè lên trên, bạn sẽ cần một hệ thống sự kiện để thông báo cho thread rằng một số sự kiện đã xảy ra, chủ yếu là resizeGl và paintGL nếu không widget sẽ không phản ứng đúng với những người khác xung quanh nó.

Phần cuối cùng là tạo ra QGLWidget. Một trong những thông số trong xây dựng là QGLWidget const * shareWidget:

QGLWidget (QWidget * parent = 0, const QGLWidget * shareWidget = 0, Qt::WindowFlags f = 0) 
QGLWidget (QGLContext * context, QWidget * parent = 0, const QGLWidget * shareWidget = 0, Qt::WindowFlags f = 0) 
QGLWidget (const QGLFormat & format, QWidget * parent = 0, const QGLWidget * shareWidget = 0, Qt::WindowFlags f = 0) 

Sau đó, bạn sẽ tạo ra QGLWidget ui và GLWidget luồng (derivided từ QGLWidget với tất cả các ghi đè đề cập ở trên) đảm bảo khi tạo GLWidget chủ đề bạn cung cấp QGLWidget làm sharedWidget.Điều này sẽ làm cho 2 opengl bối cảnh được chia sẻ và cho phép bạn tải một kết cấu trong một mà cả hai có thể nhìn thấy. Mã nên tìm kiếm một cái gì đó như thế này:

QGLWidget *glWidget=new QGLWidget(); 
GLWidget *threadedWidget=new GLWidget(0/*parent*/, glWidget); 
QThread *newThread=new QThread(); 

threadedWidget->moveToThread(newThread); 

Đối với mã tôi gần đây đã viết một chương trình ví dụ nhỏ sử dụng QGLWidgets ren chủ yếu cho OpenGL/OpenCL interop, nhưng nó cho thấy sử dụng QGLWidgets muliple trong chủ đề bốc thăm chia sẻ một bối cảnh duy nhất. Mã này nằm trên github và mô tả ở đây http://www.krazer.com/?p=109

+0

Các câu trả lời chỉ liên kết được khuyến khích. Câu trả lời của bạn sẽ trở thành không hợp lệ nếu một trong hai tài nguyên được liên kết bị di chuyển hoặc bị xóa. Một câu trả lời nên chứa ít nhất các điểm chính, ngay cả khi có nhiều nội dung hơn sau một liên kết. –

+0

+1. Liên kết được khuyến khích, nhưng đây là một phản ứng rất tốt và tôi thực sự muốn nhìn thấy bạn như là một phần của cộng đồng của chúng tôi. – Mikhail