C++ 在3D渲染场景上绘制2D HUD元素
我搜索了这篇文章,只找到了2014年的一篇帖子,询问类似的情况。然而,由于我无法理解那里做了什么,我再次询问,特别是关于我的实现,希望这也能从总体上对这个主题有所启发。我对C++和OpenGL比较陌生,所以请原谅我犯了愚蠢的错误。 我正在尝试为我的3D游戏实现一个简单的2D HUD。现在,我的游戏已经完全渲染了,因为我的游戏中有一个bloom效果,我甚至在屏幕上渲染了我的游戏。 我现在想做的是在这个渲染场景上放置一个HUD,然而,我似乎不能这样做 我的游戏屏幕四边形如下所示:C++ 在3D渲染场景上绘制2D HUD元素,c++,opengl,C++,Opengl,我搜索了这篇文章,只找到了2014年的一篇帖子,询问类似的情况。然而,由于我无法理解那里做了什么,我再次询问,特别是关于我的实现,希望这也能从总体上对这个主题有所启发。我对C++和OpenGL比较陌生,所以请原谅我犯了愚蠢的错误。 我正在尝试为我的3D游戏实现一个简单的2D HUD。现在,我的游戏已经完全渲染了,因为我的游戏中有一个bloom效果,我甚至在屏幕上渲染了我的游戏。 我现在想做的是在这个渲染场景上放置一个HUD,然而,我似乎不能这样做 我的游戏屏幕四边形如下所示: unsigned
unsigned int quadVAO = 0;
unsigned int quadVBO;
void renderQuad()
{
if (quadVAO == 0)
{
float quadVertices[] = {
// vertex attributes for a quad that fills the entire screen in Normalized Device Coordinates.
// texCoords
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 0.0f,
1.0f, 1.0f
};
// setup plane VAO
glGenVertexArrays(1, &quadVAO);
glGenBuffers(1, &quadVBO);
glBindVertexArray(quadVAO);
glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
}
glBindVertexArray(quadVAO);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
}
我试图做的是,将我的renderQuad
方法更改为renderHUDquad
方法,基本上只需更改quad的尺寸,使其显示在屏幕的左下角。
代码如下所示:
unsigned int HUDquadVAO = 0;
unsigned int HUDquadVBO;
void renderHUDQuad()
{
if (HUDquadVAO == 0)
{
float HUDquadVertices[] = {
// vertex attributes for a quad that fills the entire screen in Normalized Device Coordinates.
// texCoords
0.0f, 0.02f,
0.0f, 0.0f,
0.2f, 0.0f,
0.0f, 0.02f,
0.2f, 0.0f,
0.2f, 0.02f
};
// setup plane VAO
glGenVertexArrays(1, &HUDquadVAO);
glGenBuffers(1, &HUDquadVBO);
glBindVertexArray(HUDquadVAO);
glBindBuffer(GL_ARRAY_BUFFER, HUDquadVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(HUDquadVertices), &HUDquadVertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
}
glBindVertexArray(HUDquadVAO);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
}
因为这只需要一个小的绿色四边形,即玩家的健康栏,所以我正在考虑给它分配一个绿色纹理或其他东西。。
但是,在绘制两个四边形时,如下所示:
// Third pass = Combined bloom pictures
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
bloomShader->use();
// Set uniform for multiple layout uniforms
bloomShader->setUniform("scene", 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, colorAndLightBuffers[0]);
// Set uniform for multiple layout uniforms
bloomShader->setUniform("bloomBlur", 1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, pingpongBuffer[horizontal == 0 ? 1 : 0]);
bloomShader->setUniform("bloom", bloom);
bloomShader->setUniform("exposure", exposure);
renderQuad();
renderHUDQuad();
// Swap buffers
glfwSwapBuffers(window);
我只得到了HUD元素,没有任何我以前画的东西,就好像屏幕的其余部分被渲染成黑色一样。我想我可以把它添加到旧的缓冲区中,因为有办法做到这一点吗?你确实把你的GL状态搞砸了:
实际上,您在该函数的其余部分中使用了
quadVAO
,因此您将全屏四元体覆盖为较小的四元体,这意味着您的场景的其余部分将从下一帧开始缩小到该四元体…为什么要使用bloom明暗器渲染HUD?如果你不想让这些效果影响HUD元素,你应该在全屏效果后渲染HUD。没错,是的,我会为这个实现我自己的着色器!然而,这并不能真正回答为什么整个屏幕几乎都是黑色的问题,我担心。在我看到你的问题时,请确保你只能画出绽放的部分。确保能够单独渲染HUD部分,而不渲染展开部分;更好地使用不同的VBO、VAO和着色器。现在,渲染展开的部分,不要调用glfwSwapBuffers
,然后渲染HUD(这一步可能需要透明度)并调用glfwSwapBuffers
。非常正确,哈哈,这会导致HUD根本不显示。实际上,我们完全不清楚你的bloom着色器应该显示什么,正如@Nicol Bolas已经提到的。或者你的深度测试正在放弃它。看不到相关代码就很难说。你需要看什么代码?一个专门为HUD制作的着色器应该做什么呢?实际上是这样的。
void renderHUDQuad() {
if (HUDquadVAO == 0)
{
[...]
glGenVertexArrays(1, &quadVAO);