Search code examples
pythonopenglpygletclippingopengl-compat

Create a plane that trims cube Pyglet


I have a moving, zooming, rotating cube, I need to create a plane that will trim the cube like thatenter image description here

Here is the code of drawing

pgl.glLoadIdentity()
pgl.glViewport(650, 500, 650, 500)
pgl.glMatrixMode(ogl.GL_PROJECTION)
pgl.glLoadIdentity()

pgl.gluPerspective(self.dist, 1.3, 1, 1000)

pgl.glMatrixMode(ogl.GL_MODELVIEW)

pgl.glTranslatef(0, 0, -400)

pgl.glPushMatrix()
pgl.glTranslatef(self.x, self.y, self.z)
pgl.glRotatef(self.xRotation, 1, 0, 0)
pgl.glRotatef(self.yRotation, 0, 1, 0)
pgl.glRotatef(self.zRotation, 0, 0, 1)
pgl.glScalef(self.zoom, self.zoom, self.zoom)


if not transparant:
    pgl.glPolygonMode(pgl.GL_FRONT_AND_BACK, pgl.GL_FILL)
else:
    pgl.glPolygonMode(pgl.GL_FRONT_AND_BACK, pgl.GL_LINE)

draw_big()

pgl.glPopMatrix()

Solution

  • With Legacy OpenGL fixed function pipeline you can set a clipping plane.

    There can be more than 1 clip plane and the planes have to be enabled by glEnable(GL_CLIP_PLANEi).

    The plane is set by glClipPlane. The parameters to the clipping plane are interpreted as a Plane Equation. The first 3 components of the plane equation are the normal vector to the clipping plane. The 4th component is the distance to the origin:

    plane = plane = [-1.0, -1.0, -1.0, -280]
    ogl.glClipPlane(pgl.GL_CLIP_PLANE0, plane)
    

    For a detailed specification see OpenGL 4.6 API Compatibility Profile Specification - 13.7. PRIMITIVE CLIPPING; page 537.
    Note, that the inverse of the current model-view matrix is applied to the clipping plane coefficients at the time when it is specified.

    See the example, which is based on the code of the question:

    def on_draw(self) :
    
        self.clear()
        pgl.glClear(pgl.GL_COLOR_BUFFER_BIT | pgl.GL_DEPTH_BUFFER_BIT)
    
        pgl.glViewport(0, 0, 500, 500)
    
        pgl.glMatrixMode(ogl.GL_PROJECTION)
        pgl.glLoadIdentity()
        pgl.gluPerspective(45, 1, 1, 1000)
    
        pgl.glMatrixMode(ogl.GL_MODELVIEW)
        pgl.glLoadIdentity()
        pgl.glTranslatef(0, 0, -400)
    
        pgl.glPushMatrix()
        pgl.glTranslatef(self.x, self.y, self.z)
        pgl.glRotatef(self.xRotation, 1, 0, 0)
        pgl.glRotatef(self.yRotation, 0, 1, 0)
        pgl.glRotatef(self.zRotation, 0, 0, 1)
        pgl.glScalef(self.zoom, self.zoom, self.zoom)
    
        if not transparant:
            pgl.glPolygonMode(pgl.GL_FRONT_AND_BACK, pgl.GL_FILL)
        else:
            pgl.glPolygonMode(pgl.GL_FRONT_AND_BACK, pgl.GL_LINE)
    
        # set and enable clip plane
        plane = plane = [-1.0, -1.0, -1.0, -280]
        ogl.glEnable(pgl.GL_CLIP_PLANE0)
        ogl.glClipPlane(pgl.GL_CLIP_PLANE0, plane)
    
        draw_big()
        ogl.glDisable(pgl.GL_CLIP_PLANE0)
    
        pgl.glPopMatrix()