Reputation: 813
I am trying to make a game with python, pygame and OpenGL and I want to make a crosshair in the center of the screen so when they look around they can see what they are going to click. I made it so it hides their cursor and moves it to the center of the window but I do not know how to make a shape go on top of opengl in pygame. I am a beginner to pygame and to opengl. It is probably really easy but I could not find an answer to it where I looked.
Please help out how you can and thanks in advance.
Here is my code if you want to make sure what you do works in my situation.
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()
Upvotes: 1
Views: 1925
Reputation: 210909
Note, that drawing by glBegin
/glEnd
sequences and the fixed function matrix stack is deprecated since decades.
Anyway, I recommend to draw head-up display elements using orthographic projection.
Create a function which draws the cross hair in window coordinates:
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()
Apply the projection matrix to the projection matrix stack and the model matrix to the model view matrix stack. See glMatrixMode
:
glMatrixMode(GL_PROJECTION)
gluPerspective(45, (display[0]/display[1]), 0.1, 100.0)
glMatrixMode(GL_MODELVIEW)
glTranslatef(0.0, 0.0, -5)
Since the cross hair always should be on top of the view, you have to disable the depth test.
glDisable(GL_DEPTH_TEST)
mX, mY = pygame.mouse.get_pos()
Crosshair(mX, 600-mY, 20)
glEnable(GL_DEPTH_TEST)
Likely you can change the depth function (glDepthFunc
) to GL_ALWAYS
and change the glDepthMask
Use glLoadIdentity
to lad the identity matrix and use glOrtho
to set up an orthographic projection 1:1 to window coordinates;
glLoadIdentity()
glOrtho(0.0, display[0], 0.0, display[1], -1.0, 1.0)
Use glPushMatrix
/glPopMatrix
to store and restore the matrixes on the matrix stack:
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)
Upvotes: 2