为什么我的 pyglet 应用程序画得很有趣?
Why does my pyglet application draw funny?
我用于以 STL 格式查看 3-d 对象的 pyglet 应用程序表现得很有趣。
当我加载一个 stl 文件时,它工作正常,但是当我尝试绘制它时,它表现得很有趣。
代码没有崩溃,但我为多维数据集加载的测试文件看起来不正确。我认为它可能会加入绘制代码中我不想加入的所有点。测试文件应显示为 30 x 30 像素,而不是整个右上角:
a picture showing that a chunk of the display is the cube。
在 150 度时,看起来几乎正确...
红线是线框,绿点是顶点,灰色是立方体的一个面。
这是我的代码:
print("starting Wireframe Viewer")
import pyglet, wireframe
from pyglet.gl import *
verticeColor = (0, 100, 0)
verticeSize = 4
lineColor = (100, 0, 0)
lineSize = 2
faceColor = (200, 200, 200)
menuColor = (0, 0, 100)
backgroundColor = (0, 0, 50)
gridColor = (255, 255, 255)
mode = 'OBJ' # normal viewing - see all faces and such
pos = [0, 0, -20]
rot_y = 0
rot_x = 0
rot_z = 0
if __name__ == "__main__":
# good
window = pyglet.window.Window(640, 480, resizable=True)
wf = wireframe.Wireframe()
# good
wf.importStl('test.stl')
wf.dumpData()
@window.event
def on_draw():
# creating 3D viewport
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(10, 1, 0.1, 100)
glTranslatef(*pos)
glRotatef(rot_y, 0, 1, 0)
glRotatef(rot_x, 1, 0, 0)
glRotatef(rot_z, 0, 0, 1)
glClearColor(0.0, 0.0, 0.15, 0.0)
window.clear()
# load line width and point size
glLineWidth(lineSize)
glPointSize(verticeSize)
stlDrawDat = []
for dat in wf.stlMesh:
stlDrawDat.append([[dat[0], dat[1], dat[2]],
[dat[3], dat[4], dat[5]],
[dat[6], dat[7], dat[8]]])
# drawing the image
for dat in stlDrawDat:
pyglet.graphics.draw(3, GL_TRIANGLES,
('v3f', [*dat[0], *dat[1], *dat[2]]), ('c3B', faceColor * 3))
pyglet.graphics.draw(3, GL_LINES,
('v3f', [*dat[0], *dat[1], *dat[2]]), ('c3B', lineColor * 3))
pyglet.graphics.draw(3, GL_POINTS,
('v3f', [*dat[0], *dat[1], *dat[2]]), ('c3b', verticeColor * 3))
glFlush()
@window.event
def on_key_press(s, m):
# good
global pos, rot_y, rot_x, rot_z
if m:
pass
if s == pyglet.window.key.W:
rot_x += 5 # pos[2] -= 1
if s == pyglet.window.key.S:
rot_x -= 5 # pos[2] += 1
if s == pyglet.window.key.A:
rot_y += 5
if s == pyglet.window.key.D:
rot_y -= 5
if s == pyglet.window.key.Q:
rot_z += 5
if s == pyglet.window.key.E:
rot_z -= 5
if s == pyglet.window.key.MINUS:
pos[2] -= 1
if s == pyglet.window.key.EQUAL:
pos[2] += 1
if s == pyglet.window.key.LEFT:
pos[0] -= 1
if s == pyglet.window.key.RIGHT:
pos[0] += 1
if s == pyglet.window.key.UP:
pos[1] += 1
if s == pyglet.window.key.DOWN:
pos[1] -= 1
pyglet.app.run()
和我的外部文件 wireframe.py 如果需要我可以添加:
import numpy
from stl import mesh
class Wireframe:
def __init__(self):
self.stlMesh = numpy.zeros((0, 9))
self.originalMesh = numpy.zeros((0, 9))
self.backupMesh = numpy.zeros((0, 9))
def importStl(self, fileName):
print("importing ", fileName)
self.stlMesh = mesh.Mesh.from_file(fileName)
self.originalMesh = mesh.Mesh.from_file(fileName)
self.backupMesh = mesh.Mesh.from_file(fileName)
def dumpData(self):
print('\nstl data:')
for x in self.stlMesh:
print(x)
if __name__ == "__main__":
wf = Wireframe()
wf.importStl('test.stl')
wf.dumpData()
如果有人能帮我解决问题,我会很高兴。
我认为问题出在绘图功能的某个地方。如果我需要缩短代码,请告诉我!
它一直有效,直到我从另一个 post 添加了 3-D 视图代码:
运行 代码所需的模块:
python-utils
pyglet
numpy
numpy-stl
gluPerspective
defines a Viewing frustum.
在视图中 space 视图的原点是相机位置,所有 x 和 y 坐标 (0, 0) 的点都在视图中心的视线上。
gluPerspective
的第一个参数是沿 y 轴的视角范围,以度为单位。角度必须 0° < fovAngle < 180°
。因此 0° 和 180° 不是有效角度。
第二个参数是纵横比
10°的视野好像小了点。由于 window 的大小为 640x480,因此纵横比必须为 640.0/480.0
:
gluPerspective(10, 1, 0.1, 100)
gluPerspective(120.0, 640.0/480.0, 0.1, 100)
此外,我建议启用 Depth Test:
glEnable(GL_DEPTH_TEST)
我用于以 STL 格式查看 3-d 对象的 pyglet 应用程序表现得很有趣。 当我加载一个 stl 文件时,它工作正常,但是当我尝试绘制它时,它表现得很有趣。 代码没有崩溃,但我为多维数据集加载的测试文件看起来不正确。我认为它可能会加入绘制代码中我不想加入的所有点。测试文件应显示为 30 x 30 像素,而不是整个右上角:
a picture showing that a chunk of the display is the cube。
在 150 度时,看起来几乎正确...
红线是线框,绿点是顶点,灰色是立方体的一个面。
这是我的代码:
print("starting Wireframe Viewer")
import pyglet, wireframe
from pyglet.gl import *
verticeColor = (0, 100, 0)
verticeSize = 4
lineColor = (100, 0, 0)
lineSize = 2
faceColor = (200, 200, 200)
menuColor = (0, 0, 100)
backgroundColor = (0, 0, 50)
gridColor = (255, 255, 255)
mode = 'OBJ' # normal viewing - see all faces and such
pos = [0, 0, -20]
rot_y = 0
rot_x = 0
rot_z = 0
if __name__ == "__main__":
# good
window = pyglet.window.Window(640, 480, resizable=True)
wf = wireframe.Wireframe()
# good
wf.importStl('test.stl')
wf.dumpData()
@window.event
def on_draw():
# creating 3D viewport
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(10, 1, 0.1, 100)
glTranslatef(*pos)
glRotatef(rot_y, 0, 1, 0)
glRotatef(rot_x, 1, 0, 0)
glRotatef(rot_z, 0, 0, 1)
glClearColor(0.0, 0.0, 0.15, 0.0)
window.clear()
# load line width and point size
glLineWidth(lineSize)
glPointSize(verticeSize)
stlDrawDat = []
for dat in wf.stlMesh:
stlDrawDat.append([[dat[0], dat[1], dat[2]],
[dat[3], dat[4], dat[5]],
[dat[6], dat[7], dat[8]]])
# drawing the image
for dat in stlDrawDat:
pyglet.graphics.draw(3, GL_TRIANGLES,
('v3f', [*dat[0], *dat[1], *dat[2]]), ('c3B', faceColor * 3))
pyglet.graphics.draw(3, GL_LINES,
('v3f', [*dat[0], *dat[1], *dat[2]]), ('c3B', lineColor * 3))
pyglet.graphics.draw(3, GL_POINTS,
('v3f', [*dat[0], *dat[1], *dat[2]]), ('c3b', verticeColor * 3))
glFlush()
@window.event
def on_key_press(s, m):
# good
global pos, rot_y, rot_x, rot_z
if m:
pass
if s == pyglet.window.key.W:
rot_x += 5 # pos[2] -= 1
if s == pyglet.window.key.S:
rot_x -= 5 # pos[2] += 1
if s == pyglet.window.key.A:
rot_y += 5
if s == pyglet.window.key.D:
rot_y -= 5
if s == pyglet.window.key.Q:
rot_z += 5
if s == pyglet.window.key.E:
rot_z -= 5
if s == pyglet.window.key.MINUS:
pos[2] -= 1
if s == pyglet.window.key.EQUAL:
pos[2] += 1
if s == pyglet.window.key.LEFT:
pos[0] -= 1
if s == pyglet.window.key.RIGHT:
pos[0] += 1
if s == pyglet.window.key.UP:
pos[1] += 1
if s == pyglet.window.key.DOWN:
pos[1] -= 1
pyglet.app.run()
和我的外部文件 wireframe.py 如果需要我可以添加:
import numpy
from stl import mesh
class Wireframe:
def __init__(self):
self.stlMesh = numpy.zeros((0, 9))
self.originalMesh = numpy.zeros((0, 9))
self.backupMesh = numpy.zeros((0, 9))
def importStl(self, fileName):
print("importing ", fileName)
self.stlMesh = mesh.Mesh.from_file(fileName)
self.originalMesh = mesh.Mesh.from_file(fileName)
self.backupMesh = mesh.Mesh.from_file(fileName)
def dumpData(self):
print('\nstl data:')
for x in self.stlMesh:
print(x)
if __name__ == "__main__":
wf = Wireframe()
wf.importStl('test.stl')
wf.dumpData()
如果有人能帮我解决问题,我会很高兴。
我认为问题出在绘图功能的某个地方。如果我需要缩短代码,请告诉我!
它一直有效,直到我从另一个 post 添加了 3-D 视图代码:
运行 代码所需的模块:
python-utils
pyglet
numpy
numpy-stl
gluPerspective
defines a Viewing frustum.
在视图中 space 视图的原点是相机位置,所有 x 和 y 坐标 (0, 0) 的点都在视图中心的视线上。
gluPerspective
的第一个参数是沿 y 轴的视角范围,以度为单位。角度必须 0° < fovAngle < 180°
。因此 0° 和 180° 不是有效角度。
第二个参数是纵横比
10°的视野好像小了点。由于 window 的大小为 640x480,因此纵横比必须为 640.0/480.0
:
gluPerspective(10, 1, 0.1, 100)
gluPerspective(120.0, 640.0/480.0, 0.1, 100)
此外,我建议启用 Depth Test:
glEnable(GL_DEPTH_TEST)