Как мне сделать 3D в Pyglet? - PullRequest
0 голосов
/ 14 января 2019

Я пытался создать с использованием OpenGL, Python и pyglet, плоский треугольник в трехмерном пространстве, я видел некоторые учебники в Интернете, некоторые видео на YouTube, и в конце я написал этот код там, проблема в том, что это не сработало, как я ожидал, я подумал, что если я попытаюсь вращаться, то увижу, что треугольник поворачивается к плоскости, и когда я ушел, треугольнику не нужно было уменьшаться?

import pyglet
from pyglet.gl import *

config = Config(sample_buffers=1, samples=8)
tela = pyglet.window.Window(height=500, width=500, config=config)

glViewport(0,0,500,500)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(35,1,0.1,1000)
glMatrixMode(GL_MODELVIEW)

@tela.event
def on_draw():
    glBegin(GL_POLYGON)
    glVertex3f(10,10,0)
    glVertex3f(100,10,0)
    glVertex3f(50,100,0)
    glEnd()
    glFlush()

@tela.event
def on_key_press(s,m):
    tela.clear()
    if s == pyglet.window.key.W:
        glTranslatef(0,0,1)
    if s == pyglet.window.key.S:
        glTranslatef(0,0,-1)
    if s == pyglet.window.key.A:
        glRotatef(1,0,1,0)
    if s == pyglet.window.key.D:
        glRotatef(-1,0,1,0)

pyglet.app.run()

Когда я запускаю код, это появляется:

enter image description here

И когда я пытаюсь раскрутить сценарий, это происходит:

enter image description here

Кто-нибудь знает, где я иду не так?

1 Ответ

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

Инициализация окна просмотра и строки матрицы проекции и модели бесполезна

glViewport(0,0,500,500)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(35,1,0.1,1000)
glMatrixMode(GL_MODELVIEW) 

потому что область просмотра и ортографическая проекция устанавливаются при запуске приложения.

См. pyglet - Интерфейс OpenGL :

[...] pyglet автоматически устанавливает область просмотра и ортогональную проекцию для каждого окна.

Если вы используете перспективную проекцию

gluPerspective(35,1,0.1,1000)

тогда треугольник исчезнет, ​​потому что он будет обрезан ближней плоскостью перспективной проекции (0.1).


Чтобы решить эту проблему, настройте перспективную проекцию на событие draw:

@tela.event
def on_draw():

    tela.clear()

    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    gluPerspective(90, 1, 0.1, 100)

Я думал, что если я попытаюсь вращаться, я увижу, что треугольник поворачивается к плоскости, и когда я ушел, треугольнику не нужно было уменьшаться?

В области просмотра ось x указывает слева направо, а ось y - снизу вверх. Чтобы вращаться в плоскости XY, вы должны вращаться вокруг оси Z.

Определите позицию и угол Y для треугольника. Координата Z должна быть отрицательной, а расстояние до объекта должно быть между ближней и дальней плоскостями. Если ближний равен 0,1, а дальний равен 100, то:

0.1 <= -z <= 100
* * Например, тысяча тридцать-семь
pos = [0, 0, -20]
rot_y = 0

Манипуляции с положением и углом в случае:

@tela.event
def on_key_press(s,m):

    global pos_z, rot_y

    if s == pyglet.window.key.W:
        pos[2] -= 1
    if s == pyglet.window.key.S:
        pos[2] += 1
    if s == pyglet.window.key.A:
        rot_y += 5
    if s == pyglet.window.key.D:
        rot_y -= 5

Применить перевод и вращение к стеку матриц вида модели в draw:

@tela.event
def on_draw():

    global pos_z, rot_y

    # [...]

    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()

    glTranslatef(*pos)
    glRotatef(rot_y, 0, 1, 0)

Нарисуйте объект, который расположен вокруг (0, 0, 0). Обратите внимание, что положение объекта установлено pos, а в перспективной проекции начало координат (0, 0, 0) находится в центре окна:

glBegin(GL_POLYGON)
glVertex3f(-5,-5,0)
glVertex3f(5,-5,0)
glVertex3f(0,5,0)
glEnd()

Полный код с предложенными изменениями:

import pyglet
from pyglet.gl import *

pos = [0, 0, -20]
rot_y = 0

config = Config(sample_buffers=1, samples=8)
tela = pyglet.window.Window(height=500, width=500, config=config)

@tela.event
def on_draw():

    global pos_z, rot_y

    tela.clear()

    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    gluPerspective(90, 1, 0.1, 100)

    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()

    glTranslatef(*pos)
    glRotatef(rot_y, 0, 1, 0)

    glBegin(GL_POLYGON)
    glVertex3f(-5,-5,0)
    glVertex3f(5,-5,0)
    glVertex3f(0,5,0)
    glEnd()

    glFlush()

@tela.event
def on_key_press(s,m):

    global pos_z, rot_y

    if s == pyglet.window.key.W:
        pos[2] -= 1
    if s == pyglet.window.key.S:
        pos[2] += 1
    if s == pyglet.window.key.A:
        rot_y += 5
    if s == pyglet.window.key.D:
        rot_y -= 5

pyglet.app.run()
...