nasttam's picture
Duplicate from cownclown/Image-and-3D-Model-Creator
d444fe9
raw
history blame
14.3 kB
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()