OpenGL渲染视图,Python中没有可见窗口

时间:2018-08-01 07:26:26

标签: python opengl pygame window pyopengl

我需要渲染一些场景。我设法使用pyopengl和pygame在python中做到了。问题在于它会在很短的时间内创建一个窗口。

我想渲染相同的图像并保存它,而不创建可见的窗口(或者可能根本不创建窗口,甚至没有pygame)。

import cv2
import numpy as np
import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *

def main():
    DISPLAY_WIDTH = 900
    DISPLAY_HEIGHT = 900

    pygame.init()
    pygame.display.set_mode((DISPLAY_WIDTH, DISPLAY_HEIGHT), DOUBLEBUF | OPENGL)
    gluPerspective(90, (DISPLAY_WIDTH / DISPLAY_HEIGHT), 0.01, 12)

    glEnable(GL_TEXTURE_2D)
    glEnable(GL_DEPTH_TEST)
    glDepthFunc(GL_LEQUAL)

    glRotatef(-90, 1, 0, 0) # Straight rotation
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    glRotatef(285, 0, 0, 1) # Rotate yaw
    glTranslatef(-5, -3, -2) # Move to position

    # Draw rectangle
    glBegin(GL_QUADS)
    glColor3f(1, 0, 0)
    glVertex3f(2, 2, 0)
    glVertex3f(2, 2, 2)
    glVertex3f(2, 6, 2)
    glVertex3f(2, 6, 0)
    glEnd()

    image_buffer = glReadPixels(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, OpenGL.GL.GL_RGB, OpenGL.GL.GL_UNSIGNED_BYTE)
    image = np.frombuffer(image_buffer, dtype=np.uint8).reshape(DISPLAY_WIDTH, DISPLAY_HEIGHT, 3)

    cv2.imwrite(r"C:\temp\image.png", image)

    pygame.quit()


if __name__ == "__main__":
    main()

1 个答案:

答案 0 :(得分:5)

  

我想渲染相同的图像并保存它,而不创建可见的窗口

不可能在没有任何窗口的情况下创建版本高于1.0的OpenGL Context
请参阅问题Creating OpenGL context without window的答案。

但是可以使用完全隐藏的窗口进行“屏幕外”渲染。

遗憾的是,无法使用Pygame创建初始隐藏的窗口。
pygame.display.iconify()创建窗口后,只能将其隐藏。 另请参见Hiding pygame display

但是通过将GLFW VISIBLE设置为False,可以使用window hint库创建一个初始隐藏的窗口。

可以在glfw 1.7.0上找到glfw库。

代码可能看起来像这样:

import cv2
import numpy as np
from OpenGL.GL import *
from OpenGL.GLU import *
import glfw

def main():
    DISPLAY_WIDTH = 900
    DISPLAY_HEIGHT = 900

    # Initialize the library
    if not glfw.init():
        return
    # Set window hint NOT visible
    glfw.window_hint(glfw.VISIBLE, False)
    # Create a windowed mode window and its OpenGL context
    window = glfw.create_window(DISPLAY_WIDTH, DISPLAY_HEIGHT, "hidden window", None, None)
    if not window:
        glfw.terminate()
        return

    # Make the window's context current
    glfw.make_context_current(window)

    gluPerspective(90, (DISPLAY_WIDTH / DISPLAY_HEIGHT), 0.01, 12)

    glEnable(GL_TEXTURE_2D)
    glEnable(GL_DEPTH_TEST)
    glDepthFunc(GL_LEQUAL)

    glRotatef(-90, 1, 0, 0) # Straight rotation
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    glRotatef(285, 0, 0, 1) # Rotate yaw
    glTranslatef(-5, -3, -2) # Move to position

    # Draw rectangle
    glBegin(GL_QUADS)
    glColor3f(1, 0, 0)
    glVertex3f(2, 2, 0)
    glVertex3f(2, 2, 2)
    glVertex3f(2, 6, 2)
    glVertex3f(2, 6, 0)
    glEnd()

    image_buffer = glReadPixels(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, OpenGL.GL.GL_RGB, OpenGL.GL.GL_UNSIGNED_BYTE)
    image = np.frombuffer(image_buffer, dtype=np.uint8).reshape(DISPLAY_WIDTH, DISPLAY_HEIGHT, 3)

    cv2.imwrite(r"C:\temp\image.png", image)

    glfw.destroy_window(window)
    glfw.terminate()

if __name__ == "__main__":
    main()