简体   繁体   中英

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

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

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

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

glUseProgram( m_uiShaderProgramHandle );

5) Pass variables to shader like our 2 different textures

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

//Draw stuff

7) set things back to default in case you have other render procedures using other things

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

------------------------------FRAGMENT SHADER-----------------------------------

In the fragment shader you have to output the 2 results like this right?

#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. -I get fragColor[0] just fine. When i show the fragColor[1] to the screen I got the same result as the first one. But i also hardcoded fragColor[1] to return solid grey inside the shader as a test case and it worked.

So my assumption is somehow when I pass my textures to the shader it assumes "normalMap" is "diffuseMap"? Its my only understanding to why I would get the same result in fragColor[0] and [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.

It looks like step 1 and step 4 are in the wrong order. This is in step 1:

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

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

and this in step 4:

glUseProgram( m_uiShaderProgramHandle );

glUniform*() calls apply to the currently active program. So glUseProgram() must be called before the glUniform1i() calls.

It might also be a good idea to specifically set the location of the out variable:

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.

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. It of course should be equivalent to the number of buffers:

glDrawBuffers(3, drawBuffers);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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