赞
踩
位置:settings.py
- # colors
- BG_COLOR = glm.vec3(0.1, 0.16, 0.25)
我新增一种颜色
位置:main.py --> render()函数内
self.ctx.clear(color=BG_COLOR)
我在clear()内用BG_COLOR作为参数,以作为背景颜色
请跟着我的步骤走,如下:
然后就可以支持frag和vert文件了。
位置:Shader_program.py下
- from settings import *
-
-
- class ShaderProgram:
- def __init__(self, app):
- self.app = app
- self.ctx = app.ctx
- # --------- shaders ---------- #
- self.quad = self.get_program(shader_name='quad')
- # ---------------------------- #
- self.set_uniforms_on_init()
-
- def set_uniforms_on_init(self):
- pass
-
- def update(self):
- pass
-
- def get_program(self, shader_name):
- with open(f'shaders/{shader_name}.vert') as file:
- vertex_shader = file.read()
-
- with open(f'shaders/{shader_name}.frag') as file:
- fragment_shader = file.read()
-
- program = self.ctx.program(vertex_shader=vertex_shader, fragment_shader=fragment_shader)
- return program

我做了什么:
序号代表第几行代码,逐一解释
①我从settings.py引入所有东西
④创建了和该文件名字一样的ShaderProgram类,该类用于集中管理着色器程序
⑤该类的构造方法,接受一个参数app,代表应用程序实例
⑥在初始化过程中,将app实例存储在self.app属性中
⑦从app实例中获取 OpenGL 上下文,并存储在self.ctx中
⑨调用了 get_program()
方法,用于获取我们放在shaders文件夹下的 'quad' 着色器程序,并将返回的程序对象存储在 self.quad
属性中。
(11)调用set_uniforms_on_init()方法
(13)定义set_uniforms_on_init(),目前为无内容,但该方法用于在初始化过程中设置着色器程序的统一变量(uniform variables)
(16)定义update(),目前是无内容,开发者可以在这个方法中更新着色器程序的状态或执行其他操作
(19)我创建了一个方法叫做get_program(),它接受一个shadername作为参数,该方法用于从文件中读取顶点着色器和片段着色器的源代码,并使用这些源代码创建一个着色器程序对象
(20-21)读取shaders文件夹中的quad.vert转换并放在vertex_shader对象中,此为顶点着色器
(23-24)读取shaders文件夹中的quad.frag转换并放在fragment_shader对象中,此为片段着色器
(26)我用quad.vert和quad.frag,这两个文件中读取到的信息,创建一个着色器对象
(27)该类返回构造好的着色器对象
I.位置:shaders\quad.frag下
- #version 330 core
-
- void main() {
-
- }
II.位置:shaders\quad.vert下
- #version 330 core
-
- void main() {
-
- }
我做了什么:两个一起解释
①这是GLSL的版本声明。在这种情况下,它指定了使用OpenGL 3.3 Core Profile的GLSL版本。core
关键字表示我们正在使用OpenGL的核心配置,而不是兼容性配置,这意味着我们只能使用OpenGL核心功能,而不是过时的功能。
③这是顶点着色器(Vertex Shader)或片段着色器(Fragment Shader)的主函数;
在顶点着色器中,用于处理每个顶点;在片段着色器中,用于处理每个片段(像素)。
I. 位置:在main.py内第⑤行
from shader_program import ShaderProgram
我将刚刚创建的着色器管理程序引入进来
II. 位置:还在main.py内 总的第(27)行,就在self.is_running = True的正下面
self.on_init()
功能: 该方法调用了实例化着色器管理程序
III.位置:main.py内 在init()和on_init()方法之间 总的第(29)行
- def on_init(self):
- self.shader_program = ShaderProgram(self)
'运行
功能:该方法实例化一个着色器管理程序
IV.位置:main.py内 在update()方法内 放在第一行 总的第(33)行
self.shader_program.update()
功能:调用着色器管理程序的更新方法
位置:在base_mesh.py
- import numpy as np
-
-
- class BaseMesh:
- def __init__(self):
- # OpenGL context
- self.ctx = None
- # shader program
- self.program = None
- # vertex buffer data type format: "3f 3f"
- self.vbo_format = None
- # attribute names according to the format: ("in_position", "in_color")
- self.attrs: tuple[str, ...] = None
- # vertex array object
- self.vao = None
-
- def get_vertex_data(self) -> np.array: ...
-
- def get_vao(self):
- vertex_data = self.get_vertex_data()
- vbo = self.ctx.buffer(vertex_data)
- vao = self.ctx.vertex_array(self.program, [(vbo, self.vbo_format, *self.attrs)], skip_errors=True)
- return vao
-
- def render(self):
- self.vao.render()
'运行
我做了什么:
序号代表第几行
①引入numpy并重命名为np
④我创建了BaseMesh类作为基类,其他更复杂的网格mesh类都会继承于它,减少代码量
⑤我创建了构造方法init()以初始化一些属性参数,所有属性都初始化为空对象
⑦他们分别为:ctx ->
OpenGL 上下文对象。
⑨program
:着色器程序对象,用于渲染网格。
(11)vbo_format
:顶点缓冲区数据类型的格式,例如 "3f 3f" 表示每个顶点有两个部分,每个部分有三个浮点数。
(13)attrs
:顶点属性名称的元组,用于指定每个顶点缓冲区中的数据对应的属性名称。
(15)vao
:顶点数组对象,用于管理顶点缓冲区的状态。
(17)创建一个get_vertex_data()方法,用于从派生类中获取顶点数据;派生类需要实现这个方法,并返回一个包含顶点数据的NumPy数组。
(19)创建一个get_vao方法,该方法用于创建和返回顶点数组对象
(20)调用 get_vertex_data()
方法获取顶点数据,并存储在vertex_data对象中
(21)它创建一个顶点缓冲区对象(VBO),并使用vertex_data对象初始化它
(22-23)它使用顶点缓冲区数据、顶点缓冲区数据类型格式和顶点属性名称创建一个顶点数组对象,并返回它.
(25)创建了render()方法,方法用于渲染网格对象
(26)简单地调用了顶点数组对象的 render()
方法,该方法将执行着色器程序,绑定顶点缓冲区数据,并绘制网格。
位置:meshes\quad.mesh.py内
- from settings import *
- from meshes.base_mesh import BaseMesh
-
-
- class QuadMesh(BaseMesh):
- def __init__(self, app):
- super().__init__()
-
- self.app = app
- self.ctx = app.ctx
- self.program = app.shader_program.quad
-
- self.vbo_format = '3f 3f'
- self.attrs = ('in_position', 'in_color')
- self.vao = self.get_vao()
-
- def get_vertex_data(self):
- vertices = [
- (0.5, 0.5, 0.0), (-0.5, 0.5, 0.0), (-0.5, -0.5, 0.0),
- (0.5, 0.5, 0.0), (-0.5, -0.5, 0.0), (0.5, -0.5, 0.0),
- ]
- colors = [
- (0, 1, 0), (1, 0, 0), (1, 1, 0),
- (0, 1, 0), (1, 1, 0), (0, 0, 1)
- ]
- vertex_data = np.hstack([vertices, colors], dtype='float32')
- return vertex_data

