python - 使用 PyOpenGL 从多个角度呈现纹理投影
问题描述
我对 OpenGL 很陌生。我动手进行相机校准(平移(X,Y,Z),旋转(X,Y,Z),焦距),并且我拥有来自每个相机的图像。另外,我有一个 3d 模型(obj),我设法将其构建到我的 openGL 项目中,并绘制了一个点云。我想将图像投影到我的对象上,如图像中所示:
https://imgur.com/0lmpDcs “投影图像”
但我很难做这个预测。我希望我的投影在 Obj 和点云上都有纹理(看起来很主要)我创建模型的主要循环是:
主绘制循环:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glPushMatrix()
# Draw the Objects
for i in range(len(obj)):
glCallList(obj[i].gl_list)
# Draw some point Clouds
Ogl.draw_buffer(buffer_obj, num_of_points, 2)
glPopMatrix()
pygame.display.flip()
pygame.time.wait(20)
我如何上传我的 OBJ 并绘制它们:
class OBJ:
def __init__(self, filename, swapyz=False, stop_loop=False):
self.vertices = []
self.normals = []
self.texcoords = []
self.faces = []
self.stop = stop_loop
material = None
self.current_path = os.getcwd()
try:
os.chdir(os.path.dirname(filename))
except Exception, error_found:
print error_found
print("Path is broken => %s " % str(os.path.dirname(filename)))
try:
for line in open(filename, "r"):
if line.startswith('#'):
continue
values = line.split()
if not values:
continue
if values[0] == 'v':
v = map(float, values[1:4])
if swapyz:
v = (v[2] / float(10)) + 5, v[1], (v[0] / float(10)) - 9
self.vertices.append(v)
elif values[0] == 'vn':
v = map(float, values[1:4])
if swapyz:
v = v[2], v[1], v[0]
self.normals.append(v)
elif values[0] == 'vt':
self.texcoords.append(map(float, values[1:3]))
elif values[0] in ('usemtl', 'usemat'):
material = values[1]
elif values[0] == 'mtllib':
self.mtl = MTL(values[1])
elif values[0] == 'f':
face = []
texcoords = []
norms = []
for v in values[1:]:
w = v.split('/')
face.append(int(w[0]))
if len(w) >= 2 and len(w[1]) > 0:
texcoords.append(int(w[1]))
else:
texcoords.append(0)
if len(w) >= 3 and len(w[2]) > 0:
norms.append(int(w[2]))
else:
norms.append(0)
self.faces.append((face, norms, texcoords, material))
except Exception, error_found:
print error_found
print("Couldn't find the Obj file in path %s " % str(filename))
print("Using Default OBJ file in %s\\Assets" % str(self.current_path))
os.chdir(self.current_path + "\\Assets")
for line in open("ground_NFL.obj", "r"):
if line.startswith('#'):
continue
values = line.split()
if not values:
continue
if values[0] == 'v':
v = map(float, values[1:4])
if swapyz:
v = (v[2] / float(10)) + 5, v[1], (v[0] / float(10)) - 9
self.vertices.append(v)
elif values[0] == 'vn':
v = map(float, values[1:4])
if swapyz:
v = v[2], v[1], v[0]
self.normals.append(v)
elif values[0] == 'vt':
self.texcoords.append(map(float, values[1:3]))
elif values[0] in ('usemtl', 'usemat'):
material = values[1]
elif values[0] == 'mtllib':
self.mtl = MTL(values[1])
elif values[0] == 'f':
face = []
texcoords = []
norms = []
for v in values[1:]:
w = v.split('/')
face.append(int(w[0]))
if len(w) >= 2 and len(w[1]) > 0:
texcoords.append(int(w[1]))
else:
texcoords.append(0)
if len(w) >= 3 and len(w[2]) > 0:
norms.append(int(w[2]))
else:
norms.append(0)
self.faces.append((face, norms, texcoords, material))
else:
print("Obj file %s Was Successfully found" % str(filename))
self.gl_list = glGenLists(1)
glNewList(self.gl_list, GL_COMPILE)
glEnable(GL_TEXTURE_2D)
glFrontFace(GL_CCW)
for face in self.faces:
vertices, normals, texture_coords, material = face
mtl = self.mtl[material]
if 'texture_Kd' in mtl:
# use diffuse texmap
glBindTexture(GL_TEXTURE_2D, mtl['texture_Kd'])
else:
# just use diffuse colour
glColor(*mtl['Kd'])
glBegin(GL_POLYGON)
for i in range(len(vertices)):
if normals[i] > 0:
glNormal3fv(self.normals[normals[i] - 1])
if texture_coords[i] > 0:
glTexCoord2fv(self.texcoords[texture_coords[i] - 1])
glVertex3fv(self.vertices[vertices[i] - 1])
glEnd()
glDisable(GL_TEXTURE_2D)
glEndList()
os.chdir(self.current_path)
print("---- OBJ time = %s ----" % (time.time() - start_time))
def MTL(filename):
start_time = time.time()
print("---- started MTL ----")
contents = {}
mtl = None
for line in open(filename, "r"):
if line.startswith('#'):
continue
values = line.split()
if not values:
continue
if values[0] == 'newmtl':
mtl = contents[values[1]] = {}
elif mtl is None:
raise ValueError, "mtl file doesn't start with newmtl stmt"
elif values[0] == 'map_Kd':
# load the texture referred to by this declaration
mtl[values[0]] = values[1]
surf = pygame.image.load(mtl['map_Kd'])
image = pygame.image.tostring(surf, 'RGBA', 1)
ix, iy = surf.get_rect().size
tex_id = mtl['texture_Kd'] = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, tex_id)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ix, iy, 0, GL_RGBA, GL_UNSIGNED_BYTE, image)
else:
mtl[values[0]] = map(float, values[1:])
print("---- MTL time = %s ----" % (time.time() - start_time))
return contents
我如何上传我的点云并绘制它们:
def create_buffer(vertices, colors):
start_time = time.time()
print("---- Started Creating Buffer ----")
buffer_data = (ctypes.c_float*len(vertices))(*vertices) # float buffer
buffer_size = len(vertices)*4 # buffer size in bytes
color_buffer = (ctypes.c_float*len(colors))(*colors)
color_size = len(colors)*4
vbo = glGenBuffers(2)
glBindBuffer(GL_ARRAY_BUFFER, vbo[0])
glBufferData(GL_ARRAY_BUFFER, buffer_size, buffer_data, GL_STATIC_DRAW)
glBindBuffer(GL_ARRAY_BUFFER, vbo[1])
glBufferData(GL_ARRAY_BUFFER, color_size, color_buffer, GL_STATIC_DRAW)
glBindBuffer(GL_ARRAY_BUFFER, 0)
print("---- CreateBuffer time = %s ----" % (time.time() - start_time))
return vbo
def draw_buffer(vbo, num_of_points, point_size):
glBindBuffer(GL_ARRAY_BUFFER, vbo[0])
glEnableClientState(GL_VERTEX_ARRAY)
glVertexPointer(3, GL_FLOAT, 0, None)
glEnableClientState(GL_COLOR_ARRAY)
glBindBuffer(GL_ARRAY_BUFFER, vbo[1])
glColorPointer(3, GL_FLOAT, 0, None)
glPointSize(point_size)
glDrawArrays(GL_POINTS, 0, num_of_points)
glDisableClientState(GL_VERTEX_ARRAY)
glDisableClientState(GL_COLOR_ARRAY)
glBindBuffer(GL_ARRAY_BUFFER, 0)
我尝试使用这些功能,但缺少某些东西或者它们完全错误:)
def load_image_texture(image_path):
surf = pygame.image.load(image_path)
image = pygame.image.tostring(surf, 'RGBA', 1)
ix, iy = surf.get_rect().size
tex_id = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, tex_id)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ix, iy, 0, GL_RGBA, GL_UNSIGNED_BYTE, image)
def load_texture_projection(x,y,z,rot_x,rot_y,rot_z):
glMatrixMode(GL_TEXTURE)
glLoadIdentity()
glTranslatef(x, y, z)
glRotatef(1, rot_x, rot_y, rot_z)
glMatrixMode(GL_MODELVIEW)
解决方案
推荐阅读
- c - 使用 bazel 链接到版本化的预构建库
- arrays - JOLT 转换将相同的元素添加到所有数组中
- reactjs - 从firebase实时数据库检索时未定义的数组(但不是)
- sonarqube - 错误:SonarScanner 执行期间出错 java.lang.IllegalArgumentException:第 xx 行超出文件 IService.cs 的范围。文件有 xx 行
- algorithm - 当 N 固定且 k<=N 时 N 模 k 的最大化
- powershell - 发送请求时在 PowerShell 中使用方括号
- html - 使用 D3.js 以角度堆积条形图/图表
- mongodb - 在 ubuntu 20.04 上通过 golang 连接到 mongodb atlas 的问题
- laravel - 如何在文件上传期间保持页面可编辑(Laravel)?
- sql - 如何根据条件对 sql 上的行进行分组