Как отобразить фигуру поверх OpenGL с помощью Python и PyGame - PullRequest
0 голосов
/ 08 января 2019

Я пытаюсь сделать игру с python, pygame и OpenGL, и я хочу сделать перекрестие в центре экрана, чтобы, когда они смотрят вокруг, они могли видеть, на что они нажмут. Я сделал это так, чтобы он скрывал их курсор и перемещал его в центр окна, но я не знаю, как заставить фигуру идти поверх opengl в Pygame. Я новичок в 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()

1 Ответ

0 голосов
/ 08 января 2019

Обратите внимание, что рисование с помощью glBegin / glEnd последовательностей и набора матриц фиксированных функций устарело с десятилетий.


В любом случае, я рекомендую рисовать проекционный экран элементов с использованием ортографической проекции.

Создать функцию, которая рисует перекрестие в координатах окна:

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)

Поскольку перекрестие всегда должно быть сверху обзора, необходимо отключить тест глубины .

glDisable(GL_DEPTH_TEST)

mX, mY = pygame.mouse.get_pos()
Crosshair(mX, 600-mY, 20)

glEnable(GL_DEPTH_TEST)

Вероятно, вы можете изменить функцию глубины (glDepthFunc) на GL_ALWAYS и изменить glDepthMask

Используйте glLoadIdentity для определения единичной матрицы и используйте glOrtho для настройки ортографической проекции 1: 1 на координаты окна;

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)
...