【问题标题】:Draw a background video behind a 3D model in OpenGL在 OpenGL 中绘制 3D 模型后面的背景视频
【发布时间】:2021-10-02 14:05:34
【问题描述】:

我正在尝试通过此脚本绘制 3d 模型 (.obj)
https://github.com/yarolig/OBJFileLoader/blob/master/OBJFileLoader/objloader.py
作为 bacgrund,我想从网络摄像头中绘制视频。但是当我绘制图像和 3d 模型时,只显示图像。
这是我的图像加载器类

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

代码在这里运行。

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

【问题讨论】:

    标签: python opengl pygame cv2 pyopengl


    【解决方案1】:

    图像和模型使用不同的投影和模型视图矩阵。因此,您需要在绘制对象之前设置矩阵。

    模型未绘制,因为它没有通过Depth Test。 绘制图像时禁用深度测试。如果禁用深度测试,则不会向深度缓冲区写入任何内容。

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

    当前纹理坐标,在调用glVertex 时与顶点相关联。因此,需要在指定顶点坐标之前指定纹理坐标:

    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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-27
      • 1970-01-01
      • 2014-03-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多