502 lines
18 KiB
C++
502 lines
18 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 "camera.h"
|
|
#include <resource.h>
|
|
#include <glm/ext.hpp>
|
|
|
|
RESOURCE_PACK(shaders)
|
|
|
|
const char* Light::flagStr[] = {
|
|
"AMBIENT_LIGHT",
|
|
"DIRECTIONNAL_LIGHT",
|
|
"POINT_LIGHT",
|
|
"SPOT_LIGHT",
|
|
"SHADOWMAP",
|
|
"CASCADED"
|
|
};
|
|
|
|
const glm::mat4 Light::biasMatrix(
|
|
0.5, 0.0, 0.0, 0.0,
|
|
0.0, 0.5, 0.0, 0.0,
|
|
0.0, 0.0, 0.5, 0.0,
|
|
0.5, 0.5, 0.5, 1.0);
|
|
|
|
void AmbientLight::bindAttributes(Shader *shader, Camera *camera)
|
|
{
|
|
shader->bindVec3(shader->getLocation("lightColor"), m_color);
|
|
}
|
|
|
|
// DIRECTIONNAL LIGHT
|
|
|
|
int DirectionnalLight::m_shaderRefCounter = 0;
|
|
Shader* DirectionnalLight::m_shaders[4] = {NULL};
|
|
|
|
DirectionnalLight::DirectionnalLight(glm::vec3 dir, glm::vec3 lightColor) :
|
|
m_direction(dir),
|
|
m_shadowCaster(false)
|
|
|
|
{
|
|
m_color = lightColor;
|
|
m_shadowMap = NULL;
|
|
}
|
|
|
|
void DirectionnalLight::bindAttributes(Shader *shader, Camera *camera)
|
|
{
|
|
shader->bindVec3(shader->getLocation("lightColor"), m_color);
|
|
glm::vec4 direction = glm::vec4(m_direction, 0.f);
|
|
shader->bindVec3(shader->getLocation("dirLight"), glm::normalize(glm::vec3(camera->getViewMatrix()*direction)));
|
|
if(m_shadowCaster)
|
|
{
|
|
switch(m_projectionMatrices.size())
|
|
{
|
|
case 1:
|
|
{
|
|
m_shadowMap->getTexture(0)->bind(7); // TODO use something else than 7
|
|
shader->bindInteger(shader->getLocation("shadowMap"), 7);
|
|
glm::mat4 viewToLightMatrix = Light::biasMatrix * m_projectionMatrices[0] * m_viewMatrices[0] * glm::inverse(camera->getViewMatrix());
|
|
shader->bindMat4(shader->getLocation("viewToLightMatrix"), viewToLightMatrix);
|
|
}
|
|
break;
|
|
case 3:
|
|
{
|
|
m_shadowMap->getTexture(0)->bind(7); // TODO use something else than 7
|
|
shader->bindInteger(shader->getLocation("shadowMap"), 7);
|
|
glm::mat4 lightMVP;
|
|
lightMVP = Light::biasMatrix * m_projectionMatrices[0] * (m_viewMatrices[0] * glm::inverse(camera->getViewMatrix()));
|
|
shader->bindMat4(shader->getLocation("frontShadowMVP"), lightMVP);
|
|
lightMVP = Light::biasMatrix * m_projectionMatrices[1] * (m_viewMatrices[1] * glm::inverse(camera->getViewMatrix()));
|
|
shader->bindMat4(shader->getLocation("midShadowMVP"), lightMVP);
|
|
lightMVP = Light::biasMatrix * m_projectionMatrices[2] * (m_viewMatrices[2] * glm::inverse(camera->getViewMatrix()));
|
|
shader->bindMat4(shader->getLocation("backShadowMVP"), lightMVP);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
unsigned int DirectionnalLight::getFlags()
|
|
{
|
|
unsigned int flag = 1 << DIRECTIONNAL_FLAG;
|
|
if(m_shadowCaster)
|
|
flag |= 1 << SHADOWMAP_FLAG;
|
|
if(m_projectionMatrices.size() == 3)
|
|
flag |= 1 << CASCADED_FLAG;
|
|
return flag;
|
|
}
|
|
|
|
void DirectionnalLight::initShadowMap(int resolution, bool isCascaded)
|
|
{
|
|
m_shadowMapResolution = resolution;
|
|
|
|
// shader compilation
|
|
if(m_shaderRefCounter == 0)
|
|
{
|
|
ShaderSource source;
|
|
Resource::ResourceMap shaderMap;
|
|
Resource::getResourcePack_shaders(shaderMap);
|
|
source.setSource(shaderMap["shaders/shadow.vert.glsl"], ShaderSource::VERTEX);
|
|
source.setSource(shaderMap["shaders/shadow.frag.glsl"], ShaderSource::FRAGMENT);
|
|
unsigned int flag = 1 << DIRECTIONNAL_FLAG;
|
|
m_shaders[0] = source.compile(Mesh::MESH_3D, flag);
|
|
m_shaders[1] = source.compile(Mesh::MESH_3D & Mesh::MATERIAL_ALPHA_MASK, flag);
|
|
|
|
source.setSource(shaderMap["shaders/shadow.geom.glsl"], ShaderSource::GEOMETRY);
|
|
flag |= 1 << CASCADED_FLAG;
|
|
m_shaders[2] = source.compile(Mesh::MESH_3D, flag);
|
|
m_shaders[3] = source.compile(Mesh::MESH_3D & Mesh::MATERIAL_ALPHA_MASK, flag);
|
|
}
|
|
if(!m_shadowCaster)
|
|
++m_shaderRefCounter;
|
|
m_shadowCaster = true;
|
|
|
|
if(isCascaded)
|
|
{
|
|
m_viewMatrices.resize(3);
|
|
m_projectionMatrices.resize(3);
|
|
}
|
|
else
|
|
{
|
|
m_viewMatrices.resize(1);
|
|
m_projectionMatrices.resize(1);
|
|
}
|
|
|
|
// Depth buffer
|
|
Texture *tex = new Texture(GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, resolution, resolution, GL_FLOAT, isCascaded ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D);
|
|
if(isCascaded)
|
|
{
|
|
tex->bind();
|
|
for(int i=0; i<3; ++i)
|
|
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT, resolution, resolution, i, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
|
|
}
|
|
tex->setFiltering(GL_LINEAR);
|
|
tex->setWrap(GL_CLAMP_TO_EDGE);
|
|
tex->setParameter(GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
|
|
tex->setParameter(GL_TEXTURE_COMPARE_FUNC, GL_LESS);
|
|
|
|
// framebuffer
|
|
m_shadowCaster = true;
|
|
m_shadowMap = new FrameBuffer();
|
|
m_shadowMap->addTexture(tex, GL_DEPTH_ATTACHMENT);
|
|
m_shadowMap->initColorAttachments();
|
|
}
|
|
|
|
void DirectionnalLight::destroyShadowMap()
|
|
{
|
|
if(m_shadowCaster)
|
|
{
|
|
m_shadowCaster = false;
|
|
--m_shaderRefCounter;
|
|
if(m_shaderRefCounter == 0)
|
|
{
|
|
for(int i=0; i<4; ++i)
|
|
delete m_shaders[i];
|
|
}
|
|
if(m_shadowMap != NULL)
|
|
delete m_shadowMap;
|
|
}
|
|
m_viewMatrices.clear();
|
|
m_projectionMatrices.clear();
|
|
m_shadowMap = NULL;
|
|
}
|
|
|
|
void DirectionnalLight::setShadowView(glm::vec3 dim, glm::vec3 center)
|
|
{
|
|
m_viewMatrices[0] = glm::lookAt(center, center-m_direction, glm::vec3(0, 1, 0));
|
|
m_projectionMatrices[0] = glm::ortho(-dim.x/2, dim.x/2, -dim.y/2, dim.y/2, -dim.z/2, dim.z/2);
|
|
}
|
|
|
|
void DirectionnalLight::setCascadedShadowView(Camera *camera)
|
|
{
|
|
// TODO find projection bounding boxes and define the 3 shadowmap views
|
|
}
|
|
|
|
void DirectionnalLight::updateShadowMap(Scene* scene)
|
|
{
|
|
bool hasCascades = m_projectionMatrices.size() == 3;
|
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
|
glViewport(0, 0, m_shadowMapResolution, m_shadowMapResolution);
|
|
m_shadowMap->bindFBO();
|
|
glClearDepth(1.0);
|
|
glClear(GL_DEPTH_BUFFER_BIT);
|
|
glEnable(GL_DEPTH_TEST);
|
|
glDepthFunc(GL_LESS);
|
|
for(SceneIterator<GeometryNode*>* geometryIt = scene->getGeometry();
|
|
geometryIt->isValid(); geometryIt->next())
|
|
{
|
|
GeometryNode* node = geometryIt->getItem();
|
|
if(node->mesh->getFlags() & (1 << Mesh::MESH_SHADOWED))
|
|
{
|
|
int shaderId = (node->mesh->getFlags() & (1 << Mesh::MATERIAL_ALPHA_MASK)) != 0;
|
|
|
|
// compute matrix attributes
|
|
if(hasCascades)
|
|
{
|
|
shaderId += 2;
|
|
m_shaders[shaderId]->bind();
|
|
glm::mat4 lightMVP;
|
|
lightMVP = m_projectionMatrices[0] * (m_viewMatrices[0] * node->modelMatrix);
|
|
m_shaders[shaderId]->bindMat4(m_shaders[shaderId]->getLocation("frontShadowMVP"), lightMVP);
|
|
lightMVP = m_projectionMatrices[1] * (m_viewMatrices[1] * node->modelMatrix);
|
|
m_shaders[shaderId]->bindMat4(m_shaders[shaderId]->getLocation("midShadowMVP"), lightMVP);
|
|
lightMVP = m_projectionMatrices[2] * (m_viewMatrices[2] * node->modelMatrix);
|
|
m_shaders[shaderId]->bindMat4(m_shaders[shaderId]->getLocation("backShadowMVP"), lightMVP);
|
|
node->mesh->draw(m_shaders[shaderId], false, shaderId, false);
|
|
}
|
|
else
|
|
{
|
|
m_shaders[shaderId]->bind();
|
|
glm::mat4 lightMVP = m_projectionMatrices[0] * (m_viewMatrices[0] * node->modelMatrix);
|
|
m_shaders[shaderId]->bindMat4(m_shaders[shaderId]->getLocation("MVP"), lightMVP);
|
|
node->mesh->draw(m_shaders[shaderId], false, shaderId, false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// POINT LIGHT
|
|
|
|
int PointLight::m_shaderRefCounter = 0;
|
|
Shader* PointLight::m_shaders[2] = {NULL};
|
|
|
|
PointLight::PointLight(glm::vec3 pos, float range, glm::vec3 lightColor) :
|
|
m_position(pos),
|
|
m_range(range),
|
|
m_shadowCaster(false)
|
|
|
|
{
|
|
m_color = lightColor;
|
|
m_shadowMap = NULL;
|
|
}
|
|
|
|
void PointLight::bindAttributes(Shader *shader, Camera *camera)
|
|
{
|
|
glm::vec4 posInView = camera->getViewMatrix() * glm::vec4(m_position.x, m_position.y, m_position.z, 1.f);
|
|
shader->bindVec3(shader->getLocation("lightColor"), m_color);
|
|
shader->bindVec3(shader->getLocation("pointLight"), glm::vec3(posInView));
|
|
shader->bindFloat(shader->getLocation("range"), m_range);
|
|
if(m_shadowCaster)
|
|
{
|
|
m_shadowMap->getTexture(0)->bind(7); // TODO use something else than 7
|
|
shader->bindInteger(shader->getLocation("shadowMap"), 7);
|
|
shader->bindMat3(shader->getLocation("inverseViewMatrix"), glm::inverse(glm::mat3(camera->getViewMatrix())));
|
|
}
|
|
}
|
|
|
|
unsigned int PointLight::getFlags()
|
|
{
|
|
unsigned int flag = 1 << POINT_FLAG;
|
|
if(m_shadowCaster)
|
|
flag |= 1 << SHADOWMAP_FLAG;
|
|
return flag;
|
|
}
|
|
|
|
void PointLight::initShadowMap(int resolution)
|
|
{
|
|
m_shadowMapResolution = resolution;
|
|
setPos(m_position);
|
|
|
|
// shader compilation
|
|
if(m_shaderRefCounter == 0)
|
|
{
|
|
ShaderSource source;
|
|
Resource::ResourceMap shaderMap;
|
|
Resource::getResourcePack_shaders(shaderMap);
|
|
source.setSource(shaderMap["shaders/shadow.vert.glsl"], ShaderSource::VERTEX);
|
|
source.setSource(shaderMap["shaders/shadow.geom.glsl"], ShaderSource::GEOMETRY);
|
|
source.setSource(shaderMap["shaders/shadow.frag.glsl"], ShaderSource::FRAGMENT);
|
|
unsigned int flag = 1 << POINT_FLAG;
|
|
m_shaders[0] = source.compile(Mesh::MESH_3D, flag);
|
|
m_shaders[1] = source.compile(Mesh::MESH_3D & Mesh::MATERIAL_ALPHA_MASK, flag);
|
|
}
|
|
if(!m_shadowCaster)
|
|
++m_shaderRefCounter;
|
|
m_shadowCaster = true;
|
|
|
|
// Depth buffer
|
|
Texture *tex = new Texture(GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, resolution, resolution, GL_FLOAT, GL_TEXTURE_CUBE_MAP);
|
|
tex->setParameter(GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
|
|
tex->setParameter(GL_TEXTURE_COMPARE_FUNC, GL_LESS);
|
|
|
|
// framebuffer
|
|
m_shadowCaster = true;
|
|
m_shadowMap = new FrameBuffer();
|
|
m_shadowMap->addTexture(tex, GL_DEPTH_ATTACHMENT);
|
|
m_shadowMap->initColorAttachments();
|
|
}
|
|
|
|
void PointLight::updateTransform()
|
|
{
|
|
if(m_shadowCaster)
|
|
{
|
|
m_shadowTransforms.clear();
|
|
glm::mat4 shadowProj = glm::perspective(45.0f, 1.f, 0.01f, m_range);
|
|
m_shadowTransforms.push_back(shadowProj *
|
|
glm::lookAt(m_position, m_position + glm::vec3(1.0,0.0,0.0), glm::vec3(0.0,-1.0,0.0)));
|
|
m_shadowTransforms.push_back(shadowProj *
|
|
glm::lookAt(m_position, m_position + glm::vec3(-1.0,0.0,0.0), glm::vec3(0.0,-1.0,0.0)));
|
|
m_shadowTransforms.push_back(shadowProj *
|
|
glm::lookAt(m_position, m_position + glm::vec3(0.0,1.0,0.0), glm::vec3(0.0,0.0,1.0)));
|
|
m_shadowTransforms.push_back(shadowProj *
|
|
glm::lookAt(m_position, m_position + glm::vec3(0.0,-1.0,0.0), glm::vec3(0.0,0.0,-1.0)));
|
|
m_shadowTransforms.push_back(shadowProj *
|
|
glm::lookAt(m_position, m_position + glm::vec3(0.0,0.0,1.0), glm::vec3(0.0,-1.0,0.0)));
|
|
m_shadowTransforms.push_back(shadowProj *
|
|
glm::lookAt(m_position, m_position + glm::vec3(0.0,0.0,-1.0), glm::vec3(0.0,-1.0,0.0)));
|
|
}
|
|
}
|
|
|
|
void PointLight::destroyShadowMap()
|
|
{
|
|
if(m_shadowCaster)
|
|
{
|
|
m_shadowCaster = false;
|
|
--m_shaderRefCounter;
|
|
if(m_shaderRefCounter == 0)
|
|
{
|
|
for(int i=0; i<2; ++i)
|
|
delete m_shaders[i];
|
|
}
|
|
if(m_shadowMap != NULL)
|
|
delete m_shadowMap;
|
|
}
|
|
m_shadowMap = NULL;
|
|
}
|
|
|
|
void PointLight::updateShadowMap(Scene* scene)
|
|
{
|
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
|
m_shadowMap->bindFBO();
|
|
glViewport(0, 0, m_shadowMapResolution, m_shadowMapResolution);
|
|
glClearDepth(1.0);
|
|
glClear(GL_DEPTH_BUFFER_BIT);
|
|
glEnable(GL_DEPTH_TEST);
|
|
glDepthFunc(GL_LESS);
|
|
for(SceneIterator<GeometryNode*>* geometryIt = scene->getGeometry();
|
|
geometryIt->isValid(); geometryIt->next())
|
|
{
|
|
GeometryNode* node = geometryIt->getItem();
|
|
if(node->mesh->getFlags() & (1 << Mesh::MESH_SHADOWED))
|
|
{
|
|
int shaderId = (node->mesh->getFlags() & (1 << Mesh::MATERIAL_ALPHA_MASK)) != 0;
|
|
|
|
m_shaders[shaderId]->bind();
|
|
m_shaders[shaderId]->bindMat4(m_shaders[shaderId]->getLocation("modelMatrix"), node->modelMatrix);
|
|
m_shaders[shaderId]->bindMat4Array(m_shaders[shaderId]->getLocation("layerTransform"), m_shadowTransforms.data(), m_shadowTransforms.size());
|
|
m_shaders[shaderId]->bindFloat(m_shaders[shaderId]->getLocation("far_plane"), m_range);
|
|
node->mesh->draw(m_shaders[shaderId], false, shaderId, false);
|
|
}
|
|
}
|
|
FrameBuffer::screen->bindFBO();
|
|
}
|
|
|
|
// OLD IMPLEMENTATION
|
|
|
|
/*
|
|
void Light::initShadowMap(int resolution, glm::vec3 dim)
|
|
{
|
|
m_shadowMapResolution = resolution;
|
|
Texture* tex;
|
|
|
|
switch(m_type)
|
|
{
|
|
case DIRECTIONNAL:
|
|
// 3 orthogonal matrices (cascaded shadowmaps)
|
|
// 3 square textures
|
|
m_viewMatrix.push_back(glm::lookAt(m_position, m_position-m_direction, glm::vec3(0, 1, 0)));
|
|
m_projectionMatrix = glm::ortho(-dim.x/2, dim.x/2, -dim.y/2, dim.y/2, -dim.z/2, dim.z/2);
|
|
tex = new Texture(GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, resolution, resolution, GL_FLOAT, GL_TEXTURE_2D);
|
|
break;
|
|
case POINT:
|
|
// see http://learnopengl.com/#!Advanced-Lighting/Shadows/Point-Shadows
|
|
|
|
// 6 projection matrices
|
|
// 1 cubemap texture
|
|
m_viewMatrix = glm::lookAt(m_position, m_position-glm::vec3(0, 0, 1), glm::vec3(0, 1, 0));
|
|
m_projectionMatrix = glm::perspective(90.f, 1.f, 0.1f, 100.f);
|
|
tex = new Texture(GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, resolution, resolution, GL_FLOAT, GL_TEXTURE_CUBE_MAP);
|
|
|
|
m_viewMatrices.push_back(shadowProj *
|
|
glm::lookAt(m_position, m_position + glm::vec3(1.0,0.0,0.0), glm::vec3(0.0,-1.0,0.0));
|
|
m_viewMatrices.push_back(shadowProj *
|
|
glm::lookAt(m_position, m_position + glm::vec3(-1.0,0.0,0.0), glm::vec3(0.0,-1.0,0.0));
|
|
m_viewMatrices.push_back(shadowProj *
|
|
glm::lookAt(m_position, m_position + glm::vec3(0.0,1.0,0.0), glm::vec3(0.0,0.0,1.0));
|
|
m_viewMatrices.push_back(shadowProj *
|
|
glm::lookAt(m_position, m_position + glm::vec3(0.0,-1.0,0.0), glm::vec3(0.0,0.0,-1.0));
|
|
m_viewMatrices.push_back(shadowProj *
|
|
glm::lookAt(m_position, m_position + glm::vec3(0.0,0.0,1.0), glm::vec3(0.0,-1.0,0.0));
|
|
m_viewMatrices.push_back(shadowProj *
|
|
glm::lookAt(m_position, m_position + glm::vec3(0.0,0.0,-1.0), glm::vec3(0.0,-1.0,0.0));
|
|
break;
|
|
case SPOT:
|
|
// 1 projection matrix
|
|
// 1 square texture
|
|
m_viewMatrix.push_back(glm::lookAt(m_position, m_position+m_direction, glm::vec3(0, 1, 0)));
|
|
m_projectionMatrix = glm::perspective(m_cutOffAngle, 1.f, 0.1f, 100.f);
|
|
tex = new Texture(GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, resolution, resolution, GL_FLOAT, GL_TEXTURE_2D);
|
|
break;
|
|
case AMBIENT:
|
|
return;
|
|
}
|
|
|
|
// shader compilation
|
|
// TODO : do not compile shader for every light
|
|
ShaderSource source;
|
|
Resource::ResourceMap shaderMap;
|
|
Resource::getResourcePack_shaders(shaderMap);
|
|
source.setSource(shaderMap["shaders/shadow.vert.glsl"], ShaderSource::VERTEX);
|
|
if(m_type == POINT)
|
|
source.setSource(shaderMap["shaders/shadow.geom.glsl"], ShaderSource::GEOMETRY);
|
|
source.setSource(shaderMap["shaders/shadow.frag.glsl"], ShaderSource::FRAGMENT);
|
|
m_shaders[0] = source.compile(Mesh::MESH_3D, getFlags());
|
|
m_shaders[1] = source.compile(Mesh::MESH_3D & Mesh::MATERIAL_ALPHA_MASK, getFlags());
|
|
|
|
// Depth buffer
|
|
tex->setFiltering(GL_LINEAR);
|
|
tex->setWrap(GL_CLAMP_TO_EDGE);
|
|
tex->setParameter(GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
|
|
tex->setParameter(GL_TEXTURE_COMPARE_FUNC, GL_LESS);
|
|
|
|
// framebuffer
|
|
m_shadowCaster = true;
|
|
m_shadowMap = new FrameBuffer();
|
|
m_shadowMap->addTexture(tex, GL_DEPTH_ATTACHMENT);
|
|
m_shadowMap->initColorAttachments();
|
|
}
|
|
|
|
void Light::generateShadowMap(Scene* scene)
|
|
{
|
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
|
glViewport(0, 0, m_shadowMapResolution, m_shadowMapResolution);
|
|
m_shadowMap->bindFBO();
|
|
glClearDepth(1.0);
|
|
glClear(GL_DEPTH_BUFFER_BIT);
|
|
glEnable(GL_DEPTH_TEST);
|
|
glDepthFunc(GL_LESS);
|
|
// glCullFace(GL_FRONT);
|
|
for(SceneIterator<GeometryNode*>* geometryIt = scene->getGeometry();
|
|
geometryIt->isValid(); geometryIt->next())
|
|
{
|
|
GeometryNode* node = geometryIt->getItem();
|
|
if(node->mesh->getFlags() & (1 << Mesh::MESH_SHADOWED))
|
|
{
|
|
// compute matrix attributes
|
|
glm::mat4 lightMVP = getProjectionMatrix() * (getViewMatrix() * node->modelMatrix);
|
|
int hasAlpha = (node->mesh->getFlags() & (1 << Mesh::MATERIAL_ALPHA_MASK)) > 0;
|
|
m_shaders[hasAlpha]->bind();
|
|
m_shaders[hasAlpha]->bindMat4(m_shaders[hasAlpha]->getLocation("MVP"), lightMVP);
|
|
node->mesh->draw(m_shaders[hasAlpha], false, hasAlpha, false);
|
|
}
|
|
}
|
|
// glCullFace(GL_BACK);
|
|
}
|
|
|
|
void Light::bindShadowMap(Shader *shader)
|
|
{
|
|
glm::mat4 lightMVP = Light::biasMatrix * m_projectionMatrix * light->getViewMatrix() * node->modelMatrix;
|
|
shader->bindMat4(shader->getLocation("lightMVP"), lightMVP);
|
|
}
|
|
|
|
Texture* Light::getShadowMapTexture()
|
|
{
|
|
return m_shadowMap->getTexture(0);
|
|
}
|
|
|
|
void Light::setPosition(glm::vec3 new_pos)
|
|
{
|
|
m_position = new_pos;
|
|
m_viewMatrix = glm::lookAt(m_position, m_position+m_direction, glm::vec3(0, 1, 0));
|
|
}
|
|
|
|
unsigned int Light::getFlags()
|
|
{
|
|
unsigned int flags = 0;
|
|
switch(m_type)
|
|
{
|
|
case AMBIENT :
|
|
flags = 1 << AMBIENT_FLAG;
|
|
break;
|
|
case DIRECTIONNAL :
|
|
flags = 1 << DIRECTIONNAL_FLAG;
|
|
break;
|
|
case POINT :
|
|
flags = 1 << POINT_FLAG;
|
|
break;
|
|
case SPOT :
|
|
flags = 1 << SPOT_FLAG;
|
|
break;
|
|
}
|
|
if(m_shadowCaster)
|
|
flags |= 1 << SHADOWMAP_FLAG;
|
|
return flags;
|
|
}
|
|
*/
|