1. 引言

本文基于Python语言,描述OpenGL的绘制流程,这里描述的是OpenGL的核心模式(Core-profile)

本文基于GLFW与PyOpenGL库进行开发,Python语言下的OpenGL环境搭建可参考:

笔者这里不过多描述每个名词、函数和细节,更详细的文档可以参考:

2. 流程综述

OpenGL的绘制流程(图形渲染管线,Graphics Pipeline)如下:

  • 顶点着色(vertex shader)阶段将CPU传入的数据进行一定的变换处理
  • 图元装配(shape assembly)阶段的就是上阶段的顶点数据处理成图元(如,三角形)
  • 几何着色(geometry shader)阶段是根据一定规则将输入的图元变更或输出更多的图元(可选)
  • 光栅化(rasterization)阶段的是将上阶段的图元进行计算得到图元占据的屏幕像素列表
  • 片元着色(fragment)阶段是将上阶段生成的片元进行着色处理后
  • 测试与混合阶段计算片元的深度、颜色等从而进行舍弃或保留

绘制流程繁琐,然而,我们能配置的只有三个蓝色的着色器部分。几何着色器可选,一般配置顶点着色器和片段着色器即可,即,以下步骤就是配置顶点着色器和片段着色器

3. 生成顶点数据

生成顶点缓冲对象(Vertex Buffer Objects, VBO)并加载数据:

vertices = np.array([[-0.5, -0.5, 0.0],
[0.5, -0.5, 0.0],
[0.0, 0.5, 0.0]])
VBO = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, VBO)
glBufferData(GL_ARRAY_BUFFER, 8*vertices.size, vertices, GL_STATIC_DRAW)

4. 链接属性数据

顶点数组对象(Vertex Array Object, VAO)与VBO绑定,用于保存属性数据(先绑定VAO,再创建VBO就会绑定到VAO上):

VAO = glGenVertexArrays(1)
glBindVertexArray(VAO) vertices = np.array([[-0.5, -0.5, 0.0],
[0.5, -0.5, 0.0],
[0.0, 0.5, 0.0]])
VBO = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, VBO)
glBufferData(GL_ARRAY_BUFFER, 8*vertices.size, vertices, GL_STATIC_DRAW) glVertexAttribPointer(0, 3, GL_DOUBLE, GL_FALSE, int(8*3), None)
glEnableVertexArrayAttrib(VAO, 0)

5. 创建顶点着色器

创建顶点着色器(Vertex Shader)并编译:

vertexShaderSource = """
#version 330 core
layout (location = 0) in vec3 aPos; void main()
{
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
}
"""
vertexShader = glCreateShader(GL_VERTEX_SHADER)
glShaderSource(vertexShader, vertexShaderSource)
glCompileShader(vertexShader)

6. 创建片段着色器

创建片段着色器(Fragment Shader)并编译:

fragmentShaderSource = """
#version 330 core
out vec4 FragColor; void main()
{
FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
}
"""
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER)
glShaderSource(fragmentShader, fragmentShaderSource)
glCompileShader(fragmentShader)

7. 链接着色器

着色器程序对象(Shader Program Object)是多个着色器合并之后并最终链接完成的版本:

shaderProgram = glCreateProgram()
glAttachShader(shaderProgram, vertexShader)
glAttachShader(shaderProgram, fragmentShader)
glLinkProgram(shaderProgram)

8. 绘制

开始(循环)绘制:

glClearColor(0.2, 0.3, 0.3, 1.0);
glClear(GL_COLOR_BUFFER_BIT); glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);

9. 完整代码

基于GLFW、PyOpenGL和Numpy创建OpenGL开发环境,完整代码如下:

