Browse Source

Add Material and MaterialResource

Daniele Bartolini 12 years ago
parent
commit
2019482423

+ 3 - 0
engine/CMakeLists.txt

@@ -90,6 +90,7 @@ set (SRC
 	RenderWorld.cpp
 	Mesh.cpp
 	Sprite.cpp
+	Material.cpp
 	ConsoleServer.cpp
 )
 
@@ -100,6 +101,7 @@ set (HEADERS
 	RenderWorld.h
 	Mesh.h
 	Sprite.h
+	Material.h
 	ConsoleServer.h
 )
 
@@ -288,6 +290,7 @@ set (RESOURCE_SRC
 	resource/TextureResource.cpp
 	resource/SpriteResource.cpp
 	resource/SoundResource.cpp
+	resource/MaterialResource.cpp
 	resource/PhysicsResource.cpp
 	resource/PackageResource.cpp
 	resource/MeshResource.cpp

+ 63 - 0
engine/Material.cpp

@@ -0,0 +1,63 @@
+/*
+Copyright (c) 2013 Daniele Bartolini, Michele Rossi
+Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "Material.h"
+#include "MaterialResource.h"
+#include "Renderer.h"
+#include "Device.h"
+#include "ResourceManager.h"
+#include "TextureResource.h"
+
+namespace crown
+{
+
+//-----------------------------------------------------------------------------
+Material::Material(const MaterialResource* mr)
+	: m_resource(mr)
+{
+}
+
+//-----------------------------------------------------------------------------
+Material::~Material()
+{
+}
+
+//-----------------------------------------------------------------------------
+const MaterialResource* Material::resource()
+{
+	return m_resource;
+}
+
+//-----------------------------------------------------------------------------
+void Material::bind(Renderer& r, UniformId uniform)
+{
+	const ResourceId tr_id = m_resource->get_texture_layer(0);
+	const TextureResource* tr = (TextureResource*) device()->resource_manager()->data(tr_id);
+
+	r.set_texture(0, uniform, tr->texture(), TEXTURE_FILTER_LINEAR | TEXTURE_WRAP_CLAMP_EDGE);
+}
+
+} // namespace crown

+ 51 - 0
engine/Material.h

@@ -0,0 +1,51 @@
+/*
+Copyright (c) 2013 Daniele Bartolini, Michele Rossi
+Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#pragma once
+
+#include "RendererTypes.h"
+
+namespace crown
+{
+
+class Renderer;
+struct MaterialResource;
+
+struct Material
+{
+	Material(const MaterialResource* mr);
+	~Material();
+
+	const MaterialResource* resource();
+
+	void bind(Renderer& r, UniformId uniform);
+
+private:
+
+	const MaterialResource* m_resource;
+};
+
+} // namespace crown

+ 79 - 0
engine/resource/MaterialResource.cpp

@@ -0,0 +1,79 @@
+/*
+Copyright (c) 2013 Daniele Bartolini, Michele Rossi
+Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "MaterialResource.h"
+#include "DynamicString.h"
+#include "StringUtils.h"
+#include "Hash.h"
+#include "JSONParser.h"
+#include "Filesystem.h"
+
+namespace crown
+{
+namespace material_resource
+{
+
+//-----------------------------------------------------------------------------
+void compile(Filesystem& fs, const char* resource_path, File* out_file)
+{
+	File* file = fs.open(resource_path, FOM_READ);
+	char* buf = (char*)default_allocator().allocate(file->size());
+	file->read(buf, file->size());
+
+	JSONParser json(buf);
+	JSONElement root = json.root();
+
+	// Read texture layers
+	List<ResourceId> texture_layers(default_allocator());
+
+	JSONElement tl = root.key("texture_layers");
+	for (uint32_t i = 0; i < tl.size(); i++)
+	{
+		DynamicString tex; tex = tl[i].string_value(); tex += ".texture";
+		ResourceId tex_id; tex_id.id = hash::murmur2_64(tex.c_str(), string::strlen(tex.c_str()), 0);
+		texture_layers.push_back(tex_id);
+	}
+
+	fs.close(file);
+	default_allocator().deallocate(buf);
+
+	// Write resource
+	MaterialHeader mh;
+	mh.num_texture_layers = texture_layers.size();
+
+	uint32_t offt = sizeof(MaterialHeader);
+	mh.texture_layers_offset = offt;
+
+	out_file->write((char*) &mh, sizeof(MaterialHeader));
+
+	if (mh.num_texture_layers)
+	{
+		out_file->write((char*) texture_layers.begin(), sizeof(ResourceId) * texture_layers.size());
+	}
+}
+
+} // namespace material_resource
+} // namespace crown

+ 34 - 8
engine/resource/MaterialResource.h

@@ -37,6 +37,12 @@ OTHER DEALINGS IN THE SOFTWARE.
 namespace crown
 {
 
+struct MaterialHeader
+{
+	uint32_t num_texture_layers;
+	uint32_t texture_layers_offset;
+};
+
 /// A material describes the visual properties of a surface.
 /// It is primarly intended for rendering purposes but can
 /// also be used to drive other types of systems such as sounds or physics.
@@ -45,28 +51,48 @@ class MaterialResource
 public:
 
 	//-----------------------------------------------------------------------------
-	static void* load(Allocator& /*allocator*/, Bundle& /*bundle*/, ResourceId /*id*/)
+	static void* load(Allocator& allocator, Bundle& bundle, ResourceId id)
 	{
-		return NULL;
+		File* file = bundle.open(id);
+		const size_t file_size = file->size();
+
+		void* res = allocator.allocate(file_size);
+		file->read(res, file_size);
+
+		bundle.close(file);
+
+		return res;
 	}
 
 	//-----------------------------------------------------------------------------
