Draw a background video behind a 3D model in OpenGL

Question:

I am tring to draw 3d model (.obj) by this script
https://github.com/yarolig/OBJFileLoader/blob/master/OBJFileLoader/objloader.py

and as bacgrund I want to draw video from the webcam.but when I am drawing the image and the 3d model only the image show up.

This is my Image loder class

class ImageLoader:

    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.width = 0
        self.height = 0
        self.img_data = 0

    def load(self, image):
        im = image
        tx_image = cv2.flip(im, 0)
        tx_image = Image.fromarray(tx_image)
        self.width = tx_image.size[0]
        self.height = tx_image.size[1]
        self.img_data = tx_image.tobytes('raw', 'BGRX', 0, -1)

        self.Texture = glGenTextures(1)
        glBindTexture(GL_TEXTURE_2D, self.Texture)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, self.width, self.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, self.img_data)

    def draw(self):
        glEnable(GL_TEXTURE_2D)
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()
        glTranslate(self.x, self.y, 0)
        glBegin(GL_QUADS)
        glVertex(0, 0, 0)
        glTexCoord2f(0, 0)
        glVertex(self.width, 0, 0)
        glTexCoord2f(0, 1)
        glVertex(self.width, self.height, 0)
        glTexCoord2f(1, 1)
        glVertex(0, self.height, 0)
        glTexCoord2f(1, 0)
        glEnd()
        glDisable(GL_TEXTURE_2D)
        glFlush()

and here the code run.

 if __name__ == '__main__':

    cap = cv2.VideoCapture(0)
    width = int(cap.get(3))
    height = int(cap.get(4))

    pygame.init()
    pygame.display.set_mode((width, height), pygame.DOUBLEBUF | pygame.OPENGL)

    box = OBJ('3dglasses/oculos.obj', ) # from OBJFileLoader import OBJ

    gluPerspective(45, (width / height), 0.1, 50.0)
    glTranslate(0.0, 0.0, -5)
    glRotate(0, 0, 0, 0)

    if True:
        glClearColor(0.7, 0, 0, 1)
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        gluOrtho2D(0, width, height, 0)
        im_loader = ImageLoader(0, 0)
        while True:
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    quit()

            success, image = cap.read()
            im_loader.load(image)
            im_loader.draw()

            box.render()
            pygame.display.flip()
Asked By: Ari

||

Answers:

The image and the model use different projection and model view matrices. Therefore, you need to set the matrices before drawing the objects.

The model is not drawn because it does not pass the Depth Test.
Disable the depth test when you draw the image. If the depth test is disabled, nothing is written to the depth buffer.

if __name__ == '__main__':
    cap = cv2.VideoCapture(0)
    width, height = int(cap.get(3)), int(cap.get(4))
    pygame.init()
    pygame.display.set_mode((width, height), pygame.DOUBLEBUF | pygame.OPENGL)
    box = OBJ('3dglasses/oculos.obj', ) # from OBJFileLoader import OBJ
    im_loader = ImageLoader(0, 0)
    angle = 0

    glClearColor(0.7, 0, 0, 1)
    run = True
    while run:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
               run = False

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        gluOrtho2D(0, width, height, 0)
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()

        glDisable(GL_DEPTH_TEST)
        success, image = cap.read()
        if success:
            im_loader.load(image)
        glColor3f(1, 1, 1)
        im_loader.draw()
        
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        gluPerspective(45, (width / height), 0.1, 50.0)
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()
        glTranslate(0.0, 0.0, -5)
        glRotate(angle, 0, 1, 0)
        angle += 1
        
        glEnable(GL_DEPTH_TEST)
        box.render()

        pygame.display.flip()

    pygame.quit()
    quit()

The current texture coordinates, is associated with the vertex when glVertex is called. Therefore, you need to specify the texture coordinate before specifying the vertex coordinate:

class ImageLoader:
    # [...]

    def draw(self):
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()
        glTranslate(self.x, self.y, 0)
        
        glEnable(GL_TEXTURE_2D)  
        glBegin(GL_QUADS)
        glTexCoord2f(0, 0)
        glVertex2f(0, 0)
        glTexCoord2f(1, 0)
        glVertex2f(self.width, 0)
        glTexCoord2f(1, 1)
        glVertex2f(self.width, self.height)
        glTexCoord2f(0, 1)
        glVertex2f(0, self.height)
        glEnd()
        glDisable(GL_TEXTURE_2D)

Answered By: Rabbid76
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.