2014-06-16 21:18:15 +02:00
|
|
|
#include "graphics/material.h"
|
2014-09-07 01:10:24 +02:00
|
|
|
#include "core/crc32.h"
|
2014-06-16 21:18:15 +02:00
|
|
|
#include "core/fs/file_system.h"
|
|
|
|
#include "core/fs/ifile.h"
|
|
|
|
#include "core/json_serializer.h"
|
|
|
|
#include "core/log.h"
|
2014-06-25 23:06:30 +02:00
|
|
|
#include "core/path_utils.h"
|
2014-07-27 00:27:01 +02:00
|
|
|
#include "core/profiler.h"
|
2014-06-16 21:18:15 +02:00
|
|
|
#include "core/resource_manager.h"
|
|
|
|
#include "core/resource_manager_base.h"
|
2014-06-21 19:26:27 +02:00
|
|
|
#include "core/timer.h"
|
2014-06-16 21:18:15 +02:00
|
|
|
#include "graphics/frame_buffer.h"
|
|
|
|
#include "graphics/pipeline.h"
|
|
|
|
#include "graphics/renderer.h"
|
|
|
|
#include "graphics/shader.h"
|
|
|
|
#include "graphics/texture.h"
|
|
|
|
|
|
|
|
|
|
|
|
namespace Lumix
|
|
|
|
{
|
|
|
|
|
2014-09-07 01:10:24 +02:00
|
|
|
|
|
|
|
static const uint32_t SHADOWMAP_HASH = crc32("shadowmap");
|
|
|
|
|
|
|
|
|
2014-06-16 21:18:15 +02:00
|
|
|
Material::~Material()
|
|
|
|
{
|
|
|
|
ASSERT(isEmpty());
|
|
|
|
}
|
|
|
|
|
2014-09-07 17:29:40 +02:00
|
|
|
void Material::apply(Renderer& renderer, PipelineInstance& pipeline) const
|
2014-06-16 21:18:15 +02:00
|
|
|
{
|
2014-09-07 01:10:24 +02:00
|
|
|
PROFILE_FUNCTION();
|
2014-06-16 21:18:15 +02:00
|
|
|
if(getState() == State::READY)
|
|
|
|
{
|
2014-10-06 23:58:33 +02:00
|
|
|
renderer.applyShader(*m_shader, m_shader_combination);
|
2014-07-19 20:48:21 +02:00
|
|
|
switch (m_depth_func)
|
|
|
|
{
|
|
|
|
case DepthFunc::LEQUAL:
|
|
|
|
glDepthFunc(GL_LEQUAL);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
glDepthFunc(GL_LESS);
|
|
|
|
break;
|
|
|
|
}
|
2014-06-16 21:18:15 +02:00
|
|
|
if (m_is_backface_culling)
|
|
|
|
{
|
|
|
|
glEnable(GL_CULL_FACE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
glDisable(GL_CULL_FACE);
|
|
|
|
}
|
|
|
|
for (int i = 0, c = m_textures.size(); i < c; ++i)
|
|
|
|
{
|
2014-09-27 22:15:14 +02:00
|
|
|
m_textures[i].m_texture->apply(i);
|
2014-06-16 21:18:15 +02:00
|
|
|
}
|
2014-08-10 23:17:31 +02:00
|
|
|
renderer.enableAlphaToCoverage(m_is_alpha_to_coverage);
|
2014-06-16 21:18:15 +02:00
|
|
|
renderer.enableZTest(m_is_z_test);
|
|
|
|
for (int i = 0, c = m_uniforms.size(); i < c; ++i)
|
|
|
|
{
|
|
|
|
const Uniform& uniform = m_uniforms[i];
|
|
|
|
switch (uniform.m_type)
|
|
|
|
{
|
|
|
|
case Uniform::FLOAT:
|
2014-09-07 14:24:52 +02:00
|
|
|
renderer.setUniform(*m_shader, uniform.m_name, uniform.m_name_hash, uniform.m_float);
|
2014-06-16 21:18:15 +02:00
|
|
|
break;
|
|
|
|
case Uniform::INT:
|
2014-09-07 14:24:52 +02:00
|
|
|
renderer.setUniform(*m_shader, uniform.m_name, uniform.m_name_hash, uniform.m_int);
|
2014-06-16 21:18:15 +02:00
|
|
|
break;
|
|
|
|
case Uniform::MATRIX:
|
2014-09-07 14:24:52 +02:00
|
|
|
renderer.setUniform(*m_shader, uniform.m_name, uniform.m_name_hash, uniform.m_matrix);
|
2014-06-16 21:18:15 +02:00
|
|
|
break;
|
2014-06-21 19:26:27 +02:00
|
|
|
case Uniform::TIME:
|
2014-09-07 14:24:52 +02:00
|
|
|
renderer.setUniform(*m_shader, uniform.m_name, uniform.m_name_hash, pipeline.getScene()->getTimer()->getTimeSinceStart());
|
2014-06-21 19:26:27 +02:00
|
|
|
break;
|
2014-06-16 21:18:15 +02:00
|
|
|
default:
|
|
|
|
ASSERT(false);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_shader->isShadowmapRequired())
|
|
|
|
{
|
|
|
|
glActiveTexture(GL_TEXTURE0 + m_textures.size());
|
|
|
|
glBindTexture(GL_TEXTURE_2D, pipeline.getShadowmapFramebuffer()->getDepthTexture());
|
2014-09-07 14:24:52 +02:00
|
|
|
renderer.setUniform(*m_shader, "shadowmap", SHADOWMAP_HASH, m_textures.size());
|
2014-06-16 21:18:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-06 23:58:33 +02:00
|
|
|
|
|
|
|
void Material::updateShaderCombination()
|
|
|
|
{
|
|
|
|
static const int MAX_DEFINES_LENGTH = 1024;
|
|
|
|
char defines[MAX_DEFINES_LENGTH];
|
|
|
|
copyString(defines, MAX_DEFINES_LENGTH, m_is_alpha_cutout ? "#define ALPHA_CUTOUT\n" : "" );
|
|
|
|
catCString(defines, MAX_DEFINES_LENGTH, m_is_shadow_receiver ? "#define SHADOW_RECEIVER\n" : "" );
|
|
|
|
m_shader_combination = crc32(defines);
|
|
|
|
if(m_shader && m_shader->isReady())
|
|
|
|
{
|
|
|
|
m_shader->createCombination(defines);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-06-16 21:18:15 +02:00
|
|
|
void Material::doUnload(void)
|
|
|
|
{
|
2014-10-22 22:11:36 +02:00
|
|
|
setShader(NULL);
|
2014-06-16 21:18:15 +02:00
|
|
|
|
|
|
|
ResourceManagerBase* texture_manager = m_resource_manager.get(ResourceManager::TEXTURE);
|
|
|
|
for(int i = 0; i < m_textures.size(); i++)
|
|
|
|
{
|
2014-09-27 22:15:14 +02:00
|
|
|
removeDependency(*m_textures[i].m_texture);
|
|
|
|
texture_manager->unload(*m_textures[i].m_texture);
|
2014-06-16 21:18:15 +02:00
|
|
|
}
|
|
|
|
m_textures.clear();
|
|
|
|
|
|
|
|
m_size = 0;
|
|
|
|
onEmpty();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-11-26 20:54:22 +01:00
|
|
|
bool Material::save(JsonSerializer& serializer)
|
2014-06-16 21:18:15 +02:00
|
|
|
{
|
|
|
|
serializer.beginObject();
|
|
|
|
serializer.serialize("shader", m_shader->getPath().c_str());
|
|
|
|
for (int i = 0; i < m_textures.size(); ++i)
|
|
|
|
{
|
2014-06-28 15:52:22 +02:00
|
|
|
char path[LUMIX_MAX_PATH];
|
2014-09-27 22:15:14 +02:00
|
|
|
PathUtils::getFilename(path, LUMIX_MAX_PATH, m_textures[i].m_texture->getPath().c_str());
|
2014-09-28 17:29:39 +02:00
|
|
|
serializer.beginObject("texture");
|
|
|
|
serializer.serialize("source", path);
|
|
|
|
serializer.serialize("keep_data", m_textures[i].m_keep_data);
|
|
|
|
if (m_textures[i].m_uniform[0] != '\0')
|
|
|
|
{
|
|
|
|
serializer.serialize("uniform", m_textures[i].m_uniform);
|
|
|
|
}
|
|
|
|
serializer.endObject();
|
|
|
|
}
|
|
|
|
serializer.beginArray("uniforms");
|
|
|
|
for (int i = 0; i < m_uniforms.size(); ++i)
|
|
|
|
{
|
|
|
|
serializer.beginObject();
|
|
|
|
serializer.serialize("name", m_uniforms[i].m_name);
|
2014-10-03 12:18:24 +02:00
|
|
|
serializer.serialize("is_editable", m_uniforms[i].m_is_editable);
|
2014-09-28 17:29:39 +02:00
|
|
|
switch (m_uniforms[i].m_type)
|
|
|
|
{
|
|
|
|
case Uniform::FLOAT:
|
|
|
|
serializer.serialize("float_value", m_uniforms[i].m_float);
|
|
|
|
break;
|
|
|
|
case Uniform::TIME:
|
|
|
|
serializer.serialize("time", m_uniforms[i].m_float);
|
|
|
|
break;
|
|
|
|
case Uniform::INT:
|
|
|
|
serializer.serialize("int_value", m_uniforms[i].m_int);
|
|
|
|
break;
|
|
|
|
case Uniform::MATRIX:
|
|
|
|
serializer.beginArray("matrix_value");
|
|
|
|
for (int j = 0; j < 16; ++j)
|
|
|
|
{
|
|
|
|
serializer.serializeArrayItem(m_uniforms[i].m_matrix[j]);
|
|
|
|
}
|
|
|
|
serializer.endArray();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ASSERT(false);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
serializer.endObject();
|
2014-06-16 21:18:15 +02:00
|
|
|
}
|
2014-09-28 17:29:39 +02:00
|
|
|
serializer.endArray();
|
2014-09-03 22:15:20 +02:00
|
|
|
serializer.serialize("alpha_to_coverage", m_is_alpha_to_coverage);
|
|
|
|
serializer.serialize("backface_culling", m_is_backface_culling);
|
2014-10-06 23:58:33 +02:00
|
|
|
serializer.serialize("alpha_cutout", m_is_alpha_cutout);
|
|
|
|
serializer.serialize("shadow_receiver", m_is_shadow_receiver);
|
2014-09-03 22:15:20 +02:00
|
|
|
serializer.serialize("z_test", m_is_z_test);
|
2014-06-16 21:18:15 +02:00
|
|
|
serializer.endObject();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-11-26 20:54:22 +01:00
|
|
|
void Material::deserializeUniforms(JsonSerializer& serializer)
|
2014-06-16 21:18:15 +02:00
|
|
|
{
|
|
|
|
serializer.deserializeArrayBegin();
|
|
|
|
while (!serializer.isArrayEnd())
|
|
|
|
{
|
|
|
|
Uniform& uniform = m_uniforms.pushEmpty();
|
|
|
|
serializer.nextArrayItem();
|
|
|
|
serializer.deserializeObjectBegin();
|
|
|
|
char label[256];
|
|
|
|
while (!serializer.isObjectEnd())
|
|
|
|
{
|
|
|
|
serializer.deserializeLabel(label, 255);
|
2014-10-03 12:18:24 +02:00
|
|
|
if (strcmp(label, "is_editable") == 0)
|
|
|
|
{
|
2014-11-15 14:33:55 +01:00
|
|
|
serializer.deserialize(uniform.m_is_editable, false);
|
2014-10-03 12:18:24 +02:00
|
|
|
}
|
|
|
|
else if (strcmp(label, "name") == 0)
|
2014-06-16 21:18:15 +02:00
|
|
|
{
|
2014-11-15 14:33:55 +01:00
|
|
|
serializer.deserialize(uniform.m_name, Uniform::MAX_NAME_LENGTH, "");
|
2014-09-07 01:10:24 +02:00
|
|
|
uniform.m_name_hash = crc32(uniform.m_name);
|
2014-06-16 21:18:15 +02:00
|
|
|
}
|
|
|
|
else if (strcmp(label, "int_value") == 0)
|
|
|
|
{
|
|
|
|
uniform.m_type = Uniform::INT;
|
2014-11-15 14:33:55 +01:00
|
|
|
serializer.deserialize(uniform.m_int, 0);
|
2014-06-16 21:18:15 +02:00
|
|
|
}
|
|
|
|
else if (strcmp(label, "float_value") == 0)
|
|
|
|
{
|
|
|
|
uniform.m_type = Uniform::FLOAT;
|
2014-11-15 14:33:55 +01:00
|
|
|
serializer.deserialize(uniform.m_float, 0);
|
2014-06-16 21:18:15 +02:00
|
|
|
}
|
|
|
|
else if (strcmp(label, "matrix_value") == 0)
|
|
|
|
{
|
|
|
|
uniform.m_type = Uniform::MATRIX;
|
|
|
|
serializer.deserializeArrayBegin();
|
|
|
|
for (int i = 0; i < 16; ++i)
|
|
|
|
{
|
2014-11-15 20:58:55 +01:00
|
|
|
serializer.deserializeArrayItem(uniform.m_matrix[i], 0);
|
2014-06-16 21:18:15 +02:00
|
|
|
ASSERT(i == 15 || !serializer.isArrayEnd());
|
|
|
|
}
|
|
|
|
serializer.deserializeArrayEnd();
|
|
|
|
}
|
2014-06-21 19:26:27 +02:00
|
|
|
else if (strcmp(label, "time") == 0)
|
|
|
|
{
|
|
|
|
uniform.m_type = Uniform::TIME;
|
2014-11-15 14:33:55 +01:00
|
|
|
serializer.deserialize(uniform.m_float, 0);
|
2014-06-21 19:26:27 +02:00
|
|
|
}
|
2014-06-16 21:18:15 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
ASSERT(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
serializer.deserializeObjectEnd();
|
|
|
|
}
|
|
|
|
serializer.deserializeArrayEnd();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Material::removeTexture(int i)
|
|
|
|
{
|
2014-09-27 22:15:14 +02:00
|
|
|
if (m_textures[i].m_texture)
|
2014-06-16 21:18:15 +02:00
|
|
|
{
|
2014-09-27 22:15:14 +02:00
|
|
|
removeDependency(*m_textures[i].m_texture);
|
|
|
|
m_resource_manager.get(ResourceManager::TEXTURE)->unload(*m_textures[i].m_texture);
|
2014-06-16 21:18:15 +02:00
|
|
|
}
|
|
|
|
m_textures.erase(i);
|
|
|
|
}
|
|
|
|
|
2014-09-27 22:15:14 +02:00
|
|
|
Texture* Material::getTextureByUniform(const char* uniform) const
|
|
|
|
{
|
|
|
|
for (int i = 0; i < m_textures.size(); ++i)
|
|
|
|
{
|
|
|
|
if (strcmp(m_textures[i].m_uniform, uniform) == 0)
|
|
|
|
{
|
|
|
|
return m_textures[i].m_texture;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2014-06-16 21:18:15 +02:00
|
|
|
void Material::setTexture(int i, Texture* texture)
|
|
|
|
{
|
2014-09-27 22:15:14 +02:00
|
|
|
if (m_textures[i].m_texture)
|
2014-06-16 21:18:15 +02:00
|
|
|
{
|
2014-09-27 22:15:14 +02:00
|
|
|
removeDependency(*m_textures[i].m_texture);
|
|
|
|
m_resource_manager.get(ResourceManager::TEXTURE)->unload(*m_textures[i].m_texture);
|
2014-06-16 21:18:15 +02:00
|
|
|
}
|
|
|
|
if (texture)
|
|
|
|
{
|
|
|
|
addDependency(*texture);
|
|
|
|
}
|
2014-09-27 22:15:14 +02:00
|
|
|
m_textures[i].m_texture = texture;
|
2014-06-16 21:18:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void Material::addTexture(Texture* texture)
|
|
|
|
{
|
|
|
|
if (texture)
|
|
|
|
{
|
|
|
|
addDependency(*texture);
|
|
|
|
}
|
2014-09-27 22:15:14 +02:00
|
|
|
m_textures.pushEmpty().m_texture = texture;
|
2014-06-16 21:18:15 +02:00
|
|
|
}
|
|
|
|
|
2014-10-06 23:58:33 +02:00
|
|
|
void Material::shaderLoaded(Resource::State, Resource::State)
|
|
|
|
{
|
|
|
|
updateShaderCombination();
|
|
|
|
}
|
|
|
|
|
2014-06-16 21:18:15 +02:00
|
|
|
void Material::setShader(Shader* shader)
|
|
|
|
{
|
|
|
|
if (m_shader)
|
|
|
|
{
|
|
|
|
removeDependency(*m_shader);
|
|
|
|
m_resource_manager.get(ResourceManager::SHADER)->unload(*m_shader);
|
|
|
|
}
|
|
|
|
m_shader = shader;
|
|
|
|
if (m_shader)
|
|
|
|
{
|
|
|
|
addDependency(*m_shader);
|
2014-11-28 18:46:13 +01:00
|
|
|
|
|
|
|
m_shader->onLoaded<Material, &Material::shaderLoaded>(this);
|
2014-06-16 21:18:15 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-26 20:54:22 +01:00
|
|
|
bool Material::deserializeTexture(JsonSerializer& serializer, const char* material_dir)
|
2014-09-27 22:15:14 +02:00
|
|
|
{
|
|
|
|
char path[LUMIX_MAX_PATH];
|
|
|
|
TextureInfo& info = m_textures.pushEmpty();
|
|
|
|
serializer.deserializeObjectBegin();
|
|
|
|
char label[256];
|
|
|
|
bool data_kept = false;
|
|
|
|
while (!serializer.isObjectEnd())
|
|
|
|
{
|
|
|
|
serializer.deserializeLabel(label, sizeof(label));
|
|
|
|
if (strcmp(label, "source") == 0)
|
|
|
|
{
|
2014-11-15 14:33:55 +01:00
|
|
|
serializer.deserialize(path, MAX_PATH, "");
|
2014-09-27 22:15:14 +02:00
|
|
|
if (path[0] != '\0')
|
|
|
|
{
|
2014-11-30 00:07:35 +01:00
|
|
|
char texture_path[LUMIX_MAX_PATH];
|
|
|
|
copyString(texture_path, sizeof(texture_path), material_dir);
|
|
|
|
catCString(texture_path, sizeof(texture_path), path);
|
|
|
|
info.m_texture = static_cast<Texture*>(m_resource_manager.get(ResourceManager::TEXTURE)->load(Path(texture_path)));
|
2014-09-27 22:15:14 +02:00
|
|
|
addDependency(*info.m_texture);
|
|
|
|
|
|
|
|
if (info.m_keep_data)
|
|
|
|
{
|
|
|
|
if (info.m_texture->isReady() && !info.m_texture->getData())
|
|
|
|
{
|
|
|
|
g_log_error.log("Renderer") << "Cannot keep data for texture " << m_path.c_str() << "because the texture has already been loaded.";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (!data_kept)
|
|
|
|
{
|
|
|
|
info.m_texture->addDataReference();
|
|
|
|
data_kept = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (strcmp("uniform", label) == 0)
|
|
|
|
{
|
|
|
|
Uniform& uniform = m_uniforms.pushEmpty();
|
2014-11-15 14:33:55 +01:00
|
|
|
serializer.deserialize(uniform.m_name, Uniform::MAX_NAME_LENGTH, "");
|
2014-09-27 22:15:14 +02:00
|
|
|
copyString(info.m_uniform, sizeof(info.m_uniform), uniform.m_name);
|
|
|
|
uniform.m_name_hash = crc32(uniform.m_name);
|
|
|
|
uniform.m_type = Uniform::INT;
|
|
|
|
uniform.m_int = info.m_texture ? m_textures.size() - 1 : m_textures.size();
|
|
|
|
}
|
|
|
|
else if (strcmp("keep_data", label) == 0)
|
|
|
|
{
|
2014-11-15 14:33:55 +01:00
|
|
|
serializer.deserialize(info.m_keep_data, false);
|
2014-09-27 22:15:14 +02:00
|
|
|
if (info.m_keep_data && info.m_texture)
|
|
|
|
{
|
|
|
|
if (info.m_texture->isReady() && !info.m_texture->getData())
|
|
|
|
{
|
|
|
|
g_log_error.log("Renderer") << "Cannot keep data for texture " << info.m_texture->getPath().c_str() << ", it's already loaded.";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (!data_kept)
|
|
|
|
{
|
|
|
|
data_kept = true;
|
|
|
|
info.m_texture->addDataReference();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_log_error.log("Renderer") << "Unknown data \"" << label << "\" in material " << m_path.c_str();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
serializer.deserializeObjectEnd();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-06-16 21:18:15 +02:00
|
|
|
void Material::loaded(FS::IFile* file, bool success, FS::FileSystem& fs)
|
|
|
|
{
|
2014-07-27 00:27:01 +02:00
|
|
|
PROFILE_FUNCTION();
|
2014-06-16 21:18:15 +02:00
|
|
|
if(success)
|
|
|
|
{
|
2014-11-26 20:54:22 +01:00
|
|
|
JsonSerializer serializer(m_allocator, *file, JsonSerializer::READ, m_path.c_str());
|
2014-06-16 21:18:15 +02:00
|
|
|
serializer.deserializeObjectBegin();
|
2014-06-25 23:20:33 +02:00
|
|
|
char path[LUMIX_MAX_PATH];
|
2014-06-16 21:18:15 +02:00
|
|
|
char label[256];
|
2014-06-25 23:20:33 +02:00
|
|
|
char material_dir[LUMIX_MAX_PATH];
|
|
|
|
PathUtils::getDir(material_dir, LUMIX_MAX_PATH, m_path.c_str());
|
2014-06-25 23:06:30 +02:00
|
|
|
while (!serializer.isObjectEnd())
|
2014-06-16 21:18:15 +02:00
|
|
|
{
|
|
|
|
serializer.deserializeLabel(label, 255);
|
|
|
|
if (strcmp(label, "uniforms") == 0)
|
|
|
|
{
|
|
|
|
deserializeUniforms(serializer);
|
|
|
|
}
|
2014-09-27 22:15:14 +02:00
|
|
|
else if (strcmp(label, "texture") == 0)
|
2014-06-16 21:18:15 +02:00
|
|
|
{
|
2014-09-27 22:15:14 +02:00
|
|
|
if (!deserializeTexture(serializer, material_dir))
|
2014-06-16 21:18:15 +02:00
|
|
|
{
|
2014-09-27 22:15:14 +02:00
|
|
|
onFailure();
|
|
|
|
fs.close(file);
|
|
|
|
return;
|
2014-06-16 21:18:15 +02:00
|
|
|
}
|
2014-09-27 22:15:14 +02:00
|
|
|
|
2014-06-16 21:18:15 +02:00
|
|
|
}
|
2014-10-06 23:58:33 +02:00
|
|
|
else if (strcmp(label, "alpha_cutout") == 0)
|
|
|
|
{
|
2014-11-15 14:33:55 +01:00
|
|
|
serializer.deserialize(m_is_alpha_cutout, false);
|
2014-10-06 23:58:33 +02:00
|
|
|
}
|
|
|
|
else if (strcmp(label, "shadow_receiver") == 0)
|
|
|
|
{
|
2014-11-15 14:33:55 +01:00
|
|
|
serializer.deserialize(m_is_shadow_receiver, true);
|
2014-10-06 23:58:33 +02:00
|
|
|
}
|
2014-08-10 23:17:31 +02:00
|
|
|
else if (strcmp(label, "alpha_to_coverage") == 0)
|
|
|
|
{
|
2014-11-15 14:33:55 +01:00
|
|
|
serializer.deserialize(m_is_alpha_to_coverage, false);
|
2014-08-10 23:17:31 +02:00
|
|
|
}
|
2014-06-16 21:18:15 +02:00
|
|
|
else if (strcmp(label, "shader") == 0)
|
|
|
|
{
|
2014-11-30 00:07:35 +01:00
|
|
|
serializer.deserialize(path, LUMIX_MAX_PATH, "");
|
|
|
|
setShader(static_cast<Shader*>(m_resource_manager.get(ResourceManager::SHADER)->load(Path(path))));
|
2014-06-16 21:18:15 +02:00
|
|
|
}
|
|
|
|
else if (strcmp(label, "z_test") == 0)
|
|
|
|
{
|
2014-11-15 14:33:55 +01:00
|
|
|
serializer.deserialize(m_is_z_test, true);
|
2014-06-16 21:18:15 +02:00
|
|
|
}
|
|
|
|
else if (strcmp(label, "backface_culling") == 0)
|
|
|
|
{
|
2014-11-15 14:33:55 +01:00
|
|
|
serializer.deserialize(m_is_backface_culling, true);
|
2014-06-16 21:18:15 +02:00
|
|
|
}
|
2014-07-19 20:48:21 +02:00
|
|
|
else if (strcmp(label, "depth_func") == 0)
|
|
|
|
{
|
|
|
|
char tmp[30];
|
2014-11-15 14:33:55 +01:00
|
|
|
serializer.deserialize(tmp, 30, "lequal");
|
2014-07-19 20:48:21 +02:00
|
|
|
if (strcmp(tmp, "lequal") == 0)
|
|
|
|
{
|
|
|
|
m_depth_func = DepthFunc::LEQUAL;
|
|
|
|
}
|
|
|
|
else if (strcmp(tmp, "less") == 0)
|
|
|
|
{
|
|
|
|
m_depth_func = DepthFunc::LESS;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_log_warning.log("Renderer") << "Unknown depth function " << tmp << " in material " << m_path.c_str();
|
|
|
|
}
|
|
|
|
}
|
2014-06-16 21:18:15 +02:00
|
|
|
else
|
|
|
|
{
|
2014-06-29 11:45:32 +02:00
|
|
|
g_log_warning.log("renderer") << "Unknown parameter " << label << " in material " << m_path.c_str();
|
2014-06-16 21:18:15 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
serializer.deserializeObjectEnd();
|
|
|
|
|
|
|
|
if (!m_shader)
|
|
|
|
{
|
2014-06-29 11:45:32 +02:00
|
|
|
g_log_error.log("renderer") << "Material " << m_path.c_str() << " without a shader";
|
2014-06-16 21:18:15 +02:00
|
|
|
onFailure();
|
|
|
|
fs.close(file);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_size = file->size();
|
|
|
|
decrementDepCount();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-06-29 11:45:32 +02:00
|
|
|
g_log_info.log("renderer") << "Error loading material " << m_path.c_str();
|
2014-06-16 21:18:15 +02:00
|
|
|
onFailure();
|
|
|
|
}
|
|
|
|
fs.close(file);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} // ~namespace Lumix
|