implemented most of shadowmaps code in the shaders and in forwardmodule.cpp
This commit is contained in:
parent
a7d4391898
commit
c455d31948
@ -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()
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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()));
|
||||||
|
@ -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);
|
||||||
|
55
light.cpp
55
light.cpp
@ -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
66
light.h
@ -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
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user