OpenGL中模型-视图-投影矩阵的误解

z5btuh9x  于 2023-06-29  发布在  其他
关注(0)|答案(2)|浏览(148)

我正在尝试使用Python和pyglet在现代OpenGL中编写一个基本程序。我能够在屏幕上放置一个简单的三角形,每个角都有不同的颜色。我正试图添加投影和视图矩阵,以便能够在3D空间中移动“相机”,但当我添加两个矩阵时,它会保持黑屏。我可以添加投影矩阵,它可以按预期工作。我可以简单地添加视图矩阵,它仍然显示三角形。然而,当我将视图矩阵和投影矩阵相乘时,它给出了一个黑屏。
由于我能够用投影矩阵生成一个彩色三角形,我 * 认为 * 我可以安全地假设我所有的OpenGL上下文都是有效的。也许我误解了数学。
下面是我的相关代码的摘要:

import pyrr

fov = 60
aspect_ratio = 800 / 600 #width / height
near_clip = 0.1
far_clip = 100

#create a perspective matrix
projection_matrix = pyrr.matrix44.create_perspective_projection(
fov,
aspect_ratio,
near_clip,
far_clip
)

view_matrix = pyrr.matrix44.creat_look_at(
pyrr.vector3.create(0, 0, 1), #camera position
pyrr.vector3.create(0, 0, 0), #camera target
pyrr.vector3.create(0, 1, 0)  #camera up vector
)

mvp_matrix = projection_matrix * view_matrix

从这里,我将mvp_matrix转换为OpenGL可以理解的c_types数组。我不认为做翻译的代码是相关的,因为它只正确地处理投影矩阵。
下面是pyrr给我的矩阵:

Projection Matrix:
[[ 1.15470054  0.          0.          0.        ]
 [ 0.          1.73205081  0.          0.        ]
 [ 0.          0.         -1.002002   -1.        ]
 [ 0.          0.         -0.2002002   0.        ]]

View Matrix:
[[1.  0.  0.  0.]
 [0.  1.  0.  0.]
 [0.  0.  1.  0.]
 [0.  0. -1.  1.]]

MVP Matrix:
[[ 1.15470054  0.          0.          0.        ]
 [ 0.          1.73205081  0.          0.        ]
 [ 0.          0.         -1.002002   -0.        ]
 [ 0.          0.         -0.          0.        ]]

有什么想法,为什么只有投影矩阵能够显示三角形,但当我加入视图矩阵时,它只显示黑屏?
我试过把三角形在x、y和z轴上都做得很大,但仍然只是一个黑屏。=/

eiee3dmh

eiee3dmh1#

经过更多的测试后,我发现pyrr模块执行矩阵乘法时似乎有些奇怪。然而,Pyrr是基于numpy构建的,所以在使用之后:

numpy.matmul(projection_matrix, view_matrix)

然后,它能够正确地创建MVP矩阵。

5us2dqdw

5us2dqdw2#

我的回答被投票为“没用”我只是想展示我使用完全相同的视图和投影矩阵,我可以看到我的对象(几条线),而不仅仅是黑屏。
如果你能提供完整的代码,也许我可以提供更多的帮助。可能有很多原因导致你只能看到黑屏(可能是正常/视图矩阵/投影矩阵...我刚开始使用pyglet,所以我面临一个奇怪的问题“on_resize()”可能与这个主题无关。但我对视图/投影矩阵非常熟悉。你可以从我的repo中了解更多:https://github.com/bitlw/LearnProjMatrix
下面是我最初的答案--
顶点是什么?我试着[0,01,0],[1,0,0]画一条线,我可以用你的视图和投影看到它。在我的测试中,我注意到一个非常重要的函数on_resize(),它可以是空的(只返回pyglet.event.EVENT_HANDLED),但它应该在那里,否则我什么也看不到。不确定你是否有同样的问题。

import pyglet
from pyglet.gl import *
import pyrr

window = pyglet.window.Window(width=800, height=600)

@window.event
def on_draw():
    window.clear()
    batch.draw()

# this function is very important, I can see nothing if I remove it
@window.event
def on_resize(width, height):
    return pyglet.event.EVENT_HANDLED

def setup():
    glClearColor(0, 0, 0, 1)
    glEnable(GL_DEPTH_TEST)
    glEnable(GL_CULL_FACE)

def create_torus(shader, batch):
    # Create the vertex and normal arrays.
    O = [0, 0, 0]
    X = [1, 0, 0]
    Y = [0, 1, 0]
    Z = [0, 0, 1]

    red = [1, 0, 0, 1]
    green = [0, 1, 0, 1]
    blue = [0, 0, 1, 1]

    vertices = []
    vertices.extend(O)
    vertices.extend(X)
    vertices.extend(O)
    vertices.extend(Y)
    vertices.extend(O)
    vertices.extend(Z)

    normals = [0, 0, 1] * 6

    indices = [0, 1, 2, 3, 4, 5]
    colors = []
    colors.extend(red)
    colors.extend(red)
    colors.extend(green)
    colors.extend(green)
    colors.extend(blue)
    colors.extend(blue)

    # Create a Material and Group for the Model
    diffuse = [0.5, 0.0, 0.3, 1.0]
    ambient = [0.5, 0.0, 0.3, 1.0]
    specular = [1.0, 1.0, 1.0, 1.0]
    emission = [0.0, 0.0, 0.0, 1.0]
    shininess = 50

    material = pyglet.model.Material("custom", diffuse, ambient, specular, emission, shininess)
    group = pyglet.model.MaterialGroup(material=material, program=shader)

    vertex_list = shader.vertex_list_indexed(6, GL_LINES, indices, batch, group,
                                         position=('f', vertices),
                                         normals=('f', normals),
                                         colors=('f', colors))

    return pyglet.model.Model([vertex_list], [group], batch)

setup()

batch = pyglet.graphics.Batch()
shader = pyglet.model.get_default_shader()
torus_model = create_torus(shader, batch)

fov = 60
aspect_ratio = 800 / 600 #width / height
near_clip = 0.1
far_clip = 100

#create a perspective matrix
projection_matrix = pyrr.matrix44.create_perspective_projection(fov,aspect_ratio,near_clip,far_clip)

view_matrix = pyrr.matrix44.create_look_at(
pyrr.vector3.create(0, 0, 1), #camera position
pyrr.vector3.create(0, 0, 0), #camera target
pyrr.vector3.create(0, 1, 0)  #camera up vector
)
window.view = view_matrix.flatten()
window.projection = projection_matrix.flatten()

pyglet.app.run()

相关问题