SparrowRenderer/light.cpp

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";