【问题标题】:KeyboardSpecialFunc cant rotate opengl pythonKeyboardSpecialFunc 无法旋转opengl python
【发布时间】:2021-07-24 10:49:30
【问题描述】:

我正在为学校开发一个 OpenGL 项目,但我不知道如何找出我的“错误”。 让我解释一下:

我有函数glutKeyboardFunc 来回调我的函数keyboard。 在这个函数中,当我按下 p 字母时(例如),我可以用这个来旋转我的相机:

elif key == 'p':
    moveY = (moveY + 1) % 360
    glRotatef(moveY, 1, 0, 0)

这是有效的

然后我想使用箭头(右,左...) 所以我使用了glutSpecialFunc 和我的回调函数special_keyboard 我知道键的右箭头为 102 整数(我打印了它) 但是当我为字母 p 写同样的东西时,什么也没有发生。

elif key == 102: # Right Arrow
    moveY = (moveY + 1) % 360
    glRotatef(moveY, 1, 0, 0)

我已经尝试了很多方法,但仍然无法正常工作。

如果有人有解决方案:) 谢谢大家

这是我的代码:

这是我的全部代码

# -*- coding: utf-8 -*-

###############################################################
import sys
import math
try:
    from OpenGL.GL import *  # exception car prefixe systematique
    from OpenGL.GLU import *
    from OpenGL.GLUT import *
except:
    print("Pas de module pour OpenGL")
    print("pip install pyopengl")
    sys.exit(1)


###############################################################
# variables globales
move_pos_x, angle_canon, move_pos_z = 0, 2, 1.8
moveX, moveY, moveZ = 0, 0, 0 # utilisé pour la caméra
pas_zoom = 0
quadric = None

test = 0

def init():
    glClearColor(0.0, 0.0, 0.0, 0.0)
    glShadeModel(GL_SMOOTH)

    light()
    camera()


    glEnable(GL_DEPTH_TEST)

def light():
    """
    Fournis la lumière dans le programme
    """
    # Création des listes pour les couleurs
    red = [1, 0, 0, 1]
    white = [1.0, 1.0, 1.0, 1.0]
    diffuse = [0.7, 0.7, 0.7, 1.0]
    specular = [0.001, 0.001, 0.001, 1.0]
    pos = [10, 10, 1, 1]

    # On crée la lumière
    # glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red)
    # glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, white)
    # glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 7.0)

    glEnable(GL_LIGHTING)
    glEnable(GL_LIGHT0)
    glLightfv(GL_LIGHT0, GL_POSITION, pos)
    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse)
    glLightfv(GL_LIGHT0, GL_SPECULAR, specular)

def draw_canon():
    """
    Fonction qui dessine le canon
    Le canon est constitué de 3 parties: le canon ainsi que 2 roues
    """
    # On place un cylindre ==> canon

    glRotatef(0.0, 0.0, 1.0, 0.0)
    glTranslatef(move_pos_x, 0.15, move_pos_z)
    glRotatef(angle_canon, 0.5, 0.0, 0.0)
    glMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, [1, 1, 1, 0])
    glRotatef(180, 0, 0, 0)
    glutSolidCylinder(0.05, 0.3, 70, 70)

    # On place un tore ==> roue droite du canon
    glRotatef(90, 0, 1.0, 0.0)
    glTranslatef(0, 0.0, 0.06)
    glRotatef(0, 0.5, 0.0, 0.0)
    glTranslatef(-0.2, 0, 0)
    glMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, [1, 0, 0, 1])
    glutSolidTorus(0.01, 0.03, 70, 70)

    # Seconde roue du canon
    glRotatef(0, 0, 1.0, 0.0)
    glTranslatef(0.0, 0.0, -0.12)
    glRotatef(0, 0.5, 0.0, 0.0)
    glMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, [1, 0, 0, 1])
    glutSolidTorus(0.01, 0.03, 70, 70)

def draw_scene():
    """
    Fonction qui dessine la scène du jeu.
    La scène est constitué de 3 parties: 2 berges de couleurs jaune séparé par de l'eau au milieu
    """
    glPushMatrix()
    # On scale pour modifier les cubes
    glScalef(3, 0.2, 0.5)
    # Berge du fond de couleur jaune
    glMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, [1, 1, 0, 1])
    glutSolidCube(1)
    glPopMatrix()

    # On dessine le cube cible
    glPushMatrix()
    glTranslatef(0, 0.15, 0)
    glMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, [1, 0, 0, 1])
    glutSolidCube(0.1)
    glPopMatrix()


    glPushMatrix()
    # On translate pour placer l'eau
    glTranslatef(0, -0.1, 1)
    glScalef(3, 0.2, 1.5)
    # L'eau au milieu, qui est plus grand que les berges
    glMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, [0, 0, 1, 1])
    glutSolidCube(1)
    glPopMatrix()

    glPushMatrix()
    # On translate pour placer la dernière berge
    glTranslatef(0, 0, 2)
    glScalef(3, 0.2, 0.5)
    # Dernière berge
    glMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, [1, 1, 0, 1])
    glutSolidCube(1)

    glPopMatrix()

def camera():
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
    glRotatef(30, 2, 0, 0)
    viewMatrix = glGetFloatv(GL_MODELVIEW_MATRIX)

