使用 python opengl 绘制房屋不显示

Drawing a house using python opengl does not display

我想用 Python OpenGL 画房子。 它应该是这样的:

更多信息:房子应该通过键盘输入围绕 x 轴和 y 轴旋转。通过按 F 键,它应该在填充和未填充模式之间切换。

我的问题:window 打开了,但我没有看到任何东西。我不确定这里到底出了什么问题,或者我在绘图时缺少什么。有人可以解释一下吗?

这是我的代码:

import pygame
from pygame.locals import *

from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
# from OpenGL.GL import shaders
# from OpenGL.arrays import vbo

# import numpy as np

# general all vertices needed
vertices = (
# front wall
(2, 0, -1, 2, 1, -1, -2, 1, -1, -2, 0, -1),
# back wall
(2, 0, 1, 2, 1, 1, -2, 1, 1, -2, 0, 1, 2, 2, 0, -2, 2, 0),
# roof ridge
(2.2, 2, 0, -2.2, 2, 0),
# roof edges
(2.2, 0.9, -1.1, -2.2, 0.9, -1.1, 2.2, 0.9, 1.1, -2.2, 0.9, 1.1),
# chimney
(1, 0, 0.5, 1.25, 0, 0.5, 1.25, 0, 0.25, 1, 0, 0.25,
 1, 2.5, 0.5, 1.25, 2.5, 0.5, 1.25, 2.5, 0.25, 1, 2.5, 0.25)
)


def DrawHouse():
# house

# back wall
glBegin(GL_LINES)
glColor3f(0.5, 0.5, 0.5)
glVertex3f(2, 0, -1)  # top left
glVertex3f(2, 1, -1)  # top right
glVertex3f(-2, 1, -1)  # bottom right
glVertex3f(-2, 0, -1)  # bottom left
glEnd()

# front wall
glBegin(GL_LINES)
glColor3f(0.5, 0.5, 0.5)
glVertex3f(2, 0, 1)  # top left
glVertex3f(2, 1, 1)  # top right
glVertex3f(-2, 1, 1)  # bottom right
glVertex3f(-2, 0, 1)  # bottom right
glVertex3f(2, 2, 0)   # rooftop
glVertex3f(-2, 2, 0)  # rooftop
glEnd()

# roof
glBegin(GL_LINES)
# roof ridge
glColor3f(0, 0, 0)
glVertex3f(2.2, 2, 0)
glVertex3f(-2.2, 2, 0)
glEnd()

# roof edges
glBegin(GL_TRIANGLES)
glColor3f(0, 0, 0)
glVertex3f(2.2, 0.9, -1.1)
glVertex3f(-2.2, 0.9, -1.1)
glVertex3f(2.2, 0.9, 1.1)
glVertex3f(-2.2, 0.9, 1.1)
glEnd()

# chimney
glBegin(GL_POLYGON)
glColor3f(1, 1, 0)
glVertex3f(1, 0, 0.5)
glVertex3f(1.25, 0, 0.5)
glVertex3f(1.25, 0, 0.25)
glVertex3f(1, 0, 0.25)
glVertex3f(1, 2.5, 0.5)
glVertex3f(1.25, 2.5, 0.5)
glVertex3f(1.25, 2.5, 0.25)
glVertex3f(1, 2.5, 0.25)
glEnd()


def init():
# Switch on z-buffer for calculation of hidden surfaces
glEnable(GL_DEPTH_TEST)

# Display front and back of polygons as border lines only
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)


def reshape():
# initialize projection matrix, to 60 degrees horizontal field of view
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(60.0, 1.0, 1.0, 200.0)  # angle, aspect, near and far clip

# make modelview matrix the current matrix again
glMatrixMode(GL_MODELVIEW)


def main():
pygame.init()
window = (800, 800)
display = pygame.display.set_mode(window, DOUBLEBUF | OPENGL)
pygame.display.set_caption('Haus')
clock = pygame.time.Clock()
# GLUT.glutInitDisplayMode(GLUT_DEPTH | GLUT_RGB | GLUT_DOUBLE)  # request render context with z-buffer, doublebuffer for rgb mode
gluOrtho2D(0, 800, 0, 800)

rotX = 0.0
rotY = 0.0
polygonMode = GL_LINE

while True:
    clock.tick(100)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()

    keys = pygame.key.get_pressed()  # checking pressed keys
    if keys[pygame.K_d]:  # The keys 'a' and 'd' should rotate the house around the y-axis
        rotX -= 5
    if keys[pygame.K_a]:
        rotX += 5
    if keys[pygame.K_w]:  # the keys 'w' and 'd' should rotate the house around the x-axis
        rotY -= 5
    if keys[pygame.K_d]:
        rotY += 5
    if keys[pygame.K_f]:  # Key 'f' is to switch between wireframe and filled surfaces
        if polygonMode is GL_FILL:
            polygonMode = GL_LINE
        else:
            polygonMode = GL_FILL

    # Switch polygon display between outline and filled
    glPolygonMode(GL_FRONT_AND_BACK, polygonMode)

    # GLUT.glutPostRedisplay()  # render image again

    # remove Framebuffer and Z-Buffer
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

    # initialise Modelview Matrix
    glLoadIdentity()

    # execute Modeltransformation
    glTranslatef(0, 0, -3)  # shift by -3 in z-direction
    glRotatef(rotY, 0, 1, 0)  # rotate y-achse
    glRotatef(rotX, 1, 0, 0)  # rotate x-achse
    glTranslatef(-0.5, -0.5, -0.5)  # shift by -0.5 in all directions

    # copy Back-Buffer in Front-Buffer
    # swapBuffers()

    DrawHouse()

    # Show the screen
    pygame.display.flip()

    # callback functions
    # glutReshapeFunc(reshape)


    if __name__ == "__main__":
         main()

您的几何坐标在 [-2.2, 2.2] 范围内。但是,您在 [0, 800]:

范围内设置正交投影
gluOrtho2D(0, 800, 0, 800)

实际上有 3 个原因导致您什么都看不到

  1. 这导致屏幕左下角只绘制了几个像素。
  2. gluOrtho2D 创建一个近平面为 -1,远平面为 1 的正交投影。这将剪裁您的几何图形。
  3. 您需要为当前矩阵选择GL_PROJECTION。稍后在您的代码中,模型视图矩阵设置为具有 glLoadIdentity.
  4. 的单位矩阵
def main():
    pygame.init()
    window = (800, 800)
    display = pygame.display.set_mode(window, DOUBLEBUF | OPENGL)
    pygame.display.set_caption('Haus')
    clock = pygame.time.Clock()

    # gluOrtho2D(0, 800, 0, 800)
    
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    glOrtho(-5, 5, -5, 5, -5, 5)
    glMatrixMode(GL_MODELVIEW)

    # [...]

或者您可以使用重塑函数的透视投影:

def main():
    pygame.init()
    window = (800, 800)
    display = pygame.display.set_mode(window, DOUBLEBUF | OPENGL)
    pygame.display.set_caption('Haus')
    clock = pygame.time.Clock()
    
    # gluOrtho2D(0, 800, 0, 800)

    reshape()

    # [...]