Qt OpenGL rendering doesn't work
-
Hello,
I made a program in CPP using Qt and QTOpenGL to render mesh objects.
When I use in CPP example it works properly this is my example.cpp . Now I want to connect to a python wrapper to be able to use it in python.Here is my python setuptools application: setup.py
import glob import os from setuptools import setup, Extension # sources = glob.glob("**/**/*.cpp", recursive=True) sources = glob.glob("../pyboost_converter/**/*.cpp", recursive=True) setup( name='vmpbcvt', version='1.0', description='Python Package with Hello World C++ Extension', ext_modules=[ Extension( 'vmpbcvt', sources=['pyboost_converter/pyboost_converter.cpp', 'pyboost_converter/pbcvt_module.cpp'], # sources=sources, include_dirs=["/usr/include/numpy", "/usr/include/opencv4", "/usr/include/x86_64-linux-gnu/qt5/QtGui/", "/usr/include/x86_64-linux-gnu/qt5/", "/opt/ros/noetic/include", "/usr/include/x86_64-linux-gnu/qt5/QtWidgets", "/usr/include/x86_64-linux-gnu/qt5/QtCore", "/usr/include/x86_64-linux-gnu/qt5/QtOpenGL", ], libraries=['opencv_core', 'opencv_highgui', 'opencv_videoio', 'boost_python38', 'boost_system', "OpenGL", "cv_bridge", "roscpp", "rosbag", "image_transport", "roscpp_serialization", "Qt5Core", "Qt5Widgets", ], library_dirs=["/home/me/dev/3003/catkin_ws/devel/lib/", "/opt/ros/noetic/lib/"], extra_compile_args=['-std=c++2a', '-v'], # package_dir={'vision_module_pkg': '/home/me/dev/3003/catkin_ws/devel/lib/'}, # package_data={'vision_module_pkg': ['libvision_module.so']}, py_limited_api=False) ], )
I put in a cpp python wrapper the sample content of my example.cpp file:
#define PY_ARRAY_UNIQUE_SYMBOL vmpbcvt_ARRAY_API #include <boost/python.hpp> #include <pyboost_converter/pyboost_converter.hpp> #include <QApplication> #include <filesystem> #include <opencv2/core.hpp> #include <opencv2/highgui.hpp> #include <opencv2/imgcodecs.hpp> #include <opencv2/imgproc.hpp> #include <opencv2/opencv.hpp> #include <sstream> #include <typeinfo> int IMG_FORMAT = CV_8UC3; namespace pbcvt { using namespace boost::python; std::shared_ptr<VisionModuleManager> vision_module_manager; bool pbcvt_module_core_init(std::string vision_module_path) { /*********************** * * My example.cpp content here * */ return true; } #if (PY_VERSION_HEX >= 0x03000000) #ifndef NUMPY_IMPORT_ARRAY_RETVAL #define NUMPY_IMPORT_ARRAY_RETVAL NULL #endif static void *init_ar() { #else #ifndef NUMPY_IMPORT_ARRAY_RETVAL #define NUMPY_IMPORT_ARRAY_RETVAL #endif static void init_ar() { #endif Py_Initialize(); import_array(); return NUMPY_IMPORT_ARRAY_RETVAL; } BOOST_PYTHON_MODULE(vmpbcvt) { // using namespace XM; init_ar(); // initialize converters to_python_converter<cv::Mat, pbcvt::matToNDArrayBoostConverter>(); matFromNDArrayBoostConverter(); // expose module-level functions def("init", pbcvt_module_core_init); } } // end namespace pbcvt
On my example.cpp, the rendering works fine but in the wrapped example, it doesn't work. Is it an error in my setup.py file?
-
Hi,
Based solely on your code, there's nothing related to OpenGL rendering that would allow to understand how your code is working and why it would not it python.
An other question is: why do you need to wrap CPP since jt seems that you are using libraries that are also available through Python.
-
Here is a basic example that I hope will get you going:
import sys from OpenGL import GL from PySide6.QtCore import QTimer from PySide6.QtGui import QMatrix4x4 from PySide6.QtGui import QOpenGLFunctions from PySide6.QtGui import QSurfaceFormat from PySide6.QtOpenGL import QOpenGLShader from PySide6.QtOpenGL import QOpenGLShaderProgram from PySide6.QtOpenGLWidgets import QOpenGLWidget from PySide6.QtWidgets import QApplication vertext_shader_source = """ attribute highp vec4 posAttr; attribute lowp vec4 colAttr; varying lowp vec4 col; uniform highp mat4 matrix; void main() { col = colAttr; gl_Position = matrix * posAttr; } """ fragment_shader_source = """ varying lowp vec4 col; void main() { gl_FragColor = col; } """ class OpenGLWidget(QOpenGLWidget): def __init__(self, parent=None): super().__init__(parent) self.gl = QOpenGLFunctions() self._animating = False self._posAttr = 0 self._colAttr = 0 self._matrix_uniform = 0 self._program = None self._frame = 0 self._timer = QTimer() self._timer.timeout.connect(self.update) def initializeGL(self): self.gl.initializeOpenGLFunctions() self._program = QOpenGLShaderProgram(self) success = self._program.addShaderFromSourceCode( QOpenGLShader.Vertex, vertext_shader_source ) assert success success = self._program.addShaderFromSourceCode( QOpenGLShader.Fragment, fragment_shader_source ) assert success success = self._program.link() assert success self._posAttr = self._program.attributeLocation("posAttr") assert self._posAttr != -1 self._colAttr = self._program.attributeLocation("colAttr") assert self._colAttr != -1 self._matrix_uniform = self._program.uniformLocation("matrix") assert self._matrix_uniform != -1 def paintGL(self): retinaScale = self.devicePixelRatio() self.gl.glViewport( 0, 0, self.width() * retinaScale, self.height() * retinaScale ) self.gl.glClear(GL.GL_COLOR_BUFFER_BIT) self._program.bind() matrix = QMatrix4x4() matrix.perspective(60.0, 4.0 / 3.0, 0.1, 100.0) matrix.translate(0, 0, -2) matrix.rotate(100.0 * self._frame / self.screen().refreshRate(), 0, 1, 0) self._program.setUniformValue(self._matrix_uniform, matrix) vertices = [0.0, 0.707, -0.5, -0.5, 0.5, -0.5] colors = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0] GL.glVertexAttribPointer( self._posAttr, 2, GL.GL_FLOAT, GL.GL_FALSE, 0, vertices ) GL.glVertexAttribPointer(self._colAttr, 3, GL.GL_FLOAT, GL.GL_FALSE, 0, colors) self.gl.glEnableVertexAttribArray(self._posAttr) self.gl.glEnableVertexAttribArray(self._colAttr) self.gl.glDrawArrays(GL.GL_TRIANGLES, 0, 3) self.gl.glDisableVertexAttribArray(self._colAttr) self.gl.glDisableVertexAttribArray(self._posAttr) self._program.release() self._frame += 1 def setAnimating(self, animating: bool): self._animating = animating if animating: self._timer.start(25) if __name__ == "__main__": app = QApplication(sys.argv) format = QSurfaceFormat() format.setSamples(16) QSurfaceFormat.setDefaultFormat(format) widget = OpenGLWidget() widget.setAnimating(True) widget.show() sys.exit(app.exec())