def getMatrices(self, eye=None): # Ignores eye parameter #proj, _ = super(OrbitalCamera, self).getMatrices(eye) #mv = .. def lookat(ex, ey, ez, tx, ty, tz, ux, uy, uz): e = np.array([ex, ey, ez]) t = np.array([tx, ty, tz]) u = np.array([ux, uy, uz]) return matrix.lookat(e, t, u) aspect = self.getAspect() if self.projection: # Perspective mode proj = matrix.perspective(self.fovAngle, aspect, self.nearPlane, self.farPlane) else: # Ortho mode height = self.getScale() width = height * aspect # Camera position around world origin proj = matrix.ortho(-width, width, -height, height, self.nearPlane, self.farPlane) """ mv = lookat(self.eyeX, self.eyeY, self.eyeZ, # Eye self.focusX, self.focusY, self.focusZ, # Focus point (target) self.upX, self.upY, self.upZ) # Up """ mv = lookat(self.center[0], self.center[1], self.center[2] + self.radius, # Eye self.center[0], self.center[1], self.center[2], # Focus point (target) self.upX, self.upY, self.upZ) # Up return proj, mv
def level5_init(level, program): # 1.59 - approximate position of the eyes of a person who is 1.69 meters tall level.position = array([0, 0, 1.59, 1], dtype='float32') # looking forward in Y-axis positive direction level.orientation = array([0, 1, 0, 0], dtype='float32') level.time_start = time() level.time_checkpoint = level.time_start # get position for view matrix level.view_pos = glGetUniformLocation(program, 'view') # get position for rotating model matrix level.rotating_model_pos = glGetUniformLocation(program, 'rotating_model') # sun level.sun_color = array([1.0, 1.0, 1.0], dtype='float32') level.sun_color_pos = glGetUniformLocation(program, 'sunColor') glUniform3fv(level.sun_color_pos, 1, level.sun_color) level.sun_direction_pos = glGetUniformLocation(program, 'sunDirection') glUniform3fv(level.sun_direction_pos, 1, level.sun_direction) level.ambient_intensity = 0.2 level.ambient_intensity_pos = glGetUniformLocation(program, 'ambientIntensity') glUniform1f(level.ambient_intensity_pos, level.ambient_intensity) # initialize projection matrix once level.projection = perspective(pi / 3.5, level.screen_w / level.screen_h, 0.005, 1000000.0) level.projection_pos = glGetUniformLocation(program, 'projection') glUniformMatrix4fv(level.projection_pos, 1, GL_FALSE, level.projection)
def draw(self, width, height, z, full): glUseProgram(self.shaderProgram) glUniformMatrix4fv(self.locations["u_model"], 1, GL_TRUE, np.eye(4)) glUniformMatrix4fv(self.locations["u_view"], 1, GL_TRUE, mat.translation(np.array([0.0, 0.0, -z], np.float32))) glUniformMatrix4fv(self.locations["u_projection"], 1, GL_TRUE, mat.perspective(45.0, float(width)/float(height), 0.1, 1000.0)) glUniform4f(self.locations["u_colormod"], *(np.zeros(4)) if not full else (np.array([0.0, 0.0, 1.0, 0.0], np.float32))) glBindVertexArray(self.vertexArrayObject) glDrawElements(GL_LINES, 24 if full else 8, GL_UNSIGNED_INT, None) glBindVertexArray(0)
def opengl绘图循环(所有图层): glfw.init() glfw.window_hint(glfw.RESIZABLE, False) window = glfw.create_window(500, 500, 'Vtuber', None, None) glfw.make_context_current(window) glViewport(0, 0, 500, 500) glEnable(GL_TEXTURE_2D) glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) for 图层数据 in 所有图层: 纹理编号 = glGenTextures(1) glBindTexture(GL_TEXTURE_2D, 纹理编号) 纹理 = cv2.resize(图层数据['npdata'], (512, 512)) width, height = 纹理.shape[:2] glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_FLOAT, 纹理) glGenerateMipmap(GL_TEXTURE_2D) 图层数据['纹理编号'] = 纹理编号 while not glfw.window_should_close(window): glfw.poll_events() glClearColor(1, 1, 1, 1) glClear(GL_COLOR_BUFFER_BIT) for 图层数据 in 所有图层: a, b, c, d = 图层数据['位置'] z = 图层数据['深度'] p1 = np.array([a, b, z, 1, 0, 0]) p2 = np.array([a, d, z, 1, 1, 0]) p3 = np.array([c, d, z, 1, 1, 1]) p4 = np.array([c, b, z, 1, 0, 1]) model = matrix.scale(1 / 250, 1 / 250, 1) @ \ matrix.translate(-1, -1, 0) @ \ matrix.rotate_ax(-math.pi / 2, axis=(0, 1)) glBindTexture(GL_TEXTURE_2D, 图层数据['纹理编号']) glColor4f(1, 1, 1, 1) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) glBegin(GL_QUADS) for p in [p1, p2, p3, p4]: a = p[:4] b = p[4:6] a = a @ model a[0] *= a[2] a[1] *= a[2] if not 图层数据['名字'][:2] == '身体': 横角, 竖角 = 特征缓冲() a = a @ \ matrix.translate(0, 0, -1) @ \ matrix.rotate_ax(横角, axis=(0, 2)) @ \ matrix.rotate_ax(竖角, axis=(2, 1)) @ \ matrix.translate(0, 0, 1) a = a @ matrix.perspective(999) glTexCoord2f(*b) glVertex4f(*a) glEnd() glfw.swap_buffers(window)
def draw(self, width, height, z): glUseProgram(self.shaderProgram) glActiveTexture(GL_TEXTURE0) glBindTexture(GL_TEXTURE_2D, self.texture) glUniform1i(self.locations["u_texture"], 0) glUniformMatrix4fv(self.locations["u_model"], 1, GL_TRUE, np.eye(4)) glUniformMatrix4fv(self.locations["u_view"], 1, GL_TRUE, mat.translation(np.array([0.0, 0.0, -z], np.float32))) glUniformMatrix4fv(self.locations["u_projection"], 1, GL_TRUE, mat.perspective(45.0, float(width)/float(height), 0.1, 1000.0)) glBindVertexArray(self.vertexArrayObject) glDrawArrays(GL_QUADS, 0, 4) glBindVertexArray(0)
def draw(self, width, height, z, full): glUseProgram(self.shaderProgram) glUniformMatrix4fv(self.locations["u_model"], 1, GL_TRUE, np.eye(4)) glUniformMatrix4fv( self.locations["u_view"], 1, GL_TRUE, mat.translation(np.array([0.0, 0.0, -z], np.float32))) glUniformMatrix4fv( self.locations["u_projection"], 1, GL_TRUE, mat.perspective(45.0, float(width) / float(height), 0.1, 1000.0)) glUniform4f( self.locations["u_colormod"], *(np.zeros(4)) if not full else (np.array([0.0, 0.0, 1.0, 0.0], np.float32))) glBindVertexArray(self.vertexArrayObject) glDrawElements(GL_LINES, 24 if full else 8, GL_UNSIGNED_INT, None) glBindVertexArray(0)
def getMatrices(self, eye): def lookat(ex, ey, ez, tx, ty, tz, ux, uy, uz): e = np.array([ex, ey, ez]) t = np.array([tx, ty, tz]) u = np.array([ux, uy, uz]) return matrix.lookat(e, t, u) stereoMode = 0 if eye: stereoMode = self.stereoMode aspect = float(max(1, G.windowWidth)) / float(max(1, G.windowHeight)) if stereoMode == 0: # No stereo if self.projection: proj = matrix.perspective(self.fovAngle, aspect, self.nearPlane, self.farPlane) else: height = self.scale width = self.scale * aspect proj = matrix.ortho(-width, width, -height, height, self.nearPlane, self.farPlane) mv = lookat( self.eyeX, self.eyeY, self.eyeZ, # Eye self.focusX, self.focusY, self.focusZ, # Focus self.upX, self.upY, self.upZ) # Up elif stereoMode == 1: # Toe-in method, uses different eye positions, same focus point and projection proj = matrix.perspective(self.fovAngle, aspect, self.nearPlane, self.farPlane) if eye == 1: mv = lookat( self.eyeX - 0.5 * self.eyeSeparation, self.eyeY, self.eyeZ, # Eye self.focusX, self.focusY, self.focusZ, # Focus self.upX, self.upY, self.upZ) # Up elif eye == 2: mv = lookat( self.eyeX + 0.5 * self.eyeSeparation, self.eyeY, self.eyeZ, # Eye self.focusX, self.focusY, self.focusZ, # Focus self.upX, self.upY, self.upZ) # Up elif stereoMode == 2: # Off-axis method, uses different eye positions, focus points and projections widthdiv2 = math.tan( math.radians(self.fovAngle) / 2) * self.nearPlane left = -aspect * widthdiv2 right = aspect * widthdiv2 top = widthdiv2 bottom = -widthdiv2 if eye == 1: # Left eyePosition = -0.5 * self.eyeSeparation elif eye == 2: # Right eyePosition = 0.5 * self.eyeSeparation else: eyePosition = 0.0 left -= eyePosition * self.nearPlane / self.eyeZ right -= eyePosition * self.nearPlane / self.eyeZ # Left frustum is moved right, right frustum moved left proj = matrix.frustum(left, right, bottom, top, self.nearPlane, self.farPlane) # Left camera is moved left, right camera moved right mv = lookat( self.eyeX + eyePosition, self.eyeY, self.eyeZ, # Eye self.focusX + eyePosition, self.focusY, self.focusZ, # Focus self.upX, self.upY, self.upZ) # Up return proj, mv
def reshape(self, w, h): glViewport(0, 0, w, h) self.proj = perspective(fovy=45, aspect=w / h, z_near=0.05, z_far=30)
def getMatrices(self, eye): def lookat(ex, ey, ez, tx, ty, tz, ux, uy, uz): e = np.array([ex, ey, ez]) t = np.array([tx, ty, tz]) u = np.array([ux, uy, uz]) return matrix.lookat(e, t, u) stereoMode = 0 if eye: stereoMode = self.stereoMode aspect = float(max(1, G.windowWidth)) / float(max(1, G.windowHeight)) if stereoMode == 0: # No stereo if self.projection: proj = matrix.perspective(self.fovAngle, aspect, self.nearPlane, self.farPlane) else: height = self.scale width = self.scale * aspect proj = matrix.ortho(-width, width, -height, height, self.nearPlane, self.farPlane) mv = lookat( self.eyeX, self.eyeY, self.eyeZ, # Eye self.focusX, self.focusY, self.focusZ, # Focus self.upX, self.upY, self.upZ, ) # Up elif stereoMode == 1: # Toe-in method, uses different eye positions, same focus point and projection proj = matrix.perspective(self.fovAngle, aspect, self.nearPlane, self.farPlane) if eye == 1: mv = lookat( self.eyeX - 0.5 * self.eyeSeparation, self.eyeY, self.eyeZ, # Eye self.focusX, self.focusY, self.focusZ, # Focus self.upX, self.upY, self.upZ, ) # Up elif eye == 2: mv = lookat( self.eyeX + 0.5 * self.eyeSeparation, self.eyeY, self.eyeZ, # Eye self.focusX, self.focusY, self.focusZ, # Focus self.upX, self.upY, self.upZ, ) # Up elif stereoMode == 2: # Off-axis method, uses different eye positions, focus points and projections widthdiv2 = math.tan(math.radians(self.fovAngle) / 2) * self.nearPlane left = -aspect * widthdiv2 right = aspect * widthdiv2 top = widthdiv2 bottom = -widthdiv2 if eye == 1: # Left eyePosition = -0.5 * self.eyeSeparation elif eye == 2: # Right eyePosition = 0.5 * self.eyeSeparation else: eyePosition = 0.0 left -= eyePosition * self.nearPlane / self.eyeZ right -= eyePosition * self.nearPlane / self.eyeZ # Left frustum is moved right, right frustum moved left proj = matrix.frustum(left, right, bottom, top, self.nearPlane, self.farPlane) # Left camera is moved left, right camera moved right mv = lookat( self.eyeX + eyePosition, self.eyeY, self.eyeZ, # Eye self.focusX + eyePosition, self.focusY, self.focusZ, # Focus self.upX, self.upY, self.upZ, ) # Up return proj, mv
def opengl循环(所有图层, psd尺寸): Vtuber尺寸 = 512, 512 glfw.init() glfw.window_hint(glfw.RESIZABLE, False) window = glfw.create_window(*Vtuber尺寸, 'Vtuber', None, None) glfw.make_context_current(window) glViewport(0, 0, *Vtuber尺寸) glEnable(GL_TEXTURE_2D) glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) for 图层数据 in 所有图层: 纹理编号 = glGenTextures(1) glBindTexture(GL_TEXTURE_2D, 纹理编号) 纹理, 纹理座标 = 生成纹理(图层数据['npdata']) width, height = 纹理.shape[:2] glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_FLOAT, 纹理) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR) glGenerateMipmap(GL_TEXTURE_2D) 图层数据['纹理编号'] = 纹理编号 图层数据['纹理座标'] = 纹理座标 while not glfw.window_should_close(window): glfw.poll_events() glClearColor(1, 1, 1, 0) glClear(GL_COLOR_BUFFER_BIT) for 图层数据 in 所有图层: a, b, c, d = 图层数据['位置'] z = 图层数据['深度'] if type(z) in [int, float]: z1, z2, z3, z4 = [z, z, z, z] else: [z1, z2], [z3, z4] = z q, w = 图层数据['纹理座标'] p1 = np.array([a, b, z1, 1, 0, 0, 0, 1]) p2 = np.array([a, d, z2, 1, w, 0, 0, 1]) p3 = np.array([c, d, z3, 1, w, q, 0, 1]) p4 = np.array([c, b, z4, 1, 0, q, 0, 1]) model = matrix.scale(2 / psd尺寸[0], 2 / psd尺寸[1], 1) @ \ matrix.translate(-1, -1, 0) @ \ matrix.rotate_ax(-math.pi / 2, axis=(0, 1)) glBindTexture(GL_TEXTURE_2D, 图层数据['纹理编号']) glColor4f(1, 1, 1, 1) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) glBegin(GL_QUADS) for p in [p1, p2, p3, p4]: a = p[:4] b = p[4:] a = a @ model z = a[2] a[0:2] *= z b *= z 横旋转量 = 0 if not 图层数据['名字'] == '身体': 横旋转量 = math.sin(time.time() * 5) / 30 a = a @ matrix.translate(0, 0, -1) \ @ matrix.rotate_ax(横旋转量, axis=(0, 2)) \ @ matrix.translate(0, 0, 1) a = a @ matrix.perspective(999) glTexCoord4f(*b) glVertex4f(*a) glEnd() glfw.swap_buffers(window)
def opengl绘图循环(所有图层, psd尺寸): def 生成纹理(img): w, h = img.shape[:2] d = 2**int(max(math.log2(w), math.log2(h)) + 1) 纹理 = np.zeros([d, d, 4], dtype=img.dtype) 纹理[:w, :h] = img return 纹理, (w / d, h / d) Vtuber尺寸 = 512, 512 glfw.init() 超融合() glfw.window_hint(glfw.RESIZABLE, False) window = glfw.create_window(*Vtuber尺寸, 'Vtuber', None, None) glfw.make_context_current(window) monitor_size = glfw.get_video_mode(glfw.get_primary_monitor()).size glfw.set_window_pos(window, monitor_size.width - Vtuber尺寸[0], monitor_size.height - Vtuber尺寸[1]) glViewport(0, 0, *Vtuber尺寸) glEnable(GL_TEXTURE_2D) glEnable(GL_BLEND) glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA) for 图层数据 in 所有图层: 纹理编号 = glGenTextures(1) glBindTexture(GL_TEXTURE_2D, 纹理编号) 纹理, 纹理座标 = 生成纹理(图层数据['npdata']) width, height = 纹理.shape[:2] glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_FLOAT, 纹理) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR) glGenerateMipmap(GL_TEXTURE_2D) 图层数据['纹理编号'] = 纹理编号 图层数据['纹理座标'] = 纹理座标 while not glfw.window_should_close(window): glfw.poll_events() glClearColor(0, 0, 0, 0) glClear(GL_COLOR_BUFFER_BIT) 横旋转量, 竖旋转量 = 特征缓冲() for 图层数据 in 所有图层: a, b, c, d = 图层数据['位置'] z = 图层数据['深度'] if type(z) in [int, float]: z1, z2, z3, z4 = [z, z, z, z] else: [z1, z2], [z3, z4] = z q, w = 图层数据['纹理座标'] p1 = np.array([a, b, z1, 1, 0, 0, 0, z1]) p2 = np.array([a, d, z2, 1, z2 * w, 0, 0, z2]) p3 = np.array([c, d, z3, 1, z3 * w, z3 * q, 0, z3]) p4 = np.array([c, b, z4, 1, 0, z4 * q, 0, z4]) model = matrix.scale(2 / psd尺寸[0], 2 / psd尺寸[1], 1) @ \ matrix.translate(-1, -1, 0) @ \ matrix.rotate_ax(-math.pi / 2, axis=(0, 1)) glBindTexture(GL_TEXTURE_2D, 图层数据['纹理编号']) glColor4f(1, 1, 1, 1) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) glBegin(GL_QUADS) for p in [p1, p2, p3, p4]: a = p[:4] b = p[4:8] a = a @ model a[0:2] *= a[2] if not 图层数据['名字'][:2] == '身体': a = a @ matrix.translate(0, 0, -1) \ @ matrix.rotate_ax(横旋转量, axis=(0, 2)) \ @ matrix.rotate_ax(竖旋转量, axis=(2, 1)) \ @ matrix.translate(0, 0, 1) a = a @ matrix.perspective(999) glTexCoord4f(*b) glVertex4f(*a) glEnd() glfw.swap_buffers(window)
def opengl循环(所有图层, psd尺寸): def 生成纹理(img): w, h = img.shape[:2] d = 2**int(max(math.log2(w), math.log2(h)) + 1) 纹理 = np.zeros([d, d, 4], dtype=img.dtype) 纹理[:w, :h] = img return 纹理, (w / d, h / d) Vtuber尺寸 = 512, 512 glfw.init() glfw.window_hint(glfw.RESIZABLE, False) window = glfw.create_window(*Vtuber尺寸, 'Vtuber', None, None) glfw.make_context_current(window) glViewport(0, 0, *Vtuber尺寸) glEnable(GL_TEXTURE_2D) glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) for 图层数据 in 所有图层: 纹理编号 = glGenTextures(1) glBindTexture(GL_TEXTURE_2D, 纹理编号) 纹理, 纹理座标 = 生成纹理(图层数据['npdata']) width, height = 纹理.shape[:2] glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_FLOAT, 纹理) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR) glGenerateMipmap(GL_TEXTURE_2D) 图层数据['纹理编号'] = 纹理编号 图层数据['纹理座标'] = 纹理座标 while not glfw.window_should_close(window): glfw.poll_events() glClearColor(1, 1, 1, 1) glClear(GL_COLOR_BUFFER_BIT) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) for 图层数据 in 所有图层: a, b, c, d = 图层数据['位置'] z = 图层数据['深度'] q, w = 图层数据['纹理座标'] p1 = np.array([a, b, z, 1, 0, 0]) p2 = np.array([a, d, z, 1, w, 0]) p3 = np.array([c, d, z, 1, w, q]) p4 = np.array([c, b, z, 1, 0, q]) model = matrix.scale(2 / psd尺寸[0], 2 / psd尺寸[1], 1) @ \ matrix.translate(-1, -1, 0) @ \ matrix.rotate_ax(-math.pi / 2, axis=(0, 1)) glBindTexture(GL_TEXTURE_2D, 图层数据['纹理编号']) glColor4f(1, 1, 1, 1) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) glBegin(GL_QUADS) for p in [p1, p2, p3, p4]: a = p[:4] b = p[4:6] a = a @ model a[0:2] *= a[2] 横旋转量 = 0 if not 图层数据['名字'] == '身体': 横旋转量 = math.sin(time.time() * 5) / 30 a = a @ matrix.translate(0, 0, -1) \ @ matrix.rotate_ax(横旋转量, axis=(0, 2)) \ @ matrix.translate(0, 0, 1) # a = a @ matrix.scale(1,1,3) \ # @ matrix.rotate_ax(1.2, axis=(0, 2)) \ # @ matrix.translate(2.1, 0, 0.8) a = a @ matrix.perspective(999) glTexCoord2f(*b) glVertex4f(*a) glEnd() glfw.swap_buffers(window)
def opengl绘图循环(所有图层, psd尺寸): Vtuber尺寸 = 500, 500 glfw.init() glfw.window_hint(glfw.RESIZABLE, False) glfw.window_hint(glfw.DECORATED, False) glfw.window_hint(glfw.TRANSPARENT_FRAMEBUFFER, True) glfw.window_hint(glfw.FLOATING, True) window = glfw.create_window(*Vtuber尺寸, 'Vtuber', None, None) glfw.make_context_current(window) monitor_size = glfw.get_video_mode(glfw.get_primary_monitor()).size glfw.set_window_pos(window, monitor_size.width - Vtuber尺寸[0], monitor_size.height - Vtuber尺寸[1]) glViewport(0, 0, *Vtuber尺寸) glEnable(GL_TEXTURE_2D) glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) for 图层数据 in 所有图层: 纹理编号 = glGenTextures(1) glBindTexture(GL_TEXTURE_2D, 纹理编号) 纹理, 纹理座标 = 生成纹理(图层数据['npdata']) width, height = 纹理.shape[:2] glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_FLOAT, 纹理) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR) glGenerateMipmap(GL_TEXTURE_2D) 图层数据['纹理编号'] = 纹理编号 图层数据['纹理座标'] = 纹理座标 while not glfw.window_should_close(window): glfw.poll_events() glClearColor(0, 0, 0, 0) glClear(GL_COLOR_BUFFER_BIT) 横旋转量, 竖旋转量 = 特征缓冲() for 图层数据 in 所有图层: a, b, c, d = 图层数据['位置'] z1, z2, z3, z4 = 图层数据['深度'] q, w = 图层数据['纹理座标'] p1 = np.array([a, b, z1, 1, 0, 0, 0, z1]) p2 = np.array([a, d, z2, 1, z2 * w, 0, 0, z2]) p3 = np.array([c, d, z3, 1, z3 * w, z3 * q, 0, z3]) p4 = np.array([c, b, z4, 1, 0, z4 * q, 0, z4]) model = matrix.scale(2 / psd尺寸[0], 2 / psd尺寸[1], 1) @ \ matrix.translate(-1, -1, 0) @ \ matrix.rotate_ax(-math.pi / 2, axis=(0, 1)) glBindTexture(GL_TEXTURE_2D, 图层数据['纹理编号']) glColor4f(1, 1, 1, 1) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) glBegin(GL_QUADS) t = [] for p in [p1, p2, p3, p4]: a = p[:4] b = p[4:8] a = a @ model a[0] *= a[2] a[1] *= a[2] if not 图层数据['名字'][:2] == '身体': a = a @ \ matrix.translate(0, 0, -1) @ \ matrix.rotate_ax(横旋转量, axis=(0, 2)) @ \ matrix.rotate_ax(竖旋转量, axis=(2, 1)) @ \ matrix.translate(0, 0, 1) a = a @ matrix.perspective(999) glTexCoord4f(*b) glVertex4f(*a) glEnd() glfw.swap_buffers(window)