使用 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 个原因导致您什么都看不到
- 这导致屏幕左下角只绘制了几个像素。
gluOrtho2D
创建一个近平面为 -1,远平面为 1 的正交投影。这将剪裁您的几何图形。
- 您需要为当前矩阵选择
GL_PROJECTION
。稍后在您的代码中,模型视图矩阵设置为具有 glLoadIdentity
. 的单位矩阵
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()
# [...]
我想用 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 个原因导致您什么都看不到
- 这导致屏幕左下角只绘制了几个像素。
gluOrtho2D
创建一个近平面为 -1,远平面为 1 的正交投影。这将剪裁您的几何图形。- 您需要为当前矩阵选择
GL_PROJECTION
。稍后在您的代码中,模型视图矩阵设置为具有glLoadIdentity
. 的单位矩阵
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()
# [...]