简体   繁体   English

如何使用 OpenGL 渲染到多个纹理?

[英]How To Render To Multiple Textures With OpenGL?

This was my understanding of basic steps to rendering to multiple textures.这是我对渲染多个纹理的基本步骤的理解。

1) Bind the shader locations to render at 1) 绑定要渲染的着色器位置

m_uihDiffuseMap = glGetUniformLocation( m_iShaderProgramHandle, "diffuseMap" );

if( m_uihDiffuseMap != -1 )
    glUniform1i( m_uihDiffuseMap, 0 );

m_uihNormalMap = glGetUniformLocation( m_iShaderProgramHandle, "normalMap" );

if( m_uihNormalMap != -1 )
    glUniform1i( m_uihNormalMap, 1 );

2) Bind to what you want to render to 2)绑定到您要渲染的内容

glBindFramebuffer( GL_FRAMEBUFFER, m_uifboHandle );

//diffuse texture binding
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_uiTextureHandle1, 0);

//normal texture binding
                                   (or GL_COLOR_ATTACHMENT1)
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+1, m_uiTextureHandle2, 0);

3) Clear the buffer & specify what buffers you want to draw to 3)清除缓冲区并指定要绘制的缓冲区

glClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
glDrawBuffers(2, buffers);

4) Set your shader program for rendering 4)设置你的着色器程序进行渲染

glUseProgram( m_uiShaderProgramHandle );

5) Pass variables to shader like our 2 different textures 5) 像我们的 2 个不同纹理一样将变量传递给着色器

glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, uihDiffuseMap );

               //or(GL_TEXTURE1)
glActiveTexture( GL_TEXTURE0+1 );
glBindTexture( GL_TEXTURE_2D, uihNormalMap );

6) Do render call things 6)做渲染调用的东西

//Draw stuff

7) set things back to default in case you have other render procedures using other things 7)如果您有其他渲染程序使用其他东西,请将其设置回默认值

glBindFramebuffer( GL_FRAMEBUFFER, 0 );
glUseProgram( 0 );

------------------------------FRAGMENT SHADER----------------------------------- ------------------------------片段着色器------------------ -----------------

In the fragment shader you have to output the 2 results like this right?在片段着色器中,您必须像这样输出 2 个结果,对吗?

#version 330

in vec2 vTexCoordVary;

uniform sampler2D diffuseMap;
uniform sampler2D normalMap;

out vec4 fragColor[2];

void main( void )
{
    fragColor[0] = texture( diffuseMap, vTexCoordVary );
    fragColor[1] = texture( normalMap, vTexCoordVary );
};

I've double checked我已经仔细检查了
-My diffuse texture and normal texture are loaded fine. - 我的漫反射纹理和法线纹理加载正常。 If I pass my normal texture as the texture to use as TEXTURE0 it will show up.如果我将我的正常纹理作为纹理传递给用作 TEXTURE0 的纹理,它将显示出来。 -I get fragColor[0] just fine. - 我得到 fragColor[0] 就好了。 When i show the fragColor[1] to the screen I got the same result as the first one.当我在屏幕上显示 fragColor[1] 时,我得到了与第一个相同的结果。 But i also hardcoded fragColor[1] to return solid grey inside the shader as a test case and it worked.但我也硬编码 fragColor[1] 以在着色器内返回纯灰色作为测试用例,并且它有效。

So my assumption is somehow when I pass my textures to the shader it assumes "normalMap" is "diffuseMap"?所以我的假设是,当我将纹理传递给着色器时,它假设“normalMap”是“diffuseMap”? Its my only understanding to why I would get the same result in fragColor[0] and [1].这是我唯一理解为什么我会在 fragColor[0] 和 [1] 中得到相同结果的原因。

Yes, as of now the information how your samplers map to texture slots is missing, causing both to refer to the diffuse map. 是的,截至目前,您的采样器如何映射到纹理槽的信息丢失,导致两者都引用漫反射贴图。 Use glUniform1i() to bind the index of the correct texture to each uniform slot. 使用glUniform1i()将正确纹理的索引绑定到每个统一槽。

It looks like step 1 and step 4 are in the wrong order. 看起来步骤1和步骤4的顺序错误。 This is in step 1: 这是在第1步中:

if( m_uihDiffuseMap != -1 )
    glUniform1i( m_uihDiffuseMap, 0 );

if( m_uihNormalMap != -1 )
    glUniform1i( m_uihNormalMap, 1 );

and this in step 4: 这在第4步:

glUseProgram( m_uiShaderProgramHandle );

glUniform*() calls apply to the currently active program. glUniform*()调用适用于当前活动的程序。 So glUseProgram() must be called before the glUniform1i() calls. 所以glUseProgram()必须在之前调用glUniform1i()调用。

It might also be a good idea to specifically set the location of the out variable: 专门设置out变量的位置也可能是个好主意:

layout(location = 0) out vec4 fragColor[2];

I don't think this is causing your problem, but I don't see anything in the spec saying that the linker assigns locations starting at 0 if they are not explicitly specified. 我不认为这会导致您的问题,但我没有在规范中看到任何内容,如果没有明确指定,链接器会分配从0开始的位置。

In case someone stumbles upon here via a search engine like me, my problem with writing to multiple textures was a typo.如果有人通过像我这样的搜索引擎偶然发现这里,我写多个纹理的问题是一个错字。 My framebuffer initialization code looked like this:我的帧缓冲区初始化代码如下所示:

glGenFramebuffers(1, &renderer.gbufferFboId);
glBindFramebuffer(GL_FRAMEBUFFER, renderer.gbufferFboId);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,  GL_TEXTURE_2D, renderer.gbufferDepthTexId, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderer.gbufferColorPositionId, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, renderer.gbufferColorColorId, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, renderer.gbufferColorNormalId, 0);
opengl::fbo_check_current_status();

const GLenum drawBuffers[]
{
    GL_COLOR_ATTACHMENT0,
    GL_COLOR_ATTACHMENT1,
    GL_COLOR_ATTACHMENT2
};
glDrawBuffers(1, drawBuffers);

Can you spot the error?你能发现错误吗? It's a small typo in the glDrawBuffer call.这是glDrawBuffer调用中的一个小错字。 It of course should be equivalent to the number of buffers:它当然应该等于缓冲区的数量:

glDrawBuffers(3, drawBuffers);

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM