如何删除 PyOpenGL 中的直通

How to remove pass-through in PyOpenGL

我正在尝试创建一个环模型,对我来说唯一可能的选择是两个圆柱体(有孔和无孔)的交配。渲染模型时,我发现两个形状是完全透明的。如何删除 PyOpenGL 中的直通? (如果你知道更简单的戒指造型方法,请分享给我)

Screenshot

# !/usr/bin/env python3

import sys

from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *


global x_rotate
global y_rotate
global ambient
global metal_grey
global empty
global light_position

def init():
    global x_rotate
    global y_rotate
    global ambient
    global metal_grey
    global empty
    global light_position

    x_rotate = 0.0
    y_rotate = 0.0
    ambient = (1.0, 1.0, 1.0, 1)
    metal_grey = (0.32, 0.32, 0.32, 1.0)
    empty = (1.0, 1.0, 1.0, 1.0)
    light_position = (1.0, 1.0, 1.0)

    glClearColor(0.5, 0.5, 0.5, 1.0)
    gluOrtho2D(-1.0, 1.0, -1.0, 1.0)
    glRotatef(-90, 1.0, 0.0, 0.0)
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient)
    glEnable(GL_LIGHTING)
    glEnable(GL_LIGHT0)
    glLightfv(GL_LIGHT0, GL_POSITION, light_position)


def move(key, x, y):
    global x_rotate
    global y_rotate

    if key == GLUT_KEY_UP:
        x_rotate -= 4.0
    if key == GLUT_KEY_DOWN:
        x_rotate += 4.0
    if key == GLUT_KEY_LEFT:
        y_rotate -= 4.0
    if key == GLUT_KEY_RIGHT:
        y_rotate += 4.0

    glutPostRedisplay()


def draw():
    global x_rotate
    global y_rotate
    global metal_grey
    global empty
    global light_position

    glClear(GL_COLOR_BUFFER_BIT)
    glPushMatrix()
    glRotatef(x_rotate, 1.0, 0.0, 0.0)
    glRotatef(y_rotate, 0.0, 1.0, 0.0)
    glLightfv(GL_LIGHT0, GL_POSITION, light_position)

    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, metal_grey)
    glTranslatef(0.0, 0.0, 0.0)
    glutSolidCylinder(0.5, 0.4, 100, 100)

    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, empty)
    glTranslatef(0.0, 0.0, -0.01)
    glutWireCylinder(0.3, 0.42, 100, 100)

    glPopMatrix()
    glutSwapBuffers()


def build(self):
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB)
    glutInitWindowSize(300, 300)
    glutInitWindowPosition(50, 50)
    glutInit(sys.argv)
    glutCreateWindow("Модель изготовленной детали")
    glutDisplayFunc(draw)
    glutSpecialFunc(move)

    init()

    glutMainLoop()

您必须启用 Depth Test 并清除深度缓冲区:

glEnable(GL_DEPTH_TEST)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

完整示例:

import sys
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *

global x_rotate
global y_rotate
global ambient
global metal_grey
global empty
global light_position

def init():
    global x_rotate
    global y_rotate
    global ambient
    global metal_grey
    global empty
    global light_position

    x_rotate = 0.0
    y_rotate = 0.0
    ambient = (1.0, 1.0, 1.0, 1)
    metal_grey = (0.32, 0.32, 0.32, 1.0)
    empty = (1.0, 1.0, 1.0, 1.0)
    light_position = (1.0, 1.0, 1.0)

    glClearColor(0.5, 0.5, 0.5, 1.0)
    gluOrtho2D(-1.0, 1.0, -1.0, 1.0)
    glRotatef(-45, 1.0, 0.0, 0.0)
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient)
    glEnable(GL_LIGHTING)
    glEnable(GL_LIGHT0)
    glLightfv(GL_LIGHT0, GL_POSITION, light_position)


def move(key, x, y):
    global x_rotate
    global y_rotate

    if key == GLUT_KEY_UP:
        x_rotate -= 4.0
    if key == GLUT_KEY_DOWN:
        x_rotate += 4.0
    if key == GLUT_KEY_LEFT:
        y_rotate -= 4.0
    if key == GLUT_KEY_RIGHT:
        y_rotate += 4.0

    glutPostRedisplay()


def draw():
    global x_rotate
    global y_rotate
    global metal_grey
    global empty
    global light_position

    glEnable(GL_DEPTH_TEST)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    glPushMatrix()
    glRotatef(x_rotate, 1.0, 0.0, 0.0)
    glRotatef(y_rotate, 0.0, 1.0, 0.0)
    glLightfv(GL_LIGHT0, GL_POSITION, light_position)

    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, metal_grey)
    glTranslatef(0.0, 0.0, 0.0)
    glutSolidCylinder(0.5, 0.4, 100, 100)

    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, empty)
    glTranslatef(0.0, 0.0, -0.01)
    glutWireCylinder(0.3, 0.42, 100, 100)

    glPopMatrix()
    glutSwapBuffers()


glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB)
glutInitWindowSize(300, 300)
glutInitWindowPosition(50, 50)
glutInit(sys.argv)
glutCreateWindow("Модель изготовленной детали")
glutDisplayFunc(draw)
glutSpecialFunc(move)
init()
glutMainLoop()