How do I make 3D in pyglet?

混江龙づ霸主 提交于 2020-12-06 07:03:26

问题


I was trying to create using OpenGL, Python and pyglet, a flat triangle in 3D space, I saw some tutorials on the internet, some videos on YouTube, and in the end I wrote this code down there, the problem is that it did not work as I expected, I thought that if I tried to spin, I would see the triangle turning flat, and when I walked away, the triangle did not have to diminish?

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

When I run the code this appears:

And when I try to spin the scenario it happens:

Does anyone know where I'm going wrong?


回答1:


The initialization of the viewport and the sting pf the projection and model view matrix is useless

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

because the viewport and an orthographic projection is set when the application is started.

See pyglet - The OpenGL interface:

[...] pyglet sets up the viewport and an orthographic projection on each window automatically.

If you would use the perspective projection

gluPerspective(35,1,0.1,1000)

then the triangle would disappear, because it would be clipped by the near plane of the perspective projection (0.1).


To solve the issue, put the setup of perspective projection to the draw event:

@tela.event
def on_draw():

    tela.clear()

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

I thought that if I tried to spin, I would see the triangle turning flat, and when I walked away, the triangle did not have to diminish?

In view space, the x axis points from the left to the right and the y axis points from the bottom to the top. To rotate in the XY plane, you have to rotate around the Z axis.

Define a position and an Y-angle for the triangle. The Z coordinate has to be negative and the distance to the object has to be in between the near and far plane. If near is 0.1 and far is 100, then:

0.1 <= -z <= 100

e.g.

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

Manipulate the position and the angle in the event:

@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

Apply the translation and the rotation to the model view matrix stack in draw:

@tela.event
def on_draw():

    global pos_z, rot_y

    # [...]

    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()

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

Draw an object which is arranged around (0, 0, 0). Note the position of the object is set by pos and in perspective projection the origin (0, 0, 0) is in the center of the window:

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

Full code with the suggested changes applied:

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


来源:https://stackoverflow.com/questions/54188353/how-do-i-make-3d-in-pyglet

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!