2017-01-13 10 views
1

Итак, я пытаюсь выполнить отложенный рендеринг в opengl. Для этого я создаю FBO, который отображает 3 текстуры (один для позиции, один для обычного, один для информации о материалах), однако, поскольку я не закончил, 3-я текстура вместо этого является только окончательным цветом фрагмента. И один последний буфер глубины, чтобы позднее реализовать тени.Пытается отобразить несколько текстур для реализации отложенного рендеринга. Но все текстуры равны

Эти текстуры затем передаются в другой шейдер (и с использованием фрейма по умолчанию), который вычисляет окончательный цвет пикселя. Однако все 3 текстуры содержат ту же информацию, которая является первой выходной переменной из шейдера геометрии.

#version 330 
//Fragment shader from the lighting pass 
in vec2 vTexCoord; 

uniform sampler2D uPosTexture; 
uniform sampler2D uNormalTexture; 
uniform sampler2D uColorTexture; 

out vec4 fFragColor; 

void main() 
{ 
    //All of the following lines output the same image 
    vec3 color = texture(uNormalTexture, vTexCoord).rgb; 
    //vec3 color = texture(uPosTexture, vTexCoord).rgb; 
    //vec3 color = texture(uColorTexture, vTexCoord).rgb; 

    fFragColor = vec4(color,1); 
} 

Все три вывода этого изображения:

All 3 output this image

А вот мой фрагмент геометрии шейдер:

#version 330 

in vec3 vECPos; // S.R. Vista 
in vec3 vECNorm; // S.R. Vista 
in vec4 vShadowCoord; 

layout (location = 0) out vec3 fPosition; 
layout (location = 1) out vec3 fNormal; 
layout (location = 2) out vec4 fFragColor; 

uniform sampler2DShadow uShadowMap; 
uniform int uTipoFiltro; 

struct LightInfo { 
    vec4 lightPos; // Posición de la luz (S.R. de la vista) 
    vec3 intensity; 
}; 
uniform LightInfo uLight; 
struct MaterialInfo { 
    vec3 ambient; 
    vec3 diffuse; 
    vec3 specular; 
    float shininess; 
}; 
uniform MaterialInfo uMaterial; 


vec3 phongModelDiffAndSpec() 
{ 
    vec3 ldir = normalize(vec3(uLight.lightPos) - vECPos); 
    vec3 view = normalize(vec3(-vECPos)); 
    vec3 r = reflect(-ldir,vECNorm); 

    vec3 color = uLight.intensity * (uMaterial.diffuse * max(dot(ldir,vECNorm), 0.0) + 
            uMaterial.specular * pow(max(dot(r,view),0),uMaterial.shininess)); 

    return clamp(color, 0.0, 1.0); 
} 


void main() 
{ 

    vec3 ambient = uLight.intensity * uMaterial.ambient; 
    vec3 diffAndSpec = phongModelDiffAndSpec(); 

    fPosition = vECPos; 
    fNormal = normalize(vECNorm); 
    fFragColor = vec4(ambient + diffAndSpec,1.0); 
} 

Однако, кажется, что только первая выходная переменная делается потому, что если Я меняю это:

layout (location = 1) out vec3 fPosition; 
layout (location = 2) out vec3 fNormal; 
layout (location = 0) out vec4 fFragColor; 

Это показывает:

This shows

Вот другие важные функции

bool init() 
{ 
    glClearColor(0.93f, 0.93f, 0.93f, 0.0f); 

    glEnable(GL_DEPTH_TEST); 
    //glDepthFunc(GL_LESS); 
    //glClearDepth(1.0f); 

    //glShadeModel(GL_SMOOTH); 

    //Create shaders 
    createShader(geometryPassShader, "geometry.vert", "geometry.frag"); 
    setUniformGeometry(); 
    createShader(lightPassShader, "lighting.vert", "lighting.frag"); 
    setUniformLighting(); 

    initFBO(); 
    passTexturesToStdFBO(); 

    //Init objects 
    numVertTeapot = initTeapot(5, glm::mat4(1.0f)); 
    numVertSphere = initSphere(1.0f, 20, 30); 
    numVertPlane = initPlane(10.0f, 10.0f, 2, 2); 
    numVertTorus = initTorus(0.5f, 0.25f, 20, 40); 
    initQuad(); 

    return true; 
} 

