Kaynağa Gözat

Async tex loading

Panagiotis Christopoulos Charitos 15 yıl önce
ebeveyn
işleme
b027842907

Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
build/debug/Makefile


+ 12 - 8
src/Core/AsyncLoader.cpp

@@ -15,11 +15,11 @@ void AsyncLoader::start()
 //======================================================================================================================
 //======================================================================================================================
 // load                                                                                                                =
 // load                                                                                                                =
 //======================================================================================================================
 //======================================================================================================================
-void AsyncLoader::load(const char* filename, bool (*func)(const char*, void*), void* storage)
+void AsyncLoader::load(const char* filename, void (*loadCallback)(const char*, void*), void* storage)
 {
 {
 	INFO("New load request for \"" << filename << "\"");
 	INFO("New load request for \"" << filename << "\"");
 	boost::mutex::scoped_lock lock(mutexReq);
 	boost::mutex::scoped_lock lock(mutexReq);
-	Request f = {filename, func, storage};
+	Request f = {filename, loadCallback, storage};
 	requests.push_back(f);
 	requests.push_back(f);
 	lock.unlock();
 	lock.unlock();
 
 
@@ -50,11 +50,15 @@ void AsyncLoader::workingFunc()
 		}
 		}
 
 
 		// Exec the loader
 		// Exec the loader
-		bool ok = req.func(req.filename.c_str(), req.storage);
-
-		if(!ok)
+		bool ok = true;
+		try
+		{
+			req.loadCallback(req.filename.c_str(), req.storage);
+		}
+		catch(std::exception& e)
 		{
 		{
-			ERROR("Loading \"" << req.filename << "\" failed");
+			ERROR("Loading \"" << req.filename << "\" failed: " << e.what());
+			ok = false;
 		}
 		}
 
 
 		// Put back the response
 		// Put back the response
@@ -68,9 +72,9 @@ void AsyncLoader::workingFunc()
 
 
 
 
 //======================================================================================================================
 //======================================================================================================================
-// getLoaded                                                                                                           =
+// pollForFinished                                                                                                     =
 //======================================================================================================================
 //======================================================================================================================
-bool AsyncLoader::getLoaded(std::string& filename, void* buff, bool& ok)
+bool AsyncLoader::pollForFinished(std::string& filename, void* buff, bool& ok)
 {
 {
 	boost::mutex::scoped_lock lock(mutexResp);
 	boost::mutex::scoped_lock lock(mutexResp);
 	if(responses.empty())
 	if(responses.empty())

+ 5 - 5
src/Core/AsyncLoader.h

@@ -23,25 +23,25 @@ class AsyncLoader
 
 
 		/// Tell me what to load, how to load it and where to store it. This puts a new loading request in the stack
 		/// Tell me what to load, how to load it and where to store it. This puts a new loading request in the stack
 		/// @param filename The file to load
 		/// @param filename The file to load
-		/// @param func How to load the file. The function should gets a filename (const char*) and the storage. It returns
-		/// false if there was a loading error
+		/// @param loadCallback How to load the file. The function should gets a filename (const char*) and the storage.
+		/// It can throw an exception in case of a loading error
 		/// @param storage This points to the storage that the loader will store the data. The storage should not be
 		/// @param storage This points to the storage that the loader will store the data. The storage should not be
 		/// destroyed from other threads
 		/// destroyed from other threads
-		void load(const char* filename, bool (*func)(const char*, void*), void* storage);
+		void load(const char* filename, void (*loadCallback)(const char*, void*), void* storage);
 
 
 		/// Query the loader and see if its got something
 		/// Query the loader and see if its got something
 		/// @param[out] filename The file that finished loading
 		/// @param[out] filename The file that finished loading
 		/// @param[out] storage The data are stored in this buffer
 		/// @param[out] storage The data are stored in this buffer
 		/// @param[out] ok Its true if the loading of the resource was ok
 		/// @param[out] ok Its true if the loading of the resource was ok
 		/// @return Return true if there is something that finished loading
 		/// @return Return true if there is something that finished loading
-		bool getLoaded(std::string& filename, void* storage, bool& ok);
+		bool pollForFinished(std::string& filename, void* storage, bool& ok);
 
 
 	private:
 	private:
 		/// A loading request
 		/// A loading request
 		struct Request
 		struct Request
 		{
 		{
 			std::string filename;
 			std::string filename;
-			bool (*func)(const char*, void*);
+			void (*loadCallback)(const char*, void*);
 			void* storage;
 			void* storage;
 		};
 		};
 
 

+ 2 - 0
src/Renderer/BufferObjects/Vao.h

@@ -31,6 +31,7 @@ class Vao
 		void destroy();
 		void destroy();
 
 
 		/// Attach an array buffer VBO. See @link http://www.opengl.org/sdk/docs/man3/xhtml/glVertexAttribPointer.xml
 		/// Attach an array buffer VBO. See @link http://www.opengl.org/sdk/docs/man3/xhtml/glVertexAttribPointer.xml
+		/// @endlink
 		/// @param vbo The VBO to attach
 		/// @param vbo The VBO to attach
 		/// @param attribVar For the shader attribute location
 		/// @param attribVar For the shader attribute location
 		/// @param size Specifies the number of components per generic vertex attribute. Must be 1, 2, 3, 4
 		/// @param size Specifies the number of components per generic vertex attribute. Must be 1, 2, 3, 4
@@ -42,6 +43,7 @@ class Vao
 		                          GLboolean normalized, GLsizei stride, const GLvoid* pointer);
 		                          GLboolean normalized, GLsizei stride, const GLvoid* pointer);
 
 
 		/// Attach an array buffer VBO. See @link http://www.opengl.org/sdk/docs/man3/xhtml/glVertexAttribPointer.xml
 		/// Attach an array buffer VBO. See @link http://www.opengl.org/sdk/docs/man3/xhtml/glVertexAttribPointer.xml
