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.base_shaders import VERTEX_SHADER, GEOMETRY_SHADER, FRAGMENT_SHADER
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 BaseRenderer:
def __init__(self, height=512, width=512):
self.display, self.egl_surf, self.opengl_context = create_opengl_context(
(width, height))
self.height = height
self.width = width
self.vao = None
self.triangle_vertex_properties = None
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, face_indices, matrix_model=None, matrix_view=None,
matrix_proj=None):
if self.vao is None:
self.generate_vao(vertex_positions, face_indices)
else:
self.update_vao(vertex_positions, face_indices)
#print(self.vao)
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))
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, face_indices: np.ndarray):
assert vertex_positions.ndim == 2
assert vertex_positions.shape[1] == 3
assert face_indices.ndim == 1
face_indices = face_indices.astype(IndexType)
#vertex_attributes = np.hstack(
# (vertex_positions, texcoord)).astype(VertextAttribType)
vertex_attributes = np.hstack(
(vertex_positions,)).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)
self.triangle_indices = triangle_indices
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, face_indices: np.ndarray):
assert vertex_positions.ndim == 2
assert vertex_positions.shape[1] == 3
assert face_indices.ndim == 1
#vertex_attributes = np.hstack(
# (vertex_positions, texcoord)).astype(VertextAttribType)
vertex_attributes = np.hstack(
(vertex_positions,)).astype(VertextAttribType)
num_pos_per_vertex = vertex_positions.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))
#glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self.triangle_indices)
#glBufferData(GL_ELEMENT_ARRAY_BUFFER, face_indices.nbytes,
# face_indices, GL_STATIC_DRAW)
glBindVertexArray(0)