1.将每个顶点坐标和颜色送到渲染管线以进行光栅化
I.位置:shaders\quad.vert(顶点着色器) | 在#version 330 gore下面 但main函数方法上方
layout(location = 0) in vec3 in_position;
layout(location = 1) in vec3 in_color;
out vec3 color;
这些代码意味着什么:
这些是glsl也就是opengl的编程语言,执行在GPU上面。
①这一行定义了一个输入变量 in_position
,它是一个vec3类型的变量,表示顶点的位置信息。layout(location = 0)
指定了这个变量在顶点数组中的位置,即在顶点数组的第0个位置。
②这一行定义了另一个输入变量 in_color
,它也是一个vec3类型的变量,表示顶点的颜色信息。layout(location = 1)
指定了这个变量在顶点数组中的位置,即在顶点数组的第1个位置。
④这一行定义了一个输出变量 color
,它是一个vec3类型的变量,用于将顶点的颜色信息传递给后续的片段着色器阶段。
II.位置:shaders\quad.vert(顶点着色器),在main函数内部
color = in_color;
gl_Position = vec4(in_position, 1.0);
我做了什么:
①将输入顶点的颜色信息传递给输出变量 color
,以便后续的片段着色器使用。
②将输入顶点的位置信息转换为裁剪空间坐标,并赋值给内置的输出变量 gl_Position
。这里使用 vec4
类型构造了一个四维向量,将顶点的位置信息 (in_position
) 作为其前三个分量,第四个分量设为1.0,以符合OpenGL中的齐次坐标系统。
2.在片段着色器中,定义一个输出变量等价于来自于顶点着色器的颜色值
I.位置:shaders\quad.frag(片段着色器) | 在version 330 core下面 但main函数上面
layout (location = 0) out vec4 fragColor;
in vec3 color;
我做了什么:
①这一行定义了一个输出变量,fragColor
,它是一个vec4类型的变量,表示片段的颜色信息。layout (location = 0)
指定了这个变量在帧缓冲中的位置,即输出到第0个颜色附件。
③这一行定义了一个输入变量 color
,它是一个vec3类型的变量,表示从顶点着色器传递过来的颜色信息。
II.位置:shaders\quad.frag(片段着色器)| 在main函数内
fragColor = vec4(color, 1.0);
我做了什么:
将输入变量 color
转换为vec4类型,并赋值给输出变量 fragColor
。在这里,我们假设输入的颜色信息是vec3类型,因此将其作为vec4的RGB分量,同时将alpha分量设为1.0,以得到最终的片段颜色。
3.在scene.py模块中,创建一个四边形网格实例
位置:在scene.py类中
from settings import *
from meshes.quad_mesh import QuadMesh
class Scene:
def __init__(self, app):
self.app = app
self.quad = QuadMesh(self.app)
def update(self):
pass
def render(self):
self.quad.render()
我做了什么:
①我从settings模块中引入所有东西
②从meshes包中的quad_mesh模块中引入QuadMesh类
⑤定义了一个Scene类
⑥Scene类的初始化方法
⑦这一行将传入的app
参数赋值给self.app
属性,以便在类的其他方法中可以访问应用程序的实例。
⑧这一行创建了一个QuadMesh
对象,并将应用程序的实例传递给它。然后将创建的QuadMesh
对象赋值给self.quad
属性,以便在类的其他方法中可以访问。
⑩用于更新场景中的对象。目前这个方法是空的,没有具体的实现。
(13)用于渲染场景中的对象
(14)这一行调用了QuadMesh
对象的render
方法,用于渲染四边形网格对象。
4.在main.py模块中,引入并应用Scene类
I.位置:在on_init()方法中,就在self.shader_program = ShaderProgram(self)下面,第32行
self.scene = Scene(self)
我在on_init()方法中实例化了scene类
II.位置:在update方法内,就在self.shader_program.update()下方,第36行
self.scene.update()
我在update方法内调用scene的update方法
III.位置:在render内,就在self.ctx.clear(color=BG_COLOR)下方,第44行
self.scene.render()
我在render方法内调用scene的render方法
然后启动程序,你会看到这样的东西
注意到,这个四边形并非等边四边形,也就是正四边形。因为我没有添加相机视角。
5.新建两个py模块分别为:camera.py和player.py于根目录下
6.在settings.py中添加两个camera和player参数
位置:settings.py内 随便什么位置都可以
# camera
ASPECT_RATIO = WIN_RES.x / WIN_RES.y
FOV_DEG = 50
V_FOV = glm.radians(FOV_DEG) # 垂直视野 V-FOV
H_FOV = 2 * math.atan(math.tan(V_FOV * 0.5) * ASPECT_RATION) # 水平视野 H-FOV
NEAR = 0.1
FAR = 2000.0
PITCH_MAX = glm.radians(89)
# player
PLAYER_SPEED = 0.005
PLAYER_ROT_SPEED = 0.003
PLAYER_POS = glm.vec3(0, 0, 1)
MOUSE_SENSITIVITY = 0.002
代码解析:
②计算了屏幕的宽高比(aspect ratio),通过将屏幕的水平分辨率除以垂直分辨率得到。
③设置了相机的视野角度,50度。
④将视野角度转换为弧度(radians)。
⑤计算了相机的水平视野角度。首先,将垂直视野角度的一半转换为弧度,然后根据屏幕的宽高比来计算水平视野角度。
⑥设置了相机的近裁剪平面的距离
⑦设置了相机的远裁剪平面的距离
⑧设置了相机的最大俯仰角度,单位是弧度
(11)设置了玩家的移动速度
(12)设置了玩家的旋转速度
(13)设置了玩家的初始位置,使用了glm库中的vec3类型表示
(14)设置了鼠标灵敏度,用于控制玩家视角的移动速度