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);
|
2015-05-15 22:38:34 +02:00
|
|
|
|
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);
|
|
|
|
}
|
2015-05-31 15:48:35 +02:00
|
|
|
for (int i = 0, c = m_texture_count; i < c; ++i)
|
2014-06-16 21:18:15 +02:00
|
|
|
{
|
2015-05-31 15:48:35 +02:00
|
|
|
if (m_textures[i])
|
2015-05-28 23:30:50 +02:00
|
|
|
{
|
2015-05-31 15:48:35 +02:00
|
|
|
m_textures[i]->apply(i);
|
2015-05-28 23:30:50 +02:00
|
|
|
}
|
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:
|
2015-01-29 23:58:30 +01:00
|
|
|
renderer.setUniform(*m_shader, uniform.m_name, uniform.m_name_hash, pipeline.getScene()->getTime());
|
2014-06-21 19:26:27 +02:00
|
|
|
break;
|
2014-06-16 21:18:15 +02:00
|
|
|
default:
|
|
|
|
ASSERT(false);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-06 23:58:33 +02:00
|
|
|
|
|
|
|
void Material::updateShaderCombination()
|
|
|
|
{
|
2015-05-31 15:48:35 +02:00
|
|
|
if (isReady())
|
2014-10-06 23:58:33 +02:00
|
|
|
{
|
2015-05-31 15:48:35 +02:00
|
|
|
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" : "");
|
|
|
|
if (m_shader && m_shader->isReady())
|
|
|
|
{
|
|
|
|
for (int i = 0; i < m_shader->getTextureSlotCount(); ++i)
|
|
|
|
{
|
|
|
|
if (m_shader->getTextureSlot(i).m_define[0] != '\0' && m_textures[i])
|
|
|
|
{
|
|
|
|
catCString(defines, MAX_DEFINES_LENGTH, "#define ");
|
|
|
|
catCString(defines, MAX_DEFINES_LENGTH, m_shader->getTextureSlot(i).m_define);
|
|
|
|
catCString(defines, MAX_DEFINES_LENGTH, "\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
m_shader->createCombination(defines);
|
|
|
|
}
|
|
|
|
m_shader_combination = crc32(defines);
|
2014-10-06 23:58:33 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
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);
|
2015-05-31 15:48:35 +02:00
|
|
|
for (int i = 0; i < m_texture_count; i++)
|
2014-06-16 21:18:15 +02:00
|
|
|
{
|
2015-05-31 15:48:35 +02:00
|
|
|
if (m_textures[i])
|
2015-02-28 13:05:01 +01:00
|
|
|
{
|
2015-05-31 15:48:35 +02:00
|
|
|
removeDependency(*m_textures[i]);
|
|
|
|
texture_manager->unload(*m_textures[i]);
|
2015-02-28 13:05:01 +01:00
|
|
|
}
|
2014-06-16 21:18:15 +02:00
|
|
|
}
|
2015-05-31 15:48:35 +02:00
|
|
|
m_texture_count = 0;
|
2014-06-16 21:18:15 +02:00
|
|
|
|
|
|
|
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();
|
2015-05-28 23:30:50 +02:00
|
|
|
serializer.serialize("shader", m_shader ? m_shader->getPath().c_str() : "");
|
2015-05-31 15:48:35 +02:00
|
|
|
for (int i = 0; i < m_texture_count; ++i)
|
2014-06-16 21:18:15 +02:00
|
|
|
{
|
2014-06-28 15:52:22 +02:00
|
|
|
char path[LUMIX_MAX_PATH];
|
2015-05-31 15:48:35 +02:00
|
|
|
if (m_textures[i])
|
|
|
|
{
|
|
|
|
PathUtils::getFilename(path, LUMIX_MAX_PATH, m_textures[i]->getPath().c_str());
|
|
|
|
}
|
|
|
|
else
|
2014-09-28 17:29:39 +02:00
|
|
|
{
|
2015-05-31 15:48:35 +02:00
|
|
|
path[0] = '\0';
|
2014-09-28 17:29:39 +02:00
|
|
|
}
|
2015-05-31 15:48:35 +02:00
|
|
|
serializer.beginObject("texture");
|
|
|
|
serializer.serialize("source", path);
|
2014-09-28 17:29:39 +02:00
|
|
|
serializer.endObject();
|
|
|
|
}
|
|
|
|
serializer.beginArray("uniforms");
|
|
|
|
for (int i = 0; i < m_uniforms.size(); ++i)
|
|
|
|
{
|
|
|
|
serializer.beginObject();
|
|
|
|
serializer.serialize("name", m_uniforms[i].m_name);
|
|
|
|
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();
|
2015-05-31 15:48:35 +02:00
|
|
|
m_uniforms.clear();
|
2014-06-16 21:18:15 +02:00
|
|
|
while (!serializer.isArrayEnd())
|
|
|
|
{
|
|
|
|
Uniform& uniform = m_uniforms.pushEmpty();
|
|
|
|
serializer.nextArrayItem();
|
|
|
|
serializer.deserializeObjectBegin();
|
|
|
|
char label[256];
|
|
|
|
while (!serializer.isObjectEnd())
|
|
|
|
{
|
|
|
|
serializer.deserializeLabel(label, 255);
|
2015-05-28 23:30:50 +02:00
|
|
|
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
|
|
|
|
{
|
2015-05-30 21:12:40 +02:00
|
|
|
g_log_warning.log("material") << "Unknown label \"" << label << "\"";
|
2014-06-16 21:18:15 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
serializer.deserializeObjectEnd();
|
|
|
|
}
|
|
|
|
serializer.deserializeArrayEnd();
|
|
|
|
}
|
|
|
|
|
2015-05-28 23:30:50 +02:00
|
|
|
|
2015-05-31 15:48:35 +02:00
|
|
|
void Material::setTexturePath(int i, const Path& path)
|
2014-06-16 21:18:15 +02:00
|
|
|
{
|
2015-05-31 15:48:35 +02:00
|
|
|
if (path.length() == 0)
|
2014-06-16 21:18:15 +02:00
|
|
|
{
|
2015-05-31 15:48:35 +02:00
|
|
|
setTexture(i, nullptr);
|
2014-06-16 21:18:15 +02:00
|
|
|
}
|
2015-05-31 15:48:35 +02:00
|
|
|
else
|
2014-09-27 22:15:14 +02:00
|
|
|
{
|
2015-05-31 15:48:35 +02:00
|
|
|
Texture* texture = static_cast<Texture*>(m_resource_manager.get(ResourceManager::TEXTURE)->load(path));
|
|
|
|
setTexture(i, texture);
|
2014-09-27 22:15:14 +02:00
|
|
|
}
|
2014-12-12 00:48:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-06-16 21:18:15 +02:00
|
|
|
void Material::setTexture(int i, Texture* texture)
|
|
|
|
{
|
2015-05-31 15:48:35 +02:00
|
|
|
Texture* old_texture = m_textures[i];
|
2014-06-16 21:18:15 +02:00
|
|
|
if (texture)
|
|
|
|
{
|
|
|
|
addDependency(*texture);
|
|
|
|
}
|
2015-05-31 15:48:35 +02:00
|
|
|
m_textures[i] = texture;
|
2015-05-28 23:30:50 +02:00
|
|
|
if (old_texture)
|
|
|
|
{
|
|
|
|
removeDependency(*old_texture);
|
|
|
|
m_resource_manager.get(ResourceManager::TEXTURE)->unload(*old_texture);
|
|
|
|
}
|
2015-05-31 15:48:35 +02:00
|
|
|
if (isReady())
|
2014-06-16 21:18:15 +02:00
|
|
|
{
|
2015-05-31 15:48:35 +02:00
|
|
|
updateShaderCombination();
|
2014-06-16 21:18:15 +02:00
|
|
|
}
|
2014-10-06 23:58:33 +02:00
|
|
|
}
|
|
|
|
|
2014-12-12 00:48:06 +01:00
|
|
|
|
|
|
|
void Material::setShader(const Path& path)
|
|
|
|
{
|
|
|
|
Shader* shader = static_cast<Shader*>(m_resource_manager.get(ResourceManager::SHADER)->load(path));
|
|
|
|
setShader(shader);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-05-31 15:48:35 +02:00
|
|
|
void Material::onReady()
|
|
|
|
{
|
|
|
|
Resource::onReady();
|
|
|
|
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
|
|
|
|
2015-05-31 15:48:35 +02:00
|
|
|
if (m_shader->isReady())
|
|
|
|
{
|
|
|
|
updateShaderCombination();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Texture* Material::getTextureByUniform(const char* uniform) const
|
|
|
|
{
|
|
|
|
for (int i = 0, c = m_shader->getTextureSlotCount(); i < c; ++i)
|
|
|
|
{
|
|
|
|
if (strcmp(m_shader->getTextureSlot(i).m_uniform, uniform) == 0)
|
|
|
|
{
|
|
|
|
return m_textures[i];
|
|
|
|
}
|
2014-06-16 21:18:15 +02:00
|
|
|
}
|
2015-05-31 15:48:35 +02:00
|
|
|
return nullptr;
|
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];
|
|
|
|
serializer.deserializeObjectBegin();
|
|
|
|
char label[256];
|
|
|
|
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);
|
2015-05-31 15:48:35 +02:00
|
|
|
m_textures[m_texture_count] = static_cast<Texture*>(m_resource_manager.get(ResourceManager::TEXTURE)->load(Path(texture_path)));
|
|
|
|
addDependency(*m_textures[m_texture_count]);
|
2014-09-27 22:15:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-05-31 15:48:35 +02:00
|
|
|
g_log_warning.log("Renderer") << "Unknown data \"" << label << "\" in material " << m_path.c_str();
|
2014-09-27 22:15:14 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
serializer.deserializeObjectEnd();
|
2015-05-31 15:48:35 +02:00
|
|
|
++m_texture_count;
|
2014-09-27 22:15:14 +02:00
|
|
|
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)
|
|
|
|
{
|
2015-05-28 23:30:50 +02:00
|
|
|
m_uniforms.clear();
|
2014-12-08 01:06:51 +01:00
|
|
|
JsonSerializer serializer(*file, JsonSerializer::READ, m_path.c_str(), m_allocator);
|
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
|