-	static void online(void* material)
+	static void online(void* /*resource*/)
 	{
-		(void)material;
-		// TODO
 	}
 
 	//-----------------------------------------------------------------------------
-	static void unload(Allocator& /*allocator*/, void* /*material*/)
+	static void unload(Allocator& a, void* res)
 	{
-		// TODO
+		CE_ASSERT_NOT_NULL(res);
+		a.deallocate(res);
 	}
 
 	//-----------------------------------------------------------------------------
 	static void offline(void* /*resource*/)
 	{
-		// TODO
+	}
+
+	//-----------------------------------------------------------------------------
+	uint32_t num_texture_layers() const
+	{
+		return ((MaterialHeader*) this)->num_texture_layers;
+	}
+
+	//-----------------------------------------------------------------------------
+	ResourceId get_texture_layer(uint32_t i) const
+	{
+		MaterialHeader* h = (MaterialHeader*) this;
+		ResourceId* begin = (ResourceId*) (((char*) this) + h->texture_layers_offset);
+		return begin[i];
 	}
 
 private:

+ 32 - 0
engine/resource/PackageResource.cpp

@@ -57,6 +57,7 @@ void compile(Filesystem& fs, const char* resource_path, File* out_file)
 	List<ResourceId> m_unit(default_allocator());
 	List<ResourceId> m_sprite(default_allocator());
 	List<ResourceId> m_physics(default_allocator());
+	List<ResourceId> m_materials(default_allocator());
 
 	// Check for resource types
 	if (root.has_key("texture"))
@@ -233,6 +234,31 @@ void compile(Filesystem& fs, const char* resource_path, File* out_file)
 		}	
 	}
 
+	// Check for materials
+	if (root.has_key("material"))
+	{
+		JSONElement materials_array = root.key("material");
+		uint32_t materials_array_size = materials_array.size();
+
+		for (uint32_t i = 0; i < materials_array_size; i++)
+		{
+			TempAllocator256 alloc;
+			DynamicString materials_name(alloc);
+			materials_name += materials_array[i].string_value();
+			materials_name += ".material";
+
+			if (!fs.is_file(materials_name.c_str()))
+			{
+				Log::e("Material '%s' does not exist.", materials_name.c_str());
+				return;
+			}
+
+			ResourceId id;
+			id.id = hash::murmur2_64(materials_name.c_str(), string::strlen(materials_name.c_str()), 0);
+			m_materials.push_back(id);
+		}
+	}
+
 	PackageHeader header;
 	header.num_textures = m_texture.size();
 	header.num_scripts = m_script.size();
@@ -241,6 +267,7 @@ void compile(Filesystem& fs, const char* resource_path, File* out_file)
 	header.num_units = m_unit.size();
 	header.num_sprites = m_sprite.size();
 	header.num_physics = m_physics.size();
