Having problems rendering lights after deffered shading the whole sceene

First of all I am sorry for this long post after trying to make this work the whole day.

I have many questions about this especially because I use inheritance in C++ to build lights.

I use directional light as my core model for light since i can give the light direction and it will calculate the light, then on top of it I build point light where i just calculate the vector from light to fragment position, and finally for spot light I use point light with the addition of cut off angle to create spot lights (just ignore whatever is outside the cone). I have tested lights and they work fine with forward rendering but now I would like to change my light model to PBR (basically just change how I calculate light in directional light) and move to differed rendering.

Today i started working on deferred rendering and I can get the position, texture, normal and depth buffers, however i have a problem when trying to render lights.

That was the first problem, the second, since each type of light has it own shader and i build them using polymorphism. My second question is I can loop through each light in C++ and call each light to be renderer or there is another way that i can solve this in shaders.
Prototypes of lights are

 Light(glm::vec3& color, float intensity, float ambient, ShaderProgram& lightShader);
 DirectionalLight(glm::vec3& color = glm::vec3(1.0f, 1.0f, 1.0f), glm::vec3& position = glm::vec3(0.0f, 0.0f, 0.0f), float intensity = 1.0f, float ambient = 0.0f, ShaderProgram& lightShader = ShaderProgram("Directional Light"));
    PointLight(glm::vec3& color = glm::vec3(1.0f, 1.0f, 1.0f), glm::vec3& position = glm::vec3(0.0f, 0.0f, 0.0f), float intensity = 1.0f, float ambient = 0.0f, LightAttenuation& lightAttenuation = LightAttenuation(), ShaderProgram& lightShader = ShaderProgram("Point Light"));
 SpotLight(glm::vec3& color = glm::vec3(1.0f, 1.0f, 1.0f), glm::vec3& position = glm::vec3(0.0f, 0.0f, 0.0f), 
	 

What is being drawn
https://www.dropbox.com/s/v6izu9uehcxf2ua/PBR%20deffered%20error.png?dl=0&preview=PBR+deffered+error.png
just as example position buffer
https://www.dropbox.com/s/xuibkh9pel9tt45/PBR%20collor%20buffer.png?dl=0&preview=PBR+collor+buffer.png
My render path looks like this.



        	glEnable(GL_DEPTH_TEST);
         	glDepthFunc(GL_LESS);
		
		defferedShader_.startProgram();
		defferedShader_.setUniformMat4("VP", camera.getVP());
	

		glBindFramebuffer(GL_FRAMEBUFFER, deferredFbo);

        //the scene is small and does not need culling.
        for (auto* mesh : world.getMeshes()) {
			
			//mesh->draw(light->getLightShader());
			//mesh->draw(activeLight_->getLightShader());
			mesh->draw(defferedShader_);
            
            drawCallCounter += mesh->getMeshObjectSize();
        }

glBindFramebuffer(GL_FRAMEBUFFER, 0);
		defferedShader_.stopProgram();
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, positionFbo);
		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_2D, normalFbo);
		glActiveTexture(GL_TEXTURE2);
		glBindTexture(GL_TEXTURE_2D, albedoFbo);
	
               //This is where i got stuck, I would like to make directional light work then test other lights then test the whole program with more than one light
		//for (auto* light : world.getLights()) {
		//	//glEnable(GL_CULL_FACE);
		//	//glCullFace(GL_FRONT);
			glDisable(GL_DEPTH_TEST);
			activeLight_->getLightShader().startProgram();
		
			activeLight_->getLightShader().setUniformMat4("VP", camera.getVP());
			activeLight_->getLightShader().setUniformVec3("eyePosition", camera.getCameraPosition());
		
			//activeLight_->getLightShader();
			RenderQuad();
             
			activeLight_->getLightShader().stopProgram();

  //}

The shader code that i started building is (PS i removed the shadows for now)
Vertex Shader


#version 410 core

#include "../Global/GlobalShader.inc"
#include "../Global/GlobalMesh.inc"

out vec3 Position;
out vec2 TexCoord;
//out vec4 ShadowCoord;

//uniform mat4 ShadowMatrix;

void main() {

	Position = position;
	TexCoord = texCoord;

	//ShadowCoord = ShadowMatrix * vec4(position, 1.0);
	gl_Position = VP * vec4(position, 1.0);
}

Fragment shader
One thing that is bothering me is i can not set the uniform values for gPosition, gPosition and gAlbedoSpec even if I use them, and no matter what i change in the shader the output will be the same.

#version 410 core

#include "../Global/GlobalShader.inc"
#include "../Global/GlobalMesh.inc"
#include "../Global/GlobalLight.inc"
//#include "../Global/ShadowSampling.inc"

in vec3 Position;
in vec2 TexCoord;
//in vec4 ShadowCoord;

uniform sampler2D gPosition;
uniform sampler2D gNormal;
uniform sampler2D gAlbedoSpec;

float specularStrength = 32.0f; // to be impelemented

