基于GLFW的PyOpenGL的使用

1. GLFW概述

OpenGL只是一种规范,不仅语言无关,而且平台无关。规范只字未提获得和管理OpenGL上下文相关的内容,而是将这些作为细节交给底层的窗口系统。出于同样的原因,OpenGL纯粹专注于渲染,而不提供输入、音频以及窗口相关的API

GLFW是一个开源的多平台库,用于桌面上的OpenGL,OpenGL ES和Vulkan开发。它提供了一个简单的 API,用于创建窗口、上下文、接收输入和事件

GLFW的官网:An OpenGL library | GLFW

GLFW的GitHub地址:glfw/glfw: A multi-platform library for OpenGL, OpenGL ES, Vulkan, window and input (github.com)

GLFW的Python绑定:glfw · PyPI

GLFW、GLUT、freeglut都是OpenGL相关的窗口管理库,GLFW有着更为完善的功能

三者的的对比可以参考:

GLFW有着丰富的官方文档,本文结合官方示例搭建GLFW与OpenGL的C++与Python开发环境

2. GLFW的安装

GLFW的C++开发环境搭建可以参考:

GLFW的Python开发环境搭建可以参考:glfw · PyPI

Windows上GLFW的Python包自带了DLL,可以不用再额外安装,其余平台需要额外将DLL文件加入环境变量

使用Pip安装:

$ pip install glfw

使用Python开发还需安装OpenGL库的Python绑定,这里笔者使用的是PyOpenGL

PyOpenGL的安装参考:PyOpenGL的安装与错误解决 - 当时明月在曾照彩云归 - 博客园 (cnblogs.com)

使用Pip安装:

$ pip install PyOpenGL PyOpenGL_accelerate

基于C++语言的GLFW的资料广泛,尤其是官方资料详细,这里笔者主要讲述的是Python平台

3. GLFW(C++)的使用

GLFW官网给出了简单的示例代码:Documentation | GLFW

其流程是:

  • 初始化GLFW
  • 创建窗体
  • 获取上下文环境
  • 循环绘制、监听事件直至关闭

代码如下:

#include <GLFW/glfw3.h>

int main(void)
{
    GLFWwindow* window;

    /* Initialize the library */
    if (!glfwInit())
        return -1;

    /* Create a windowed mode window and its OpenGL context */
    window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        return -1;
    }

    /* Make the window's context current */
    glfwMakeContextCurrent(window);

    /* Loop until the user closes the window */
    while (!glfwWindowShouldClose(window))
    {
        /* Render here */
        glClear(GL_COLOR_BUFFER_BIT);

        /* Swap front and back buffers */
        glfwSwapBuffers(window);

        /* Poll for and process events */
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}

更详细的函数解释请参考官网文档:GLFW: Getting started

4. GLFW(Python)的使用

Python环境中的GLFW库是GLFW(C编写)的绑定,提供的API接口大致相同,但也存在着一点区别

参考官方说明:glfw · PyPI

可以知道主要区别有:

  • 函数名使用下划线的风格而不是原来的驼峰命名
  • GLFW_glfw前缀被删除
  • 带有指针的函数往往将指针作为返回值

Python环境中的GLFW库与原始C编写的GLFW库的API基本相同,流程也基本一致,所以,创建一个简单的OpenGL的步骤也是一样的:

  • 初始化GLFW
  • 创建窗体
  • 获取上下文环境
  • 循环绘制、监听事件直至关闭

4.1 导入相关包

导入GLFW与OpenGL

import glfw
from OpenGL.GL import *

4.2 初始化GLFW

调用glfw.init()进行初始化GLFW,还可以设置一些相关的初始化配置,例如OpenGL版本等

glfw.init()
'''
初始化相关的函数
'''

4.3 创建窗体

调用glfw.create_window()创建一个窗体

  • 第一个参数是宽
  • 第二个参数是高
  • 第三个参数是窗口标题
  • 后两个可以先不用管,具体可查GLFWAPI文档
window = glfw.create_window(800, 600, "glfw first", None, None)

4.4 获取上下文环境

调用glfw.make_context_current()获取上下文环境

  • 传入参数是获取上下文的窗体
glfw.make_context_current(window)

4.5 循环绘制、监听事件直至关闭

GLFW会轮询事件与窗体状态

glfw.window_should_close()获得窗体是否关闭的状态,点击窗口的关闭按钮时会改变为True

glfw.swap_buffers()交换缓存数据进行绘制

glfw.poll_events()轮询事件,检测是否有键鼠指令

while not glfw.window_should_close(window):
    glClear(GL_COLOR_BUFFER_BIT)
    '''
    OpenGL绘制函数
    '''
    
    glfw.swap_buffers(window)
    glfw.poll_events()

4.6 代码总结

把上述的代码总结一下,整合在一起,就可以创建一个GLFW窗体来编写OpenGL

为了测试环境,笔者加入一个清洗的背景颜色glClearColor(0.2, 0.3, 0.3, 1.0)(大约为深青色)

代码如下:

import glfw
from OpenGL.GL import *

glfw.init()
window = glfw.create_window(800, 600, "glfw first", None, None)
glfw.make_context_current(window)

while not glfw.window_should_close(window):
    glClearColor(0.2, 0.3, 0.3, 1.0)
    glClear(GL_COLOR_BUFFER_BIT)
    
    glfw.swap_buffers(window)
    glfw.poll_events()


不出意外的话将会出现如下的结果:

image-20220711221934766

不妨使用立即渲染模式进行渲染一个三角形(即只需要指定顶点数据就可以渲染):

import glfw
from OpenGL.GL import *

glfw.init()
window = glfw.create_window(800, 600, "glfw first", None, None)
glfw.make_context_current(window)

while not glfw.window_should_close(window):
    glClearColor(0.2, 0.3, 0.3, 1.0)
    glClear(GL_COLOR_BUFFER_BIT)

    glColor3f(1.0, 1.0, 1.0)
    glBegin(GL_TRIANGLES)
    glVertex3f(-0.5, -0.5, 0.0)
    glVertex3f(0.5, -0.5, 0.0)
    glVertex3f(0.0, 0.5, 0.0)
    glEnd()

    glfw.swap_buffers(window)
    glfw.poll_events()

不出意外的话将会出现如下的结果:

image-20220711223220381

可以看到OpenGL的代码正确绘制

5. 参考资料

[1]Documentation | GLFW

[2]GLFW: Introduction to the API

[3]glfw · PyPI

[4]GLFW入门学习 - 简书 (jianshu.com)

[5]PyOpenGL的安装与错误解决 - 当时明月在曾照彩云归 - 博客园 (cnblogs.com)

[6]你好,窗口 - LearnOpenGL CN (learnopengl-cn.github.io)

posted @ 2022-07-11 22:41  当时明月在曾照彩云归  阅读(773)  评论(1编辑  收藏  举报