implemented most of shadowmaps code in the shaders and in forwardmodule.cpp

This commit is contained in:
Anselme 2015-12-13 17:10:44 +01:00
parent a7d4391898
commit c455d31948
11 changed files with 261 additions and 116 deletions

View File

@ -25,7 +25,7 @@ GBuffer::GBuffer(int width, int height) : FrameBuffer()
tex->setFiltering(GL_NEAREST); tex->setFiltering(GL_NEAREST);
addTexture(tex, GL_DEPTH_ATTACHMENT); addTexture(tex, GL_DEPTH_ATTACHMENT);
initGL(); initColorAttachments();
} }
GBuffer::~GBuffer() GBuffer::~GBuffer()

View File

@ -35,6 +35,11 @@ in mat3 tangentSpace;
in vec3 varNormal; in vec3 varNormal;
#endif #endif
#ifdef SHADOWMAP
uniform sampler2D shadowMap;
in vec4 posInLightSpace;
#endif
in vec2 varTexCoord; in vec2 varTexCoord;
in vec3 lightDirInView; in vec3 lightDirInView;
@ -48,6 +53,11 @@ vec3 phongLighting(in vec3 kd, in vec3 ks, in float ns, in vec3 color, in vec3 n
return color*diffuseComponent*(kd+ks*pow(specularComponent, ns)); return color*diffuseComponent*(kd+ks*pow(specularComponent, ns));
} }
float computeShadow(sampler2D shadowmap, vec3 shadow){
float lightFragDepth = texture(shadowmap, shadow.xy).r;
return lightFragDepth < shadow.z ? 0 : 1;
}
void main(void) { void main(void) {
#ifdef ALPHA_MASK #ifdef ALPHA_MASK
if(texture(alphaMask, varTexCoord).r < 0.5) if(texture(alphaMask, varTexCoord).r < 0.5)
@ -56,6 +66,7 @@ void main(void) {
#ifdef NORMAL_MAP #ifdef NORMAL_MAP
vec3 normal = normalize(texture(normalMap, varTexCoord).xyz * tangentSpace); vec3 normal = normalize(texture(normalMap, varTexCoord).xyz * tangentSpace);
normal = normalize(vec3(0, 0, 1) * tangentSpace);
#else #else
vec3 normal = normalize(varNormal); vec3 normal = normalize(varNormal);
#endif #endif
@ -78,10 +89,16 @@ void main(void) {
vec3 specular = materialKs; vec3 specular = materialKs;
#endif #endif
#ifdef SHADOWMAP
float shadow = computeShadow(shadowMap, posInLightSpace.xyz/posInLightSpace.w);
#else
float shadow = 1;
#endif
#ifdef AMBIENT_LIGHT #ifdef AMBIENT_LIGHT
outColor = vec4(0, 0, 0, 1); outColor = vec4(0, 0, 0, 1);
#else #else
vec3 light = phongLighting(diffuse, specular, materialNs, lightColor, normal, lightDirInView, halfVecInView); vec3 light = phongLighting(diffuse, specular, materialNs, lightColor, normal, lightDirInView, halfVecInView);
outColor = vec4(light, 1); outColor = vec4(shadow*light, 1);
#endif #endif
} }

View File

@ -34,6 +34,11 @@ out vec3 lightDirInView;
out vec3 halfVecInView; out vec3 halfVecInView;
#endif #endif
#ifdef SHADOWMAP
uniform mat4 lightMVP;
out vec4 posInLightSpace;
#endif
void main(void) { void main(void) {
vec3 posInView = vec3(modelViewMatrix*vec4(inPosition, 1.0)); vec3 posInView = vec3(modelViewMatrix*vec4(inPosition, 1.0));
@ -42,6 +47,10 @@ void main(void) {
halfVecInView = normalize(lightDirInView - normalize(posInView)); halfVecInView = normalize(lightDirInView - normalize(posInView));
#endif #endif
#ifdef SHADOWMAP
posInLightSpace = lightMVP * vec4(inPosition, 1.0);
#endif
#ifdef POINT_LIGHT #ifdef POINT_LIGHT
vec4 lightPosInView = viewMatrix*vec4(pointLight, 1); vec4 lightPosInView = viewMatrix*vec4(pointLight, 1);
lightDirInView = normalize(lightPosInView.xyz - posInView); lightDirInView = normalize(lightPosInView.xyz - posInView);

View File

@ -5,6 +5,7 @@
#include "shader.h" #include "shader.h"
#include "light.h" #include "light.h"
#include "glassert.h" #include "glassert.h"
#include "texture.h"
#include <glm/ext.hpp> #include <glm/ext.hpp>
const char* const ForwardModule::flagStr[] = const char* const ForwardModule::flagStr[] =
@ -16,13 +17,6 @@ const char* const ForwardModule::flagStr[] =
"ALPHA_MASK" "ALPHA_MASK"
}; };
const char* const ForwardModule::lightStr[] =
{
"AMBIENT_LIGHT",
"DIRECTIONNAL_LIGHT",
"POINT_LIGHT"
};
void ForwardModule::renderGL(Camera* myCamera, Scene* scene) void ForwardModule::renderGL(Camera* myCamera, Scene* scene)
{ {
// bind target // bind target
@ -32,7 +26,7 @@ void ForwardModule::renderGL(Camera* myCamera, Scene* scene)
glAssert(glDepthFunc(GL_LESS)); glAssert(glDepthFunc(GL_LESS));
glAssert(glDisable(GL_BLEND)); glAssert(glDisable(GL_BLEND));
lightPass(myCamera, scene, NULL, AMBIENT_LIGHT); lightPass(myCamera, scene, NULL);
// render directionnal lighting and point lighting // render directionnal lighting and point lighting
glAssert(glDepthFunc(GL_LEQUAL)); glAssert(glDepthFunc(GL_LEQUAL));
@ -40,38 +34,56 @@ void ForwardModule::renderGL(Camera* myCamera, Scene* scene)
glAssert(glBlendFunc(GL_ONE, GL_ONE)); glAssert(glBlendFunc(GL_ONE, GL_ONE));
glAssert(glDepthMask(GL_FALSE)); glAssert(glDepthMask(GL_FALSE));
for(SceneIterator<Light*>* lightIt = scene->getLights(); for(SceneIterator<Light*>* lightIt = scene->getLights(); lightIt->isValid(); lightIt->next())
lightIt->isValid(); lightIt->next()) lightPass(myCamera, scene, lightIt->getItem());
{
Light* l = lightIt->getItem();
unsigned int type = l->isDirectionnal() ? DIRECTIONNAL_LIGHT : POINT_LIGHT;
lightPass(myCamera, scene, l, type);
}
glAssert(glDisable(GL_BLEND)); glAssert(glDisable(GL_BLEND));
glAssert(glDepthFunc(GL_LESS)); glAssert(glDepthFunc(GL_LESS));
glAssert(glDepthMask(GL_TRUE)); glAssert(glDepthMask(GL_TRUE));
} }
void ForwardModule::lightPass(Camera* myCamera, Scene* scene, Light* light, unsigned int type) void ForwardModule::lightPass(Camera* myCamera, Scene* scene, Light* light)
{ {
// loop over all types of geometry // loop over all types of geometry
for(int i=0; i<flags.size(); ++i) for(int i=0; i<geometryFlagList.size(); ++i)
{ {
// bind shader int j;
Shader* shader = shaders[i*NB_LIGHT_FLAGS + type]; for(j=0; j<lightFlagList.size(); ++j)
if(lightFlagList[j] == Light::getFlags(light))
break;
Shader* shader = shaders[i*lightFlagList.size() + j];
shader->bind(); shader->bind();
// bind light attributes // bind light attributes
if(type == DIRECTIONNAL_LIGHT) if(light == NULL)
shader->bindVec3(shader->getLocation("dirLight"), light->getDir()); {
if(type == POINT_LIGHT) // ambient light
shader->bindVec3(shader->getLocation("pointLight"), light->getPos()); shader->bindVec3(shader->getLocation("lightColor"), glm::vec3(0.1f)); // add attribute, and setter for ambient lighting
glm::vec3 color; }
if(type == AMBIENT_LIGHT)
color = glm::vec3(0.1f); // add attribute, and setter for ambient lighting
else else
color = light->getColor(); {
shader->bindVec3(shader->getLocation("lightColor"), color); switch(light->getType())
{
case Light::DIRECTIONNAL:
shader->bindVec3(shader->getLocation("dirLight"), light->getDir());
shader->bindVec3(shader->getLocation("lightColor"), light->getColor());
if(light->isShadowCaster())
{
light->getShadowMap()->bind(NB_FLAGS); // NB_FLAGS has the value of the first available slot after the phong material texture slots
shader->bindInteger(shader->getLocation("shadowMap"), NB_FLAGS);
}
break;
case Light::POINT:
shader->bindVec3(shader->getLocation("pointLight"), light->getPos());
shader->bindVec3(shader->getLocation("lightColor"), light->getColor());
// TODO add attenuation
break;
case Light::SPOT:
shader->bindVec3(shader->getLocation("lightColor"), light->getColor());
// TODO add cutoff and attenuation
break;
}
}
for(SceneIterator<PhongEntity*>* entityIt = scene->getGeometry(); for(SceneIterator<PhongEntity*>* entityIt = scene->getGeometry();
entityIt->isValid(); entityIt->next()) entityIt->isValid(); entityIt->next())
{ {
@ -80,18 +92,23 @@ void ForwardModule::lightPass(Camera* myCamera, Scene* scene, Light* light, unsi
glm::mat4 modelViewMatrix = myCamera->getViewMatrix() * entity->modelMatrix; glm::mat4 modelViewMatrix = myCamera->getViewMatrix() * entity->modelMatrix;
glm::mat4 mvp = myCamera->getProjectionMatrix() * modelViewMatrix; glm::mat4 mvp = myCamera->getProjectionMatrix() * modelViewMatrix;
glm::mat4 normalMatrix = glm::transpose(glm::inverse(modelViewMatrix)); glm::mat4 normalMatrix = glm::transpose(glm::inverse(modelViewMatrix));
if(light != NULL && light->isShadowCaster())
{
glm::mat4 lightMVP = light->getProjectionMatrix() * (light->getViewMatrix() * entity->modelMatrix);
shader->bindMat4(shader->getLocation("lightMVP"), lightMVP);
}
shader->bindMat4(shader->getLocation("viewMatrix"), myCamera->getViewMatrix());
shader->bindMat4(shader->getLocation("modelViewMatrix"), modelViewMatrix);
shader->bindMat3(shader->getLocation("normalMatrix"), glm::mat3(normalMatrix));
shader->bindMat4(shader->getLocation("MVP"), mvp);
// loop over material groups // loop over material groups
for(int j=0; j<entity->getMesh()->indiceGroups.size(); ++j) for(int j=0; j<entity->getMesh()->indiceGroups.size(); ++j)
{ {
Material* mat = entity->getMesh()->indiceGroups[j].material; Material* mat = entity->getMesh()->indiceGroups[j].material;
if(mat->getFlags() == flags[i]) if(mat->getFlags() == geometryFlagList[i])
{ {
// bind material attributes // bind material attributes
mat->bindAttributes(shader); mat->bindAttributes(shader);
shader->bindMat4(shader->getLocation("viewMatrix"), myCamera->getViewMatrix());
shader->bindMat4(shader->getLocation("modelViewMatrix"), modelViewMatrix);
shader->bindMat3(shader->getLocation("normalMatrix"), glm::mat3(normalMatrix));
shader->bindMat4(shader->getLocation("MVP"), mvp);
// draw geometry // draw geometry
entity->drawGroup(j); entity->drawGroup(j);
} }
@ -111,17 +128,18 @@ void ForwardModule::setShaderSource(ShaderSource* source)
void ForwardModule::compileShaders(Scene* scene) void ForwardModule::compileShaders(Scene* scene)
{ {
flags.clear(); geometryFlagList.clear();
lightFlagList.clear();
for(Shader* s : shaders) for(Shader* s : shaders)
delete(s); delete(s);
shaders.clear(); shaders.clear();
int size = 1 << NB_FLAGS; // get material flags
bool geometryFlags[size]; const int nb_geometry_flags = 1 << NB_FLAGS;
for(int i=0; i<size; ++i) bool geometryFlags[nb_geometry_flags];
for(int i=0; i<nb_geometry_flags; ++i)
geometryFlags[i] = false; geometryFlags[i] = false;
// get material flags
for(SceneIterator<PhongEntity*>* entityIt = scene->getGeometry(); for(SceneIterator<PhongEntity*>* entityIt = scene->getGeometry();
entityIt->isValid(); entityIt->next()) entityIt->isValid(); entityIt->next())
{ {
@ -129,36 +147,62 @@ void ForwardModule::compileShaders(Scene* scene)
for(Mesh::Group &g : m->indiceGroups) for(Mesh::Group &g : m->indiceGroups)
geometryFlags[g.material->getFlags()] = true; geometryFlags[g.material->getFlags()] = true;
} }
for(int i=0; i<nb_geometry_flags; ++i)
// shader compilation
for(int i=0; i<size; ++i)
{ {
if(geometryFlags[i]) if(geometryFlags[i])
geometryFlagList.push_back(i);
}
// get light flags
const int nb_light_flags = 1 << Light::NB_LIGHT_FLAGS;
bool lightFlags[nb_light_flags];
for(int i=0; i<nb_light_flags; ++i)
lightFlags[i] = false;
// ambient light
lightFlags[Light::getFlags(NULL)] = true;
// scene lights
for(SceneIterator<Light*>* lightIt = scene->getLights();
lightIt->isValid(); lightIt->next())
{
Light* l = lightIt->getItem();
lightFlags[Light::getFlags(l)] = true;
}
for(int i=0; i<nb_light_flags; ++i)
{
if(lightFlags[i])
lightFlagList.push_back(i);
}
// shader compilation
for(int i : geometryFlagList)
{
std::vector<const char*> defines;
// set geometry defines
if(i & NORMAL_MAP_FLAG)
defines.push_back(flagStr[NORMAL_MAP]);
if(i & AMBIENT_TEXTURE_FLAG)
defines.push_back(flagStr[AMBIENT_TEXTURE]);
if(i & DIFFUSE_TEXTURE_FLAG)
defines.push_back(flagStr[DIFFUSE_TEXTURE]);
if(i & SPECULAR_TEXTURE_FLAG)
defines.push_back(flagStr[SPECULAR_TEXTURE]);
if(i & ALPHA_MASK_FLAG)
defines.push_back(flagStr[ALPHA_MASK]);
int boundary = defines.size();
for(int j : lightFlagList)
{ {
std::vector<const char*> defines; while(defines.size() > boundary)
defines.push_back(lightStr[AMBIENT_LIGHT]); defines.pop_back();
// set light defines
// set defines for(int k=0; k<Light::NB_LIGHT_FLAGS; ++k)
if(i & NORMAL_MAP_FLAG) {
defines.push_back(flagStr[NORMAL_MAP]); if(j & (1 << k))
if(i & AMBIENT_TEXTURE_FLAG) defines.push_back(Light::flagStr[k]);
defines.push_back(flagStr[AMBIENT_TEXTURE]); }
if(i & DIFFUSE_TEXTURE_FLAG) // compilation
defines.push_back(flagStr[DIFFUSE_TEXTURE]);
if(i & SPECULAR_TEXTURE_FLAG)
defines.push_back(flagStr[SPECULAR_TEXTURE]);
if(i & ALPHA_MASK_FLAG)
defines.push_back(flagStr[ALPHA_MASK]);
// for each geometry flag, 3 shaders are compiled, one for each kind of lighting
flags.push_back(i);
// ambient
shaders.push_back(shaderSources->compile(defines.size(), defines.data()));
// directionnal
defines[0] = lightStr[DIRECTIONNAL_LIGHT];
shaders.push_back(shaderSources->compile(defines.size(), defines.data()));
// point
defines[0] = lightStr[POINT_LIGHT];
shaders.push_back(shaderSources->compile(defines.size(), defines.data())); shaders.push_back(shaderSources->compile(defines.size(), defines.data()));
} }
} }

View File

@ -32,24 +32,15 @@ public:
void setRenderTarget(FrameBuffer* target); void setRenderTarget(FrameBuffer* target);
private: private:
enum {
// light flags
AMBIENT_LIGHT,
DIRECTIONNAL_LIGHT,
POINT_LIGHT,
// count
NB_LIGHT_FLAGS
};
static const char* const flagStr[NB_FLAGS]; static const char* const flagStr[NB_FLAGS];
static const char* const lightStr[NB_LIGHT_FLAGS];
ShaderSource* shaderSources; ShaderSource* shaderSources;
std::vector<Shader*> shaders; std::vector<Shader*> shaders;
std::vector<unsigned int> flags; std::vector<unsigned int> geometryFlagList;
std::vector<unsigned int> lightFlagList;
const FrameBuffer* renderTarget; const FrameBuffer* renderTarget;
void lightPass(Camera* myCamera, Scene* scene, Light* light, unsigned int type); void lightPass(Camera* myCamera, Scene* scene, Light* light);
}; };
#endif // FORWARDMODULE_H #endif // FORWARDMODULE_H

View File

@ -22,13 +22,14 @@ void FrameBuffer::addTexture(Texture* tex, GLenum attachment)
textures.push_back(tex); textures.push_back(tex);
bindFBO(); bindFBO();
glAssert(glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, tex->getTarget(), tex->getId(), 0)); glAssert(glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, tex->getTarget(), tex->getId(), 0));
attachments.push_back(attachment); if(attachment != GL_DEPTH_ATTACHMENT)
attachments.push_back(attachment);
} }
} }
void FrameBuffer::initGL() void FrameBuffer::initColorAttachments()
{ {
if(fbo != 0) if(fbo != 0 && attachments.size() != 0)
{ {
bindFBO(); bindFBO();
glAssert(glDrawBuffers(attachments.size(), attachments.data())); glAssert(glDrawBuffers(attachments.size(), attachments.data()));

View File

@ -20,7 +20,7 @@ public:
FrameBuffer(); FrameBuffer();
~FrameBuffer(); ~FrameBuffer();
void addTexture(Texture* tex, GLenum attachment); void addTexture(Texture* tex, GLenum attachment);
void initGL(); void initColorAttachments();
void bindFBO() const; void bindFBO() const;
Texture* getTexture(int texId); Texture* getTexture(int texId);

View File

@ -9,6 +9,14 @@
#include "glassert.h" #include "glassert.h"
#include <glm/ext.hpp> #include <glm/ext.hpp>
const char* Light::flagStr[] = {
"AMBIENT_LIGHT",
"DIRECTIONNAL_LIGHT",
"POINT_LIGHT",
"SPOT_LIGHT",
"SHADOWMAP"
};
Light::Light() Light::Light()
{ {
initPointLight(); initPointLight();
@ -16,37 +24,43 @@ Light::Light()
void Light::initDirectionnalLight(glm::vec3 dir, glm::vec3 lightColor) void Light::initDirectionnalLight(glm::vec3 dir, glm::vec3 lightColor)
{ {
type = DIRECTIONNAL;
position = glm::vec3(0);
direction = dir; direction = dir;
color = lightColor; color = lightColor;
shadowCaster = false; shadowCaster = false;
isDir = true; isDir = true;
viewMatrix = glm::lookAt(position, position+direction, glm::vec3(0, 1, 0));
} }
void Light::initPointLight(glm::vec3 pos, glm::vec3 lightColor) void Light::initPointLight(glm::vec3 pos, glm::vec3 lightColor)
{ {
type = POINT;
position = pos; position = pos;
angle = 360; cutOffAngle = 360;
color = lightColor; color = lightColor;
shadowCaster = false; shadowCaster = false;
isDir = false; isDir = false;
viewMatrix = glm::mat4();
} }
/*
void Light::initSpotLight(glm::vec3 pos, glm::vec3 dir, float spotAngle, glm::vec3 lightColor) void Light::initSpotLight(glm::vec3 pos, glm::vec3 dir, float spotAngle, glm::vec3 lightColor)
{ {
type = SPOT;
position = pos; position = pos;
direction = dir; direction = dir;
angle = spotAngle; cutOffAngle = spotAngle;
color = lightColor; color = lightColor;
shadowCaster = false; shadowCaster = false;
isDir = false; isDir = false;
} }
*/
bool Light::isDirectionnal() bool Light::isDirectionnal()
{ {
return isDir; return isDir;
} }
void Light::initShadowMap(int resWidth, int resHeight) void Light::initShadowMap(int resWidth, int resHeight, glm::vec3 dim)
{ {
shadowCaster = true; shadowCaster = true;
shadowMap = new FrameBuffer(); shadowMap = new FrameBuffer();
@ -54,7 +68,7 @@ void Light::initShadowMap(int resWidth, int resHeight)
Texture* tex = new Texture(GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, resWidth, resHeight, GL_FLOAT); Texture* tex = new Texture(GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, resWidth, resHeight, GL_FLOAT);
tex->setFiltering(GL_NEAREST); tex->setFiltering(GL_NEAREST);
shadowMap->addTexture(tex, GL_DEPTH_ATTACHMENT); shadowMap->addTexture(tex, GL_DEPTH_ATTACHMENT);
shadowMap->initGL(); shadowMap->initColorAttachments();
ShaderSource source; ShaderSource source;
source.setSource(vertSource, ShaderSource::VERTEX); source.setSource(vertSource, ShaderSource::VERTEX);
@ -67,7 +81,7 @@ void Light::initShadowMap(int resWidth, int resHeight)
void Light::generateShadowMap(Scene* scene) void Light::generateShadowMap(Scene* scene)
{ {
glm::mat4 viewMatrix = glm::lookAt(position, position+direction, glm::vec3(0, 1, 0)); viewMatrix = glm::lookAt(position, position+direction, glm::vec3(0, 1, 0));
shadowMap->bindFBO(); shadowMap->bindFBO();
glAssert(glEnable(GL_DEPTH_TEST)); glAssert(glEnable(GL_DEPTH_TEST));
@ -77,7 +91,7 @@ void Light::generateShadowMap(Scene* scene)
// compute matrix attributes // compute matrix attributes
PhongEntity* entity = entityIt->getItem(); PhongEntity* entity = entityIt->getItem();
glm::mat4 modelViewMatrix = viewMatrix * entity->modelMatrix; glm::mat4 modelViewMatrix = viewMatrix * entity->modelMatrix;
glm::mat4 mvp = /*myCamera->getProjectionMatrix() * */modelViewMatrix; glm::mat4 mvp = projectionMatrix * modelViewMatrix;
// loop over material groups // loop over material groups
for(int j=0; j<entity->getMesh()->indiceGroups.size(); ++j) for(int j=0; j<entity->getMesh()->indiceGroups.size(); ++j)
{ {
@ -104,6 +118,31 @@ Texture* Light::getShadowMap()
return shadowMap->getTexture(0); return shadowMap->getTexture(0);
} }
unsigned int Light::getFlags(Light* l)
{
if(l == NULL)
return 1 << AMBIENT_FLAG;
else
{
unsigned int flags = 0;
switch(l->getType())
{
case DIRECTIONNAL :
flags |= 1 << DIRECTIONNAL_FLAG;
break;
case POINT :
flags |= 1 << POINT_FLAG;
break;
case SPOT :
flags |= 1 << SPOT_FLAG;
break;
}
if(l->isShadowCaster())
flags |= 1 << SHADOWMAP_FLAG;
return flags;
}
}
const char* Light::vertSource = const char* Light::vertSource =
"#version 330 core\n\ "#version 330 core\n\
layout(location = 0)in vec3 inPosition;\n\ layout(location = 0)in vec3 inPosition;\n\

66
light.h
View File

@ -2,20 +2,65 @@
#define LIGHT_H #define LIGHT_H
#include <glm/vec3.hpp> #include <glm/vec3.hpp>
#include <glm/mat4x4.hpp>
#include <string> #include <string>
#include "camera.h"
class FrameBuffer; class FrameBuffer;
class Shader; class Shader;
class Scene; class Scene;
class Texture; class Texture;
class Light class Light : public Camera
{ {
public:
enum LightType {
DIRECTIONNAL,
POINT,
SPOT
};
enum LightFlags {
AMBIENT_FLAG,
DIRECTIONNAL_FLAG,
POINT_FLAG,
SPOT_FLAG,
SHADOWMAP_FLAG,
NB_LIGHT_FLAGS
};
static const char* flagStr[];
Light();
void initDirectionnalLight(glm::vec3 dir = glm::vec3(1, 0, 0), glm::vec3 lightColor = glm::vec3(1));
void initPointLight(glm::vec3 pos = glm::vec3(0), glm::vec3 lightColor = glm::vec3(1));
void initSpotLight(glm::vec3 pos = glm::vec3(0), glm::vec3 dir = glm::vec3(1, 0, 0), float spotAngle = 360, glm::vec3 lightColor = glm::vec3(1));
bool isDirectionnal();
LightType getType() {return type;}
glm::vec3 getDir() {return direction;}
glm::vec3 getPos() {return position;}
glm::vec3 getColor() {return color;}
bool isShadowCaster() {return shadowCaster;}
void initShadowMap(int resWidth, int resHeight);
void generateShadowMap(Scene* scene);
Texture* getShadowMap();
// camera inheritance
virtual glm::mat4 getProjectionMatrix() {return projectionMatrix;}
virtual glm::mat4 getViewMatrix() {return viewMatrix;}
// does nothing, just required for inheriting Camera
virtual void resize(int width, int height) {}
static unsigned int getFlags(Light* l);
private: private:
// standard attributes // standard attributes
LightType type;
glm::vec3 position; glm::vec3 position;
glm::vec3 direction; glm::vec3 direction;
float angle; // spotlight not supported yet float cutOffAngle;
float attenuation;
glm::vec3 color; glm::vec3 color;
bool isDir; bool isDir;
@ -24,23 +69,10 @@ private:
bool shadowCaster; bool shadowCaster;
FrameBuffer* shadowMap; FrameBuffer* shadowMap;
Shader* shaders[2]; Shader* shaders[2];
glm::mat4 viewMatrix;
glm::mat4 projectionMatrix;
static const char* vertSource; static const char* vertSource;
static const char* fragSource; static const char* fragSource;
public:
Light();
void initDirectionnalLight(glm::vec3 dir = glm::vec3(1, 0, 0), glm::vec3 lightColor = glm::vec3(1));
void initPointLight(glm::vec3 pos = glm::vec3(0), glm::vec3 lightColor = glm::vec3(1));
// spotlight not supported yet
//void initSpotLight(glm::vec3 pos = glm::vec3(0), glm::vec3 dir = glm::vec3(1, 0, 0), float spotAngle = 360, glm::vec3 lightColor = glm::vec3(1));
bool isDirectionnal();
glm::vec3 getDir() {return direction;}
glm::vec3 getPos() {return position;}
glm::vec3 getColor() {return color;}
void initShadowMap(int resWidth, int resHeight);
void generateShadowMap(Scene* scene);
Texture* getShadowMap();
}; };
#endif // LIGHT_H #endif // LIGHT_H

View File

@ -27,7 +27,7 @@ PostEffectModule::PostEffectModule(int width, int height)
tex->setFiltering(GL_NEAREST); tex->setFiltering(GL_NEAREST);
inputFBO->addTexture(tex, GL_DEPTH_ATTACHMENT); inputFBO->addTexture(tex, GL_DEPTH_ATTACHMENT);
inputFBO->initGL(); inputFBO->initColorAttachments();
outputFBO = FrameBuffer::screen; outputFBO = FrameBuffer::screen;

View File

@ -1,5 +1,6 @@
#include "shadersource.h" #include "shadersource.h"
#include <string> #include <string>
#include <vector>
#include <sstream> #include <sstream>
#include "shader.h" #include "shader.h"
@ -58,23 +59,34 @@ std::string ShaderSource::preprocess(std::string source, int nbDefines, const ch
std::string compiled = ""; std::string compiled = "";
std::istringstream ss(source); std::istringstream ss(source);
std::string line; std::string line;
bool allowed = true; std::vector<bool> allowedStack;
while (std::getline(ss, line)) { while (std::getline(ss, line)) {
if(line.size() > 0 && line.at(0) == '#') if(line.size() > 0 && line.at(0) == '#')
{ {
if(line.compare(0, 8, "#version") == 0) if(line.compare(0, 8, "#version") == 0)
compiled.append(line+'\n'); compiled.append(line+'\n');
else if(line.compare(0, 7, "#ifdef ") == 0) else if(line.compare(0, 7, "#ifdef ") == 0)
allowed = isDefined(line.substr(7), nbDefines, defines); allowedStack.push_back(isDefined(line.substr(7), nbDefines, defines));
else if(line.compare(0, 8, "#ifndef ") == 0) else if(line.compare(0, 8, "#ifndef ") == 0)
allowed = !isDefined(line.substr(8), nbDefines, defines); allowedStack.push_back(!isDefined(line.substr(8), nbDefines, defines));
else if(line.compare("#endif") == 0) else if(line.compare("#endif") == 0)
allowed = true; allowedStack.pop_back();
else if(line.compare("#else") == 0) else if(line.compare("#else") == 0)
allowed = !allowed; allowedStack.back() = !allowedStack.back();
}
else
{
bool ok = true;
for(bool allowed : allowedStack)
{
if(!allowed)
{
ok = false; break;
}
}
if(ok)
compiled.append(line+'\n');
} }
else if(allowed)
compiled.append(line+'\n');
} }
return compiled; return compiled;
} }