Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 2D openGL引擎简单光源和帧缓冲区(c+;+;)_C++_Opengl_Shader_Framebuffer - Fatal编程技术网

C++ 2D openGL引擎简单光源和帧缓冲区(c+;+;)

C++ 2D openGL引擎简单光源和帧缓冲区(c+;+;),c++,opengl,shader,framebuffer,C++,Opengl,Shader,Framebuffer,我目前正在尝试学习openGL,我有点困于为我的应用程序制作一个非常简单的照明引擎。它是2D的,我发现大多数资料只涉及相当复杂的3D操作。我想做的事情与本教程中介绍的内容一样简单: 它将我推向了正确的方向,我要理解的是,我将使用一个帧缓冲区和一种“光照贴图”,我将它与我正在渲染的纹理一起发送给我的着色器,这样我就可以组合这些值来创建照明效果。第一件事:我不能让我的帧缓冲区工作 我遵循了以下教程:这已经足够整洁了。这让我了解了以下创建帧缓冲区的代码: GLuint frameBuffer; glG

我目前正在尝试学习openGL,我有点困于为我的应用程序制作一个非常简单的照明引擎。它是2D的,我发现大多数资料只涉及相当复杂的3D操作。我想做的事情与本教程中介绍的内容一样简单:

它将我推向了正确的方向,我要理解的是,我将使用一个帧缓冲区和一种“光照贴图”,我将它与我正在渲染的纹理一起发送给我的着色器,这样我就可以组合这些值来创建照明效果。第一件事:我不能让我的帧缓冲区工作

我遵循了以下教程:这已经足够整洁了。这让我了解了以下创建帧缓冲区的代码:

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是该纹理的胶点。(我可以使用默认的帧缓冲区很容易地将其渲染到屏幕上,它显示得很好,所以我知道这是可行的)。完成此操作后,我运行测试以检查是否一切正常(如教程所述):

然后一切正常。我的帧缓冲区有什么问题?我一直在到处寻找一个简单的项目示例,我可以通过复制粘贴和运行来查看它是否有效,但它不是错误的语言,就是使用了我不想使用的库。此外,我不能完全确定我是否理解帧缓冲区是如何工作的。我知道这只是另一个要绘制的屏幕(或者,据我所知,在渲染过程中添加另一个步骤?)

目前,我正在通过绑定纹理绘制所有内容,绘制具有纹理大小的四边形,然后移动到下一个纹理。这意味着对于我的应用程序中的每一个图像,它们都运行一个着色器(或者应该说,当前完全相同的着色器的副本)。我是否理解,例如,如果我有20个不同的图像,首先在屏幕上运行20个着色器,然后我可以通过额外的“步骤”将它们与我在帧缓冲区中创建的光照贴图混合,还是我错了


很抱歉,如果这些问题听起来很愚蠢,但我现在已经浏览了大量教程,每个教程提出的问题都比它似乎回答的要多,我通常通过实验学习得最好,但当我甚至无法启动帧缓冲区时,我有点卡住了

DirectX中帧缓冲区对象技术的名称是“渲染到纹理”。因此,这不是“另一个屏幕上画”;这是一种离线纹理

一些关键概念:

  • 数据存储在纹理中。FBO(帧缓冲区对象)只是告诉OpenGL如何渲染该纹理
  • 只有一个“屏幕上”对象,即后台缓冲区。所有其他“渲染目标”(OpenGL中的FBO)都处于脱机状态。如果你想在屏幕上显示一些东西,你必须画到后缓冲区
  • 使用FBO的基本步骤是:

  • 创建纹理
  • 创建固定基地运营商;将纹理绑定到FBO;将FBO绑定为“渲染目标”
  • 吸引外资银行
  • 切换回后台缓冲区(
    glBindFramebuffer(GL\u FRAMEBUFFER,0);
  • 将纹理绑定为“纹理”
  • 在后缓冲区绘制一些东西,现在就可以对纹理进行采样了

  • 有关详细的代码示例,请参阅。

    此调用中的参数不正确:

    GLenum check_framebuffer = glCheckFramebufferStatus(frameBuffer);
    
    此调用的参数不是帧缓冲区id(名称),而是帧缓冲区目标。这应该是:

    glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
    GLenum check_framebuffer = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    

    如果使用此调用,它将提供有关实际渲染失败原因的更多详细信息。调用glFramebufferTexture2D()看起来基本正常。因此,它很可能与纹理的设置有关,这在发布的代码中没有显示。

    纹理的状态如何?你打电话给
    TexImage2D
    确定它的大小和格式了吗?是的,这就是我制作纹理的方式。大小(宽度和高度)存储在我的纹理类中。。。。您是否已检查是否正在获取OpenGL 3.2或更高版本的上下文?这就是
    glFramebufferTexture
    到达的时间。在创建帧缓冲区对象之前,请尝试调用glGetError(),看看是否一切正常,这可能是一个陈旧的错误。使用opengl编程的一大技巧是:创建一个调用glGetError()的函数,如果有错误,则记录其枚举名(例如GL_INVALID_enum)、API中的错误描述以及_文件和_行。然后在每次gl*函数调用之后添加该函数调用。调试轻而易举。我将我的代码包装在一个调试宏中,该宏只有在定义了调试标志的情况下才会编译。在测试帧缓冲区之前运行glGetError()会返回0,之后返回1280。对于Tommy来说,事实上我没有使用openGL版本3.2或更高版本,我使用的是3.1!没有看到任何地方提到过。请注意,尝试将我的上下文从3.2更改为3.1,我的openGL将不再初始化。伊加德,谢谢你澄清。我已经看了一些这个例子,但我仍然不明白为什么glCheckFramebufferStatus返回0。这对我来说太典型了,它一直在起作用。谢谢
    GLenum check_framebuffer = glCheckFramebufferStatus(frameBuffer);
    
    glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
    GLenum check_framebuffer = glCheckFramebufferStatus(GL_FRAMEBUFFER);