【发布时间】:2014-08-19 20:02:02
【问题描述】:
我目前正在尝试学习 openGL,但在为我的应用程序制作一个非常简单的照明引擎时遇到了困难。它是 2D 的,我发现的大多数资源只涵盖相当复杂的 3D 操作。我想做的就像本教程中介绍的一样简单:http://www.alcove-games.com/opengl-es-2-tutorials/lightmap-shader-fire-effect-glsl/
它把我推向了正确的方向,我明白我将使用带有“光照贴图”的帧缓冲区,我将它与我正在渲染的纹理一起发送到我的着色器,这样我就可以将这些组合起来值以创建照明效果。首先要做的事:我无法让我的帧缓冲区工作!
我遵循了以下教程:http://open.gl/framebuffers,这已经足够简洁了。它引导我使用以下代码非常简单地创建帧缓冲区:
GLuint frameBuffer;
glGenFramebuffers(1, &frameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
glFramebufferTexture2D(
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, myTexture2.texture_id, 0);
这里 myTexture2 是我的纹理类,texture_id 是这个纹理的 GLuint。 (我可以使用默认的帧缓冲区很容易地将它渲染到屏幕上,并且它显示得很好,所以我知道这是可行的)。完成此操作后,我运行测试以检查一切是否正常(如教程所述):
GLenum check_framebuffer = glCheckFramebufferStatus(frameBuffer);
if (check_framebuffer == GL_FRAMEBUFFER_COMPLETE)
{
std::cout << "Everything is fine\n";
}
else{
std::cout << "glCheckFramebufferStatus returned: " << glCheckFramebufferStatus(frameBuffer) << std::endl;
std::cout << "GlError: " << glGetError() << std::endl;
}
glCheckFramebufferStatus 返回 0,GLerror 为 1280(无效枚举?)。
不出所料,如果我在绘制之前绑定到这个帧缓冲区,一切都是黑色的(glClearColor 设置为红色,所以至少如果它正在工作,它应该是红色的)。如果我将其设置回
glBindFramebuffer(GL_FRAMEBUFFER, 0);
然后一切正常。我的帧缓冲区有什么问题?我一直在到处寻找一个简单的项目示例,我可以复制粘贴并运行它以查看它是否有效,但它要么是错误的语言,要么使用了一些我不打算使用的库。此外,我并不完全确定我是否了解帧缓冲区的工作原理。我知道这只是另一个要绘制的屏幕(或者据我所知,在渲染过程中添加另一个步骤?)。
目前我正在通过绑定纹理来绘制所有内容,绘制具有纹理大小的四边形,然后移动到下一个纹理。这意味着对于我的应用程序中的每一个图像,它们都运行一个着色器(或者我应该说,当前完全相同的着色器的副本)。我是否理解如果我有例如 20 个不同的图像首先在屏幕上运行 20 个着色器,然后我可以通过一个额外的“步骤”运行这些图像以将它们与我在帧缓冲区中创建的光照贴图混合,还是我弄错了?
很抱歉,如果这些问题听起来很愚蠢,但我现在浏览了大量教程,每个教程提出的问题都比看起来要回答的要多,我通常通过实验学得最好,但是当我什至无法得到我的帧缓冲区正在运行,我有点卡住了!
【问题讨论】:
-
你的纹理进入这个状态是什么?您是否已致电
TexImage2D确定其大小和格式? -
是的,这就是我制作纹理的方式。大小(宽度和高度)存储在我的纹理类中。
-
...您是否检查过您正在获取 3.2 或更高版本的 OpenGL 版本的上下文?那是
glFramebufferTexture到达的时候。 -
在创建帧缓冲区对象之前尝试调用 glGetError() 看看是否一切正常,这可能是一个过时的错误。使用 opengl 编程的一个重要技巧:创建一个调用 glGetError() 的函数,如果有错误,记录其枚举名称(例如 GL_INVALID_ENUM)、来自 API 的错误描述以及 __FILE__ 和 __LINE__。然后在每个 gl* 函数调用之后添加该函数调用。使调试变得轻而易举。我将我的调试宏包装在一个调试宏中,该宏仅在定义了调试标志时才编译。
-
在测试帧缓冲区之前运行 glGetError() 返回 0,在返回 1280 之后。对于 Tommy,我实际上没有使用 openGL 3.2 或更高版本,我使用的是 3.1!没有看到任何地方提到的。请注意,尝试将我的上下文从 3.2 更改为 3.1,我的 openGL 将不再初始化。埃加德。
标签: c++ opengl shader framebuffer