如何在 pyglet 中制作 3D? [英] How do I make 3D in pyglet?

查看:91
本文介绍了如何在 pyglet 中制作 3D?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用 OpenGL、Python 和 pyglet 创建一个 3D 空间中的平面三角形,我在互联网上看到了一些教程,在 YouTube 上看到了一些视频,最后我在那里写下了这段代码,问题是没有像我想象的那样工作,我想如果我尝试旋转,我会看到三角形变平,而当我走开时​​,三角形不必缩小?

导入pyglet从 pyglet.gl 导入 *配置=配置(样本缓冲区=1,样本=8)tela = pyglet.window.Window(高度=500,宽度=500,配置=配置)glViewport(0,0,500,500)glMatrixMode(GL_PROJECTION)glLoadIdentity()gluPerspective(35,1,0.1,1000)glMatrixMode(GL_MODELVIEW)@tela.event定义 on_draw():glBegin(GL_POLYGON)glVertex3f(10,10,0)glVertex3f(100,10,0)glVertex3f(50,100,0)glEnd()glFlush()@tela.eventdef on_key_press(s,m):tela.clear()如果 s == pyglet.window.key.W:glTranslatef(0,0,1)如果 s == pyglet.window.key.S:glTranslatef(0,0,-1)如果 s == pyglet.window.key.A:glRotatef(1,0,1,0)如果 s == pyglet.window.key.D:glRotatef(-1,0,1,0)pyglet.app.run()

当我运行代码时出现:

当我尝试旋转场景时,它发生了:

有人知道我哪里出错了吗?

解决方案

视口的初始化和投影和模型视图矩阵的刺没用

<块引用>

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

因为在应用程序启动时设置了视口和正交投影.

请参阅

导入pyglet从 pyglet.gl 导入 *位置 = [0, 0, -20]rot_y = 0配置=配置(样本缓冲区=1,样本=8)tela = pyglet.window.Window(高度=500,宽度=500,配置=配置)@tela.event定义 on_draw():全局 pos_z, rot_ytela.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.eventdef on_key_press(s,m):全局 pos_z, rot_y如果 s == pyglet.window.key.W:位置 [2] -= 1如果 s == pyglet.window.key.S:位置[2] += 1如果 s == pyglet.window.key.A:腐烂 += 5如果 s == pyglet.window.key.D:rot_y -= 5pyglet.app.run()

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?

解决方案

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

这篇关于如何在 pyglet 中制作 3D?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