简体   繁体   English

OpenGL - 从不同角度渲染相同的场景,无需重绘所有内容

[英]OpenGL - Render same scene from different angles without redrawing everything

I have a scene that I'm trying to render in all directions (later stitched together, outside OpenGL). 我有一个场景,我正试图在各个方向渲染(后来缝合在一起,在OpenGL之外)。

Currently for creating each frame - I redraw the entire scene 4 times (front, right, back, left). 目前用于创建每个帧 - 我重绘整个场景4次(前,右,后,左)。 Can I somehow just render the 4 cubes together without redrawing the entire scene 4 times? 我可以不知何故只将4个立方体渲染在一起而不重绘整个场景4次吗?

Here is a sample code that I use (Specifically I use PyOpenGL - But that doesn't really matter): 这是我使用的示例代码(具体来说,我使用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()

There are ways how one could render four different views at once like Layered Rendering , but that still means that everything after the geometry shader stage is executed once per layer. 有多种方法可以像Layered Rendering一样渲染四个不同的视图,但这仍然意味着几何着色器阶段之后的所有内容每层执行一次。 This could improve the speed when a lot of work is done in the vertex shader stage (or in Tessellation Shader), but won't change much when the bottleneck is the pixel fill rate. 这可以在顶点着色器阶段(或在曲面细分着色器中)完成大量工作时提高速度,但在瓶颈为像素填充率时不会有太大变化。

There is no way to render the same scene from a different without any redraw. 没有任何重绘,无法从不同的场景渲染相同的场景。 The whole rasterization (and clipping, etc.) operates in NDC space, which is usually after applying the view and projection matrix, so at least those stages have to be performed once per view. 整个光栅化(和剪裁等)在NDC空间中操作,这通常在应用视图和投影矩阵之后,因此每个视图至少必须执行一次这些阶段。

I'm also not sure if layered rendering goes together with the ancient version of OpenGL you are using. 我也不确定分层渲染是否与您正在使用的古老版本的OpenGL一起使用。 The fixed function pipeline is deprecated since a decade and should be avoided as much as possible. 固定功能管道自十年后就被弃用,应尽可能避免使用。

The solution was achieved using the idea by "Rabbid76" in the comment. 该解决方案是在评论中使用“Rabbid76”的想法实现的。

Moving all of the vertices to a VBO and then drawing them all at once gives the needed performance improvement 将所有顶点移动到VBO然后立即绘制它们可以提高所需的性能

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 PyQt-动画而不重绘所有内容? - PyQt - Animations without redrawing everything? 在pyglet中使用opengl渲染3d场景无需事件循环 - Using opengl in pyglet to render 3d scene without event loop 在面板上绘制橡皮筋而不重绘wxpython中的所有内容 - Drawing a rubberband on a panel without redrawing everything in wxpython Mayavi - 鼠标悬停交互并从不同角度绘制相同场景 - Mayavi - Mouse hovering interaction & plot same scene from different perspectives 训练模型-不同角度的冗余图片 - Training a model - Redundant Pictures from Different Angles 在Python中没有可见窗口的OpenGL渲染视图 - OpenGL render view without a visible window in python 从Matplotlib图中隐藏线而不重绘? - Hide Lines from Matplotlib Plot without redrawing them? 如何将欧拉角转换为四元数并从四元数返回相同的欧拉角? - How to convert Euler angles to Quaternions and get the same Euler angles back from Quaternions? 如何动态更新同一 window 中的图形而不在新选项卡中打开和重绘? - How to update figure in same window dynamically without opening and redrawing in new tab? 机器学习的周期性数据(像度角度 - > 179与-179不同) - Periodic Data with Machine Learning (Like Degree Angles -> 179 is 2 different from -179)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM