SparrowRenderer/src/phongmaterial.cpp

140 lines
4.0 KiB
C++

#include "phongmaterial.h"
#include "texture.h"
#include "sparrowrenderer.h"
#include "shader.h"
#include "mesh.h"
#include <glm/ext.hpp>
void PhongMaterial::bindAttributes(Shader* myShader)
{
// TODO store the attributes location
myShader->bindFloat(myShader->getLocation("materialNs"), shininess);
if(textures[NORMALS_SLOT] != NULL)
{
textures[NORMALS_SLOT]->bind(NORMALS_SLOT);
myShader->bindInteger(myShader->getLocation("normalMap"), NORMALS_SLOT);
}
if(textures[EMISSION_SLOT] != NULL)
{
textures[EMISSION_SLOT]->bind(EMISSION_SLOT);
myShader->bindInteger(myShader->getLocation("emissionTexture"), EMISSION_SLOT);
}
else
myShader->bindVec3(myShader->getLocation("materialEmission"), emission);
if(textures[DIFFUSE_SLOT] != NULL)
{
textures[DIFFUSE_SLOT]->bind(DIFFUSE_SLOT);
myShader->bindInteger(myShader->getLocation("diffuseTexture"), DIFFUSE_SLOT);
}
else
myShader->bindVec3(myShader->getLocation("materialKd"), diffuse);
if(textures[SPECULAR_SLOT] != NULL)
{
textures[SPECULAR_SLOT]->bind(SPECULAR_SLOT);
myShader->bindInteger(myShader->getLocation("specularTexture"), SPECULAR_SLOT);
}
else
myShader->bindVec3(myShader->getLocation("materialKs"), specular);
if(textures[ALPHA_SLOT] != NULL)
{
textures[ALPHA_SLOT]->bind(ALPHA_SLOT);
myShader->bindInteger(myShader->getLocation("alphaMask"), ALPHA_SLOT);
}
}
unsigned int PhongMaterial::getFlags()
{
unsigned int flags = 1 << Mesh::MATERIAL_PHONG;
if(textures[NORMALS_SLOT] != NULL)
flags |= 1 << Mesh::MATERIAL_PHONG_NORMAL_MAP;
if(textures[EMISSION_SLOT] != NULL)
flags |= 1 << Mesh::MATERIAL_PHONG_EMISSION_TEXTURE;
if(textures[DIFFUSE_SLOT] != NULL)
flags |= 1 << Mesh::MATERIAL_PHONG_DIFFUSE_TEXTURE;
if(textures[SPECULAR_SLOT] != NULL)
flags |= 1 << Mesh::MATERIAL_PHONG_SPECULAR_TEXTURE;
if(textures[ALPHA_SLOT] != NULL)
flags |= 1 << Mesh::MATERIAL_ALPHA_MASK;
return flags;
}
// serialisation methods :
struct MaterialHeader
{
glm::vec3 emission;
glm::vec3 diffuse;
glm::vec3 specular;
float shininess;
int textureLengths[PhongMaterial::NB_PHONG_SLOTS];
};
bool PhongMaterial::serialize(PhongMaterial* mat, FILE *file)
{
unsigned int flags = mat->getFlags();
if(!fwrite(&flags, sizeof(unsigned int), 1, file))
return false;
if(flags & (1 << Mesh::MATERIAL_PHONG))
{
MaterialHeader header;
header.emission = mat->emission;
header.diffuse = mat->diffuse;
header.specular = mat->specular;
header.shininess = mat->shininess;
for(int i=0; i<PhongMaterial::NB_PHONG_SLOTS; ++i)
{
if(mat->textures[i] != NULL)
header.textureLengths[i] = mat->textureNames[i].length()+1;
}
if(!std::fwrite(&header, sizeof(MaterialHeader), 1, file))
return false;
for(int i=0; i<PhongMaterial::NB_PHONG_SLOTS; ++i)
{
if(header.textureLengths[i] > 0)
{
if(!std::fwrite(mat->textureNames[i].c_str(), header.textureLengths[i], 1, file))
return false;
}
}
}
return true;
}
PhongMaterial* PhongMaterial::deserialize(FILE *file)
{
int flags;
if(!std::fread(&flags, sizeof(int), 1, file))
return NULL;
MaterialHeader header;
if(!std::fread(&header, sizeof(MaterialHeader), 1, file))
return NULL;
PhongMaterial *mat = new PhongMaterial();
mat->diffuse = header.diffuse;
mat->emission = header.emission;
mat->specular = header.specular;
mat->shininess = header.shininess;
for(int i=0; i<PhongMaterial::NB_PHONG_SLOTS; ++i)
{
char str[256];
if(!std::fread(str, header.textureLengths[i], 1, file))
{ delete mat; return NULL; }
mat->textureNames[i] = std::string(str);
}
return mat;
}