added point light, added name to mesh serialisation

This commit is contained in:
Anselme 2016-06-17 14:54:07 +02:00
parent 5eef43156b
commit a8f57882cc
8 changed files with 209 additions and 19 deletions

View File

@ -27,11 +27,23 @@ const glm::mat4 Light::biasMatrix(
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0);
const glm::mat4 PointLight::m_viewMatrices[6] =
{
glm::lookAt(glm::vec3(0), glm::vec3(1, 0, 0 ), glm::vec3(0,-1, 0 )),
glm::lookAt(glm::vec3(0), glm::vec3(-1,0, 0 ), glm::vec3(0,-1, 0 )),
glm::lookAt(glm::vec3(0), glm::vec3(0, 1, 0 ), glm::vec3(0, 0, 1 )),
glm::lookAt(glm::vec3(0), glm::vec3(0, -1,0 ), glm::vec3(0, 0, -1)),
glm::lookAt(glm::vec3(0), glm::vec3(0, 0, 1 ), glm::vec3(0,-1, 0 )),
glm::lookAt(glm::vec3(0), glm::vec3(0, 0, -1), glm::vec3(0,-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};
@ -218,6 +230,119 @@ void DirectionnalLight::updateShadowMap(Scene* scene)
}
}
}
// POINT LIGHT
int PointLight::m_shaderRefCounter = 0;
Shader* PointLight::m_shaders[2] = {NULL};
PointLight::PointLight(glm::vec3 pos, float attenuation, glm::vec3 lightColor) :
m_position(pos),
m_attenuation(attenuation),
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("attenuation"), m_attenuation);
if(m_shadowCaster)
{
m_shadowMap->getTexture(0)->bind(7); // TODO use something else than 7
shader->bindInteger(shader->getLocation("shadowMap"), 7);
}
}
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;
// 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::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);
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;
m_shaders[shaderId]->bind();
m_shaders[shaderId]->bindMat4(m_shaders[shaderId]->getLocation("modelMatrix"), node->modelMatrix);
m_shaders[shaderId]->bindMat4(m_shaders[shaderId]->getLocation("projectionMatrix"), m_projectionMatrix);
m_shaders[shaderId]->bindMat4Array(m_shaders[shaderId]->getLocation("viewMatrices"), m_viewMatrices, 6);
m_shaders[shaderId]->bindVec3(m_shaders[shaderId]->getLocation("pointLight"), m_position);
node->mesh->draw(m_shaders[shaderId], false, shaderId, false);
}
}
}
// OLD IMPLEMENTATION

View File

@ -89,4 +89,37 @@ private:
static Shader* m_shaders[4];
};
class PointLight : public Light
{
public:
PointLight(glm::vec3 pos = glm::vec3(0), float attenuation = 1, glm::vec3 lightColor = glm::vec3(1));
glm::vec3 getPos() { return m_position; }
float getAttenuation() { return m_attenuation; }
void setPos(glm::vec3 pos) { m_position = pos; /* TODO : update projection matrix */ }
void setAttenuation(float attenuation) { m_attenuation = attenuation; }
virtual LightType getType() { return POINT; }
virtual void bindAttributes(Shader *shader, Camera *camera);
virtual unsigned int getFlags();
void initShadowMap(int resolution);
void destroyShadowMap();
void updateShadowMap(Scene* scene);
private:
glm::vec3 m_position;
float m_attenuation;
bool m_shadowCaster;
int m_shadowMapResolution;
FrameBuffer* m_shadowMap;
static const glm::mat4 m_viewMatrices[6];
glm::mat4 m_projectionMatrix;
static int m_shaderRefCounter;
static Shader* m_shaders[2];
};
#endif // LIGHT_H

View File

@ -32,7 +32,8 @@ const char* const Mesh::flagStr[Mesh::NB_FLAGS] =
"BUMP_MAP"
};
Mesh::Mesh() :
Mesh::Mesh(const std::string &name) :
m_name(name),
material(NULL),
isDoubleSided(false),
isBillboard(false),

View File

