pythonPython工作笔记

Cython:加速OpenGL

2019-10-14  本文已影响0人  txfly

本文主要介绍如何使用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

上一篇下一篇

猜你喜欢

热点阅读