out vec4 gl_FragColor;
void main() {

	//vec4 lightning = vec4(0.0f);
	////vec4 shadowMapping = vec4(0.0f);
	//
	vec3 FragPos = texture(gPosition, TexCoord).rgb;
	vec3 Normal = texture(gNormal, TexCoord).rgb;
	vec3 Diffuse = texture(gAlbedoSpec, TexCoord).rgb;
	float Specular = texture(gAlbedoSpec, TexCoord).a;

	//vec3 Diffuse = texture(gAlbedoSpec, TexCoord).rgb;
	//lightning = calculateDirectionalLight(directionalLight.light, directionalLight.position, Normal, Position, specularStrength, eyePosition, material, TexCoord);
	//gl_fragColor = vec3(Position, 1.0);
	//shadowMapping = calculateShadow(shadowMap, ShadowCoord, directionalLight.light.ambient);
	//gl_FragColor = vec4(Diffuse, 1.0);
	gl_FragColor = vec4(1.0); //vec4(Diffuse, 1.0);// lightning;//g * shadowMapping;

	//gl_FragColor = lightning;// * shadowMapping;
}

in case you want to see global light


struct Light
{
	vec3 color;
	float intensity;
	float ambient;
};

struct DirectionalLight
{
	Light light;
	vec3 position;
};

struct Attenuation
{
	float constant;
	float linear;
	float quadratic;
};

struct PointLight
{
	Light light;
	Attenuation atten;
	vec3 position;
	float range;
};

struct SpotLight
{
	PointLight pointLight;
	//vec3 lookAt;
	vec3 direction;
	float cutOff;
};

vec3 GAMMA = vec3(1.0/2.2);

vec4 calculateDirectionalLight(Light light, vec3 direction, vec3 normal, vec3 worldPosition, float specularIntensity, vec3 eyePosition, Material material, vec2 texCoord)
{
        vec3 diffuseFactor = ( light.color * material.diffuse * vec3(texture(material.texture.diffuse, texCoord.st)) )
                                                 * (light.intensity * clamp(dot(normal, direction), 0.0, 1.0) ) ;

        vec3 viewDir = normalize(eyePosition - worldPosition);
        vec3 reflectDir = normalize(reflect(-direction, normal));

        float specularFactor = pow(clamp(dot(viewDir, reflectDir), 0.0, 1.0), specularIntensity);
        vec3 specularColor = ( light.color * material.specular * vec3(texture(material.texture.specular, texCoord.st)) ) * (specularFactor * material.shininess);

        return vec4(pow((diffuseFactor + specularColor + light.ambient + material.ambient), GAMMA), 1.0);
}

vec4 calculatePointLight(PointLight pointLight, vec3 normal, vec3 worldPosition, float specularIntensity, vec3 eyePosition, Material material, vec2 texCoord)
{
        // DO NOT NORMALIZE lightDirection, WE NEED IT TO CALCULATE THE DISTANCE TO COMPARE RANGE OF LIGHT
        vec3 lightDirection = pointLight.position - worldPosition;
        float distanceToPoint = length(lightDirection);

        // I dont like conditionals in shader, but since this is fragment based lighting i believe
        // this will speed-up things insetead of calculating the light
        if(distanceToPoint > pointLight.range)
                return vec4(0.0,0.0,0.0,0.0);

        vec4 light = calculateDirectionalLight(pointLight.light, lightDirection, normal, worldPosition,  specularIntensity, eyePosition, material, texCoord);

        // light attenuateion explained https://developer.valvesoftware.com/wiki/Constant-Linear-Quadratic_Falloff
        // http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Light+Attenuation+Shortcut
        float attenuation = max(pointLight.atten.constant
                                + pointLight.atten.linear * distanceToPoint
                                + pointLight.atten.quadratic * distanceToPoint * distanceToPoint,
								1.0);

    return light / attenuation;
}

vec4 calculateSpotLight(SpotLight spotLight, vec3 normal, vec3 worldPosition, float specularIntensity, vec3 eyePosition, Material material, vec2 texCoord) 
{
	vec3 lightDirection = normalize(spotLight.pointLight.position - worldPosition);
	float spotFactor = dot(lightDirection, spotLight.direction);

    vec4 light = vec4(0.0f);
    if(spotFactor > spotLight.cutOff)
    {
		light = calculatePointLight(spotLight.pointLight, normal, worldPosition, specularIntensity, eyePosition, material, texCoord) * (1.0 - (1.0 - spotFactor)/(1.0 - spotLight.cutOff));
	}

    return light;
}

Fixed it. I had the clean buffer and color in the wrong place. It should be after I bind the buffer not at the beginning of each frame.


    glEnable(GL_DEPTH_TEST);


	glBindFramebuffer(GL_FRAMEBUFFER, deferredFbo);

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	//glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    	defferedShader_.startProgram();
    	defferedShader_.setUniformMat4("VP", camera.getVP());
    .
    .
    . rest of the code

OK i figure out one problem. I was applying View Projection transformation to the quad i was rendering.

