Skip to content

【PyOpenGL】4.变换

1.准备数据

  • 创建Actor

  • 添加Transform组件

    python
        def init(self):
            transform_comp = TransformComponent()
            transform_comp.position = glm.vec3(0, 0, 0)
            transform_comp.rotation = glm.vec3(0, 0, 1.0)
            transform_comp.scale = glm.vec3(0.5, 0.5, 0.5)
            transform_comp.update_matrix()
            self._main_actor.add_component(transform_comp)

    Actor-Component架构非常方便。

  • 在vs shader中添加uniform transform

    glsl
    #version 330
    layout (location = 0) in vec3 aPos;
    layout (location = 1) in vec3 aColor;
    layout (location = 2) in vec2 aTexCoord;
    
    uniform mat4 transform;
    
    out vec3 ourColor;
    out vec2 TexCoord;
    
    void main()
    {
        gl_Position = transform * vec4(aPos, 1.0);
        ourColor = aColor;
        TexCoord = aTexCoord;
    }
  • 绑定Transform矩阵到Shader的transform上

    python
    mat_comp.bind_param('transform', 'mat4', transform_comp)
  • 在Game的update中更新transform的position, rotation, scale信息,更新transform矩阵信息。

    python
        def __init__(self, title='') -> None:
            self._title: str = title
            self._is_running: bool = False
            self._main_window: Window = None
            self._asset_manager: AssetManager = None
            self._main_actor: Actor = None
    
            self._frame_time = 0
            self._last_frame_time_point = 0
    
            self.pos_index = 0
            self.pos_flag = 1
            self.rotation_index = 0
            self.scale_index = 0
            self.scale_flag = 1    
       
        def _update(self):
            cur_time_point = time.perf_counter_ns() / 1000000  # ns -> ms
            self._frame_time = cur_time_point - self._last_frame_time_point
            self._last_frame_time_point = cur_time_point
    
            frame_time_ms = round(self._frame_time, 2)
            self._main_window.set_title(self._title + ' ' + str(frame_time_ms) + 'ms')
    
            transform: TransformComponent = self._main_actor.get_component('TransformComponent')
            transform.position = glm.vec3(self.pos_index, 0, 0)
            transform.angle = - self.rotation_index
            transform.scale = glm.vec3((self.scale_index % 150) * 0.01)
            transform.update_matrix()
            self._main_actor.update()
    
            if self.scale_index >= 149:  # 注意:这里比上面小1。因为等于时,scale会突变为0
                self.scale_flag = -1
            elif self.scale_index <= 20:
                self.scale_flag = 1
            self.scale_index += self.scale_flag * 0.07 * self._frame_time
    
            if self.pos_index - 1.0 > 0.001:
                self.pos_index = 1.0
                self.pos_flag = -1
            elif self.pos_index + 1.0 < -0.001:
                self.pos_index = -1.0
                self.pos_flag = 1
            self.pos_index += self.pos_flag * 0.001 * self._frame_time
    
            self.rotation_index += 1 * 0.08 * self._frame_time

2.渲染过程

  • 在MeshRenderer的render中添加材质Material的uniform绑定过程。将mat中的参数传递到shader中。

  • 其他和《3.绘制图片》中过程相同。

3.结果展示

alt text