+		/// @endlink
 		/// @param vbo The VBO to attach
 		/// @param vbo The VBO to attach
 		/// @param attribVarLocation Shader attribute location
 		/// @param attribVarLocation Shader attribute location
 		/// @param size Specifies the number of components per generic vertex attribute. Must be 1, 2, 3, 4
 		/// @param size Specifies the number of components per generic vertex attribute. Must be 1, 2, 3, 4

+ 24 - 0
src/Resources/Core/ResourceManager.cpp

@@ -13,6 +13,9 @@
 #include "Skin.h"
 #include "Skin.h"
 #include "DummyRsrc.h"
 #include "DummyRsrc.h"
 
 
+#include "Image.h"
+#include "Logger.h"
+
 
 
 // Because we are bored to write the same
 // Because we are bored to write the same
 #define SPECIALIZE_TEMPLATE_STUFF(type__, container__) \
 #define SPECIALIZE_TEMPLATE_STUFF(type__, container__) \
@@ -41,3 +44,24 @@ SPECIALIZE_TEMPLATE_STUFF(Script, scripts)
 SPECIALIZE_TEMPLATE_STUFF(Model, models)
 SPECIALIZE_TEMPLATE_STUFF(Model, models)
 SPECIALIZE_TEMPLATE_STUFF(Skin, skins)
 SPECIALIZE_TEMPLATE_STUFF(Skin, skins)
 SPECIALIZE_TEMPLATE_STUFF(DummyRsrc, dummies)
 SPECIALIZE_TEMPLATE_STUFF(DummyRsrc, dummies)
+
+
+//======================================================================================================================
+// allocAndLoadRsrc <Texture>                                                                                          =
+//======================================================================================================================
+template<>
+void ResourceManager::allocAndLoadRsrc(const char* filename, Texture*& ptr)
+{
+	// Load the dummy
+	if(dummyTex.get() == NULL)
+	{
+		dummyTex.reset(new Texture);
+		dummyTex->load("gfx/default.png");
+	}
+	
+	// Send a loading request
+	rsrcAsyncLoadingReqsHandler.sendNewLoadingRequest(filename, &ptr);
+
+	ptr = dummyTex.get();
+}
+

+ 18 - 38
src/Resources/Core/ResourceManager.h

@@ -1,13 +1,14 @@
 #ifndef RESOURCE_MANAGER_H
 #ifndef RESOURCE_MANAGER_H
 #define RESOURCE_MANAGER_H
 #define RESOURCE_MANAGER_H
 
 