@ -3,6 +3,7 @@
#include "opengl.h"
#include <vector>
#include <string>
#include <glm/vec3.hpp>
#include <glm/vec2.hpp>
@ -86,9 +87,12 @@ public:
/**
* @brief Mesh builds an empty mesh, to be renderable, a mesh must have vertices and a material.
*/
Mesh();
Mesh(const std::string &name = "mesh");
~Mesh();
void setName(const std::string &name) { m_name = name; }
std::string getName() { return m_name; }
/**
* OpenGL methods :
* - initGL allocates the GPU buffers and sends the mesh data to the GPU
@ -206,7 +210,8 @@ public:
void setPrimitiveType(GLenum type) {primitive_type = type;}
protected:
std::string m_name;
Material* material;
bool isDoubleSided;
bool isBillboard;

View File

@ -8,7 +8,7 @@
Mesh* MeshGenerator::generateParametricMesh(Material* mat, int width, int height, float size, bool alternate)
{
m_size = size;
m_mesh = new Mesh();
m_mesh = new Mesh("parametric_mesh");
m_mesh->setMaterial(mat);
for(int i=0; i<=width; ++i)
@ -46,7 +46,7 @@ Mesh* MeshGenerator::generateParametricMesh(Material* mat, int width, int height
Mesh* MeshGenerator::generateGeodesicMesh(Material* mat, int n, float size)
{
m_size = size;
m_mesh = new Mesh();
m_mesh = new Mesh("geodesic_mesh");
m_mesh->setMaterial(mat);
// icosahedron :

View File

@ -19,6 +19,7 @@ struct MeshHeader
int depth;
int nbInstances_offsets;
int nbIndices;
int nameLength;
};
struct MaterialHeader
@ -85,6 +86,7 @@ bool saveMesh(const std::string &filename, Mesh *mesh)
}
header.nbIndices = mesh->indices.size();
header.nbInstances_offsets = mesh->instances_offsets.size();
header.nameLength = mesh->getName().size();
// serializing
bool ok = false;
@ -99,9 +101,18 @@ bool saveMesh(const std::string &filename, Mesh *mesh)
bool serializeMesh(Mesh* mesh, const MeshHeader &header, FILE *file)
{
// writing header
size_t nbWritten = std::fwrite(&header, sizeof(MeshHeader), 1, file);
size_t nbWritten;
nbWritten = std::fwrite(&header, sizeof(MeshHeader), 1, file);
if(nbWritten != 1)
return false;
if(header.nameLength != 0)
{
nbWritten = std::fwrite(mesh->getName().data(), header.nameLength, 1, file);
if(nbWritten != 1)
return false;
}
// writing buffers
if(header.flags & (1 << Mesh::MESH_3D))
@ -206,6 +217,15 @@ Mesh* loadMesh(const std::string &filename)
bool deserializeMesh(Mesh* mesh, const MeshHeader &header, FILE *file)
{
std::string name = "mesh";
if(header.nameLength != 0)
{
name.resize(header.nameLength);
if(!fread(&(name[0]), header.nameLength, 1, file))
return false;
}
mesh->setName(name);
if(header.flags & (1 << Mesh::MESH_3D))
{
mesh->positions3D.reserve(header.nbPositions);

View File

@ -162,32 +162,37 @@ void Shader::bindFloat(GLuint location, float val)
glUniform1f(location, val);
}
void Shader::bindMat3(GLuint location, glm::mat3 mat)
void Shader::bindMat3(GLuint location, const glm::mat3 &mat)
{
glUniformMatrix3fv(location, 1, GL_FALSE, glm::value_ptr(mat));
}
void Shader::bindMat4(GLuint location, glm::mat4 mat)
void Shader::bindMat4(GLuint location, const glm::mat4 &mat)
{
glUniformMatrix4fv(location, 1, GL_FALSE, glm::value_ptr(mat));
}
void Shader::bindVec2(GLuint location, glm::vec2 vec)
void Shader::bindMat4Array(GLuint location, const glm::mat4 *matrices, int nbMat)
{
glUniformMatrix4fv(location, nbMat, GL_FALSE, (GLfloat*)matrices);
}
void Shader::bindVec2(GLuint location, const glm::vec2 &vec)
{
glUniform2fv(location, 1, glm::value_ptr(vec));
}
void Shader::bindVec3(GLuint location, glm::vec3 vec)
void Shader::bindVec3(GLuint location, const glm::vec3 &vec)
{
glUniform3fv(location, 1, glm::value_ptr(vec));
}
void Shader::bindVec4(GLuint location, glm::vec4 vec)
void Shader::bindVec4(GLuint location, const glm::vec4 &vec)
{
glUniform4fv(location, 1, glm::value_ptr(vec));
}
void Shader::bindVec3Array(GLuint location, glm::vec3* vec, int nb_elements)
void Shader::bindVec3Array(GLuint location, const glm::vec3* vec, int nb_elements)
{
glUniform3fv(location, nb_elements, (GLfloat*)vec);
}

View File

@ -21,12 +21,13 @@ public:
void bind();
void unbind();
void bindFloat(GLuint location, float val);
void bindMat3(GLuint location, glm::mat3 mat);
void bindMat4(GLuint location, glm::mat4 mat);
void bindVec2(GLuint location, glm::vec2 vec);
void bindVec3(GLuint location, glm::vec3 vec);
void bindVec4(GLuint location, glm::vec4 vec);
void bindVec3Array(GLuint location, glm::vec3* vec, int nb_elements);
void bindMat3(GLuint location, const glm::mat3 &mat);
void bindMat4(GLuint location, const glm::mat4 &mat);
void bindMat4Array(GLuint location, const glm::mat4 *matrices, int nbMat);
void bindVec2(GLuint location, const glm::vec2 &vec);
void bindVec3(GLuint location, const glm::vec3 &vec);
void bindVec4(GLuint location, const glm::vec4 &vec);
void bindVec3Array(GLuint location, const glm::vec3* vec, int nb_elements);
void bindUnsignedInteger(GLuint location, GLuint unsigned_integer);
void bindInteger(GLuint location, GLint integer);
};