OpenGL:如何在 3D 模式下优化多个图层相互重叠的 2D 渲染?

发布于 2024-11-13 12:19:57 字数 840 浏览 4 评论 0原文

我知道如何通过首先渲染最近的平面来加速 3d 渲染。

但是我如何在 2d 模式下利用这种方法呢?我无法使用深度测试,因为它们都处于相同的 z 级别。

所以我在想当我不需要渲染“下面”层的不可见部分时是否可以加快速度。这可能吗?

请注意,我是在 3d 模式下渲染的,可能同时存在 3d 对象和 2d 对象。所以我不能只切换到 2d 渲染,我总是使用 3d 坐标来处理所有事情。而且我可以根据需要旋转相机,因此相机特定的技巧是不可接受的。

编辑:我尝试了Ville建议的方法: 在此处输入图像描述

( http://img815.imageshack.us/img815/7857/zfighting.png )

但正如你所看到的,这会导致深度冲突。

我用于渲染的代码在这里:

glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
glDisable(GL_ALPHA_TEST);
glDisable(GL_POLYGON_OFFSET_FILL);

glColor4f(1,0,0,1);
DrawQuad(0, 0, 10, 10);

glColor4f(0,0,1,1);
DrawQuad(5, 5, 15, 15);

glDepthFunc(GL_LEQUAL);

I know how to speed up rendering in 3d by simply rendering the nearest planes first.

But how do i get advantage of this type of method in 2d mode? I cant use depth testing because they are all in the same z-level.

So i was thinking if it could be speed up when i dont need to render the invisible parts of the layers "below". Is this possible?

Note that i am rendering in 3d mode, there may be 3d objects and 2d objects at the same time. So i cant switch to 2d render only, i always use 3d coordinates for everything. And i may rotate the camera as i wish, so camera-specific tricks arent acceptable.

Edit: i tried the method Ville suggested:
enter image description here

( http://img815.imageshack.us/img815/7857/zfighting.png )

but as you see, it will result in z-fighting.

The code i used for rendering that is here:

glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
glDisable(GL_ALPHA_TEST);
glDisable(GL_POLYGON_OFFSET_FILL);

glColor4f(1,0,0,1);
DrawQuad(0, 0, 10, 10);

glColor4f(0,0,1,1);
DrawQuad(5, 5, 15, 15);

glDepthFunc(GL_LEQUAL);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

來不及說愛妳 2024-11-20 12:19:57

听起来您正在同一平面上渲染所有“2D”对象。您可以使用正交投影将 2D 零件渲染到离屏帧缓冲区中,并按照 datenwolf 的建议为它们提供不同的 Z 值。然后将帧缓冲区纹理渲染到主 3D 场景中。

It sounds like you are rendering all your "2D" objects on the same plane. You could render your 2D parts into an off-screen framebuffer with an orthographic projection and give them different Z values as datenwolf suggested. Then render the framebuffer texture into your main 3D scene.

你对2D模式的理解是什么?你的意思是正交投影吗?然后我有个好消息:深度测试在那里也能完美地工作。 gluOrtho2D 与 glOrtho(..., -1, 1) 基本相同;即您有 Z 范围 -1 ... 1 可供花费。

根据评论进行编辑:

完全有可能在一个帧中组合渲染多个投影:

void render_perspective_scene(void);

void render_ortho_scene(void);

void render_HUD();

void display()
{
    float const aspect = (float)win_width/(float)win_height;

    glViewport(0,0,win_width,win_height);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-aspect*near/lens, aspect*near/lens, -near/lens, near/lens, near, far);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    render_perspective_scene();

    // just clear the depth buffer, so that everything that's
    // drawn next will overlay the previously rendered scene.
    glClear(GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-aspect*scale, aspect*scale, -scale, scale, 0, 1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    render_ortho_scene();

    // Same for the HUD, only that we render
    // that one in pixel coordinates.
    glClear(GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, win_width, 0, win_height, 0, 1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    render_HUD();
}

当然,如果您喜欢那些将投影矩阵设置放在重塑处理程序中的糟糕教程,那么您就会当然,头脑受阻,无法看到明显的解决方案。

What do you understand by 2D mode? Do you mean orthographic projection? Then I have good news: Depth testing works there perfectly as well. gluOrtho2D is basically the same like glOrtho(..., -1, 1); i.e. you have the Z range -1 ... 1 to spend.

EDIT due to comment:

It is perfectly possible to combine rendering several projections in one single frame:

void render_perspective_scene(void);

void render_ortho_scene(void);

void render_HUD();

void display()
{
    float const aspect = (float)win_width/(float)win_height;

    glViewport(0,0,win_width,win_height);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-aspect*near/lens, aspect*near/lens, -near/lens, near/lens, near, far);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    render_perspective_scene();

    // just clear the depth buffer, so that everything that's
    // drawn next will overlay the previously rendered scene.
    glClear(GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-aspect*scale, aspect*scale, -scale, scale, 0, 1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    render_ortho_scene();

    // Same for the HUD, only that we render
    // that one in pixel coordinates.
    glClear(GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, win_width, 0, win_height, 0, 1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    render_HUD();
}

Of course if you've fallen for those bad tutorials that place the projection matrix setup in the reshape handler you're of course mind blocked, to see that obvious solution.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文