-#include <list>
 #include <boost/ptr_container/ptr_vector.hpp>
 #include <boost/ptr_container/ptr_vector.hpp>
+#include <memory.h>
 #include <string>
 #include <string>
 #include "Singleton.h"
 #include "Singleton.h"
 #include "AsyncLoader.h"
 #include "AsyncLoader.h"
 #include "Properties.h"
 #include "Properties.h"
 #include "RsrcHook.h"
 #include "RsrcHook.h"
+#include "RsrcAsyncLoadingReqsHandler.h"
 
 
 
 
 class Texture;
 class Texture;
@@ -33,14 +34,14 @@ class ResourceManager
 		struct Types
 		struct Types
 		{
 		{
 			typedef RsrcHook<Type> Hook;
 			typedef RsrcHook<Type> Hook;
-			typedef std::list<Hook> Container;
+			typedef boost::ptr_vector<Hook> Container;
 			typedef typename Container::iterator Iterator;
 			typedef typename Container::iterator Iterator;
 			typedef typename Container::const_iterator ConstIterator;
 			typedef typename Container::const_iterator ConstIterator;
 		};
 		};
 
 
 		/// Load a resource
 		/// Load a resource
 		/// See if its already loaded, if its not:
 		/// See if its already loaded, if its not:
-		/// - Create a instance
+		/// - Create an instance
 		/// - Call load method of the instance
 		/// - Call load method of the instance
 		/// If its loaded:
 		/// If its loaded:
 		/// - Increase the resource counter
 		/// - Increase the resource counter
@@ -50,6 +51,9 @@ class ResourceManager
 		/// Unload a resource if no one uses it
 		/// Unload a resource if no one uses it
 		template<typename Type>
 		template<typename Type>
 		void unload(const typename Types<Type>::Hook& info);
 		void unload(const typename Types<Type>::Hook& info);
+		
+		/// See RsrcAsyncLoadingReqsHandler::serveFinishedRequests
+		void serveFinishedRequests(uint maxTime) {rsrcAsyncLoadingReqsHandler.serveFinishedRequests();}
 
 
 	private:
 	private:
 		/// @name Containers
 		/// @name Containers
@@ -68,41 +72,11 @@ class ResourceManager
 		Types<DummyRsrc>::Container dummies;
 		Types<DummyRsrc>::Container dummies;
 		/// @}
 		/// @}
 
 
-		/// Request for the AsyncLoader [Base class]
-		class LoadingRequestBase
-		{
-			public:
-				enum RequestType
-				{
-					RT_IMAGE,
-					RT_MESH_DATA
-				};
-
-				LoadingRequestBase(const char* filename_, RequestType type_): filename(filename_), type(type_) {}
-
-				GETTER_R(std::string, filename, getFilename)
-				GETTER_R(RequestType, type, getType)
-
-			private:
-				std::string filename;
-				RequestType type;
-		};
-
-		/// Request for the AsyncLoader
-		template<typename Type>
-		struct LoadingRequest: public LoadingRequestBase
-		{
-			public:
-				//LoadingRequestBase
-				//GETTER_RW(Type, object, getObject)
-
-			private:
-				Type object; ///< The object to load
-		};
-
-		boost::ptr_vector<LoadingRequestBase> loadingRequests; ///< Loading requests
-
-		AsyncLoader al; ///< Asynchronous loader
+		RsrcAsyncLoadingReqsHandler rsrcAsyncLoadingReqsHandler;
+		
+		/// This will be used in every new texture until the async loader is finished with the loading of tha actual
+		/// texure. Its initialized when its first needed so that we wont have colflicts with opengl initialization.
+		std::auto_ptr<Texture> dummyTex;
 
 
 		/// Find a resource using the filename
 		/// Find a resource using the filename
 		template<typename Type>
 		template<typename Type>
@@ -119,6 +93,12 @@ class ResourceManager
 		/// Unload a resource if no one uses it. This is the real deal
 		/// Unload a resource if no one uses it. This is the real deal
 		template<typename Type>
 		template<typename Type>
 		void unloadR(const typename Types<Type>::Hook& info);
 		void unloadR(const typename Types<Type>::Hook& info);
