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