python - PyOpenGL:分别移动两个对象?
问题描述
我在使用 PyOpenGL 方面很新,我想加载一个 obj 文件,移动它,然后绘制一个球体并移动它。当我使用不同的键盘按钮时,我希望这两个对象分别移动。是否可以?(我还需要每个对象的中心坐标)。问题是即使我使用 Push 和 Pop 矩阵命令,它们也会移动
这是我的代码:
rom objloader import *
def main():
pygame.init()
display = (800,600)
pygame.display.set_mode(display, OPENGL | DOUBLEBUF)
glMatrixMode(GL_PROJECTION)
gluPerspective(45.0, display[0]/display[1], 0.1, 100.0)
glLightfv(GL_LIGHT5, GL_POSITION, (-40, 200, 100, 0.0))
glLightfv(GL_LIGHT5, GL_AMBIENT, (0.2, 0.2, 0.2, 1.0))
glLightfv(GL_LIGHT5, GL_DIFFUSE, (0.5, 0.5, 0.5, 1.0))
glEnable(GL_LIGHT5)
glEnable(GL_LIGHTING)
glEnable(GL_COLOR_MATERIAL)
glEnable(GL_DEPTH_TEST)
glShadeModel(GL_SMOOTH)
glMatrixMode(GL_MODELVIEW)
glTranslatef(0, 0, -5)
x = 0
y = 0
z = - 5
xx = 0
yy = 0
zz = -5
# LOAD OBJECT
obj = OBJ(sys.argv[1], swapyz=True)
sphere = gluNewQuadric() #Create new sphere
model = glGetDoublev(GL_MODELVIEW_MATRIX)
rx, ry = (0,0)
tx, ty = (0,0)
zpos = 5
rotate = move = False
clock = pygame.time.Clock()
while 1:
clock.tick(30)
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT) #Clear the screen
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE or event.key == pygame.K_RETURN:
sys.exit()
keypress = pygame.key.get_pressed()
glMatrixMode(GL_MODELVIEW)
glPushMatrix()
glLoadIdentity()
if keypress[pygame.K_w]:
glTranslatef(0,-0.01,0)
y = y - 0.01
if keypress[pygame.K_s]:
glTranslatef(0,0.01,0)
y = y + 0.01
if keypress[pygame.K_d]:
glTranslatef(0.01,0,0)
x = x + 0.01
if keypress[pygame.K_a]:
glTranslatef(-0.01,0,0)
x = x - 0.01
if keypress[pygame.K_z]:
glTranslatef(0, 0, -0.01)
z = z - 0.01
if keypress[pygame.K_x]:
glTranslatef(0,0,0.01)
z = z + 0.01
if keypress[pygame.K_0]:
start = x, y, z
print('start is', start)
#model = glGetDoublev(GL_MODELVIEW_MATRIX)
glMultMatrixf(model)
model = glGetDoublev(GL_MODELVIEW_MATRIX)
glMultMatrixf(model)
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
glScalef(0.1, 0.1, 0.1)
glColor4f(0.5, 0.2, 0.2, 1)
gluSphere(sphere, 1.0, 32, 16)
glPopMatrix()
glPushMatrix()
glLoadIdentity()
if keypress[pygame.K_u]:
glTranslatef(0,-0.01,0)
yy = yy - 0.01
if keypress[pygame.K_j]:
glTranslatef(0,0.01,0)
yy = yy + 0.01
if keypress[pygame.K_k]:
glTranslatef(0.01,0,0)
xx = xx + 0.01
if keypress[pygame.K_h]:
glTranslatef(-0.01,0,0)
xx = xx - 0.01
if keypress[pygame.K_n]:
glTranslatef(0, 0, -0.01)
zz = zz - 0.01
if keypress[pygame.K_m]:
glTranslatef(0,0,0.01)
zz = zz + 0.01
if keypress[pygame.K_l]:
glRotatef(1, 0, 1, 5)
xx = xx*math.cos(rad)-y*math.sin(rad)
yy = xx*math.sin(rad)+yy*math.cos(rad)
if keypress[pygame.K_g]:
#glTranslatef(xx, yy, zz)
glRotatef(1, 0, 1, -5)
#glTranslatef(-xx, -yy, -zz)
rad = 1*180/math.pi
xx = xx*math.cos(rad)-yy*math.sin(rad)
yy = xx*math.sin(rad)+yy*math.cos(rad)
print(xx, yy, math.sin( rad))
if keypress [pygame.K_9]:
print('obj coord', xx, yy, zz)
glMultMatrixf(model)
model = glGetDoublev(GL_MODELVIEW_MATRIX)
glMultMatrixf(model)
#glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT) --> se lo metti non vedi l'oggetto prima
glScalef(0.1, 0.1, 0.1)
glCallList(obj.gl_list)
glPopMatrix()
pygame.display.flip() #Update the screen
main()
解决方案
问题是即使我使用 Push 和 Pop 矩阵命令,它们也会移动
模型矩阵定义场景中单个对象(网格)的位置方向和比例。因此,每个对象都需要一个单独的模型矩阵:
def main():
# [...]
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45.0, display[0]/display[1], 0.1, 100.0)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glTranslatef(0, 0, -5)
model_1 = glGetDoublev(GL_MODELVIEW_MATRIX)
model_2 = model_1
# [...]
while 1:
# [...]
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
glMatrixMode(GL_MODELVIEW)
# Model 1
glPushMatrix()
glLoadIdentity()
# rotate and translate model 1
# [...]
glMultMatrixf(model_1)
model_1 = glGetDoublev(GL_MODELVIEW_MATRIX)
glScalef(0.1, 0.1, 0.1)
# draw model 1
glColor4f(0.5, 0.2, 0.2, 1)
gluSphere(sphere, 1.0, 32, 16)
glPopMatrix()
# Model 2
glPushMatrix()
glLoadIdentity()
# rotate and translate model 2
# [...]
glMultMatrixf(model_2)
model_2 = glGetDoublev(GL_MODELVIEW_MATRIX)
glScalef(0.1, 0.1, 0.1)
# draw model 1
glCallList(obj.gl_list)
glPopMatrix()
pygame.display.flip() #Update the screen
推荐阅读
- android - 在设备上运行 React Native 时出现问题
- leaflet - 如何在 crs.simple 中测量距离?
- sql - 使用具有较高偏移量的 LAG 函数
- html - 我的列没有显示在 Safari 中(但它们在 Chrome、Explorer、Firefox 中)?
- python - 使用部分评估的函数作为另一个函数的参数
- sass - 在依赖项中导入 Sass 文件时汇总 CommonJS 插件抛出错误
- database - Laravel 编辑表单 - 选择框 - 表单加载/提交时选择的旧值或数据库值
- android - 在 Xamarin.Forms 中创建多个单独的弹出式项目的最佳方法是什么?
- microservices - 使用事件驱动的微服务架构在 Web 应用程序中显示数据
- python - 如何绘制二维数组