+		
+		/// Allocate and load a resource.
+		/// This method allocates memory for a resource and loads it (calls the load metod). Its been used by the load
+		/// method. Its a sepperate method because we want to specialize it for async loaded resources
+		template<typename Type>
+		void allocAndLoadRsrc(const char* filename, Type*& ptr);
 };
 };
 
 
 
 

+ 30 - 18
src/Resources/Core/ResourceManager.inl.h

@@ -1,7 +1,31 @@
-#include <boost/type_traits.hpp>
 #include "Exception.h"
 #include "Exception.h"
 
 
 
 
+//======================================================================================================================
+// allocAndLoadRsrc                                                                                                    =
+//======================================================================================================================
+template<typename Type>
+void ResourceManager::allocAndLoadRsrc(const char* filename, Type*& newInstance)
+{
+	newInstance = NULL;
+
+	try
+	{
+		newInstance = new Type();
+		newInstance->load(filename);
+	}
+	catch(std::exception& e)
+	{
+		if(newInstance != NULL)
+		{
+			delete newInstance;
+		}
+		
+		throw EXCEPTION(e.what());
+	}
+}
+
+
 //======================================================================================================================
 //======================================================================================================================
 // loadRsrc                                                                                                            =
 // loadRsrc                                                                                                            =
 //======================================================================================================================
 //======================================================================================================================
@@ -22,25 +46,13 @@ typename ResourceManager::Types<Type>::Hook& ResourceManager::load(const char* f
 	// else create new, load it and update the container
 	// else create new, load it and update the container
 	else
 	else
 	{
 	{
-		Type* newInstance = NULL;
-
-		try
-		{
-			newInstance = new Type();
-			newInstance->load(filename);
-		}
-		catch(std::exception& e)
-		{
-			if(newInstance != NULL)
-			{
-				delete newInstance;
-			}
-		}
-
-		c.push_back(typename Types<Type>::Hook(filename, 1, newInstance));
+		c.push_back(new typename Types<Type>::Hook(filename, 1, allocAndLoadRsrc<Type>(filename)));
+		
+		it = c.end();
+		--it;
 	}
 	}
 
 
-	return c.back();
+	return *it;
 }
 }
 
 
 
 

+ 65 - 0
src/Resources/Core/RsrcAsyncLoadingReqsHandler.cpp

@@ -0,0 +1,65 @@
+#include "RsrcAsyncLoadingReqsHandler.h"
+#include "Texture.h"
+
+
+//======================================================================================================================
+// sendNewLoadingRequest <Texture>                                                                                     =
+//======================================================================================================================
+template<>
+void RsrcAsyncLoadingReqsHandler::sendNewLoadingRequest<Texture>(const char* filename, Texture** objToLoad)
+{
+	TextureRequest* req = new TextureRequest(filename, objToLoad);
+	requests.push_back(req);
+	al.load(filename, &loadImageCallback, (void*)&req->getHelperObj());
+}
+
+
+//======================================================================================================================
+// serveFinishedRequests                                                                                               =
+//======================================================================================================================
+void RsrcAsyncLoadingReqsHandler::serveFinishedRequests(uint /*maxTime*/)
+{
+	while(1)
+	{
+		std::string filename;
+		void* storage = NULL;
+		bool ok;
+		
+		if(!al.pollForFinished(filename, storage, ok)) // If no pending 
+		{
+			break;
+		}
+
+		LoadingRequestBase& req = requests.front();	
+		RASSERT_THROW_EXCEPTION(filename != req.getFilename());
+
+		switch(req.getType())
+		{
+			case LoadingRequestBase::RT_TEXTURE:
+			{
+				TextureRequest& texReq = static_cast<TextureRequest&>(req);
+				Texture* tex = new Texture;
+				tex->load(texReq.getHelperObj());
+				//*texReq.getObjToLoad()->load(texReq.getHelperObj());
+				break;
+			}
+				
+			case LoadingRequestBase::RT_MESH:
+				/// @todo handle it
+				break;
+		}
+		
+		requests.pop_front();
+	}
+}
+
+
+//======================================================================================================================
+// loadImageCallback                                                                                                   =
+//======================================================================================================================
+void RsrcAsyncLoadingReqsHandler::loadImageCallback(const char* filename, void* img_)
+{
+	Image* img = (Image*)img_;
+	img->load(filename);
+}
+

