我怎样才能使用Python和Pygame(没有GLUT)在OpenGL中进行深度测试?

问题描述 投票:0回答:1

我正在尝试在 Python 中使用 OpenGL。我还没有设法让深度测试发挥作用。 我还没有成功安装 GLUT,所以我只是使用 Pygame 创建窗口并且它可以工作。

仅激活深度测试 (

glEnable(GL_DEPTH_TEST)
) 会导致空白屏幕。 编写片段着色器来显示每个像素的深度值会导致所有对象都是纯白色(无论我距离它们有多近),而不是灰度,并且背景按预期为黑色。

#version 330 core
out vec4 fragColor;

void main()
{             
    fragColor = vec4(vec3(gl_FragCoord.z), 1.0);
}

我在某处读到,你需要在显示模式下请求深度缓冲区(使用 GLUT 时),但我还没有找到在 Pygame 中做到这一点的方法。

这是我的代码的最小版本:

import OpenGL
from OpenGL.GL import *
from OpenGL.GLU import *
import pygame
from pygame.locals import *

display = (2560, 1440)

def setup_perspective_projection():
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    gluPerspective(70, (display[0] / display[1]), 0.0, 10.0)
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()

def draw_3d_cube(translatef_x, translatef_y, translatef_z):
    setup_perspective_projection()

    glTranslatef(translatef_x, translatef_y, translatef_z)

    glBegin(GL_QUADS)
    # Front face
    glColor3f(1.0, 0.0, 0.0)  # Red
    glVertex3f(-1.0, -1.0, 1.0)
    glVertex3f(1.0, -1.0, 1.0)
    glVertex3f(1.0, 1.0, 1.0)
    glVertex3f(-1.0, 1.0, 1.0)
    # Back face
    glColor3f(0.0, 1.0, 0.0)  # Green
    glVertex3f(-1.0, -1.0, -1.0)
    glVertex3f(-1.0, 1.0, -1.0)
    glVertex3f(1.0, 1.0, -1.0)
    glVertex3f(1.0, -1.0, -1.0)
    # Top face
    glColor3f(0.0, 0.0, 1.0)  # Blue
    glVertex3f(-1.0, 1.0, -1.0)
    glVertex3f(-1.0, 1.0, 1.0)
    glVertex3f(1.0, 1.0, 1.0)
    glVertex3f(1.0, 1.0, -1.0)
    # Bottom face
    glColor3f(1.0, 1.0, 0.0)  # Yellow
    glVertex3f(-1.0, -1.0, -1.0)
    glVertex3f(1.0, -1.0, -1.0)
    glVertex3f(1.0, -1.0, 1.0)
    glVertex3f(-1.0, -1.0, 1.0)
    # Right face
    glColor3f(1.0, 0.0, 1.0)  # Magenta
    glVertex3f(1.0, -1.0, -1.0)
    glVertex3f(1.0, 1.0, -1.0)
    glVertex3f(1.0, 1.0, 1.0)
    glVertex3f(1.0, -1.0, 1.0)
    # Left face
    glColor3f(0.0, 1.0, 1.0)  # Cyan
    glVertex3f(-1.0, -1.0, -1.0)
    glVertex3f(-1.0, -1.0, 1.0)
    glVertex3f(-1.0, 1.0, 1.0)
    glVertex3f(-1.0, 1.0, -1.0)
    glEnd()

# Shader source code
fragment_shader_source = """
#version 330 core
out vec4 fragColor;

void main()
{             
    fragColor = vec4(vec3(gl_FragCoord.z), 1.0);
}
"""

def compile_shader(shader_type, source):
    shader = glCreateShader(shader_type)
    glShaderSource(shader, source)
    glCompileShader(shader)
    return shader

def create_shader_program(fragment_source):
    fragment_shader = compile_shader(GL_FRAGMENT_SHADER, fragment_source)

    shader_program = glCreateProgram()
    glAttachShader(shader_program, fragment_shader)
    glLinkProgram(shader_program)

    return shader_program

def main():
    pygame.init()
    pygame.display.set_mode(display, DOUBLEBUF | OPENGL | HWSURFACE | FULLSCREEN)
    #glEnable(GL_DEPTH_TEST)
    glDepthFunc(GL_LESS)
    glEnable(GL_CULL_FACE)

    shader_program = create_shader_program(fragment_shader_source)
    glUseProgram(shader_program)

    clock = pygame.time.Clock()
    FPS = 144

    while True:
        clock.tick(FPS)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                return

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        draw_3d_cube(-2, -2, -5)
        draw_3d_cube(-2,-2,-10)

        pygame.display.flip()

if __name__ == "__main__":
    main()

您可能想在第 7 行更改显示器的分辨率/尺寸。 第 89 行是注释,因为否则屏幕是空白的。 要停用着色器,您只需删除第 94 行即可(您可以看到后面的立方体是如何绘制在前面的立方体前面的)。

python windows opengl pygame depth-testing
1个回答
0
投票

您的代码中的问题是透视投影。整洁的计划必须 > 0。参见

gluPerspective

gluPerspective(70, (display[0] / display[1]), 0, 10.0)

gluPerspective(70, (display[0] / display[1]), 0.01, 10.0)

透视投影矩阵定义了一个视锥体,其中0< near < far。视锥体受到近平面和远平面的限制。几何体在截锥体的 6 个平面处被剪裁。近期计划的值为 0 会导致未定义的行为,并且很可能在内部计算中除以 0。

© www.soinside.com 2019 - 2024. All rights reserved.