【问题标题】:how to drag camera with the mouse like in blender如何像在搅拌机中一样用鼠标拖动相机
【发布时间】:2022-01-20 16:53:50
【问题描述】:

我找到了一个程序,你可以在 pyopengl 中用鼠标在相机周围移动,通过做一些我没有完全理解的事情

from pygame.locals import *
import pygame
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *


def cube():
    vertices = (
        (1,-1,-1),
        (1,1,-1),
        (-1,1,-1),
        (-1,-1,-1),
        (1,-1,1),
        (1,1,1),
        (-1,-1,1),
        (-1,1,1)
    )
    edegs = (
        (0,1),
        (0,3),
        (0,4),
        (2,1),
        (2,3),
        (2,7),
        (6,3),
        (6,4),
        (6,7),
        (5,1),
        (5,4),
        (5,7),
    )
    glBegin(GL_LINES)
    glColor3fv((1,1,1))
    for edeg in edegs:
        for vertex in edeg:
            glVertex3fv(vertices[vertex])
    glEnd()
pygame.init()
screen = (800,600)
pygame.display.set_mode(screen, DOUBLEBUF|OPENGL)
glMatrixMode(GL_PROJECTION)

gluPerspective(45, (screen[0]/screen[1]), 0.1, 50.0)

glTranslate(0.0,0.0,-5)
glMatrixMode(GL_MODELVIEW)  
modelMatrix = glGetFloatv(GL_MODELVIEW_MATRIX)

busy = True
button_down = False
zoom = -0.5
while True:
    glPushMatrix()
    glLoadIdentity()

    for event in pygame.event.get():
        if(event.type == pygame.QUIT):
            pygame.quit()
            busy = False
        elif event.type == pygame.MOUSEMOTION:
            if(button_down):
                glRotatef(event.rel[1], 1, 0, 0)
                glRotatef(event.rel[0], 0, 1, 0)
        elif event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 4:
                zoom += 0.2
            if event.button == 5:
                zoom -= 0.2
    if(not busy): break
    for event in pygame.mouse.get_pressed():
        if pygame.mouse.get_pressed()[0] == 1:
            button_down = True
        elif pygame.mouse.get_pressed()[0] == 0:
            button_down = False
            
    #mouse scroll
    
            
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
    glMultMatrixf(modelMatrix)
    modelMatrix = glGetFloatv(GL_MODELVIEW_MATRIX)

    glLoadIdentity()
    glTranslatef(0.0,0.0,zoom)
    
    glMultMatrixf(modelMatrix)

    cube()

    
    glPopMatrix()
    
        

    pygame.display.flip()
    pygame.time.wait(10)

但是当你在它周围拖动对象时,它开始失去从上到下的方向,这与 Blender 和 SketchUp 等程序不同,有没有办法解决这个问题或用其他方法来操纵相机?

【问题讨论】:

    标签: python opengl pygame pyopengl opengl-compat


    【解决方案1】:

    只需将绕 x 轴的旋转和绕 y 轴的旋转相加即可。先绕y轴旋转,再绕x轴旋转:

    modelview = translate * rotateY * raotateX
    

    完整示例:

    from pygame.locals import *
    import pygame
    from OpenGL.GL import *
    from OpenGL.GLU import *
    from OpenGL.GLUT import *
    
    def cube():
        vertices = (
            (1,-1,-1), (1,1,-1), (-1,1,-1), (-1,-1,-1),
            (1,-1,1), (1,1,1), (-1,-1,1), (-1,1,1)
        )
        edegs = (
            (0,1), (0,3), (0,4), (2,1), (2,3), (2,7),
            (6,3), (6,4), (6,7), (5,1), (5,4), (5,7),
        )
        glBegin(GL_LINES)
        glColor3fv((1,1,1))
        for edeg in edegs:
            for vertex in edeg:
                glVertex3fv(vertices[vertex])
        glColor3fv((1,0,0))    
        glVertex3f(0, -2, 0)  
        glVertex3f(0, 2, 0)    
        glEnd()
    
    pygame.init()
    screen = (400, 300)
    pygame.display.set_mode(screen, DOUBLEBUF|OPENGL)
    
    glEnable(GL_DEPTH_TEST)
    
    glMatrixMode(GL_PROJECTION)
    gluPerspective(45, (screen[0]/screen[1]), 0.1, 50.0)
    
    glMatrixMode(GL_MODELVIEW)  
    glTranslate(0.0,0.0,-5)
    
    rot_x, rot_y, zoom = 0, 0, -0.5
    
    clock = pygame.time.Clock()
    busy = True
    while busy:
    
        mouse_buttons = pygame.mouse.get_pressed()
        button_down = mouse_buttons[0] == 1
       
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                busy = False
            elif event.type == pygame.MOUSEMOTION:
                if button_down:
                    rot_x += event.rel[1]
                    rot_y += event.rel[0]
            elif event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 4:
                    zoom += 0.2
                if event.button == 5:
                    zoom -= 0.2
                
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
    
        glPushMatrix()
        glTranslatef(0.0,0.0, zoom)
        glRotatef(rot_x, 1, 0, 0)    
        glRotatef(rot_y, 0, 1, 0)    
        cube()
        glPopMatrix()
        
        pygame.display.flip()
        clock.tick(100)
    
    pygame.quit()
    

    另请参阅How to implement alt+MMB camera rotation like in 3ds max?How to implement camera pan like in 3dsMax?How to implement zoom towards mouse like in 3dsMax?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-06
      • 1970-01-01
      • 2012-01-06
      • 1970-01-01
      • 2017-12-31
      • 2016-01-29
      • 2016-01-19
      相关资源
      最近更新 更多