Cython:加速OpenGL

本文介绍了如何使用Cython结合PySide2和glad来加速OpenGL应用。通过创建项目,引入必要的头文件并进行Cython编译,特别强调了在QOpenGLWidget中初始化glad的重要性,以避免程序闪退。利用Cython可以显著提升OpenGL的性能。
摘要由CSDN通过智能技术生成

测试环境:PySide2 + Cython + glad
本教程主要介绍Cython + glad头文件的引入和编译,以及在PySide2中初始化glad。glad下载步骤见CLion:OpenGL + GLAD配置.

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

    6141703-81a11dc0181bb258.png
    项目结构

  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的初始化就行了。
若有不清楚地方,可联系我一起探讨探讨。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值