+ 95 - 0
src/Resources/Core/RsrcAsyncLoadingReqsHandler.h

@@ -0,0 +1,95 @@
+#ifndef RSRC_ASYNC_LOADING_REQS_HANDLER_H
+#define RSRC_ASYNC_LOADING_REQS_HANDLER_H
+
+#include <string>
+#include <boost/ptr_container/ptr_list.hpp>
+#include "AsyncLoader.h"
+#include "Properties.h"
+#include "Image.h"
+#include "MeshData.h"
+
+
+// Dont even think to include the files those:
+class Texture;
+class Mesh;
+
+
+/// Handles the loading requests on behalf of the resource manager. Its a different class because we want to keep the
+/// source of the manager clean
+class RsrcAsyncLoadingReqsHandler
+{
+	public:
+		/// Send a loading requst to an AsyncLoader
+		/// @tparam Type It should be Texture or Mesh
+		/// @param filename The file to load
+		/// @param objToLoad Pointer to a pointer to the object to load asynchronusly
+		template<typename Type>
+		void sendNewLoadingRequest(const char* filename, Type** objToLoad);
+		
+		/// Serve the finished requests. This should be called periodicaly in the main loop
+		/// @param maxTime The max time to spend serving finished requests in a single call. If for example there are many
+		/// requests it wont serve them all at one time, it will leave some for later
+		void serveFinishedRequests(uint maxTime);
+		
+	
+	private:
+		/// Request for the AsyncLoader [Base class]
+		class LoadingRequestBase
+		{
+			public:
+				enum RequestType
+				{
+					RT_TEXTURE,
+					RT_MESH
+				};
+
+				LoadingRequestBase(const char* filename_, RequestType type_): filename(filename_), type(type_) {}
+
+				GETTER_R(std::string, filename, getFilename)
+				GETTER_R(RequestType, type, getType)
+
+			private:
+				std::string filename;
+				RequestType type;
+		};
+
+		/// Request for the AsyncLoader. The combination of the template params is: <MeshData, Mesh> or <Image, Texture>
+		template<typename HelperType, typename LoadType, LoadingRequestBase::RequestType type>
+		struct LoadingRequest: public LoadingRequestBase
+		{
+			public:
+				LoadingRequest(const char* filename, LoadType** objToLoad_);
+				GETTER_R(HelperType, helperObj, getHelperObj)
+				LoadType** getObjToLoad() {return objToLoad;}
+
+			private:
+				HelperType helperObj; ///< The object to pass to the AsyncLoader
+				LoadType** objToLoad; ///< The object to serve in the main thread
+		};
+		
+		typedef LoadingRequest<Image, Texture, LoadingRequestBase::RT_TEXTURE> TextureRequest;
+		typedef LoadingRequest<MeshData, Mesh, LoadingRequestBase::RT_MESH> MeshRequest;
+		
+		boost::ptr_list<LoadingRequestBase> requests; ///< Loading requests
+
+		AsyncLoader al; ///< Asynchronous loader
+		
+		/// @name Async loader callbacks
+		/// @{
+		
+		/// Load image callback. Passed to al
+		static void loadImageCallback(const char* filename, void* img);
+		
+		/// @}
+};
+
+
+template<typename HelperType, typename LoadType, RsrcAsyncLoadingReqsHandler::LoadingRequestBase::RequestType type_>
+inline RsrcAsyncLoadingReqsHandler::LoadingRequest<HelperType, LoadType, type_>::LoadingRequest(const char* filename, 
+                                                                                                LoadType** objToLoad_):
+LoadingRequestBase(filename, type_),
+objToLoad(objToLoad_)
+{}
+
+
+#endif

+ 10 - 5
src/Resources/Helpers/Image.h

@@ -18,10 +18,15 @@ class Image
 			CT_RGBA /// RGB plus alpha
 			CT_RGBA /// RGB plus alpha
 		};
 		};
 
 
