2017-01-13 2 views
1

Also ich versuche, verzögerte Wiedergabe in opengl zu implementieren. Dazu erstelle ich einen FBO, der 3 Texturen rendert (eine für Position, eine für Normal, eine für Materialinfo), aber da ich nicht fertig bin, ist die 3. Textur stattdessen nur die letzte Farbe des Fragments. Und ein letzter Tiefenpuffer, um später Schatten zu implementieren.Der Versuch, mehrere Texturen zu rendern, um das verzögerte Rendering zu implementieren. Aber alle Texturen sind gleich

Diese Texturen werden dann an einen anderen Shader (und mit dem Standard-Frame-Buffer) übergeben, der die endgültige Farbe des Pixels berechnet. Alle 3 Texturen enthalten jedoch die gleichen Informationen, die die erste Ausgabevariable des Geometry-Pass-Shaders ist.

#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); 
} 

Alle 3 Ausgang dieses Bild:

All 3 output this image

Und hier ist meine Geometrie Fragment-Shader:

#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); 
} 

Allerdings scheint es, dass nur die erste Ausgangsgröße da getan wird, wenn Ich ändere das:

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

Dies zeigt:

This shows

Hier sind weitere wichtige Funktionen

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); 
} 

Antwort

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 wirkt auf den aktuellen Programm, wie glUseProgram definiert. Ich sehe eine deutliche fehlende von Aufrufen dieser Funktion, bevor Sie setUniformLighting aufrufen. So müssen Sie eine der folgenden Funktionen ausführen:

  1. Haben Sie den Code, setUniformLighting Anruf ruft glUseProgram(lightPassShader) vorher.
  2. Haben setUniformLighting selbst intern diesen Aufruf machen.
  3. Verwenden Sie glProgramUniform, die auf das von Ihnen angegebene Programm einwirkt, und nicht auf das derzeit gebundene Programm. Beachten Sie, dass diese Funktion GL 4.1/ARB_separate_shader_object benötigt.