OpenGL - 从不同角度渲染同一场景而不重绘所有内容
OpenGL - Render same scene from different angles without redrawing everything
我有一个场景,我试图在各个方向渲染(稍后在 OpenGL 之外拼接在一起)。
目前用于创建每一帧 - 我重绘了整个场景 4 次(前、右、后、左)。我能否以某种方式将 4 个立方体渲染在一起而不重绘整个场景 4 次?
这是我使用的示例代码(特别是我使用 PyOpenGL - 但这并不重要):
import cv2
import numpy as np
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
import glfw
# Draws some model (The real code draws a much more complicated model)
def draw_model():
glBegin(GL_QUADS)
glColor3f(1.0, 1.0, 1.0)
glVertex(10, 10, 0); glVertex(10, 10, 3); glVertex(10, -10, 3); glVertex(10, -10, 0)
glColor3f(1.0, 1.0, 0)
glVertex(-10, 10, 0); glVertex(-10, 10, 3); glVertex(-10, -10, 3); glVertex(-10, -10, 0)
glColor3f(1.0, 0, 1.0)
glVertex(10, 10, 0); glVertex(10, 10, 3); glVertex(-10, 10, 3); glVertex(-10, 10, 0)
glColor3f(0, 1.0, 0)
glVertex(10, -10, 0); glVertex(10, -10, 3); glVertex(-10, -10, 3); glVertex(-10, -10, 0)
glEnd()
# Reads the pixels to NP
def get_display_pixels(rendered_image_width, rendered_image_height):
data = glReadPixels(0, 0, rendered_image_width, rendered_image_height, OpenGL.GL.GL_RGB, OpenGL.GL.GL_UNSIGNED_BYTE)
return np.frombuffer(data, dtype=np.uint8).reshape(rendered_image_height, rendered_image_width, 3)[::-1]
DISPLAY_WIDTH = 900
DISPLAY_HEIGHT = 900
glfw.init()
glfw.window_hint(glfw.VISIBLE, False)
window = glfw.create_window(DISPLAY_WIDTH, DISPLAY_HEIGHT, "some window", None, None)
glfw.make_context_current(window)
gluPerspective(90, (DISPLAY_WIDTH / DISPLAY_HEIGHT), 0.01, 30)
glEnable(GL_TEXTURE_2D)
glEnable(GL_DEPTH_TEST)
glDepthFunc(GL_LEQUAL)
position = (0, 3, 1)
# Get cube 1
glPushMatrix()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
gluLookAt(*position, 1, 4, 1, 0, 0, 1)
draw_model()
cube1 = get_display_pixels(DISPLAY_WIDTH, DISPLAY_HEIGHT)
glPopMatrix()
# Get cube 2
glPushMatrix()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
gluLookAt(*position, 1, 2, 1, 0, 0, 1)
draw_model()
cube2 = get_display_pixels(DISPLAY_WIDTH, DISPLAY_HEIGHT)
glPopMatrix()
# Get cube 3
glPushMatrix()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
gluLookAt(*position, -1, 2, 1, 0, 0, 1)
draw_model()
cube3 = get_display_pixels(DISPLAY_WIDTH, DISPLAY_HEIGHT)
glPopMatrix()
# Get cube 4
glPushMatrix()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
gluLookAt(*position, -1, 4, 1, 0, 0, 1)
draw_model()
cube4 = get_display_pixels(DISPLAY_WIDTH, DISPLAY_HEIGHT)
glPopMatrix()
cv2.imwrite(r"C:\temp\image1.png", cube1)
cv2.imwrite(r"C:\temp\image2.png", cube2)
cv2.imwrite(r"C:\temp\image3.png", cube3)
cv2.imwrite(r"C:\temp\image4.png", cube4)
glfw.destroy_window(window)
glfw.terminate()
有一些方法可以像 Layered Rendering 一样一次渲染四个不同的视图,但这仍然意味着几何着色器阶段之后的所有内容每层执行一次。当在顶点着色器阶段(或在细分着色器中)完成大量工作时,这可以提高速度,但当瓶颈是像素填充率时不会有太大变化。
无法在不重绘的情况下从不同的场景渲染同一场景。整个光栅化(和裁剪等)在 NDC space 中运行,通常在应用视图和投影矩阵之后,因此每个视图至少必须执行一次这些阶段。
我也不确定分层渲染是否与您使用的旧版 OpenGL 兼容。固定功能管道已弃用十年,应尽可能避免。
解决方案是使用评论中 "Rabbid76" 的想法实现的。
将所有顶点移动到一个 VBO,然后一次绘制它们可以提供所需的性能改进
我有一个场景,我试图在各个方向渲染(稍后在 OpenGL 之外拼接在一起)。
目前用于创建每一帧 - 我重绘了整个场景 4 次(前、右、后、左)。我能否以某种方式将 4 个立方体渲染在一起而不重绘整个场景 4 次?
这是我使用的示例代码(特别是我使用 PyOpenGL - 但这并不重要):
import cv2
import numpy as np
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
import glfw
# Draws some model (The real code draws a much more complicated model)
def draw_model():
glBegin(GL_QUADS)
glColor3f(1.0, 1.0, 1.0)
glVertex(10, 10, 0); glVertex(10, 10, 3); glVertex(10, -10, 3); glVertex(10, -10, 0)
glColor3f(1.0, 1.0, 0)
glVertex(-10, 10, 0); glVertex(-10, 10, 3); glVertex(-10, -10, 3); glVertex(-10, -10, 0)
glColor3f(1.0, 0, 1.0)
glVertex(10, 10, 0); glVertex(10, 10, 3); glVertex(-10, 10, 3); glVertex(-10, 10, 0)
glColor3f(0, 1.0, 0)
glVertex(10, -10, 0); glVertex(10, -10, 3); glVertex(-10, -10, 3); glVertex(-10, -10, 0)
glEnd()
# Reads the pixels to NP
def get_display_pixels(rendered_image_width, rendered_image_height):
data = glReadPixels(0, 0, rendered_image_width, rendered_image_height, OpenGL.GL.GL_RGB, OpenGL.GL.GL_UNSIGNED_BYTE)
return np.frombuffer(data, dtype=np.uint8).reshape(rendered_image_height, rendered_image_width, 3)[::-1]
DISPLAY_WIDTH = 900
DISPLAY_HEIGHT = 900
glfw.init()
glfw.window_hint(glfw.VISIBLE, False)
window = glfw.create_window(DISPLAY_WIDTH, DISPLAY_HEIGHT, "some window", None, None)
glfw.make_context_current(window)
gluPerspective(90, (DISPLAY_WIDTH / DISPLAY_HEIGHT), 0.01, 30)
glEnable(GL_TEXTURE_2D)
glEnable(GL_DEPTH_TEST)
glDepthFunc(GL_LEQUAL)
position = (0, 3, 1)
# Get cube 1
glPushMatrix()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
gluLookAt(*position, 1, 4, 1, 0, 0, 1)
draw_model()
cube1 = get_display_pixels(DISPLAY_WIDTH, DISPLAY_HEIGHT)
glPopMatrix()
# Get cube 2
glPushMatrix()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
gluLookAt(*position, 1, 2, 1, 0, 0, 1)
draw_model()
cube2 = get_display_pixels(DISPLAY_WIDTH, DISPLAY_HEIGHT)
glPopMatrix()
# Get cube 3
glPushMatrix()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
gluLookAt(*position, -1, 2, 1, 0, 0, 1)
draw_model()
cube3 = get_display_pixels(DISPLAY_WIDTH, DISPLAY_HEIGHT)
glPopMatrix()
# Get cube 4
glPushMatrix()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
gluLookAt(*position, -1, 4, 1, 0, 0, 1)
draw_model()
cube4 = get_display_pixels(DISPLAY_WIDTH, DISPLAY_HEIGHT)
glPopMatrix()
cv2.imwrite(r"C:\temp\image1.png", cube1)
cv2.imwrite(r"C:\temp\image2.png", cube2)
cv2.imwrite(r"C:\temp\image3.png", cube3)
cv2.imwrite(r"C:\temp\image4.png", cube4)
glfw.destroy_window(window)
glfw.terminate()
有一些方法可以像 Layered Rendering 一样一次渲染四个不同的视图,但这仍然意味着几何着色器阶段之后的所有内容每层执行一次。当在顶点着色器阶段(或在细分着色器中)完成大量工作时,这可以提高速度,但当瓶颈是像素填充率时不会有太大变化。
无法在不重绘的情况下从不同的场景渲染同一场景。整个光栅化(和裁剪等)在 NDC space 中运行,通常在应用视图和投影矩阵之后,因此每个视图至少必须执行一次这些阶段。
我也不确定分层渲染是否与您使用的旧版 OpenGL 兼容。固定功能管道已弃用十年,应尽可能避免。
解决方案是使用评论中 "Rabbid76" 的想法实现的。
将所有顶点移动到一个 VBO,然后一次绘制它们可以提供所需的性能改进