+	header.num_materials = m_materials.size();
 
 	header.textures_offset = sizeof(PackageHeader);
 	header.scripts_offset  = header.textures_offset + sizeof(ResourceId) * header.num_textures;
@@ -249,6 +276,7 @@ void compile(Filesystem& fs, const char* resource_path, File* out_file)
 	header.units_offset = header.meshes_offset + sizeof(ResourceId) * header.num_meshes;
 	header.sprites_offset = header.units_offset + sizeof(ResourceId) * header.num_units;
 	header.physics_offset = header.sprites_offset + sizeof(ResourceId) * header.num_sprites;
+	header.materials_offset = header.physics_offset + sizeof(ResourceId) * header.num_physics;
 
 	out_file->write((char*) &header, sizeof(PackageHeader));
 
@@ -280,6 +308,10 @@ void compile(Filesystem& fs, const char* resource_path, File* out_file)
 	{
 		out_file->write((char*) m_physics.begin(), sizeof(ResourceId) * header.num_physics);
 	}
+	if (m_materials.size() > 0)
+	{
+		out_file->write((char*) m_materials.begin(), sizeof(ResourceId) * header.num_materials);
+	}
 }
 
 } // namespace package_resource

+ 18 - 1
engine/resource/PackageResource.h

@@ -52,6 +52,8 @@ struct PackageHeader
 	uint32_t sprites_offset;
 	uint32_t num_physics;
 	uint32_t physics_offset;
+	uint32_t num_materials;
+	uint32_t materials_offset;
 };
 
 struct PackageResource
@@ -129,6 +131,12 @@ struct PackageResource
 		return ((PackageHeader*) this)->num_physics;
 	}
 
+	//-----------------------------------------------------------------------------
+	uint32_t num_materials() const
+	{
+		return ((PackageHeader*) this)->num_materials;
+	}
+
 	//-----------------------------------------------------------------------------
 	ResourceId get_texture_id(uint32_t i) const
 	{
@@ -190,7 +198,16 @@ struct PackageResource
 
 		ResourceId* begin = (ResourceId*) ((char*) this + ((PackageHeader*) this)->physics_offset);
 		return begin[i];
-	}	
+	}
+
+	//-----------------------------------------------------------------------------
+	ResourceId get_material_id(uint32_t i) const
+	{
+		CE_ASSERT(i < num_materials(), "Index out of bounds");
+
+		ResourceId* begin = (ResourceId*) ((char*) this + ((PackageHeader*) this)->materials_offset);
+		return begin[i];
+	}
 
 private:
 

+ 10 - 0
engine/resource/ResourcePackage.h

@@ -87,11 +87,21 @@ public:
 		{
 			m_resource_manager->load(PHYSICS_TYPE, m_package->get_physics_id(i));
 		}
+
+		for (uint32_t i = 0; i < m_package->num_materials(); i++)
+		{
+			m_resource_manager->load(MATERIAL_TYPE, m_package->get_material_id(i));
+		}
 	}
 
 	/// Unloads all the resources in the package.
 	void unload()
 	{
+		for (uint32_t i = 0; i < m_package->num_materials(); i++)
+		{
+			m_resource_manager->unload(m_package->get_material_id(i));
+		}
+
 		for (uint32_t i = 0; i < m_package->num_physics(); i++)
 		{
 			m_resource_manager->unload(m_package->get_physics_id(i));

+ 2 - 0
engine/resource/ResourceRegistry.cpp

@@ -33,6 +33,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "PackageResource.h"
 #include "UnitResource.h"
 #include "PhysicsResource.h"
+#include "MaterialResource.h"
 
 namespace crown
 {
@@ -47,6 +48,7 @@ static const ResourceCallback RESOURCE_CALLBACK_REGISTRY[] =
 	{ SPRITE_TYPE, SpriteResource::load, SpriteResource::unload, SpriteResource::online, SpriteResource::offline},
 	{ PACKAGE_TYPE, PackageResource::load, PackageResource::unload, PackageResource::online, PackageResource::offline },
 	{ PHYSICS_TYPE, PhysicsResource::load, PhysicsResource::unload, PhysicsResource::online, PhysicsResource::offline },
+	{ MATERIAL_TYPE, MaterialResource::load, MaterialResource::unload, MaterialResource::online, MaterialResource::offline },	
 	{ 0, NULL, NULL, NULL, NULL }
 };