2010-02-11 23 views
7

Tôi muốn có thể hiển thị cửa sổ X chỉ với id của nó.Tôi có thể làm cho cửa sổ X11 OpenGL có khả năng sau khi nó đã được tạo không?

Trong trường hợp này, tôi có cửa sổ được tạo bằng python bởi gtk.

Tôi có thể lấy ID cửa sổ là gtk.Drawable và chuyển nó vào mô-đun python C của tôi, nhưng tôi có thể thực hiện cuộc gọi OpenGL với nó không?

Tôi biết về gtkglext, nhưng không muốn sử dụng nó nếu có thể.

Cập nhật 1:

Ok, do đó (chứ không phải rõ ràng là bây giờ mà tôi nhìn thấy nó) Bạn chỉ cần làm một XCreateWindow với cha mẹ của id Window mà bạn nhận được từ gtk.window.xid, bằng cách sử dụng lá cờ chính xác cho OpenGL cửa sổ, và hey mau.

Vấn đề duy nhất là tôi không thể làm cho nó hoạt động nếu không có nhiều tiện ích trong cửa sổ, nếu không thì có vẻ như xid đại diện cho một cửa sổ bao phủ toàn bộ cửa sổ to. Bạn không chắc chắn cách khắc phục điều này.

Cập nhật 2: Nó chỉ ra rằng nếu bạn có một cửa sổ gl đó là kích thước tương tự như mục cấp đầu sau đó cửa sổ mục cấp đầu sẽ không được tiếp xúc với các sự kiện cho đến khi cửa sổ gl có bộ đệm của nó đổi chỗ. Bạn chỉ cần tiếp tục trao đổi bộ đệm và mọi thứ sẽ ổn.

Cập nhật 3:

Để trả lời @ bình luận babele của:

This page trong python docs gtk nói như thế nào để thực hiện một cửa sổ gtk từ một XID hiện có. Sau đó bạn chỉ cần nhớ giữ lại glXSwapBuffers cho cửa sổ đó (nếu nó là một cửa sổ đệm được mở, nếu không nó sẽ chỉ hoạt động khi bạn sử dụng window_foreign_new).

Vì vậy, quá trình đi:

  1. Tạo một widget gtk sẽ chứa cửa sổ OpenGL của bạn (một DrawingArea là một lựa chọn tốt - bạn không thể sử dụng như một nhãn vì nó sẽ không có XID riêng của mình)
  2. Lấy của widget gtk.gdk.Window (docs)
  3. Lấy XID từ gtk.gdk.Window (gọi W1 cửa sổ này)
  4. đèo nó để C/C++
  5. Tạo gió có khả năng opengl ow (W2) như một đứa trẻ của W1
  6. Vượt qua XID của W2 lại python
  7. Sử dụng window_foreign_new với XID W2 để tạo ra các đối tượng gtk.gdk.window mới
  8. Mỗi lần bạn gọi glXSwapBuffers trên W2 gtk nên sau đó có thể phản ứng để phơi bày các sự kiện.

Một bit thực sự ném cho tôi là nếu W2 bao gồm toàn bộ W1 thì W1 sẽ không nhận được sự kiện cho đến khi bộ đệm của W2 được đổi chỗ. Điều này đặc biệt khó hiểu nếu W1 là một cửa sổ cấp cao vì nó có thể không có gì xuất hiện trên màn hình của bạn cả (cửa sổ ở đó nhưng có vẻ như bất cứ thứ gì ở đằng sau nó cho đến khi nó được vẽ, nó sẽ không xảy ra cho đến khi nó nhận được một sự kiện phơi bày).

Cũng lưu ý rằng bạn sẽ phải quản lý kích thước của W2 theo cách thủ công bằng cách kết nối với các sự kiện thay đổi kích thước gtk. Bạn có thể thực hiện việc này bằng cách kết nối với this signal, sau đó gọi số this function trong trình xử lý và chuyển kết quả đến mô-đun c/C++ của bạn, nơi bạn có thể định lại kích thước W2 một cách thích hợp. Một ý tưởng hay là request a minimum size.

+0

"Tôi đã tìm thấy cách để tải gtk để quản lý cửa sổ được tạo thủ công bằng cách sử dụng XCreateWindow" ... XIN, bạn có thể giải thích thêm một chút về cách thực hiện điều đó không? Tôi đang tìm kiếm một số đoạn mã tương tự nhưng tôi không thể tìm thấy bất cứ điều gì .. chỉ là một cái nhìn tổng quan thô :) THX! –

Trả lời

6

Bạn không cần tạo cửa sổ mới, bạn chuyển một cửa sổ hiện có tới glXMakeCurrent().
Trong thiết lập hiện tại của bạn, bạn sẽ cần phải:

  1. XGetWindowAttributes() để lấy lại hình ảnh cửa sổ được tạo ra với
  2. glXCreateContext() sử dụng này visual
  3. glXMakeCurrent() sử dụng bối cảnh này và id cửa sổ

Tuy nhiên, điều này đang làm ngược lại, buộc OpenGL sử dụng hình ảnh được sử dụng cho CreateWindow. Điều này thường hoạt động vì hình ảnh mặc định có thuộc tính GLX sane, nhưng một ứng dụng chính xác sẽ glXChooseVisual với các thuộc tính GLX mong muốn, sau đó sử dụng hình ảnh đó để tạo cửa sổ.

+0

Điều gì về XSetWindowAttributes để thay đổi Visual của cửa sổ thành một OpenGL thích hợp? Liệu điều đó có hiệu quả ? – Loomchild

+0

Tôi có nghĩa là XChangeWindowAttributes tất nhiên. – Loomchild

+1

XChangeWindowAttributes không thể thay đổi trực quan của cửa sổ. Bạn cần tạo cửa sổ Visual mong muốn. –

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