void initFBO() 
{ 
    //Crear 1 FBO 
    glGenFramebuffers(1, &gBuffer); 
    glBindFramebuffer(GL_FRAMEBUFFER, gBuffer); 

    //Crear textura que guarda posicion 
    glGenTextures(1, &gPositionTex); 
    //glActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D, gPositionTex); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, g_Width, g_Height, 0, GL_RGB, GL_FLOAT, NULL); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
    //Añadir la textura al FBO 
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gPositionTex, 0); 

    //Crear textura que guarda normal 
    glGenTextures(1, &gNormalTex); 
    //glActiveTexture(GL_TEXTURE1); 
    glBindTexture(GL_TEXTURE_2D, gNormalTex); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, g_Width, g_Height, 0, GL_RGB, GL_FLOAT, NULL); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
    //Añadir textura al FBO 
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, gNormalTex, 0); 

    //Crear textura que guarda informacion del material del "pixel" 
    glGenTextures(1, &gMaterialTex); 
    //glActiveTexture(GL_TEXTURE2); 
    glBindTexture(GL_TEXTURE_2D, gMaterialTex); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, g_Width, g_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, gMaterialTex, 0); 

    //Crear depth buffer 
    glGenTextures(1, &depth_texture); 
    glActiveTexture(GL_TEXTURE3); 
    glBindTexture(GL_TEXTURE_2D, depth_texture); 

    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, g_Width, g_Height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 

    //Indicamos que buffers (texturas) seran escritos con el output del fragment shader 
    glDrawBuffers(3, attachments); //attachments[3] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 }; 

    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_texture, 0); 


    GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER); 
    if (result == GL_FRAMEBUFFER_COMPLETE) 
     std::cout << "Frame buffer complete" << std::endl; 
    else 
     std::cout << "Frame buffer is not complete" << std::endl; 

    glBindFramebuffer(GL_FRAMEBUFFER, 0); 
} 

void display() 
{ 

    //glClear of this FBO is done inside drawFBO() 
    glUseProgram(geometryPassShader); 
    drawFBO(); 
    glUseProgram(0); 

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glUseProgram(lightPassShader); 
    //passTexturesToStdFBO(); 
    drawQuad(); 
    glUseProgram(0); 

    glutSwapBuffers(); 
} 

void drawFBO() 
{ 
    glBindFramebuffer(GL_FRAMEBUFFER, gBuffer); 
    glViewport(0, 0, g_Width, g_Height); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    drawScene(); 

    glBindFramebuffer(GL_FRAMEBUFFER, 0); 
} 

void passTexturesToStdFBO() 
{ 
    glBindBuffer(GL_FRAMEBUFFER, 0); 

    glActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D, gPositionTex); 
    glActiveTexture(GL_TEXTURE1); 
    glBindTexture(GL_TEXTURE_2D, gNormalTex); 
    glActiveTexture(GL_TEXTURE2); 
    glBindTexture(GL_TEXTURE_2D, gMaterialTex); 
    glActiveTexture(GL_TEXTURE3); 
    glBindTexture(GL_TEXTURE_2D, depth_texture); 
} 

void setUniformLighting() 
{ 
    GLuint loc0 = glGetUniformLocation(lightPassShader, "uPosTexture"); 
    glUniform1i(loc0, 0); 

    GLuint loc1 = glGetUniformLocation(lightPassShader, "uNormalTexture"); 
    glUniform1i(loc1, 1); 

    GLuint loc2 = glGetUniformLocation(lightPassShader, "uColorTexture"); 
    glUniform1i(loc2, 2); 
} 

ответ

2
void setUniformLighting() 
{ 
    GLuint loc0 = glGetUniformLocation(lightPassShader, "uPosTexture"); 
    glUniform1i(loc0, 0); 

    GLuint loc1 = glGetUniformLocation(lightPassShader, "uNormalTexture"); 
    glUniform1i(loc1, 1); 

    GLuint loc2 = glGetUniformLocation(lightPassShader, "uColorTexture"); 
    glUniform1i(loc2, 2); 
} 

glUniform действует на текущей программе , как определено glUseProgram. Я вижу отдельный недостаток вызовов этой функции, прежде чем вы вызовете setUniformLighting. Так что вам нужно сделать одно из следующих действий:

  1. Есть код, вызывающий setUniformLighting вызов glUseProgram(lightPassShader) заранее.
  2. Иметь setUniformLighting сам по себе сделать этот звонок.
  3. Используйте glProgramUniform, который действует на указанную вами программу, а не связанную с ней. Обратите внимание, что для этой функции требуется GL 4.1/ARB_separate_shader_object.