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