+		/// Do nothing
+		Image() {}
+
 		/// Load an image
 		/// Load an image
 		/// @param[in] filename The image file to load
 		/// @param[in] filename The image file to load
 		/// @exception Exception
 		/// @exception Exception
 		Image(const char* filename) {load(filename);}
 		Image(const char* filename) {load(filename);}
+		
+		/// Do nothing
 		~Image() {}
 		~Image() {}
 
 
 		/// @name Accessors
 		/// @name Accessors
@@ -31,6 +36,11 @@ class Image
 		ColorType getColorType() const {return type;}
 		ColorType getColorType() const {return type;}
 		const Vec<uchar>& getData() const {return data;}
 		const Vec<uchar>& getData() const {return data;}
 		/// @}
 		/// @}
+		
+		/// Load an image file
+		/// @param[in] filename The file to load
+		/// @exception Exception
+		void load(const char* filename);
 
 
 	private:
 	private:
 		uint width; ///< Image width
 		uint width; ///< Image width
@@ -44,11 +54,6 @@ class Image
 		static uchar tgaHeaderCompressed[12];
 		static uchar tgaHeaderCompressed[12];
 		/// @}
 		/// @}
 
 
-		/// Load an image file
-		/// @param[in] filename The file to load
-		/// @exception Exception
-		void load(const char* filename);
-
 		/// Load a TGA
 		/// Load a TGA
 		/// @param[in] filename The file to load
 		/// @param[in] filename The file to load
 		/// @exception Exception
 		/// @exception Exception

+ 69 - 109
src/Resources/Texture.cpp

@@ -40,126 +40,86 @@ Texture::~Texture()
 
 
 
 
 //======================================================================================================================
 //======================================================================================================================