def display():

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

    glPushMatrix()

    draw_scene()

    draw_canon()

    glPopMatrix()

    glutSwapBuffers()


def keyboard(key, x, y):
    global move_pos_x, move_pos_z
    global angle_canon
    global moveX, moveY, moveZ
    global test
    # On bouge le cyclindre canon de haut en bas
    try:
        key = key.decode()
    except UnicodeDecodeError: # avoid decode error when pressing key
        pass
    if key == "a":
        angle_canon = (angle_canon + 1) % 30
        test += 0.1
        """
        if angle_canon != 29:
            angle_canon = (angle_canon + 1) % 30 # "angle" de 30°
        """
    elif key == "e":
        if angle_canon > 0:
            angle_canon = (angle_canon - 1) % 30
    elif key == "z": # Bouge en avant le canon
        if move_pos_z > 1.6:
            move_pos_z -= 0.1
    elif key == "s": # Bouge en arrière le canon
        if move_pos_z < 2.0:
            move_pos_z += 0.1
    # On bouge le canon vers la droite ou la gauche
    elif key == 'd':
        if move_pos_x < 1.4:
            move_pos_x += 0.1

    elif key == 'q':
        if move_pos_x > -1.4:
            move_pos_x -= 0.1

    # Changement de caméra
    elif key == 'p':
        """
        Rotation selon l'axe Y
        """
        moveY = (moveY + 1) % 30
        glRotatef(moveY, 0, 1, 0)


    elif key == 'p':
        """
        Rotation selon l'axe X
        """
        moveX = (moveX + 1) % 100
        glRotatef(moveX, 1, 0, 0)


    elif key == 'o':
        """
        Rotation selon l'axe Z
        """

    elif key == '\033':
        sys.exit()
    glutPostRedisplay()  # indispensable en Python

def mouse(button, state, x, y):
    global pas_zoom
    if button == 3:
        print("zoom up")
        pas_zoom += 0.1
        glTranslatef(0, 0, pas_zoom)

    elif button == 4:
        print("zoom down")


def special_keyboard(key, x, y):
    global moveX, moveY, moveZ
    print(key.decode())
    if key == 103: # Fleche du bas
        pass
    elif key == 101: # Fleche du haut
        pass
    elif key == 100: # Fleche de gauche
        pass
    elif key == GLUT_KEY_RIGHT: # Fleche de droite
        print(key)
        moveY = (moveY + 1) % 100
        glRotatef(moveY, 0, 1, 0)




def reshape(width, height):
    glViewport(0, 0, width, height)
    glMatrixMode(GL_PROJECTION) # Projection orthographique
    glLoadIdentity()
    if width <= height:
           glOrtho(-2.5, 2.5, -2.5*height/width, 2.5*height/width, -10.0, 10.0)
    else:
           glOrtho(-2.5*width/height, 2.5*width/height, -2.5, 2.5, -10.0, 10.0)
    glMatrixMode(GL_MODELVIEW) # On switch de type de projection

###############################################################
# MAIN

glutInit()
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH)

glutCreateWindow('CANOOOOON')
glutReshapeWindow(800,800)

glutReshapeFunc(reshape)
glutDisplayFunc(display)
glutSpecialFunc(special_keyboard)
glutKeyboardFunc(keyboard)
glutMouseFunc(mouse)



init()

glutMainLoop()


"""
A faire:
lever le fut du canon
bouger le canon avec les roues
"""

【问题讨论】:

  • 是的,我已经尝试过了,但没有。如果我在 if 下打印“嘿”之类的内容,则会打印“嘿”但相机没有移动
  • 我正在使用 python3 开发 Ubuntu 20.04.2
  • 我正在开发最新版本的 pyopengl。我刚刚用 pip 更新了它
  • 我得到整数(右箭头为 102,左箭头为 100..)
  • 不,条件为真。如果我在if key == 102 下打印一些东西,就会打印出来

标签: python glut pyopengl


【解决方案1】:

您在更改当前矩阵后错过了调用glutPostRedisplay()

def special_keyboard(key, x, y):
    global moveX, moveY, moveZ
    #print(key.decode())
    if key == 103: # Fleche du bas
        pass
    elif key == 101: # Fleche du haut
        pass
    elif key == 100: # Fleche de gauche
        pass
    elif key == GLUT_KEY_RIGHT: # Fleche de droite
        print(key)
        moveY = (moveY + 1) % 100
        glRotatef(moveY, 0, 1, 0)#

    glutPostRedisplay()  # <--- THIS IS MISSING

glutPostRedisplay导致当前矩阵改变后重新显示当前窗口。

【讨论】:

  • 哦,谢谢伙计。我不知道这个函数(我是 OpenGL 的新手),因为我没有将它用于 KeyboardFunc,所以我不知道我必须使用它。但现在这正在奏效。不好意思打扰了^^
  • @BaptisteLeroux 实际上你是在函数 glutPostRedisplay 的末尾调用 keyboard
  • 是的,我看到了,但这不是我的代码。这是我的老师代码(这是一个学校项目),他给了我们(代码的骨架)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-29
  • 2021-05-20
相关资源
最近更新 更多