我做了什么:
①从settings.py引入所有东西
②从meshes文件夹下的base_mesh.py文件中引入BaseMesh网格基类
⑤定义一个QuadMesh()类,意思是四边形网格,它继承至BaseMesh类,
⑥这是 QuadMesh
类的构造函数,它接受一个参数 app
,代表应用程序的实例
⑦调用了基类 BaseMesh
的构造函数,使用 super().__init__()
进行初始化
⑨获得app的实例并存储在self.app属性中
⑩获得app的openGL上下文对象并存储在self.ctx中
(11)获得app实例化的四边形着色器程序
(13-14)设置了顶点坐标数为'3f '和颜色数据格式为 '3f',意思是顶点坐标和颜色都是三个浮点数
(15)调用了基类的 get_vao()
方法来创建顶点数组对象(VAO)
(17)创建get_vertex_data()方法,定义四边形的顶点数据
(18-21)根据opengl的要求,我在此处需要定义两个逆时针遍历的三角形,每个括号内的三个数字构成一个顶点坐标(x,y,z),此处的两组坐标分别为可形成两个互补为正方形的直角三角形,(感兴趣的可以动手自己试画下)。
(22-25)这是一个颜色列表,包含了六个元组,每个元组代表一个颜色(R,G,B),从左到右,从上到下,分别为绿色,红色,黄色,绿色,黄色,蓝色。
(26)将上述的顶点坐标和颜色列表作为参数,np.hstack
函数将这两个数组按水平方向堆叠在一起,即将 colors
数组的每一行添加到 vertices
数组的对应行的右侧,形成一个形状为 (6, 6) 的新数组;
dtype='float32'
:这个参数指定了新数组的数据类型为 32 位浮点数,确保了顶点数据和颜色数据的数值类型一致。
(27)vertex_data
数组的形状为 (6, 6),其中每行代表一个顶点,前三个元素表示顶点的坐标,后三个元素表示顶点的颜色,这个数组将作为顶点缓冲区的数据传递给 OpenGL
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。