我正在try 在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行(您可以看到后面的立方体是如何绘制在立方体前面的).

推荐答案

您代码中的问题在于透视投影.到near计划的距离必须为>;0.请参见gluPerspective.您可以通过将near更改为大于0的小值来解决此问题,例如:0.01

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

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

透视投影矩阵定义为Viewing frustum,即0 < near < far.视锥受近平面和远平面的限制.几何图形在截锥体的6个平面处被剪裁.如果Near计划的值为0,则会导致未定义的行为,并且很可能会在内部计算中被0除以.在您的情况下,深度测试不起作用,因为Homogeneous剪裁空间坐标的z和w分量的计算不正确.

Python相关问答推荐

时间序列分解

如何在箱形图中添加绘制线的传奇?

类型错误:输入类型不支持ufuncisnan-在执行Mann-Whitney U测试时[SOLVED]

pandas滚动和窗口中有效观察的最大数量

将9个3x3矩阵按特定顺序排列成9x9矩阵

递归访问嵌套字典中的元素值

不能使用Gekko方程'

幂集,其中每个元素可以是正或负""""

Python Pandas—时间序列—时间戳缺失时间精确在00:00

Python避免mypy在相互引用中从另一个类重定义类时失败

基于另一列的GROUP-BY聚合将列添加到Polars LazyFrame

如何在Great Table中处理inf和nans

如果有2个或3个,则从pandas列中删除空格

判断Python操作:如何从字面上得到所有decorator ?

BeautifulSoup-Screper有时运行得很好,很健壮--但有时它失败了::可能这里需要一些更多的异常处理?

Django Table—如果项目是唯一的,则单行

freq = inject在pandas中做了什么?''它与freq = D有什么不同?''

如何将泛型类类型与函数返回类型结合使用?

Scipy.linprog的可行性有问题吗?(A_ub@x0<;=b_ub).all()为True-但是-linprog(np.zeros_like(X0),A_ub=A_ub,b_ub=b_ub)不可行

如何批量训练样本大小为奇数的神经网络?