import glfw
from OpenGL.GL import *
import numpy as np glfw.init()
window = glfw.create_window(800, 600, "hello triangle", None, None)
glfw.make_context_current(window) VAO = glGenVertexArrays(1)
glBindVertexArray(VAO) vertices = np.array([[-0.5, -0.5, 0.0],
[0.5, -0.5, 0.0],
[0.0, 0.5, 0.0]])
VBO = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, VBO)
glBufferData(GL_ARRAY_BUFFER, 8*vertices.size, vertices, GL_STATIC_DRAW)
glVertexAttribPointer(0, 3, GL_DOUBLE, GL_FALSE, int(8*3), None)
glEnableVertexArrayAttrib(VAO, 0) vertexShaderSource = """
#version 330 core
layout (location = 0) in vec3 aPos; void main()
{
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
}
"""
vertexShader = glCreateShader(GL_VERTEX_SHADER)
glShaderSource(vertexShader, vertexShaderSource)
glCompileShader(vertexShader) fragmentShaderSource = """
#version 330 core
out vec4 FragColor; void main()
{
FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
}
"""
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER)
glShaderSource(fragmentShader, fragmentShaderSource)
glCompileShader(fragmentShader) shaderProgram = glCreateProgram()
glAttachShader(shaderProgram, vertexShader)
glAttachShader(shaderProgram, fragmentShader)
glLinkProgram(shaderProgram) glDeleteShader(vertexShader)
glDeleteShader(fragmentShader) while not glfw.window_should_close(window):
glClearColor(0.2, 0.3, 0.3, 1.0)
glClear(GL_COLOR_BUFFER_BIT) glUseProgram(shaderProgram)
glBindVertexArray(VAO);
glDrawArrays(GL_LINE_STRIP, 0, 3) glfw.swap_buffers(window)
glfw.poll_events()

运行结果如下:

10. 参考资料

[1]你好,三角形 - LearnOpenGL CN (learnopengl-cn.github.io)

[2]【Learn OpenGL笔记】三角形(Triangle) - 知乎 (zhihu.com)

[3]基于GLFW的PyOpenGL的使用 - 当时明月在曾照彩云归 - 博客园 (cnblogs.com)

[4](Python OpenGL)【3】着色器 PyOpenGL - WSX_1994 - 博客园 (cnblogs.com)

