OpenGL render view without a visible window in python

↘锁芯ラ 提交于 2019-12-10 12:55:57

问题


I need to render some scene. I managed to do it in python using pyopengl and pygame. The problem is that it creates a window for a short period of time.

I want to render the same image and save it, without creating a visible window (Or possibly without creating a window at all, and even without 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:


I want to render the same image and save it, without creating a visible window

It is not possible to create an OpenGL Context with an version above 1.0 without any window.
See the answer to the question Creating OpenGL context without window.

But it is possible to use a completely hidden window for "offscreen" rendering.

Sadly it is not possible to create a initially hidden window with Pygame.
It is only possible to hide a window after it was created by pygame.display.iconify(). See also Hiding pygame display.

But it is possible to create a initially hidden window with the GLFW library by setting the window hint VISIBLE to False.

The glfw library can be found at glfw 1.7.0.

The code may look like this:

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


来源:https://stackoverflow.com/questions/51627603/opengl-render-view-without-a-visible-window-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!