Now the problem is that i can dont know what is happening with the buffers because when I apply the coordinates i just get a black screen.
The code that i have to draw into frame buffer is this
PS. If anyone can tell me how to render frambuffers into smaller screens so i will have them for debugging I would be very happy. I have problems using Nvidia opengl tools but with GPU PerfStudio I can see that framebuffers have correct textures.


	
	clearScreen(CLEAR_BUFFER_TYPES::COLOR_DEPTH_BUFFER);
	clearBuffer(CLEAR_BUFFER_TYPES::COLOR_DEPTH_BUFFER);

	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LESS);
	//glEnable(GL_CULL_FACE);
	//glCullFace(GL_BACK);

	//glFrontFace(GL_CW);
	//glCullFace(GL_FRONT);
	//glEnable(GL_CULL_FACE);
	//glEnable(GL_DEPTH_TEST);

	defferedShader_.startProgram();
	defferedShader_.setUniformMat4("VP", camera.getVP());


	glBindFramebuffer(GL_FRAMEBUFFER, deferredFbo);
	for (auto* mesh : world.getMeshes()) {
		//mesh->draw(activeLight_->getLightShader());
		mesh->draw(defferedShader_);

		drawCallCounter += mesh->getMeshObjectSize();
	}
	glBindFramebuffer(GL_FRAMEBUFFER, 0);
	defferedShader_.stopProgram();

	glDisable(GL_DEPTH_TEST);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	activeLight_->getLightShader().startProgram();
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, positionFbo);
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, normalFbo);
	glActiveTexture(GL_TEXTURE2);
	glBindTexture(GL_TEXTURE_2D, albedoFbo);

	activeLight_->getLightShader().setUniformMat4("VP", camera.getVP());
	activeLight_->getLightShader().setUniformVec3("eyePosition", camera.getCameraPosition());

	RenderQuad();

	activeLight_->getLightShader().stopProgram();

	drawCallCounter = 0;

Deffered VS


#version 410 core

#include "../Global/GlobalShader.inc"
#include "../Global/GlobalMesh.inc"

out vec3 Position;
out vec3 Normal;
out vec2 TexCoord;

void main() {

	Position = position;
	Normal = normal;
	TexCoord = texCoord;

	gl_Position = VP * vec4(position, 1.0);
}


Deffered FS


#version 410 core

#include "../Global/GlobalShader.inc"
#include "../Global/GlobalMesh.inc"

in vec3 Position;
in vec3 Normal;
in vec2 TexCoord;
 
layout(location = 0) out vec3 o_Position;
layout(location = 1) out vec3 o_Normal;
layout(location = 2) out vec4 o_AlbedoSpec;

//out vec4 gl_FragColor;
void main() {

	o_Position = Position;
	o_Normal = Normal;
	
	o_AlbedoSpec.rgb = texture(material.texture.diffuse, TexCoord.st).rgb * material.diffuse;
	o_AlbedoSpec.a = texture(material.texture.specular, TexCoord.st).r;

	gl_FragColor = vec4(texture(material.texture.diffuse, TexCoord.st).rgb * material.diffuse, 1.0);

	//gl_FragColor = vec4(TexCoord ,1.0 ,1.0)
}


I just want to get the color for a texture using this VS


#version 410 core

#include "../Global/GlobalShader.inc"
#include "../Global/GlobalMesh.inc"

//out vec3 Position;
out vec2 TexCoord;
//out vec4 ShadowCoord;

//uniform mat4 ShadowMatrix;

void main() {
	gl_Position = vec4(position, 1.0);
	TexCoord = texCoord;

	//ShadowCoord = ShadowMatrix * vec4(position, 1.0);	
}


and the FS


#version 410 core

#include "../Global/GlobalShader.inc"
#include "../Global/GlobalMesh.inc"
#include "../Global/GlobalLight.inc"
//#include "../Global/ShadowSampling.inc"

in vec2 TexCoord;
//in vec4 ShadowCoord;

uniform sampler2D gPosition;
uniform sampler2D gNormal;
uniform sampler2D gAlbedoSpec;

uniform vec3 eyePosition;
uniform DirectionalLight directionalLight;
uniform int lightNumber; // implement this for light loop so i wont render allways max light number

float specularStrength = 32.0; // to be impelemented

out vec4 gl_FragColor;
void main() {

	//vec4 lightning = vec4(0.0);
	//vec4 shadowMapping = vec4(0.0f);
	
	vec3 FragPos = texture(gPosition, TexCoord).rgb;
	vec3 Normal = texture(gNormal, TexCoord).rgb;
	vec3 Diffuse = texture(gAlbedoSpec, TexCoord).rgb;
	float Specular = texture(gAlbedoSpec, TexCoord).a;

	//lightning = calculateDirectionalLight(directionalLight.light, directionalLight.position, Normal, FragPos, specularStrength, eyePosition, material, TexCoord);
	//shadowMapping = calculateShadow(shadowMap, ShadowCoord, directionalLight.light.ambient);
	//gl_FragColor = lightning;// * shadowMapping;

	//gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);// +vec4(FragPos, 1.0); //vec4(Diffuse, 1.0);
	gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0) + vec4(Diffuse, 1.0);
	//gl_FragColor = vec4(Diffuse, 1.0);
}