创建 UI 和 glRotatef() 的问题
Problems with creating a UI and glRotatef()
我正在使用 Python、PyGame 和 旧版 PyOpenGL。我希望玩家能够通过按左右箭头键使用 glRotatef()
向前、向后、向左和向右四个方向环顾四周。
出现了一些问题:
一把枪(一个应用了纹理的立方体,它根据玩家面对的方向改变纹理坐标)应该始终出现在相机前面 0.5 个单位的相应 x 和 z 位置根据角度 glRotatef()
将其设置为朝向,如果我在 x 轴上移动然后向左看,它会移动到一个奇怪的位置,除非我站在房间的死角。即使我向它提供从 glGetDoublev()
获得的 x 值,当我向左和向右移动时,立方体也似乎是静止的,而当我向前移动时,枪似乎在缩放,即使我从未实现过这样的功能。
当我打电话时
if event.type == pygame.KEYDOWN: # key pressed events
if event.key == pygame.K_LEFT:
glRotatef(-90,0,1,0)
if direction == 0:
direction = 3
else:
direction -= 1
往房间左边看,我偶尔会被移到墙内,这有时会进一步影响枪的位置。
我已经尝试添加固定的 x 和 z 变量(x_steps
和 z_steps
),每次玩家移动它们都会增加 0.1。我不是特别确定为什么会消除 "static gun" 问题,但确实如此。但是,当我旋转相机时,仍然出现同样的问题(枪移动到一个奇怪的位置)。
## pygame/opengl initialisation code
def main():
pygame.init()
display = (800,600)
global displaySurface
displaySurface = pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
pygame.display.set_caption("Wolfenstein 4D")
glEnable(GL_TEXTURE_2D)
glEnable(GL_DEPTH_TEST)
gluPerspective(45, (display[0]/display[1]),0.1,50.0)
## game loop, obtaining x,y,z positions and looking around the room
def room1():
direction = 3 ## 3 = forward, 2 = left, 1 = backward, 0 = right
while True:
pos = glGetDoublev(GL_MODELVIEW_MATRIX)
x = pos[3][0]
y = pos[3][1]
z = pos[3][2]
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN: # key pressed events
if event.key == pygame.K_LEFT:
glRotatef(-90,0,1,0)
if direction == 0:
direction = 3
else:
direction -= 1
x_steps = 0
z_steps = 0
if event.key == pygame.K_RIGHT:
glRotatef(90,0,1,0)
if direction == 3:
direction = 0
else:
direction += 1
x_steps = 0
z_steps = 0
## movement code
spd = 0.1
keys = pygame.key.get_pressed()
if direction == 3:
if keys[pygame.K_a]:
glTranslatef(spd,0,0)
x_steps -= spd
if keys[pygame.K_d]:
glTranslatef(-spd,0,0)
x_steps += spd
if keys[pygame.K_w]:
glTranslatef(0,0,spd)
z_steps -= spd
if keys[pygame.K_s]:
glTranslatef(0,0,-spd)
z_steps += spd
if direction == 2:
if keys[pygame.K_a]:
glTranslatef(0,0,-spd)
x_steps += spd
if keys[pygame.K_d]:
glTranslatef(0,0,spd)
x_steps -= spd
if keys[pygame.K_w]:
glTranslatef(spd,0,0)
z_steps -= spd
if keys[pygame.K_s]:
glTranslatef(-spd,0,0)
z_steps += spd
## gun drawing code in game loop
if direction == 3:
loadTexture("gun1.png")
drawHUDGun(x,-0.1,z-0.5,3,0.1,0.1,0.1)
if direction == 2:
loadTexture("gun.png")
drawHUDGun(z-0.5,-0.1,x+0.5,2,0.1,0.1,0.1)
## gun drawing function
def drawHUDGun(x,y,z,angle,width,height,depth=0.5,color = ((1,1,1))):
vertices = (
(width+x,-height+y,-depth+z),
(width+x,height+y,-depth+z),
(-width+x,height+y,-depth+z),
(-width+x,-height+y,-depth+z),
(width+x,-height+y,depth+z),
(width+x,height+y,depth+z),
(-width+x,-height+y,depth+z),
(-width+x,height+y,depth+z)
)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glBegin(GL_QUADS)
if angle == 3:
j = 0
if angle == 2:
j = 8
i = 0
for surface in surfaces:
i += 1
for vertex in surface:
glColor4f(1,1,1,1)
setTexCoord(0, texCoords, j)
if angle == 3:
if i >= 0 and i < 4:
if j < 4:
j += 1
if angle == 2:
if i == 2:
if j < 12:
j += 1
glVertex3fv(vertices[vertex])
glEnd()
glDisable(GL_BLEND)
glBegin(GL_LINES)
for edge in edges:
glColor3fv((0,1,0))
for vertex in edge:
glVertex3fv(vertices[vertex])
glEnd()
## implementation of the functions
main()
room1()
我希望无论玩家在房间的哪个方向,枪支都会在玩家前方 0.5 个单位处出现,但由于分配了不正确的 x 或 z 坐标,枪支通常不在视线范围内。
在旧版 OpenGL 中存在不同的电流矩阵。当前受矩阵运算影响的矩阵可以通过glMatrixMode
. Each matrix is organized on a stack. Matrices can be pushed and popped by glPushMatrix
/glPopMatrix
.
选择
投影矩阵应设置为投影矩阵堆栈,视图和模型转换为模型视图矩阵堆栈:
// choose projection matrix stack
glMatrixMode(GL_PROJECTION)
gluPerspective(45, (display[0]/display[1]),0.1,50.0)
// choose modelview matrix stack, for the following matrix operations
glMatrixMode(GL_MODELVIEW)
枪应该放在第一人称视角 ("in front of you")。实现这一点的最简单方法是在视图空间中绘制枪支,这意味着您必须取消所有先前对模型视图矩阵的转换。矩阵可以替换为 identity matrix by glLoadIdentity
.
将模型视图矩阵保存到堆栈上,设置单位矩阵,绘制枪并最终恢复模型视图matrix.e.g:
glPushMatrix()
glLoadIdentity()
drawHUDGun(x,-0.1,z-0.5,3,0.1,0.1,0.1)
glPopMatrix()
我正在使用 Python、PyGame 和 旧版 PyOpenGL。我希望玩家能够通过按左右箭头键使用 glRotatef()
向前、向后、向左和向右四个方向环顾四周。
出现了一些问题:
一把枪(一个应用了纹理的立方体,它根据玩家面对的方向改变纹理坐标)应该始终出现在相机前面 0.5 个单位的相应 x 和 z 位置根据角度
glRotatef()
将其设置为朝向,如果我在 x 轴上移动然后向左看,它会移动到一个奇怪的位置,除非我站在房间的死角。即使我向它提供从glGetDoublev()
获得的 x 值,当我向左和向右移动时,立方体也似乎是静止的,而当我向前移动时,枪似乎在缩放,即使我从未实现过这样的功能。当我打电话时
if event.type == pygame.KEYDOWN: # key pressed events if event.key == pygame.K_LEFT: glRotatef(-90,0,1,0) if direction == 0: direction = 3 else: direction -= 1
往房间左边看,我偶尔会被移到墙内,这有时会进一步影响枪的位置。
我已经尝试添加固定的 x 和 z 变量(
x_steps
和z_steps
),每次玩家移动它们都会增加 0.1。我不是特别确定为什么会消除 "static gun" 问题,但确实如此。但是,当我旋转相机时,仍然出现同样的问题(枪移动到一个奇怪的位置)。## pygame/opengl initialisation code def main(): pygame.init() display = (800,600) global displaySurface displaySurface = pygame.display.set_mode(display, DOUBLEBUF|OPENGL) pygame.display.set_caption("Wolfenstein 4D") glEnable(GL_TEXTURE_2D) glEnable(GL_DEPTH_TEST) gluPerspective(45, (display[0]/display[1]),0.1,50.0) ## game loop, obtaining x,y,z positions and looking around the room def room1(): direction = 3 ## 3 = forward, 2 = left, 1 = backward, 0 = right while True: pos = glGetDoublev(GL_MODELVIEW_MATRIX) x = pos[3][0] y = pos[3][1] z = pos[3][2] for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() quit() if event.type == pygame.KEYDOWN: # key pressed events if event.key == pygame.K_LEFT: glRotatef(-90,0,1,0) if direction == 0: direction = 3 else: direction -= 1 x_steps = 0 z_steps = 0 if event.key == pygame.K_RIGHT: glRotatef(90,0,1,0) if direction == 3: direction = 0 else: direction += 1 x_steps = 0 z_steps = 0 ## movement code spd = 0.1 keys = pygame.key.get_pressed() if direction == 3: if keys[pygame.K_a]: glTranslatef(spd,0,0) x_steps -= spd if keys[pygame.K_d]: glTranslatef(-spd,0,0) x_steps += spd if keys[pygame.K_w]: glTranslatef(0,0,spd) z_steps -= spd if keys[pygame.K_s]: glTranslatef(0,0,-spd) z_steps += spd if direction == 2: if keys[pygame.K_a]: glTranslatef(0,0,-spd) x_steps += spd if keys[pygame.K_d]: glTranslatef(0,0,spd) x_steps -= spd if keys[pygame.K_w]: glTranslatef(spd,0,0) z_steps -= spd if keys[pygame.K_s]: glTranslatef(-spd,0,0) z_steps += spd ## gun drawing code in game loop if direction == 3: loadTexture("gun1.png") drawHUDGun(x,-0.1,z-0.5,3,0.1,0.1,0.1) if direction == 2: loadTexture("gun.png") drawHUDGun(z-0.5,-0.1,x+0.5,2,0.1,0.1,0.1) ## gun drawing function def drawHUDGun(x,y,z,angle,width,height,depth=0.5,color = ((1,1,1))): vertices = ( (width+x,-height+y,-depth+z), (width+x,height+y,-depth+z), (-width+x,height+y,-depth+z), (-width+x,-height+y,-depth+z), (width+x,-height+y,depth+z), (width+x,height+y,depth+z), (-width+x,-height+y,depth+z), (-width+x,height+y,depth+z) ) glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glBegin(GL_QUADS) if angle == 3: j = 0 if angle == 2: j = 8 i = 0 for surface in surfaces: i += 1 for vertex in surface: glColor4f(1,1,1,1) setTexCoord(0, texCoords, j) if angle == 3: if i >= 0 and i < 4: if j < 4: j += 1 if angle == 2: if i == 2: if j < 12: j += 1 glVertex3fv(vertices[vertex]) glEnd() glDisable(GL_BLEND) glBegin(GL_LINES) for edge in edges: glColor3fv((0,1,0)) for vertex in edge: glVertex3fv(vertices[vertex]) glEnd() ## implementation of the functions main() room1()
我希望无论玩家在房间的哪个方向,枪支都会在玩家前方 0.5 个单位处出现,但由于分配了不正确的 x 或 z 坐标,枪支通常不在视线范围内。
在旧版 OpenGL 中存在不同的电流矩阵。当前受矩阵运算影响的矩阵可以通过glMatrixMode
. Each matrix is organized on a stack. Matrices can be pushed and popped by glPushMatrix
/glPopMatrix
.
投影矩阵应设置为投影矩阵堆栈,视图和模型转换为模型视图矩阵堆栈:
// choose projection matrix stack
glMatrixMode(GL_PROJECTION)
gluPerspective(45, (display[0]/display[1]),0.1,50.0)
// choose modelview matrix stack, for the following matrix operations
glMatrixMode(GL_MODELVIEW)
枪应该放在第一人称视角 ("in front of you")。实现这一点的最简单方法是在视图空间中绘制枪支,这意味着您必须取消所有先前对模型视图矩阵的转换。矩阵可以替换为 identity matrix by glLoadIdentity
.
将模型视图矩阵保存到堆栈上,设置单位矩阵,绘制枪并最终恢复模型视图matrix.e.g:
glPushMatrix()
glLoadIdentity()
drawHUDGun(x,-0.1,z-0.5,3,0.1,0.1,0.1)
glPopMatrix()