added point light, added name to mesh serialisation
This commit is contained in:
parent
5eef43156b
commit
a8f57882cc
125
src/light.cpp
125
src/light.cpp
@ -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
|
||||
|
||||
|
33
src/light.h
33
src/light.h
@ -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
|
||||
|
@ -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),
|
||||
|
11
src/mesh.h
11
src/mesh.h
@ -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;
|
||||
|
@ -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 :
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
13
src/shader.h
13
src/shader.h
@ -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);
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user