如何使用 Python 和 PyGame 在 OpenGL 上显示二维形状
How to display a 2D shape over OpenGL with Python and PyGame
我正在尝试使用 python、pygame 和 OpenGL 制作游戏,我想在屏幕中央制作一个十字准线,这样当他们环顾四周时,他们可以看到他们是什么要点击。我做到了,所以它隐藏了他们的光标并将其移动到 window 的中心,但我不知道如何在 pygame 中使形状位于 opengl 之上。我是 pygame 和 opengl 的初学者。这可能真的很容易,但我找不到我看过的答案。
请帮助您如何做并提前致谢。
如果你想确保你所做的在我的情况下有效,这是我的代码。
import pygame
import time
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *
block = [
[0,1,0],
[1,0,0],
[1,0,1],
[0,0,1],
[1,1,0],
[0,1,1]
]
def Cube(x,y,z):
glBegin(GL_TRIANGLES)
glColor3f(block[0][0], block[0][1], block[0][2]) # N
glVertex3f(x + .5, y + 1, z + .5)
glVertex3f(x - .5, y + 1, z + .5)
glVertex3f(x - .5, y, z + .5)
glVertex3f(x - .5, y, z + .5)
glVertex3f(x + .5, y, z + .5)
glVertex3f(x + .5, y + 1, z + .5)
glColor3f(block[1][0], block[1][1], block[1][2]) # S
glVertex3f(x - .5, y + 1, z - .5)
glVertex3f(x + .5, y + 1, z - .5)
glVertex3f(x + .5, y, z - .5)
glVertex3f(x + .5, y, z - .5)
glVertex3f(x - .5, y, z - .5)
glVertex3f(x - .5, y + 1, z - .5)
glColor3f(block[2][0], block[2][1], block[2][2]) # W
glVertex3f(x + .5, y + 1, z - .5)
glVertex3f(x + .5, y + 1, z + .5)
glVertex3f(x + .5, y, z + .5)
glVertex3f(x + .5, y, z + .5)
glVertex3f(x + .5, y, z - .5)
glVertex3f(x + .5, y + 1, z - .5)
glColor3f(block[3][0], block[3][1], block[3][2]) # E
glVertex3f(x - .5, y + 1, z + .5)
glVertex3f(x - .5, y + 1, z - .5)
glVertex3f(x - .5, y, z - .5)
glVertex3f(x - .5, y, z - .5)
glVertex3f(x - .5, y, z + .5)
glVertex3f(x - .5, y + 1, z + .5)
glColor3f(block[4][0], block[4][1], block[4][2]) # U
glVertex3f(x + .5, y + 1, z - .5)
glVertex3f(x - .5, y + 1, z - .5)
glVertex3f(x - .5, y + 1, z + .5)
glVertex3f(x - .5, y + 1, z + .5)
glVertex3f(x + .5, y + 1, z + .5)
glVertex3f(x + .5, y + 1, z - .5)
glColor3f(block[5][0], block[5][1], block[5][2]) # D
glVertex3f(x + .5, y, z - .5)
glVertex3f(x + .5, y, z + .5)
glVertex3f(x - .5, y, z + .5)
glVertex3f(x - .5, y, z + .5)
glVertex3f(x - .5, y, z - .5)
glVertex3f(x + .5, y, z - .5)
glEnd()
def main():
controls = False
pygame.init()
display = (800,600)
pygame.display.set_mode(display, DOUBLEBUF | OPENGL)
glClearColor(0.0, 0.0, 0.0, 0.0)
glClearDepth(1.0)
glDepthMask(GL_TRUE)
glDepthFunc(GL_LESS)
glEnable(GL_DEPTH_TEST)
glEnable(GL_CULL_FACE)
glCullFace(GL_BACK)
glFrontFace(GL_CCW)
glShadeModel(GL_SMOOTH)
glDepthRange(0.0,1.0)
gluPerspective(45, (display[0]/display[1]), 0.1, 100.0)
glTranslatef(0.0, 0.0, -5)
while True:
if controls:
pygame.mouse.set_pos([400, 300])
pygame.mouse.set_visible(False)
else:
pygame.mouse.set_visible(True)
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
controls = not controls
if event.type == pygame.QUIT:
pygame.quit()
quit()
glRotatef(1, 3, 1, 1,)
glClearDepth(1.0)
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
Cube(0,0,0)
Cube(0,1,0)
Cube(1,1,1)
glCullFace(GL_BACK)
pygame.display.flip()
time.sleep(.01)
main()
请注意,几十年来不推荐使用 glBegin
/glEnd
序列和固定函数矩阵堆栈进行绘制。
无论如何,我建议使用正交投影绘制 head-up display 个元素。
创建一个在 window 坐标中绘制十字准线的函数:
def Crosshair(x, y, w):
glColor3f(1.0, 1.0, 1.0)
glBegin(GL_LINES)
glVertex2f(x-w, y)
glVertex2f(x+w, y)
glVertex2f(x, y-w)
glVertex2f(x, y+w)
glEnd()
将投影矩阵应用于投影矩阵堆栈,将模型矩阵应用于模型视图矩阵堆栈。见 glMatrixMode
:
glMatrixMode(GL_PROJECTION)
gluPerspective(45, (display[0]/display[1]), 0.1, 100.0)
glMatrixMode(GL_MODELVIEW)
glTranslatef(0.0, 0.0, -5)
由于十字准线始终应位于视图的顶部,因此您必须禁用 depth test。
glDisable(GL_DEPTH_TEST)
mX, mY = pygame.mouse.get_pos()
Crosshair(mX, 600-mY, 20)
glEnable(GL_DEPTH_TEST)
您可能可以更改深度函数 (glDepthFunc
) to GL_ALWAYS
and change the glDepthMask
使用glLoadIdentity
to lad the identity matrix and use glOrtho
设置正投影1:1到window坐标;
glLoadIdentity()
glOrtho(0.0, display[0], 0.0, display[1], -1.0, 1.0)
使用glPushMatrix
/glPopMatrix
存储和恢复矩阵栈上的矩阵:
glMatrixMode(GL_PROJECTION)
gluPerspective(45, (display[0]/display[1]), 0.1, 100.0)
glMatrixMode(GL_MODELVIEW)
glTranslatef(0.0, 0.0, -5)
while True:
if controls:
pygame.mouse.set_pos([400, 300])
pygame.mouse.set_visible(False)
else:
pygame.mouse.set_visible(True)
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
controls = not controls
if event.type == pygame.QUIT:
pygame.quit()
quit()
glClearDepth(1.0)
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
glRotate(1, 3, 1, 1,)
Cube(0,0,0)
Cube(0,1,0)
Cube(1,1,1)
glMatrixMode(GL_PROJECTION)
glPushMatrix()
glLoadIdentity()
glOrtho(0.0, display[0], 0.0, display[1], -1.0, 1.0)
glMatrixMode(GL_MODELVIEW)
glPushMatrix()
glLoadIdentity()
glDisable(GL_DEPTH_TEST)
mX, mY = pygame.mouse.get_pos()
Crosshair(mX, 600-mY, 20)
glEnable(GL_DEPTH_TEST)
glMatrixMode(GL_PROJECTION)
glPopMatrix()
glMatrixMode(GL_MODELVIEW)
glPopMatrix()
glCullFace(GL_BACK)
pygame.display.flip()
time.sleep(.01)
我正在尝试使用 python、pygame 和 OpenGL 制作游戏,我想在屏幕中央制作一个十字准线,这样当他们环顾四周时,他们可以看到他们是什么要点击。我做到了,所以它隐藏了他们的光标并将其移动到 window 的中心,但我不知道如何在 pygame 中使形状位于 opengl 之上。我是 pygame 和 opengl 的初学者。这可能真的很容易,但我找不到我看过的答案。
请帮助您如何做并提前致谢。
如果你想确保你所做的在我的情况下有效,这是我的代码。
import pygame
import time
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *
block = [
[0,1,0],
[1,0,0],
[1,0,1],
[0,0,1],
[1,1,0],
[0,1,1]
]
def Cube(x,y,z):
glBegin(GL_TRIANGLES)
glColor3f(block[0][0], block[0][1], block[0][2]) # N
glVertex3f(x + .5, y + 1, z + .5)
glVertex3f(x - .5, y + 1, z + .5)
glVertex3f(x - .5, y, z + .5)
glVertex3f(x - .5, y, z + .5)
glVertex3f(x + .5, y, z + .5)
glVertex3f(x + .5, y + 1, z + .5)
glColor3f(block[1][0], block[1][1], block[1][2]) # S
glVertex3f(x - .5, y + 1, z - .5)
glVertex3f(x + .5, y + 1, z - .5)
glVertex3f(x + .5, y, z - .5)
glVertex3f(x + .5, y, z - .5)
glVertex3f(x - .5, y, z - .5)
glVertex3f(x - .5, y + 1, z - .5)
glColor3f(block[2][0], block[2][1], block[2][2]) # W
glVertex3f(x + .5, y + 1, z - .5)
glVertex3f(x + .5, y + 1, z + .5)
glVertex3f(x + .5, y, z + .5)
glVertex3f(x + .5, y, z + .5)
glVertex3f(x + .5, y, z - .5)
glVertex3f(x + .5, y + 1, z - .5)
glColor3f(block[3][0], block[3][1], block[3][2]) # E
glVertex3f(x - .5, y + 1, z + .5)
glVertex3f(x - .5, y + 1, z - .5)
glVertex3f(x - .5, y, z - .5)
glVertex3f(x - .5, y, z - .5)
glVertex3f(x - .5, y, z + .5)
glVertex3f(x - .5, y + 1, z + .5)
glColor3f(block[4][0], block[4][1], block[4][2]) # U
glVertex3f(x + .5, y + 1, z - .5)
glVertex3f(x - .5, y + 1, z - .5)
glVertex3f(x - .5, y + 1, z + .5)
glVertex3f(x - .5, y + 1, z + .5)
glVertex3f(x + .5, y + 1, z + .5)
glVertex3f(x + .5, y + 1, z - .5)
glColor3f(block[5][0], block[5][1], block[5][2]) # D
glVertex3f(x + .5, y, z - .5)
glVertex3f(x + .5, y, z + .5)
glVertex3f(x - .5, y, z + .5)
glVertex3f(x - .5, y, z + .5)
glVertex3f(x - .5, y, z - .5)
glVertex3f(x + .5, y, z - .5)
glEnd()
def main():
controls = False
pygame.init()
display = (800,600)
pygame.display.set_mode(display, DOUBLEBUF | OPENGL)
glClearColor(0.0, 0.0, 0.0, 0.0)
glClearDepth(1.0)
glDepthMask(GL_TRUE)
glDepthFunc(GL_LESS)
glEnable(GL_DEPTH_TEST)
glEnable(GL_CULL_FACE)
glCullFace(GL_BACK)
glFrontFace(GL_CCW)
glShadeModel(GL_SMOOTH)
glDepthRange(0.0,1.0)
gluPerspective(45, (display[0]/display[1]), 0.1, 100.0)
glTranslatef(0.0, 0.0, -5)
while True:
if controls:
pygame.mouse.set_pos([400, 300])
pygame.mouse.set_visible(False)
else:
pygame.mouse.set_visible(True)
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
controls = not controls
if event.type == pygame.QUIT:
pygame.quit()
quit()
glRotatef(1, 3, 1, 1,)
glClearDepth(1.0)
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
Cube(0,0,0)
Cube(0,1,0)
Cube(1,1,1)
glCullFace(GL_BACK)
pygame.display.flip()
time.sleep(.01)
main()
请注意,几十年来不推荐使用 glBegin
/glEnd
序列和固定函数矩阵堆栈进行绘制。
无论如何,我建议使用正交投影绘制 head-up display 个元素。
创建一个在 window 坐标中绘制十字准线的函数:
def Crosshair(x, y, w):
glColor3f(1.0, 1.0, 1.0)
glBegin(GL_LINES)
glVertex2f(x-w, y)
glVertex2f(x+w, y)
glVertex2f(x, y-w)
glVertex2f(x, y+w)
glEnd()
将投影矩阵应用于投影矩阵堆栈,将模型矩阵应用于模型视图矩阵堆栈。见 glMatrixMode
:
glMatrixMode(GL_PROJECTION)
gluPerspective(45, (display[0]/display[1]), 0.1, 100.0)
glMatrixMode(GL_MODELVIEW)
glTranslatef(0.0, 0.0, -5)
由于十字准线始终应位于视图的顶部,因此您必须禁用 depth test。
glDisable(GL_DEPTH_TEST)
mX, mY = pygame.mouse.get_pos()
Crosshair(mX, 600-mY, 20)
glEnable(GL_DEPTH_TEST)
您可能可以更改深度函数 (glDepthFunc
) to GL_ALWAYS
and change the glDepthMask
使用glLoadIdentity
to lad the identity matrix and use glOrtho
设置正投影1:1到window坐标;
glLoadIdentity()
glOrtho(0.0, display[0], 0.0, display[1], -1.0, 1.0)
使用glPushMatrix
/glPopMatrix
存储和恢复矩阵栈上的矩阵:
glMatrixMode(GL_PROJECTION)
gluPerspective(45, (display[0]/display[1]), 0.1, 100.0)
glMatrixMode(GL_MODELVIEW)
glTranslatef(0.0, 0.0, -5)
while True:
if controls:
pygame.mouse.set_pos([400, 300])
pygame.mouse.set_visible(False)
else:
pygame.mouse.set_visible(True)
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
controls = not controls
if event.type == pygame.QUIT:
pygame.quit()
quit()
glClearDepth(1.0)
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
glRotate(1, 3, 1, 1,)
Cube(0,0,0)
Cube(0,1,0)
Cube(1,1,1)
glMatrixMode(GL_PROJECTION)
glPushMatrix()
glLoadIdentity()
glOrtho(0.0, display[0], 0.0, display[1], -1.0, 1.0)
glMatrixMode(GL_MODELVIEW)
glPushMatrix()
glLoadIdentity()
glDisable(GL_DEPTH_TEST)
mX, mY = pygame.mouse.get_pos()
Crosshair(mX, 600-mY, 20)
glEnable(GL_DEPTH_TEST)
glMatrixMode(GL_PROJECTION)
glPopMatrix()
glMatrixMode(GL_MODELVIEW)
glPopMatrix()
glCullFace(GL_BACK)
pygame.display.flip()
time.sleep(.01)