def model(xz, zy, xy, 脸大小, x偏移, y偏移): model_p = \ matrix.translate(0, 0, -0.9) @ \ matrix.rotate_ax(xz, axis=(0, 2)) @ \ matrix.rotate_ax(zy, axis=(2, 1)) @ \ matrix.translate(0, 0.9, 0.9) @ \ matrix.rotate_ax(xy, axis=(0, 1)) @ \ matrix.translate(0, -0.9, 0) @ \ matrix.perspective(999) f = 750/(800-脸大小) extra = matrix.translate(x偏移*0.6, -y偏移*0.8, 0) @ \ matrix.scale(f, f, 1) return model_p @ extra
def 画图(纹理编号, 纹理座标): glClear(GL_COLOR_BUFFER_BIT) glBindTexture(GL_TEXTURE_2D, 纹理编号) glColor4f(1, 1, 1, 1) a = b = -1 c = d = 1 q, w = 纹理座标 [[p1, p2], [p4, p3]] = np.array([ [[a, b, 0, 1, 0, 0], [a, d, 0, 1, w, 0]], [[c, b, 0, 1, 0, q], [c, d, 0, 1, w, q]], ]) t = matrix.rotate_ax(-math.pi / 2, axis=(0, 1)) glBegin(GL_QUADS) for p in [p1, p2, p3, p4]: glTexCoord2f(*p[4:]) glVertex4f(*(p[:4] @ t)) glEnd() glfw.swap_buffers(window)
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绘图循环(self, window, 数据源, line_box=False): def 没有状态但是却能均匀变化的随机数(范围=(0, 1), 速度=1): now = time.time()*速度 a, b = int(now), int(now)+1 random.seed(a) f0 = random.random() random.seed(b) f1 = random.random() f = f0 * (b-now) + f1 * (now-a) return 范围[0] + (范围[1]-范围[0])*f def 锚击(x, a, b): x = sorted([x, a, b])[1] return (x-a)/(b-a) @functools.lru_cache(maxsize=16) def model(xz, zy, xy, 脸大小, x偏移, y偏移): model_p = \ matrix.translate(0, 0, -0.9) @ \ matrix.rotate_ax(xz, axis=(0, 2)) @ \ matrix.rotate_ax(zy, axis=(2, 1)) @ \ matrix.translate(0, 0.9, 0.9) @ \ matrix.rotate_ax(xy, axis=(0, 1)) @ \ matrix.translate(0, -0.9, 0) @ \ matrix.perspective(999) f = 750/(800-脸大小) extra = matrix.translate(x偏移*0.6, -y偏移*0.8, 0) @ \ matrix.scale(f, f, 1) return model_p @ extra model_g = \ matrix.scale(2 / self.切取范围[0], 2 / self.切取范围[1], 1) @ \ matrix.translate(-1, -1, 0) @ \ matrix.rotate_ax(-math.pi / 2, axis=(0, 1)) def draw(图层): 源 = 图层.顶点组导出() x, y, _ = 源.shape 所有顶点 = 源.reshape(x*y, 8) a, b = 所有顶点[:, :4], 所有顶点[:, 4:] a = a @ model_g z = a[:, 2:3] z -= 0.1 a[:, :2] *= z 眼睛左右 = 横旋转量*4 + 没有状态但是却能均匀变化的随机数((-0.2, 0.2), 速度=1.6) 眼睛上下 = 竖旋转量*7 + 没有状态但是却能均匀变化的随机数((-0.1, 0.1), 速度=2) 闭眼强度 = 锚击(左眼大小+右眼大小, -0.001, -0.008) 眉上度 = 锚击(左眉高+右眉高, -0.03, 0.01) - 闭眼强度*0.1 闭嘴强度 = 锚击(嘴大小, 0.05, 0) * 1.1 - 0.1 a, b = self.多重附加变形([ ['永远', 1], ['眉上', 眉上度], ['左眼远离', 眼睛左右], ['右眼远离', -眼睛左右], ['左眼上', 眼睛上下], ['右眼上', 眼睛上下], ['左眼闭', 闭眼强度], ['右眼闭', 闭眼强度], ['闭嘴', 闭嘴强度], ], 图层.名字, a, b) xz = 横旋转量 / 1.3 zy = 竖旋转量 / 1.5 xy = Z旋转量 / 5 if not 图层.名字.startswith('头/'): xz /= 8 zy = 0 a = a @ model(xz, zy, xy, 脸大小, x偏移, y偏移) b *= z 所有顶点[:, :4], 所有顶点[:, 4:] = a, b 所有顶点 = 所有顶点.reshape([x, y, 8]) glBegin(GL_QUADS) for i in range(x-1): for j in range(y-1): for p in [所有顶点[i, j], 所有顶点[i, j+1], 所有顶点[i+1, j+1], 所有顶点[i+1, j]]: glTexCoord4f(*p[4:]) glVertex4f(*p[:4]) glEnd() while not glfw.window_should_close(window): with 计时.帧率计('绘图'): glfw.poll_events() glClearColor(0, 0, 0, 0) glClear(GL_COLOR_BUFFER_BIT) 横旋转量, 竖旋转量, Z旋转量, y偏移, x偏移, 嘴大小, 脸大小, 左眼大小, 右眼大小, 左眉高, 右眉高 = 数据源() for 图层 in self.所有图层: glEnable(GL_TEXTURE_2D) glBindTexture(GL_TEXTURE_2D, 图层.纹理编号) glColor4f(1, 1, 1, 1) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) draw(图层) if line_box: glDisable(GL_TEXTURE_2D) glColor4f(0.3, 0.3, 1, 0.2) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) draw(图层) glfw.swap_buffers(window) if self.启用截图: glReadBuffer(GL_FRONT) self.截图 = glReadPixels(0, 0, *Vtuber尺寸, GL_RGBA, GL_UNSIGNED_BYTE)
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)