基于Python的OpenGL 01 之Hello Triangle的更多相关文章

  1. Python基于回溯法解决01背包问题实例

    Python基于回溯法解决01背包问题实例 这篇文章主要介绍了Python基于回溯法解决01背包问题,结合实例形式分析了Python回溯法采用深度优先策略搜索解决01背包问题的相关操作技巧,需要的朋友 ...

  2. 【笔记】基于Python的数字图像处理

    [博客导航] [Python相关] 前言 基于Python的数字图像处理,离不开相关处理的第三方库函数.搜索网络资源,列出如下资源链接. Python图像处理库到底用哪家 python计算机视觉编程— ...

  3. 基于Python的卷积神经网络和特征提取

    基于Python的卷积神经网络和特征提取 用户1737318发表于人工智能头条订阅 224 在这篇文章中: Lasagne 和 nolearn 加载MNIST数据集 ConvNet体系结构与训练 预测 ...

  4. 基于Cocos2d-x学习OpenGL ES 2.0之多纹理

    没想到原文出了那么多错别字,实在对不起观众了.介绍opengl es 2.0的不多.相信介绍基于Cocos2d-x学习OpenGL ES 2.0之多纹理的,我是独此一家吧.~~ 子龙山人出了一个系列: ...

  5. 基于Cocos2d-x学习OpenGL ES 2.0系列——纹理贴图(6)

    在上一篇文章中,我们介绍了如何绘制一个立方体,里面涉及的知识点有VBO(Vertex Buffer Object).IBO(Index Buffer Object)和MVP(Modile-View-P ...

  6. 基于Python接口自动化测试框架+数据与代码分离(进阶篇)附源码

    引言 在上一篇<基于Python接口自动化测试框架(初级篇)附源码>讲过了接口自动化测试框架的搭建,最核心的模块功能就是测试数据库初始化,再来看看之前的框架结构: 可以看出testcase ...

  7. python网络编程01 /C/S架构|B/S架构、网络通信原理、五层协议、七层协议简述、端口映射技术

    python网络编程01 /C/S架构|B/S架构.网络通信原理.五层协议.七层协议简述.端口映射技术 目录 python网络编程01 /C/S架构|B/S架构.网络通信原理.五层协议.七层协议简述. ...

  8. 基于Python的邮件检测工具

    邮件快速检测工具 概要介绍 mmpi,是一款使用python实现的开源邮件快速检测工具库,基于community框架设计开发.mmpi支持对邮件头.邮件正文.邮件附件的解析检测,并输出json检测报告 ...

  9. Python数学建模-01.新手必读

    Python 完全可以满足数学建模的需要. Python 是数学建模的最佳选择之一,而且在其它工作中也无所不能. 『Python 数学建模 @ Youcans』带你从数模小白成为国赛达人. 1. 数学 ...

  10. 【Machine Learning】决策树案例:基于python的商品购买能力预测系统

    决策树在商品购买能力预测案例中的算法实现 作者:白宁超 2016年12月24日22:05:42 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现的深入理解.本 ...

随机推荐

  1. MetaTown:一个可以自己构建数字资产的平台

    摘要:华为云Solution as Code重磅推出<基于MetaTown构建数字资产平台>解决方案. 本文分享自华为云社区<基于MetaTown构建数字资产平台>,作者: 阿 ...

  2. (java 实现开箱即用基于 redis 的分布式锁

    项目简介 lock 为 java 设计的分布式锁,开箱即用,纵享丝滑. 开源地址:https://github.com/houbb/lock 目的 开箱即用,支持注解式和过程式调用 基于 redis ...

  3. 文件压缩和vi编辑器

    一.压缩,解压缩 1.gzip 和 bzip2 gzip和bzip都是压缩软件,比如windows里的好压和360 压缩或微软自带的等等 命令格式是:gzip或者bzip  + 0-9的压缩等级(数字 ...

  4. web项目部署上线(无虚拟主机,待学习)

    购买阿里云服务器 阿里云服务器ECS 系统镜像使用Ubuntu 20.04 LTS 使用ssh连接服务器,终端或者CMD中执行:$ssh root@x.x.x(阿里云服务器账号名@公网地址) 输入账号 ...

  5. Windows关闭网络防火墙教程

    Win10操作系统 1. 打开控制面板,点击"系统和安全" 2. 点击"Windows Defender 防火墙" 3. 点击"启用或关闭Window ...

  6. 大数据 - DWS层 业务实现

    统计主题 需求指标[ADS] 输出方式 计算来源 来源层级 访客[DWS] pv 可视化大屏 page_log 直接可求 dwd UV(DAU) 可视化大屏 需要用 page_log 过滤去重 dwm ...

  7. 优化if...else...语句

    写代码的时候经常遇到这样的场景:根据某个字段值来进行不同的逻辑处理.例如,不同的会员等级在购物时有不同的折扣力度.如果会员的等级很多,那么代码中与之相关的if...elseif...else...会特 ...

  8. Echarts点击多组数据多个柱子中的一个柱子,获取当前点击的是第几组数据,并获取点击的是当前组别第几根柱子,以及对应横坐标,

    遇到一需求,一般都是点击图后获取其中一组数据就可以了,不需要详细到获取点击了当前X轴对应的其中的哪个, 今天的需求是 Echarts点击多组数据多个柱子中的一个柱子,获取当前点击的是第几组数据,并获取 ...

  9. angular Ionic CLI组件建立,使用图标,弹窗,按钮,卡片,列表,无尽滚动,刷新

  10. BC7-牛牛的字符矩形

    题目描述 牛牛尝试用键盘读入一个字符,然后在屏幕上显示用这个字符组成的 3*3 的矩形. 输入描述 一行读入一个 char 类型的字符. 输出描述 输出这个字符组成的 3*3 矩形. 示例 1 输入: ...