132 lines
3.6 KiB
C++
132 lines
3.6 KiB
C++
#include "light.h"
|
|
#include "framebuffer.h"
|
|
#include "texture.h"
|
|
#include "scene.h"
|
|
#include "shader.h"
|
|
#include "shadersource.h"
|
|
#include "phongmaterial.h"
|
|
#include "mesh.h"
|
|
#include "glassert.h"
|
|
#include <glm/ext.hpp>
|
|
|
|
Light::Light()
|
|
{
|
|
initPointLight();
|
|
}
|
|
|
|
void Light::initDirectionnalLight(glm::vec3 dir, glm::vec3 lightColor)
|
|
{
|
|
direction = dir;
|
|
color = lightColor;
|
|
shadowCaster = false;
|
|
isDir = true;
|
|
}
|
|
|
|
void Light::initPointLight(glm::vec3 pos, glm::vec3 lightColor)
|
|
{
|
|
position = pos;
|
|
angle = 360;
|
|
color = lightColor;
|
|
shadowCaster = false;
|
|
isDir = false;
|
|
}
|
|
/*
|
|
void Light::initSpotLight(glm::vec3 pos, glm::vec3 dir, float spotAngle, glm::vec3 lightColor)
|
|
{
|
|
position = pos;
|
|
direction = dir;
|
|
angle = spotAngle;
|
|
color = lightColor;
|
|
shadowCaster = false;
|
|
isDir = false;
|
|
}
|
|
*/
|
|
bool Light::isDirectionnal()
|
|
{
|
|
return isDir;
|
|
}
|
|
|
|
void Light::initShadowMap(int resWidth, int resHeight)
|
|
{
|
|
shadowCaster = true;
|
|
shadowMap = new FrameBuffer();
|
|
// Depth buffer
|
|
Texture* tex = new Texture(GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, resWidth, resHeight, GL_FLOAT);
|
|
tex->setFiltering(GL_NEAREST);
|
|
shadowMap->addTexture(tex, GL_DEPTH_ATTACHMENT);
|
|
shadowMap->initGL();
|
|
|
|
ShaderSource source;
|
|
source.setSource(vertSource, ShaderSource::VERTEX);
|
|
source.setSource(fragSource, ShaderSource::FRAGMENT);
|
|
std::vector<const char*> defines;
|
|
shaders[0] = source.compile(defines.size(), defines.data());
|
|
defines.push_back("ALPHA_MASK");
|
|
shaders[1] = source.compile(defines.size(), defines.data());
|
|
}
|
|
|
|
void Light::generateShadowMap(Scene* scene)
|
|
{
|
|
glm::mat4 viewMatrix = glm::lookAt(position, position+direction, glm::vec3(0, 1, 0));
|
|
|
|
shadowMap->bindFBO();
|
|
glAssert(glEnable(GL_DEPTH_TEST));
|
|
for(SceneIterator<PhongEntity*>* entityIt = scene->getGeometry();
|
|
entityIt->isValid(); entityIt->next())
|
|
{
|
|
// compute matrix attributes
|
|
PhongEntity* entity = entityIt->getItem();
|
|
glm::mat4 modelViewMatrix = viewMatrix * entity->modelMatrix;
|
|
glm::mat4 mvp = /*myCamera->getProjectionMatrix() * */modelViewMatrix;
|
|
// loop over material groups
|
|
for(int j=0; j<entity->getMesh()->indiceGroups.size(); ++j)
|
|
{
|
|
Material* mat = entity->getMesh()->indiceGroups[j].material;
|
|
if(mat->getFlags() & ALPHA_MASK)
|
|
{
|
|
PhongMaterial* pmat = (PhongMaterial*)mat;
|
|
shaders[1]->bind();
|
|
pmat->alpha_mask->bind(ALPHA_MASK);
|
|
shaders[1]->bindInteger(shaders[1]->getLocation("alphaMask"), ALPHA_MASK);
|
|
entity->drawGroup(j, false, true, false);
|
|
}
|
|
else
|
|
{
|
|
entity->drawGroup(j, false, false, false);
|
|
shaders[0]->bind();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Texture* Light::getShadowMap()
|
|
{
|
|
return shadowMap->getTexture(0);
|
|
}
|
|
|
|
const char* Light::vertSource =
|
|
"#version 330 core\n\
|
|
layout(location = 0)in vec3 inPosition;\n\
|
|
out vec3 varTexCoord;\n\
|
|
uniform mat4 MVP;\n\
|
|
void main()\n\
|
|
{\n\
|
|
gl_Position = MVP * vec4(inPosition, 1.0);\n\
|
|
}\n";
|
|
|
|
const char* Light::fragSource =
|
|
"#version 330 core\n\
|
|
#ifdef ALPHA_MASK\n\
|
|
uniform sampler2D alphaMask;\n\
|
|
#endif\n\
|
|
in vec3 varTexCoord;\n\
|
|
out float fragmentdepth;\n\
|
|
void main()\n\
|
|
{\n\
|
|
#ifdef ALPHA_MASK\n\
|
|
if(texture(alphaMask, varTexCoord).r < 0.5)\n\
|
|
discard;\n\
|
|
#endif\n\
|
|
fragmentdepth = gl_FragCoord.z;\n\
|
|
}\n";
|