added deferred pipeline
This commit is contained in:
parent
66784724d8
commit
01973cea0b
83
shaders/gbuffer.frag.glsl
Normal file
83
shaders/gbuffer.frag.glsl
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
// - Normal buffer
|
||||||
|
layout (location = 0) out vec3 outNormal;
|
||||||
|
// - Color + objectId buffer
|
||||||
|
layout (location = 1) out vec4 outColor;
|
||||||
|
// - Specular color + Specular exponent buffer
|
||||||
|
layout (location = 2) out vec4 outSpecular;
|
||||||
|
// - Position in view space
|
||||||
|
layout (location = 3) out vec4 outPosition;
|
||||||
|
|
||||||
|
uniform float materialNs;
|
||||||
|
|
||||||
|
// variables used for picking
|
||||||
|
uniform unsigned int object_identifier;
|
||||||
|
#ifdef INSTANCED
|
||||||
|
flat in int instanceId;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ALPHA_MASK
|
||||||
|
uniform sampler2D alphaMask;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DIFFUSE_TEXTURE
|
||||||
|
uniform sampler2D diffuseTexture;
|
||||||
|
#else
|
||||||
|
uniform vec3 materialKd;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SPECULAR_TEXTURE
|
||||||
|
uniform sampler2D specularTexture;
|
||||||
|
#else
|
||||||
|
uniform vec3 materialKs;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
in vec4 posInView;
|
||||||
|
#ifdef NORMAL_MAP
|
||||||
|
uniform sampler2D normalMap;
|
||||||
|
|
||||||
|
in vec3 varTangent;
|
||||||
|
in vec3 varBinormal;
|
||||||
|
#endif
|
||||||
|
in vec3 varNormal;
|
||||||
|
|
||||||
|
in vec2 varTexCoord;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
#ifdef ALPHA_MASK
|
||||||
|
if(texture(alphaMask, varTexCoord).r < 0.5)
|
||||||
|
discard;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NORMAL_MAP
|
||||||
|
vec3 normalTexel = normalize(texture(normalMap, varTexCoord).xyz -0.5);
|
||||||
|
vec3 tangent = normalize(varTangent);
|
||||||
|
vec3 binormal = normalize(varBinormal);
|
||||||
|
vec3 normal = normalize(varNormal);
|
||||||
|
mat3 tangentSpace = mat3(vec3(tangent.x, binormal.x, normal.x),
|
||||||
|
vec3(tangent.y, binormal.y, normal.y),
|
||||||
|
vec3(tangent.z, binormal.z, normal.z));
|
||||||
|
|
||||||
|
outNormal = normalize(normalTexel * tangentSpace);
|
||||||
|
#else
|
||||||
|
outNormal = normalize(varNormal);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DIFFUSE_TEXTURE
|
||||||
|
outColor.rgb = texture(diffuseTexture, varTexCoord).rgb;
|
||||||
|
#else
|
||||||
|
outColor.rgb = materialKd;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
outColor.a = float(object_identifier)/255;
|
||||||
|
|
||||||
|
#ifdef SPECULAR_TEXTURE
|
||||||
|
outSpecular.rgb = texture(specularTexture, varTexCoord).rgb;
|
||||||
|
#else
|
||||||
|
outSpecular.rgb = materialKs;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
outSpecular.w = float(materialNs)/255;
|
||||||
|
|
||||||
|
outPosition = posInView;
|
||||||
|
}
|
49
shaders/gbuffer.vert.glsl
Normal file
49
shaders/gbuffer.vert.glsl
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
uniform mat4 projectionMatrix;
|
||||||
|
uniform mat4 modelViewMatrix;
|
||||||
|
uniform mat3 normalMatrix;
|
||||||
|
|
||||||
|
out vec4 posInView;
|
||||||
|
#ifdef NORMAL_MAP
|
||||||
|
out vec3 varTangent;
|
||||||
|
out vec3 varBinormal;
|
||||||
|
#endif
|
||||||
|
out vec3 varNormal;
|
||||||
|
|
||||||
|
out vec2 varTexCoord;
|
||||||
|
|
||||||
|
layout(location = 0)in vec3 inPosition;
|
||||||
|
layout(location = 2)in vec2 inTexCoord;
|
||||||
|
layout(location = 1)in vec3 inNormal;
|
||||||
|
#ifdef NORMAL_MAP
|
||||||
|
layout(location = 3)in vec3 inTangent;
|
||||||
|
layout(location = 4)in vec3 inBinormal;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef INSTANCED
|
||||||
|
layout(location = 5)in vec3 inInstanceOffset;
|
||||||
|
|
||||||
|
flat out int instanceId;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
// computing normals
|
||||||
|
#ifdef NORMAL_MAP
|
||||||
|
varTangent = normalize(normalMatrix*inTangent);
|
||||||
|
varBinormal = normalize(normalMatrix*inBinormal);
|
||||||
|
#endif
|
||||||
|
varNormal = normalize(normalMatrix*inNormal);
|
||||||
|
|
||||||
|
//computing UVs
|
||||||
|
varTexCoord = inTexCoord.xy;
|
||||||
|
|
||||||
|
// computing positions
|
||||||
|
#ifdef INSTANCED
|
||||||
|
instanceId = gl_InstanceID;
|
||||||
|
vec4 pos = vec4(inPosition + inInstanceOffset, 1.0);
|
||||||
|
#else
|
||||||
|
vec4 pos = vec4(inPosition, 1.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
posInView = modelViewMatrix*pos;
|
||||||
|
gl_Position = projectionMatrix * posInView;
|
||||||
|
}
|
131
shaders/lighting.frag.glsl
Normal file
131
shaders/lighting.frag.glsl
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
// G-BUFFER
|
||||||
|
|
||||||
|
// - Normal buffer
|
||||||
|
uniform sampler2DRect normalBuffer;
|
||||||
|
// - Color + objectId buffer
|
||||||
|
uniform sampler2DRect colorBuffer;
|
||||||
|
// - Specular color + Specular exponent buffer
|
||||||
|
uniform sampler2DRect specularBuffer;
|
||||||
|
// - Position in view space
|
||||||
|
uniform sampler2DRect positionBuffer;
|
||||||
|
// - depth buffer
|
||||||
|
uniform sampler2DRect depthBuffer;
|
||||||
|
|
||||||
|
// LIGHT ATTRIBUTES
|
||||||
|
|
||||||
|
uniform vec3 lightColor;
|
||||||
|
|
||||||
|
#ifdef SHADOWMAP
|
||||||
|
uniform sampler2DShadow shadowMap;
|
||||||
|
uniform mat4 viewToLightMatrix;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined POINT_LIGHT
|
||||||
|
uniform vec3 pointLight;
|
||||||
|
uniform float attenuation;
|
||||||
|
#elif defined DIRECTIONNAL_LIGHT
|
||||||
|
uniform vec3 dirLight;
|
||||||
|
#elif defined SPOT_LIGHT
|
||||||
|
uniform vec3 pointLight;
|
||||||
|
uniform float attenuation;
|
||||||
|
uniform vec3 dirLight;
|
||||||
|
uniform float cutoff;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// FRAGMENT POSITIONNING
|
||||||
|
|
||||||
|
in vec2 screenPos;
|
||||||
|
|
||||||
|
uniform mat4 inverseProjectionMatrix;
|
||||||
|
|
||||||
|
// OUTPUT LIGHT
|
||||||
|
|
||||||
|
layout(location = 0)out vec4 outColor;
|
||||||
|
|
||||||
|
// FUNCTIONS
|
||||||
|
|
||||||
|
const float CELL_SHADING = 0.3333;
|
||||||
|
|
||||||
|
vec3 phongLighting(in vec3 kd, in vec3 ks, in float ns, in vec3 color, in vec3 normal, in vec3 lightDir, in vec3 halfVec, in vec3 viewDir){
|
||||||
|
float diffuseComponent = max(dot(normal, lightDir), 0);
|
||||||
|
float specularComponent = max(dot(halfVec, normal), 0);
|
||||||
|
return color*diffuseComponent*(kd+ks*pow(specularComponent, ns));
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 CookTorranceSpecularHighlight(in vec3 ks, in float ns, in vec3 normal, in vec3 lightDir, in vec3 halfVec, in vec3 viewDir){
|
||||||
|
float HN = dot(halfVec, normal);
|
||||||
|
float VN = dot(viewDir, normal);
|
||||||
|
float VH = dot(viewDir, halfVec);
|
||||||
|
float LN = dot(lightDir, normal);
|
||||||
|
|
||||||
|
HN = max(HN, 0);
|
||||||
|
VN = max(VN, 0);
|
||||||
|
LN = max(LN, 0);
|
||||||
|
|
||||||
|
// GGX normal distribution :
|
||||||
|
float roughness = 2/(ns+2);
|
||||||
|
float denom = mix(1, roughness, HN*HN);
|
||||||
|
float D = roughness/(3.1416*denom*denom);
|
||||||
|
//D = pow(HN, ns);
|
||||||
|
|
||||||
|
// Fresnel term with Schlick's approximation
|
||||||
|
vec3 F = mix(ks, vec3(1), pow(1 - VH, 5));
|
||||||
|
|
||||||
|
VH = max(VH, 0);
|
||||||
|
|
||||||
|
// Geometric attenuation
|
||||||
|
float G = min(1, min(2*HN*VN/VH, 2*HN*LN/VH));
|
||||||
|
|
||||||
|
return D * F * G;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 testLighting(in vec3 kd, in vec3 ks, in float ns, in vec3 color, in vec3 normal, in vec3 lightDir, in vec3 halfVec, in vec3 viewDir){
|
||||||
|
float diffuseComponent = max(dot(normal, lightDir), 0);
|
||||||
|
return color*diffuseComponent*(kd+ks*CookTorranceSpecularHighlight(ks, ns, normal, lightDir, halfVec, viewDir));
|
||||||
|
}
|
||||||
|
|
||||||
|
float computeShadow(sampler2D shadowmap, vec3 shadow){
|
||||||
|
float lightFragDepth = texture(shadowmap, shadow.xy).r;
|
||||||
|
return lightFragDepth < shadow.z ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MAIN PROGRAM
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
ivec2 texCoord = ivec2(gl_FragCoord.xy);
|
||||||
|
vec3 normal = texelFetch(normalBuffer, texCoord).xyz;
|
||||||
|
vec4 diffuseTexel = texelFetch(colorBuffer, texCoord);
|
||||||
|
vec3 diffuse = diffuseTexel.rgb;
|
||||||
|
vec4 specularTexel = texelFetch(specularBuffer, texCoord);
|
||||||
|
vec3 specular = specularTexel.rgb;
|
||||||
|
float shininess = specularTexel.w*255;
|
||||||
|
vec4 fragPos = texelFetch(positionBuffer, texCoord);
|
||||||
|
float depth = texelFetch(depthBuffer, texCoord).r;
|
||||||
|
|
||||||
|
#ifdef SHADOWMAP
|
||||||
|
vec4 fragInLightSpace = viewToLightMatrix * fragPos;
|
||||||
|
fragInLightSpace.z = fragInLightSpace.z - 0.002;
|
||||||
|
float shadow = texture(shadowMap, fragInLightSpace.xyz/fragInLightSpace.w);
|
||||||
|
#else
|
||||||
|
float shadow = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
float att = 1;
|
||||||
|
#ifdef POINT_LIGHT
|
||||||
|
vec3 dirLight = pointLight - fragPos.xyz;
|
||||||
|
float dist = length(dirLight);
|
||||||
|
if(dist > attenuation)
|
||||||
|
att = 0;
|
||||||
|
att = 1 - dist/attenuation;
|
||||||
|
dirLight = normalize(dirLight);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef AMBIENT_LIGHT
|
||||||
|
outColor = vec4(diffuse*lightColor, 1);
|
||||||
|
#else
|
||||||
|
vec3 viewDir = normalize(-fragPos.xyz);
|
||||||
|
vec3 halfVec = normalize(viewDir + dirLight);
|
||||||
|
vec3 light = testLighting(diffuse, specular, shininess, lightColor, normal, dirLight, halfVec, viewDir);
|
||||||
|
outColor = vec4(mix(vec3(0.0), light*shadow, att*att), 1);
|
||||||
|
#endif
|
||||||
|
}
|
8
shaders/lighting.vert.glsl
Normal file
8
shaders/lighting.vert.glsl
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
layout(location = 0)in vec2 inPosition;
|
||||||
|
|
||||||
|
out vec2 screenPos;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
gl_Position = vec4(inPosition, 0.0, 1.0);
|
||||||
|
screenPos = inPosition;
|
||||||
|
}
|
17
shaders/posteffects.frag.glsl
Normal file
17
shaders/posteffects.frag.glsl
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#version 330 core
|
||||||
|
|
||||||
|
// LIGHT BUFFER
|
||||||
|
|
||||||
|
uniform sampler2DRect lightBuffer;
|
||||||
|
|
||||||
|
// OUTPUT LIGHT
|
||||||
|
|
||||||
|
layout(location = 0)out vec4 outColor;
|
||||||
|
|
||||||
|
// MAIN PROGRAM
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
ivec2 texCoord = ivec2(gl_FragCoord.xy);
|
||||||
|
vec3 color = texelFetch(lightBuffer, texCoord).xyz;
|
||||||
|
outColor = vec4(color, 1.0);
|
||||||
|
}
|
7
shaders/posteffects.vert.glsl
Normal file
7
shaders/posteffects.vert.glsl
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#version 330 core
|
||||||
|
|
||||||
|
layout(location = 0)in vec2 inPosition;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
gl_Position = vec4(inPosition, 0.0, 1.0);
|
||||||
|
}
|
228
src/deferredpipeline.cpp
Normal file
228
src/deferredpipeline.cpp
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
#include <sparrowrenderer.h>
|
||||||
|
#include "deferredpipeline.h"
|
||||||
|
#include <texture.h>
|
||||||
|
#include <scene.h>
|
||||||
|
#include <mesh.h>
|
||||||
|
#include <shader.h>
|
||||||
|
#include <glm/ext.hpp>
|
||||||
|
#include <shadersource.h>
|
||||||
|
#include <phongmaterial.h>
|
||||||
|
#include <camera.h>
|
||||||
|
#include <resource.h>
|
||||||
|
|
||||||
|
RESOURCE_PACK(shaders)
|
||||||
|
|
||||||
|
GBuffer::GBuffer(int width, int height) : FrameBuffer()
|
||||||
|
{
|
||||||
|
Texture* tex;
|
||||||
|
// - Normal buffer
|
||||||
|
tex = new Texture(GL_RGB, GL_RGB16F, width, height, GL_FLOAT, GL_TEXTURE_RECTANGLE);
|
||||||
|
tex->setFiltering(GL_NEAREST);
|
||||||
|
tex->setUnit(NORMAL);
|
||||||
|
addTexture(tex, GL_COLOR_ATTACHMENT0);
|
||||||
|
|
||||||
|
// - Color + objectId buffer
|
||||||
|
tex = new Texture(GL_RGBA, GL_RGBA, width, height, GL_UNSIGNED_BYTE, GL_TEXTURE_RECTANGLE);
|
||||||
|
tex->setFiltering(GL_NEAREST);
|
||||||
|
tex->setUnit(DIFFUSE);
|
||||||
|
addTexture(tex, GL_COLOR_ATTACHMENT1);
|
||||||
|
|
||||||
|
// - Specular color + Specular exponent buffer
|
||||||
|
tex = new Texture(GL_RGBA, GL_RGBA, width, height, GL_UNSIGNED_BYTE, GL_TEXTURE_RECTANGLE);
|
||||||
|
tex->setFiltering(GL_NEAREST);
|
||||||
|
tex->setUnit(SPECULAR);
|
||||||
|
addTexture(tex, GL_COLOR_ATTACHMENT2);
|
||||||
|
|
||||||
|
// - Position buffer
|
||||||
|
tex = new Texture(GL_RGBA, GL_RGBA16F, width, height, GL_FLOAT, GL_TEXTURE_RECTANGLE);
|
||||||
|
tex->setFiltering(GL_NEAREST);
|
||||||
|
tex->setUnit(POSITION);
|
||||||
|
addTexture(tex, GL_COLOR_ATTACHMENT3);
|
||||||
|
|
||||||
|
// - depth buffer
|
||||||
|
tex = new Texture(GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, width, height, GL_FLOAT, GL_TEXTURE_RECTANGLE);
|
||||||
|
tex->setFiltering(GL_NEAREST);
|
||||||
|
tex->setUnit(DEPTH);
|
||||||
|
addTexture(tex, GL_DEPTH_ATTACHMENT);
|
||||||
|
|
||||||
|
initColorAttachments();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GBuffer::bindTextures()
|
||||||
|
{
|
||||||
|
for(int i=0; i<NB_BUFFERS; ++i)
|
||||||
|
getTexture(i)->bind();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GBuffer::unbindTextures()
|
||||||
|
{
|
||||||
|
for(int i=0; i<NB_BUFFERS; ++i)
|
||||||
|
getTexture(i)->unbind();
|
||||||
|
}
|
||||||
|
|
||||||
|
LightingBuffer::LightingBuffer(int width, int height) : FrameBuffer()
|
||||||
|
{
|
||||||
|
// colors are encoded in float to allow tonemapping
|
||||||
|
Texture* tex = new Texture(GL_RGBA, GL_RGBA16F, width, height, GL_FLOAT, GL_TEXTURE_RECTANGLE);
|
||||||
|
tex->setFiltering(GL_NEAREST);
|
||||||
|
addTexture(tex, GL_COLOR_ATTACHMENT0);
|
||||||
|
|
||||||
|
initColorAttachments();
|
||||||
|
}
|
||||||
|
|
||||||
|
DeferredPipeline::DeferredPipeline() :
|
||||||
|
m_camera(NULL),
|
||||||
|
m_width(512),
|
||||||
|
m_height(512),
|
||||||
|
m_gBuffer(NULL),
|
||||||
|
m_lightingBuffer(NULL),
|
||||||
|
m_renderTarget(NULL)
|
||||||
|
{
|
||||||
|
Resource::ResourceMap shaderMap;
|
||||||
|
Resource::getResourcePack_shaders(shaderMap);
|
||||||
|
m_gBufferSource = new ShaderSource();
|
||||||
|
m_gBufferSource->setSource(shaderMap["shaders/gbuffer.vert.glsl"], ShaderSource::VERTEX);
|
||||||
|
m_gBufferSource->setSource(shaderMap["shaders/gbuffer.frag.glsl"], ShaderSource::FRAGMENT);
|
||||||
|
m_lightingSource = new ShaderSource();
|
||||||
|
m_lightingSource->setSource(shaderMap["shaders/lighting.vert.glsl"], ShaderSource::VERTEX);
|
||||||
|
m_lightingSource->setSource(shaderMap["shaders/lighting.frag.glsl"], ShaderSource::FRAGMENT);
|
||||||
|
std::string vertSource = shaderMap["shaders/posteffects.vert.glsl"];
|
||||||
|
std::string fragSource = shaderMap["shaders/posteffects.frag.glsl"];
|
||||||
|
m_postEffectsShader = new Shader(vertSource, fragSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeferredPipeline::renderGL(Scene *scene)
|
||||||
|
{
|
||||||
|
if(m_renderTarget == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// GEOMETRY PASS
|
||||||
|
m_gBuffer->bindFBO();
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
glDepthFunc(GL_LESS);
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
glClearColor(0.0f, 0.0f, 0.0f, 1.f);
|
||||||
|
glClearDepth(1.0f);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
// loop on geometry
|
||||||
|
unsigned int id = 2;
|
||||||
|
for(SceneIterator<GeometryNode*>* geometryIt = scene->getGeometry();
|
||||||
|
geometryIt->isValid(); geometryIt->next())
|
||||||
|
{
|
||||||
|
|
||||||
|
GeometryNode* node = geometryIt->getItem();
|
||||||
|
Shader *shader = m_meshShaders[node->mesh->getFlags()];
|
||||||
|
if(shader == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "no shader to render this geometry, please use refreshScene to generate the shader\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
shader->bind();
|
||||||
|
|
||||||
|
shader->bindUnsignedInteger(shader->getLocation("object_identifier"), id);
|
||||||
|
if(node->mesh->instances_offsets.empty())
|
||||||
|
++id;
|
||||||
|
else
|
||||||
|
id += node->mesh->instances_offsets.size();
|
||||||
|
|
||||||
|
glm::mat4 modelViewMatrix = m_camera->getViewMatrix() * node->modelMatrix;
|
||||||
|
glm::mat4 normalMatrix = glm::transpose(glm::inverse(modelViewMatrix));
|
||||||
|
shader->bindMat4(shader->getLocation("projectionMatrix"), m_camera->getProjectionMatrix());
|
||||||
|
shader->bindMat4(shader->getLocation("modelViewMatrix"), modelViewMatrix);
|
||||||
|
shader->bindMat3(shader->getLocation("normalMatrix"), glm::mat3(normalMatrix));
|
||||||
|
// draw geometry
|
||||||
|
node->mesh->draw(shader);
|
||||||
|
}
|
||||||
|
|
||||||
|
// LIGHTING PASS
|
||||||
|
m_lightingBuffer->bindFBO();
|
||||||
|
glDepthFunc(GL_LEQUAL);
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_ONE, GL_ONE);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
m_gBuffer->bindTextures();
|
||||||
|
for(SceneIterator<Light*>* lightIt = scene->getLights();
|
||||||
|
lightIt->isValid(); lightIt->next())
|
||||||
|
{
|
||||||
|
Light* light = lightIt->getItem();
|
||||||
|
Shader *shader = m_lightShaders[light->getFlags()];
|
||||||
|
if(shader == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "no shader to render this light, please use refreshScene to generate the shader\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
shader->bind();
|
||||||
|
|
||||||
|
// bind GBuffer
|
||||||
|
shader->bindInteger(shader->getLocation("normalBuffer"), GBuffer::NORMAL);
|
||||||
|
shader->bindInteger(shader->getLocation("colorBuffer"), GBuffer::DIFFUSE);
|
||||||
|
shader->bindInteger(shader->getLocation("specularBuffer"), GBuffer::SPECULAR);
|
||||||
|
shader->bindInteger(shader->getLocation("positionBuffer"), GBuffer::POSITION);
|
||||||
|
shader->bindInteger(shader->getLocation("depthBuffer"), GBuffer::DEPTH);
|
||||||
|
|
||||||
|
// bind light
|
||||||
|
light->bindAttributes(shader, m_camera);
|
||||||
|
|
||||||
|
// compute fragments
|
||||||
|
SparrowRenderer::drawQuad();
|
||||||
|
}
|
||||||
|
m_gBuffer->unbindTextures();
|
||||||
|
|
||||||
|
// post effects pass
|
||||||
|
m_renderTarget->bindFBO();
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
m_lightingBuffer->getTexture(0)->bind(0);
|
||||||
|
m_postEffectsShader->bind();
|
||||||
|
m_postEffectsShader->bindInteger(m_postEffectsShader->getLocation("lightBuffer"), 0);
|
||||||
|
// TODO : send uniforms
|
||||||
|
SparrowRenderer::drawQuad();
|
||||||
|
m_lightingBuffer->getTexture(0)->unbind();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeferredPipeline::resizeGL(int w, int h)
|
||||||
|
{
|
||||||
|
// updating dimensions
|
||||||
|
m_width = w;
|
||||||
|
m_height = h;
|
||||||
|
|
||||||
|
// rebuilding FrameBuffers
|
||||||
|
if(m_gBuffer != NULL)
|
||||||
|
{
|
||||||
|
delete m_gBuffer;
|
||||||
|
delete m_lightingBuffer;
|
||||||
|
}
|
||||||
|
m_gBuffer = new GBuffer(w, h);
|
||||||
|
m_lightingBuffer = new LightingBuffer(w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSources(ShaderSource *gBufferSource, ShaderSource *lightingSource, Shader *postEffectsShader)
|
||||||
|
{
|
||||||
|
if(m_gBufferSource != NULL)
|
||||||
|
delete m_gBufferSource;
|
||||||
|
m_gBufferSource = gBufferSource;
|
||||||
|
if(m_lightingSource != NULL)
|
||||||
|
delete m_lightingSource;
|
||||||
|
m_lightingSource = lightingSource;
|
||||||
|
if(m_postEffectsShader != NULL)
|
||||||
|
delete m_postEffectsShader;
|
||||||
|
m_postEffectsShader = postEffectsShader;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeferredPipeline::refreshScene(Scene *scene)
|
||||||
|
{
|
||||||
|
for(auto it : m_meshShaders)
|
||||||
|
delete it.second;
|
||||||
|
m_meshShaders.clear();
|
||||||
|
m_meshTypes.clear();
|
||||||
|
scene->getMeshTypes(m_meshTypes);
|
||||||
|
for(unsigned int type : m_meshTypes)
|
||||||
|
m_meshShaders[type] = m_gBufferSource->compile(type, 0);
|
||||||
|
|
||||||
|
for(auto it : m_lightShaders)
|
||||||
|
delete it.second;
|
||||||
|
m_lightShaders.clear();
|
||||||
|
m_lightTypes.clear();
|
||||||
|
scene->getLightTypes(m_lightTypes);
|
||||||
|
for(unsigned int type : m_lightTypes)
|
||||||
|
m_lightShaders[type] = m_lightingSource->compile(0, type);
|
||||||
|
}
|
61
src/deferredpipeline.h
Normal file
61
src/deferredpipeline.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#ifndef DEFERREDPIPELINE_H
|
||||||
|
#define DEFERREDPIPELINE_H
|
||||||
|
|
||||||
|
#include <pipeline.h>
|
||||||
|
#include <framebuffer.h>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
class Shader;
|
||||||
|
class Camera;
|
||||||
|
|
||||||
|
class GBuffer : public FrameBuffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Buffers { NORMAL, DIFFUSE, SPECULAR, POSITION, DEPTH, NB_BUFFERS };
|
||||||
|
GBuffer(int width, int height);
|
||||||
|
void bindTextures();
|
||||||
|
void unbindTextures();
|
||||||
|
};
|
||||||
|
|
||||||
|
class LightingBuffer : public FrameBuffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LightingBuffer(int width, int height);
|
||||||
|
};
|
||||||
|
|
||||||
|
class DeferredPipeline : public Pipeline
|
||||||
|
{
|
||||||
|
Camera *m_camera;
|
||||||
|
|
||||||
|
int m_width;
|
||||||
|
int m_height;
|
||||||
|
|
||||||
|
// shaders
|
||||||
|
std::vector<unsigned int> m_meshTypes;
|
||||||
|
std::vector<unsigned int> m_lightTypes;
|
||||||
|
|
||||||
|
std::unordered_map<unsigned int, Shader*> m_meshShaders;
|
||||||
|
std::unordered_map<unsigned int, Shader*> m_lightShaders;
|
||||||
|
|
||||||
|
ShaderSource *m_gBufferSource;
|
||||||
|
ShaderSource *m_lightingSource;
|
||||||
|
Shader *m_postEffectsShader;
|
||||||
|
|
||||||
|
// framebuffers
|
||||||
|
GBuffer *m_gBuffer;
|
||||||
|
LightingBuffer *m_lightingBuffer;
|
||||||
|
const FrameBuffer *m_renderTarget;
|
||||||
|
|
||||||
|
public:
|
||||||
|
DeferredPipeline();
|
||||||
|
|
||||||
|
void setCamera(Camera *camera) { m_camera = camera; }
|
||||||
|
void setSources(ShaderSource *gBufferSource, ShaderSource *lightingSource, Shader *postEffectsShader);
|
||||||
|
void setRenderTarget(const FrameBuffer *fbo) { m_renderTarget = fbo; }
|
||||||
|
void refreshScene(Scene *scene);
|
||||||
|
|
||||||
|
virtual void renderGL(Scene *scene);
|
||||||
|
virtual void resizeGL(int w, int h);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DEFERREDPIPELINE_H
|
Loading…
x
Reference in New Issue
Block a user