Search code examples
pythonopenglpyopengl

How to remove pass-through in PyOpenGL


I am trying to create a model of a ring and the only possible option for me was the copulation of two cylinders (with and without a hole). When rendering the model, I find the two shapes are completely transparent. How do I remove the pass-through in PyOpenGL? (If you know an easier method for modeling a ring, please share it with me)

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()

Solution

  • You must enable the Depth Test and clear the depth buffer:

    glEnable(GL_DEPTH_TEST)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    

    Complete example:

    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()