import numpy as np import random from .framework import * from .cam_render import CamRender class PRTRender(CamRender): def __init__(self, width=1600, height=1200, name='PRT Renderer', uv_mode=False, ms_rate=1, egl=False): program_files = ['prt.vs', 'prt.fs'] if not uv_mode else ['prt_uv.vs', 'prt_uv.fs'] CamRender.__init__(self, width, height, name, program_files=program_files, color_size=8, ms_rate=ms_rate, egl=egl) # WARNING: this differs from vertex_buffer and vertex_data in Render self.vert_buffer = {} self.vert_data = {} self.norm_buffer = {} self.norm_data = {} self.tan_buffer = {} self.tan_data = {} self.btan_buffer = {} self.btan_data = {} self.prt1_buffer = {} self.prt1_data = {} self.prt2_buffer = {} self.prt2_data = {} self.prt3_buffer = {} self.prt3_data = {} self.uv_buffer = {} self.uv_data = {} self.render_texture_mat = {} self.vertex_dim = {} self.n_vertices = {} self.norm_mat_unif = glGetUniformLocation(self.program, 'NormMat') self.normalize_matrix = np.eye(4) self.shcoeff_unif = glGetUniformLocation(self.program, 'SHCoeffs') self.shcoeffs = np.zeros((9,3)) self.shcoeffs[0,:] = 1.0 #self.shcoeffs[1:,:] = np.random.rand(8,3) self.hasAlbedoUnif = glGetUniformLocation(self.program, 'hasAlbedoMap') self.hasNormalUnif = glGetUniformLocation(self.program, 'hasNormalMap') self.analyticUnif = glGetUniformLocation(self.program, 'analytic') self.analytic = False self.rot_mat_unif = glGetUniformLocation(self.program, 'RotMat') self.rot_matrix = np.eye(3) def set_texture(self, mat_name, smplr_name, texture): # texture_image: H x W x 3 width = texture.shape[1] height = texture.shape[0] texture = np.flip(texture, 0) img_data = np.fromstring(texture.tostring(), np.uint8) if mat_name not in self.render_texture_mat: self.render_texture_mat[mat_name] = {} if smplr_name in self.render_texture_mat[mat_name].keys(): glDeleteTextures([self.render_texture_mat[mat_name][smplr_name]]) del self.render_texture_mat[mat_name][smplr_name] self.render_texture_mat[mat_name][smplr_name] = glGenTextures(1) glActiveTexture(GL_TEXTURE0) glPixelStorei(GL_UNPACK_ALIGNMENT, 1) glBindTexture(GL_TEXTURE_2D, self.render_texture_mat[mat_name][smplr_name]) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, img_data) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 3) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR) glGenerateMipmap(GL_TEXTURE_2D) def set_albedo(self, texture_image, mat_name='all'): self.set_texture(mat_name, 'AlbedoMap', texture_image) def set_normal_map(self, texture_image, mat_name='all'): self.set_texture(mat_name, 'NormalMap', texture_image) def set_mesh(self, vertices, faces, norms, faces_nml, uvs, faces_uvs, prt, faces_prt, tans, bitans, mat_name='all'): self.vert_data[mat_name] = vertices[faces.reshape([-1])] self.n_vertices[mat_name] = self.vert_data[mat_name].shape[0] self.vertex_dim[mat_name] = self.vert_data[mat_name].shape[1] if mat_name not in self.vert_buffer.keys(): self.vert_buffer[mat_name] = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, self.vert_buffer[mat_name]) glBufferData(GL_ARRAY_BUFFER, self.vert_data[mat_name], GL_STATIC_DRAW) self.uv_data[mat_name] = uvs[faces_uvs.reshape([-1])] if mat_name not in self.uv_buffer.keys(): self.uv_buffer[mat_name] = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, self.uv_buffer[mat_name]) glBufferData(GL_ARRAY_BUFFER, self.uv_data[mat_name], GL_STATIC_DRAW) self.norm_data[mat_name] = norms[faces_nml.reshape([-1])] if mat_name not in self.norm_buffer.keys(): self.norm_buffer[mat_name] = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, self.norm_buffer[mat_name]) glBufferData(GL_ARRAY_BUFFER, self.norm_data[mat_name], GL_STATIC_DRAW) self.tan_data[mat_name] = tans[faces_nml.reshape([-1])] if mat_name not in self.tan_buffer.keys(): self.tan_buffer[mat_name] = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, self.tan_buffer[mat_name]) glBufferData(GL_ARRAY_BUFFER, self.tan_data[mat_name], GL_STATIC_DRAW) self.btan_data[mat_name] = bitans[faces_nml.reshape([-1])] if mat_name not in self.btan_buffer.keys(): self.btan_buffer[mat_name] = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, self.btan_buffer[mat_name]) glBufferData(GL_ARRAY_BUFFER, self.btan_data[mat_name], GL_STATIC_DRAW) self.prt1_data[mat_name] = prt[faces_prt.reshape([-1])][:,:3] self.prt2_data[mat_name] = prt[faces_prt.reshape([-1])][:,3:6] self.prt3_data[mat_name] = prt[faces_prt.reshape([-1])][:,6:] if mat_name not in self.prt1_buffer.keys(): self.prt1_buffer[mat_name] = glGenBuffers(1) if mat_name not in self.prt2_buffer.keys(): self.prt2_buffer[mat_name] = glGenBuffers(1) if mat_name not in self.prt3_buffer.keys(): self.prt3_buffer[mat_name] = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, self.prt1_buffer[mat_name]) glBufferData(GL_ARRAY_BUFFER, self.prt1_data[mat_name], GL_STATIC_DRAW) glBindBuffer(GL_ARRAY_BUFFER, self.prt2_buffer[mat_name]) glBufferData(GL_ARRAY_BUFFER, self.prt2_data[mat_name], GL_STATIC_DRAW) glBindBuffer(GL_ARRAY_BUFFER, self.prt3_buffer[mat_name]) glBufferData(GL_ARRAY_BUFFER, self.prt3_data[mat_name], GL_STATIC_DRAW) glBindBuffer(GL_ARRAY_BUFFER, 0) def set_mesh_mtl(self, vertices, faces, norms, faces_nml, uvs, faces_uvs, tans, bitans, prt): for key in faces: self.vert_data[key] = vertices[faces[key].reshape([-1])] self.n_vertices[key] = self.vert_data[key].shape[0] self.vertex_dim[key] = self.vert_data[key].shape[1] if key not in self.vert_buffer.keys(): self.vert_buffer[key] = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, self.vert_buffer[key]) glBufferData(GL_ARRAY_BUFFER, self.vert_data[key], GL_STATIC_DRAW) self.uv_data[key] = uvs[faces_uvs[key].reshape([-1])] if key not in self.uv_buffer.keys(): self.uv_buffer[key] = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, self.uv_buffer[key]) glBufferData(GL_ARRAY_BUFFER, self.uv_data[key], GL_STATIC_DRAW) self.norm_data[key] = norms[faces_nml[key].reshape([-1])] if key not in self.norm_buffer.keys(): self.norm_buffer[key] = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, self.norm_buffer[key]) glBufferData(GL_ARRAY_BUFFER, self.norm_data[key], GL_STATIC_DRAW) self.tan_data[key] = tans[faces_nml[key].reshape([-1])] if key not in self.tan_buffer.keys(): self.tan_buffer[key] = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, self.tan_buffer[key]) glBufferData(GL_ARRAY_BUFFER, self.tan_data[key], GL_STATIC_DRAW) self.btan_data[key] = bitans[faces_nml[key].reshape([-1])] if key not in self.btan_buffer.keys(): self.btan_buffer[key] = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, self.btan_buffer[key]) glBufferData(GL_ARRAY_BUFFER, self.btan_data[key], GL_STATIC_DRAW) self.prt1_data[key] = prt[faces[key].reshape([-1])][:,:3] self.prt2_data[key] = prt[faces[key].reshape([-1])][:,3:6] self.prt3_data[key] = prt[faces[key].reshape([-1])][:,6:] if key not in self.prt1_buffer.keys(): self.prt1_buffer[key] = glGenBuffers(1) if key not in self.prt2_buffer.keys(): self.prt2_buffer[key] = glGenBuffers(1) if key not in self.prt3_buffer.keys(): self.prt3_buffer[key] = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, self.prt1_buffer[key]) glBufferData(GL_ARRAY_BUFFER, self.prt1_data[key], GL_STATIC_DRAW) glBindBuffer(GL_ARRAY_BUFFER, self.prt2_buffer[key]) glBufferData(GL_ARRAY_BUFFER, self.prt2_data[key], GL_STATIC_DRAW) glBindBuffer(GL_ARRAY_BUFFER, self.prt3_buffer[key]) glBufferData(GL_ARRAY_BUFFER, self.prt3_data[key], GL_STATIC_DRAW) glBindBuffer(GL_ARRAY_BUFFER, 0) def cleanup(self): glBindBuffer(GL_ARRAY_BUFFER, 0) for key in self.vert_data: glDeleteBuffers(1, [self.vert_buffer[key]]) glDeleteBuffers(1, [self.norm_buffer[key]]) glDeleteBuffers(1, [self.uv_buffer[key]]) glDeleteBuffers(1, [self.tan_buffer[key]]) glDeleteBuffers(1, [self.btan_buffer[key]]) glDeleteBuffers(1, [self.prt1_buffer[key]]) glDeleteBuffers(1, [self.prt2_buffer[key]]) glDeleteBuffers(1, [self.prt3_buffer[key]]) glDeleteBuffers(1, []) for smplr in self.render_texture_mat[key]: glDeleteTextures([self.render_texture_mat[key][smplr]]) self.vert_buffer = {} self.vert_data = {} self.norm_buffer = {} self.norm_data = {} self.tan_buffer = {} self.tan_data = {} self.btan_buffer = {} self.btan_data = {} self.prt1_buffer = {} self.prt1_data = {} self.prt2_buffer = {} self.prt2_data = {} self.prt3_buffer = {} self.prt3_data = {} self.uv_buffer = {} self.uv_data = {} self.render_texture_mat = {} self.vertex_dim = {} self.n_vertices = {} def randomize_sh(self): self.shcoeffs[0,:] = 0.8 self.shcoeffs[1:,:] = 1.0*np.random.rand(8,3) def set_sh(self, sh): self.shcoeffs = sh def set_norm_mat(self, scale, center): N = np.eye(4) N[:3, :3] = scale*np.eye(3) N[:3, 3] = -scale*center self.normalize_matrix = N def draw(self): self.draw_init() glDisable(GL_BLEND) #glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glEnable(GL_MULTISAMPLE) glUseProgram(self.program) glUniformMatrix4fv(self.norm_mat_unif, 1, GL_FALSE, self.normalize_matrix.transpose()) glUniformMatrix4fv(self.model_mat_unif, 1, GL_FALSE, self.model_view_matrix.transpose()) glUniformMatrix4fv(self.persp_mat_unif, 1, GL_FALSE, self.projection_matrix.transpose()) if 'AlbedoMap' in self.render_texture_mat['all']: glUniform1ui(self.hasAlbedoUnif, GLuint(1)) else: glUniform1ui(self.hasAlbedoUnif, GLuint(0)) if 'NormalMap' in self.render_texture_mat['all']: glUniform1ui(self.hasNormalUnif, GLuint(1)) else: glUniform1ui(self.hasNormalUnif, GLuint(0)) glUniform1ui(self.analyticUnif, GLuint(1) if self.analytic else GLuint(0)) glUniform3fv(self.shcoeff_unif, 9, self.shcoeffs) glUniformMatrix3fv(self.rot_mat_unif, 1, GL_FALSE, self.rot_matrix.transpose()) for mat in self.vert_buffer: # Handle vertex buffer glBindBuffer(GL_ARRAY_BUFFER, self.vert_buffer[mat]) glEnableVertexAttribArray(0) glVertexAttribPointer(0, self.vertex_dim[mat], GL_DOUBLE, GL_FALSE, 0, None) # Handle normal buffer glBindBuffer(GL_ARRAY_BUFFER, self.norm_buffer[mat]) glEnableVertexAttribArray(1) glVertexAttribPointer(1, 3, GL_DOUBLE, GL_FALSE, 0, None) # Handle uv buffer glBindBuffer(GL_ARRAY_BUFFER, self.uv_buffer[mat]) glEnableVertexAttribArray(2) glVertexAttribPointer(2, 2, GL_DOUBLE, GL_FALSE, 0, None) # Handle tan buffer glBindBuffer(GL_ARRAY_BUFFER, self.tan_buffer[mat]) glEnableVertexAttribArray(3) glVertexAttribPointer(3, 3, GL_DOUBLE, GL_FALSE, 0, None) # Handle btan buffer glBindBuffer(GL_ARRAY_BUFFER, self.btan_buffer[mat]) glEnableVertexAttribArray(4) glVertexAttribPointer(4, 3, GL_DOUBLE, GL_FALSE, 0, None) # Handle PTR buffer glBindBuffer(GL_ARRAY_BUFFER, self.prt1_buffer[mat]) glEnableVertexAttribArray(5) glVertexAttribPointer(5, 3, GL_DOUBLE, GL_FALSE, 0, None) glBindBuffer(GL_ARRAY_BUFFER, self.prt2_buffer[mat]) glEnableVertexAttribArray(6) glVertexAttribPointer(6, 3, GL_DOUBLE, GL_FALSE, 0, None) glBindBuffer(GL_ARRAY_BUFFER, self.prt3_buffer[mat]) glEnableVertexAttribArray(7) glVertexAttribPointer(7, 3, GL_DOUBLE, GL_FALSE, 0, None) for i, smplr in enumerate(self.render_texture_mat[mat]): glActiveTexture(GL_TEXTURE0 + i) glBindTexture(GL_TEXTURE_2D, self.render_texture_mat[mat][smplr]) glUniform1i(glGetUniformLocation(self.program, smplr), i) glDrawArrays(GL_TRIANGLES, 0, self.n_vertices[mat]) glDisableVertexAttribArray(7) glDisableVertexAttribArray(6) glDisableVertexAttribArray(5) glDisableVertexAttribArray(4) glDisableVertexAttribArray(3) glDisableVertexAttribArray(2) glDisableVertexAttribArray(1) glDisableVertexAttribArray(0) glBindBuffer(GL_ARRAY_BUFFER, 0) glUseProgram(0) glDisable(GL_BLEND) glDisable(GL_MULTISAMPLE) self.draw_end()