PySideでDirectXウインドウを表示してみる
↑PySideで表示したWindowにDirectXの画面を表示しています。
C++
- pyd用のプロジェクトを作成
- DirectXのTutorialをコピペしてInitWindow、WinProcなどの不要な関数を削除
- InitDeviceでウインドウハンドルを受け取るように変更
- boost::pythonを使ってDirectXの処理をpythonに公開する
#define BOOST_PYTHON_STATIC_LIB #include <boost/python.hpp> #include <d3d11_1.h> #include <d3dcompiler.h> #include <directxmath.h> #include <directxcolors.h> HRESULT InitDevice(PyObject* hwnd, int width, int height); void CleanupDevice(); void Render(); /* コード長いので省略 */ BOOST_PYTHON_MODULE(pydx) { boost::python::def("InitDevice", &InitDevice); boost::python::def("CleanupDevice", &CleanupDevice); boost::python::def("Render", &Render); }
Python
PySideを使ってGUIを作成する。paint系の関数をオーバーライドしてDirectXのRenderが呼ばれるようにしてあげる。
# conding: utf-8 import sys from PySide.QtCore import * from PySide.QtGui import * import pydx # dx view class View(QWidget): def __init__(self, parent=None): super().__init__(parent) self.setAttribute(Qt.WA_PaintOnScreen) self.setAttribute(Qt.WA_NoSystemBackground) self.setAttribute(Qt.WA_OpaquePaintEvent) pydx.InitDevice(self.winId(), parent.width(), parent.height()) def __del__(self): pydx.CleanupDevice() def _render(self): pydx.Render() self.update() # override methods def paintEngine(self, *args): return None def paintEvent(self, *args): self._render() def render(self, *args): self._render() def repaint(self, *args): self._render() myapp = QApplication(sys.argv) wnd = QMainWindow() wnd.resize(640, 480) wnd.setCentralWidget(View(wnd)) wnd.show() wnd.setWindowTitle('pydx') sys.exit(myapp.exec_())
注意点
QWidgetのwinIdがPyCObjectを返すのでHWNDに変換してあげる必要があった。
g_hWnd = HWND(PyCapsule_GetPointer(hwnd, NULL));
リサイズ処理してないのでレンダリング解像度は固定。