-// load                                                                                                                =
+// load (const char*)                                                                                                  =
 //======================================================================================================================
 //======================================================================================================================
 void Texture::load(const char* filename)
 void Texture::load(const char* filename)
 {
 {
 	try
 	try
 	{
 	{
-		/// @todo delete this
-		if(std::string("textures/stone.001.diff.tga") == filename)
-		{
-			target = GL_TEXTURE_2D;
-			glGenTextures(1, &glId);
-			bind(LAST_TEX_UNIT);
-
-			setRepeat(true);
-			int internalFormat;
-			int format;
-			int type;
-			internalFormat = GL_RGBA;
+		load(Image(filename));
+	}
+	catch(std::exception& e)
+	{
+		throw EXCEPTION("File \"" + filename + "\": " + e.what());
+	}
+}
+
+
+//======================================================================================================================
+// load (const Image&)                                                                                                 =
+//======================================================================================================================
+void Texture::load(const Image& img)
+{
+	target = GL_TEXTURE_2D;
+	if(isLoaded())
+	{
+		throw EXCEPTION("Texture already loaded");
+	}
+
+	// bind the texture
+	glGenTextures(1, &glId);
+	bind(LAST_TEX_UNIT);
+	if(mipmappingEnabled)
+	{
+		setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+	}
+	else
+	{
+		setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+	}
+
+	setTexParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+	setTexParameter(GL_TEXTURE_MAX_ANISOTROPY_EXT, float(anisotropyLevel));
+
+	// leave to GL_REPEAT. There is not real performance hit
+	setRepeat(true);
+
+	// chose formats
+	int internalFormat;
+	int format;
+	int type;
+	switch(img.getColorType())
+	{
+		case Image::CT_R:
+			internalFormat = (compressionEnabled) ? GL_COMPRESSED_RED : GL_RED;
+			format = GL_RED;
+			type = GL_UNSIGNED_BYTE;
+			break;
+
+		case Image::CT_RGB:
+			internalFormat = (compressionEnabled) ? GL_COMPRESSED_RGB : GL_RGB;
+			format = GL_RGB;
+			type = GL_UNSIGNED_BYTE;
+			break;
+
+		case Image::CT_RGBA:
+			internalFormat = (compressionEnabled) ? GL_COMPRESSED_RGBA : GL_RGBA;
 			format = GL_RGBA;
 			format = GL_RGBA;
 			type = GL_UNSIGNED_BYTE;
 			type = GL_UNSIGNED_BYTE;
+			break;
 
 
-			int w = 100, h = 100;
-			int level = 0;
-			uint cols[3] = {0xFF0000FF, 0xFF00FF00, 0xFFFF0000};
-			uint ii = 0;
-			while(1)
-			{
-				uint col = cols[ii++];
-				Vec<uint> buff(w * h, col);
-				glTexImage2D(target, level, internalFormat, w, h, 0, format, type, &buff[0]);
-				++level;
-				w /= 2;
-				h /= 2;
-				if(ii > 2)
-				{
-					ii = 0;
-				}
-
-				if(w == 0 || h == 0)
-				{
-					break;
-				}
-			}
-
-			setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
-			//setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-			setTexParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-			//setTexParameter(GL_TEXTURE_MAX_ANISOTROPY_EXT, float(anisotropyLevel));
-			return;
-		}
-
-
-
-		target = GL_TEXTURE_2D;
-		if(isLoaded())
-		{
-			throw EXCEPTION("Texture already loaded");
-		}
-
-		Image img(filename);
-
-		// bind the texture
-		glGenTextures(1, &glId);
-		bind(LAST_TEX_UNIT);
-		if(mipmappingEnabled)
-		{
-			setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
-		}
-		else
-		{
-			setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-		}
-
-		setTexParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
-		setTexParameter(GL_TEXTURE_MAX_ANISOTROPY_EXT, float(anisotropyLevel));
-
-		// leave to GL_REPEAT. There is not real performance hit
-		setRepeat(true);
-
-		// chose formats
-		int internalFormat;
-		int format;
-		int type;
-		switch(img.getColorType())
-		{
-			case Image::CT_R:
-				internalFormat = (compressionEnabled) ? GL_COMPRESSED_RED : GL_RED;
-				format = GL_RED;
-				type = GL_UNSIGNED_BYTE;
-				break;
-
-			case Image::CT_RGB:
-				internalFormat = (compressionEnabled) ? GL_COMPRESSED_RGB : GL_RGB;
-				format = GL_RGB;
-				type = GL_UNSIGNED_BYTE;
-				break;
-
-			case Image::CT_RGBA:
-				internalFormat = (compressionEnabled) ? GL_COMPRESSED_RGBA : GL_RGBA;
-				format = GL_RGBA;
-				type = GL_UNSIGNED_BYTE;
-				break;
-
-			default:
-				throw EXCEPTION("See file");
-		}
-
-		glTexImage2D(target, 0, internalFormat, img.getWidth(), img.getHeight(), 0, format, type, &img.getData()[0]);
-		if(mipmappingEnabled)
-		{
-			glGenerateMipmap(target);
-		}
-
-		ON_GL_FAIL_THROW_EXCEPTION();
+		default:
+			throw EXCEPTION("See file");
 	}
 	}
-	catch(std::exception& e)
+
+	glTexImage2D(target, 0, internalFormat, img.getWidth(), img.getHeight(), 0, format, type, &img.getData()[0]);
+	if(mipmappingEnabled)
 	{
 	{
-		throw EXCEPTION("File \"" + filename + "\": " + e.what());
+		glGenerateMipmap(target);
 	}
 	}
+
+	ON_GL_FAIL_THROW_EXCEPTION();
 }
 }
 
 
 
 

+ 6 - 0
src/Resources/Texture.h

@@ -6,6 +6,9 @@
 #include "Exception.h"
 #include "Exception.h"
 
 
 
 
+class Image;
+
+
 /// Texture resource class
 /// Texture resource class
 ///
 ///
 /// It loads or creates an image and then loads it in the GPU. Its an OpenGL container. It supports compressed and
 /// It loads or creates an image and then loads it in the GPU. Its an OpenGL container. It supports compressed and
@@ -36,6 +39,9 @@ class Texture
 		/// Implements Resource::load
 		/// Implements Resource::load
 		/// @exception Exception
 		/// @exception Exception
 		void load(const char* filename);
 		void load(const char* filename);
+		
+		/// @exception Exception
+		void load(const Image& img);
 
 
 		/// Create empty texture.
 		/// Create empty texture.
 		/// Used by the Renderer
 		/// Used by the Renderer

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor