Ali Mohsin
feat: Add virtual try-on system components including DensePose, SMPL, and pix2pixHD models, rendering, and utilities.
5db43ff
| import argparse | |
| import os | |
| os.environ["PYOPENGL_PLATFORM"] = "egl" | |
| import numpy as np | |
| import OpenGL.EGL as egl | |
| from OpenGL.GL import * | |
| from OpenGL.GL import shaders | |
| from PIL import Image | |
| from OffscreenRenderer.gl_utils import create_opengl_context, init_frame_buffer | |
| from OffscreenRenderer.off_screen_render import VertextAttribType, IndexType, generate_vao, set_shader_params, render, \ | |
| read_texture | |
| VertextAttribType = np.float32 | |
| IndexType = np.uint32 | |
| OpenglVertexAttrType = GL_FLOAT | |
| OpenglTriangleIndexType = GL_UNSIGNED_INT | |
| class FlatRenderer: | |
| def __init__(self, height=512, width=512, texPath="./assets/measurement.png", back_black=False, phong=False): | |
| self.display, self.egl_surf, self.opengl_context = create_opengl_context( | |
| (width, height)) | |
| self.height = height | |
| self.width = width | |
| self.texID = read_texture(texPath) | |
| self.vao = None | |
| self.triangle_vertex_properties = None | |
| self.back_black = back_black | |
| if phong: | |
| from OffscreenRenderer.Shaders.backblack_phong_shaders import VERTEX_SHADER, GEOMETRY_SHADER, FRAGMENT_SHADER | |
| self.shader = shaders.compileProgram( | |
| shaders.compileShader(VERTEX_SHADER, GL_VERTEX_SHADER), | |
| shaders.compileShader(GEOMETRY_SHADER, GL_GEOMETRY_SHADER), | |
| shaders.compileShader(FRAGMENT_SHADER, GL_FRAGMENT_SHADER), ) | |
| else: | |
| if not back_black: | |
| from OffscreenRenderer.shaders import VERTEX_SHADER, FRAGMENT_SHADER | |
| self.shader = shaders.compileProgram( | |
| shaders.compileShader(VERTEX_SHADER, GL_VERTEX_SHADER), | |
| shaders.compileShader(FRAGMENT_SHADER, GL_FRAGMENT_SHADER), ) | |
| else: | |
| from OffscreenRenderer.Shaders.backblack_shaders import VERTEX_SHADER, GEOMETRY_SHADER, FRAGMENT_SHADER | |
| self.shader = shaders.compileProgram( | |
| shaders.compileShader(VERTEX_SHADER, GL_VERTEX_SHADER), | |
| shaders.compileShader(GEOMETRY_SHADER, GL_GEOMETRY_SHADER), | |
| shaders.compileShader(FRAGMENT_SHADER, GL_FRAGMENT_SHADER), ) | |
| self.rendered_image = np.zeros((height, width, 3), dtype=np.uint8) | |
| self.render_frame_object = init_frame_buffer(self.rendered_image) | |
| def __del__(self): | |
| #glDeleteFramebuffers(1, self.render_frame_object) | |
| egl.eglDestroySurface(self.display, self.egl_surf) | |
| egl.eglDestroyContext(self.display, self.opengl_context) | |
| def render(self, vertex_positions, vertex_texcoord, face_indices, matrix_model=None, matrix_view=None, | |
| matrix_proj=None): | |
| if self.vao is None: | |
| self.generate_vao(vertex_positions, vertex_texcoord, face_indices) | |
| else: | |
| self.update_vao(vertex_positions, vertex_texcoord, face_indices) | |
| glBindFramebuffer(GL_FRAMEBUFFER, self.render_frame_object) | |
| glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) | |
| glClearColor(0, 0, 0.0, 1.0) | |
| # glEnable(GL_MULTISAMPLE) | |
| # glDisable(GL_MULTISAMPLE) | |
| glEnable(GL_DEPTH_TEST) | |
| glDepthFunc(GL_LESS) | |
| glDepthMask(GL_TRUE) | |
| glDisable(GL_CULL_FACE) | |
| # glCullFace(GL_FRONT) | |
| glUseProgram(self.shader) | |
| # Orto projection in range [0; 1] | |
| set_shader_params(self.shader, matrix_model=matrix_model, matrix_view=matrix_view, matrix_proj=matrix_proj) | |
| glBindVertexArray(self.vao) | |
| render(GL_TRIANGLES, len(face_indices), self.texID) | |
| glBindVertexArray(0) | |
| glBindFramebuffer(GL_FRAMEBUFFER, 0) | |
| glBindFramebuffer(GL_FRAMEBUFFER, self.render_frame_object) | |
| glReadBuffer(GL_COLOR_ATTACHMENT0) | |
| data = glReadPixels(0, 0, self.width, self.height, GL_RGB, GL_UNSIGNED_BYTE) | |
| glBindFramebuffer(GL_FRAMEBUFFER, 0) | |
| # glDeleteFramebuffers(1, render_frame_object) | |
| glUseProgram(self.shader) | |
| image = Image.frombuffer("RGB", (self.width, self.height), data) | |
| return np.array(image) | |
| def generate_vao(self, vertex_positions: np.ndarray, texcoord: np.ndarray, face_indices: np.ndarray): | |
| assert vertex_positions.ndim == 2 | |
| assert vertex_positions.shape[1] == 3 | |
| assert vertex_positions.shape[0] == texcoord.shape[0] | |
| assert texcoord.shape[1] == 2 | |
| assert face_indices.ndim == 1 | |
| face_indices = face_indices.astype(IndexType) | |
| vertex_attributes = np.hstack( | |
| (vertex_positions, texcoord)).astype(VertextAttribType) | |
| num_pos_per_vertex = vertex_positions.shape[1] | |
| num_texcoord_per_vertex = texcoord.shape[1] | |
| triangle_vao = glGenVertexArrays(1) | |
| self.vao = triangle_vao | |
| glBindVertexArray(triangle_vao) | |
| num_properties_per_vertex = vertex_attributes.shape[1] | |
| triangle_vertex_properties = glGenBuffers(1) | |
| self.triangle_vertex_properties = triangle_vertex_properties | |
| glBindBuffer(GL_ARRAY_BUFFER, triangle_vertex_properties) | |
| glBufferData(GL_ARRAY_BUFFER, vertex_attributes.nbytes, | |
| vertex_attributes, GL_DYNAMIC_DRAW) | |
| glEnableVertexAttribArray(0) | |
| # Position attribute layout, size, stride, offset | |
| glVertexAttribPointer(0, num_pos_per_vertex, OpenglVertexAttrType, GL_FALSE, vertex_attributes.itemsize * | |
| num_properties_per_vertex, ctypes.c_void_p(0)) | |
| glEnableVertexAttribArray(1) | |
| glVertexAttribPointer(1, num_texcoord_per_vertex, OpenglVertexAttrType, GL_FALSE, vertex_attributes.itemsize * | |
| num_properties_per_vertex, | |
| ctypes.c_void_p(vertex_attributes.itemsize * num_pos_per_vertex)) | |
| triangle_indices = glGenBuffers(1) | |
| glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, triangle_indices) | |
| glBufferData(GL_ELEMENT_ARRAY_BUFFER, face_indices.nbytes, | |
| face_indices, GL_STATIC_DRAW) | |
| glBindVertexArray(0) | |
| def update_vao(self, vertex_positions: np.ndarray, texcoord: np.ndarray, face_indices: np.ndarray): | |
| assert vertex_positions.ndim == 2 | |
| assert vertex_positions.shape[1] == 3 | |
| assert vertex_positions.shape[0] == texcoord.shape[0] | |
| assert texcoord.shape[1] == 2 | |
| assert face_indices.ndim == 1 | |
| vertex_attributes = np.hstack( | |
| (vertex_positions, texcoord)).astype(VertextAttribType) | |
| num_pos_per_vertex = vertex_positions.shape[1] | |
| num_texcoord_per_vertex = texcoord.shape[1] | |
| triangle_vao = self.vao | |
| glBindVertexArray(triangle_vao) | |
| num_properties_per_vertex = vertex_attributes.shape[1] | |
| triangle_vertex_properties = self.triangle_vertex_properties | |
| glBindBuffer(GL_ARRAY_BUFFER, triangle_vertex_properties) | |
| glBufferData(GL_ARRAY_BUFFER, vertex_attributes.nbytes, | |
| vertex_attributes, GL_DYNAMIC_DRAW) | |
| glEnableVertexAttribArray(0) | |
| # Position attribute layout, size, stride, offset | |
| glVertexAttribPointer(0, num_pos_per_vertex, OpenglVertexAttrType, GL_FALSE, vertex_attributes.itemsize * | |
| num_properties_per_vertex, ctypes.c_void_p(0)) | |
| glEnableVertexAttribArray(1) | |
| glVertexAttribPointer(1, num_texcoord_per_vertex, OpenglVertexAttrType, GL_FALSE, vertex_attributes.itemsize * | |
| num_properties_per_vertex, | |
| ctypes.c_void_p(vertex_attributes.itemsize * num_pos_per_vertex)) | |
| glBindVertexArray(0) | |