Cython:加速OpenGL

作者: txfly | 来源:发表于2019-10-14 16:46 被阅读0次

    本文主要介绍如何使用Cython加速OpenGL,涉及到glad头文件的引入和编译,以及PyQt5或者PySide2中glad的初始化。glad下载步骤见CLion:OpenGL + GLAD配置.

    测试环境:PySide2 + Cython + glad

    1. 新建项目,解压glad.zip到项目根目录,最后项目结构为:

      项目结构
    2. 编写pyx文件,比较重要的有两点:首先是cdef extern from "glad/glad.h" nogil:中添加nogil,主要是为了在使用OpenGL函数时释放GIL;其次是 glad初始化部分,如果在QOpenGLWidget的initializeGL函数里没有调用glad初始化函数,程序会闪退。例如:

      def initializeGL(self):
            print("gladLoadGL", demo.glad_init())
            glEnable(GL_BLEND)
            # glEnable(GL_POINT_SMOOTH)
            # glEnable(GL_LINE_SMOOTH)
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
            glClearColor(9 / 255, 28 / 255, 38 / 255, 1)
    

    Cython示例代码如下:

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    
    # cython: language_level = 3
    # cython: boundscheck = False
    # cython: wraparound = False
    # cython: nonecheck = False
    # cython: overflowcheck  = False
    # cython: cdivision  = True
    # cython: c_string_type  = bytes
    
    cdef extern from "glad/glad.h" nogil:
        ctypedef int            GLint
        ctypedef unsigned int   GLenum
        ctypedef float          GLfloat
        ctypedef unsigned int GLbitfield
        ctypedef void         GLvoid
        ctypedef unsigned int GLuint
        ctypedef int          GLsizei
        ctypedef double       GLdouble
    
        int GL_LINE_STRIP
        void glBegin(GLenum mode)
        void glEnd()
        void glVertex2f(GLfloat x, GLfloat y)
        void glVertex3f(GLfloat x, GLfloat y, GLfloat z)
        void glColor3f(GLfloat red, GLfloat green, GLfloat blue);
    
    cdef extern from "glad/glad.h" nogil:
        int GL_ARRAY_BUFFER
        int GL_ELEMENT_ARRAY_BUFFER
        int GL_STATIC_DRAW
        int GL_DYNAMIC_DRAW
        int GL_STREAM_DRAW
        int GL_READ_ONLY
        int GL_WRITE_ONLY
        int GL_READ_WRITE
        void *glMapBuffer(GLenum target, GLenum access)
        void glUnmapBuffer(GLenum target)
        int gladLoadGL()
    
    # 初始化glad
    cpdef int glad_init():
        return gladLoadGL()
    
    cpdef void draw(float[:] data, float dx, int length, int interval) nogil:
        cdef int i
        for i from 0 <= i <length by interval:
            glVertex2f(i * dx, data[i])
    
    cpdef int map_buffer(float[:,:] data, const int chs, int index, int block, int size) nogil:
        cdef int i, j
        cdef float *d
        d = <float*>glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY)
        for i in range(chs):
            for j in range(block):
                d[i * size + index + j] = data[i][j]
    
        index = (index + block) % size
        glUnmapBuffer(GL_ARRAY_BUFFER)
        return index
    
    1. 编写编译脚本
      编译时,需要指定头文件目录和添加glad.c源文件。完整setup.py为:
    from distutils.core import setup
    from Cython.Distutils import build_ext, Extension
    
    # python setup.py build_ext --inplace
    setup(
        name="demo",
        ext_modules=[Extension("demo", ["demo.pyx", "./src/glad.c"], include_dirs=["./include"])],
        cmdclass={'build_ext': build_ext}
    )
    

    最后运行python setup.py build_ext --inplace即可。

    总的来说,使用Cython加速OpenGL很简单,而且效果显著,使用时注意glad的初始化就行了。
    若有不清楚地方,可联系我一起探讨探讨。

    版权声明:本文为「txfly」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://www.jianshu.com/p/418b49e3f285

    相关文章

      网友评论

        本文标题:Cython:加速OpenGL

        本文链接:https://www.haomeiwen.com/subject/bxermctx.html