From 19937c751292b2d41ee1cc8886ddd84cfac95e22 Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Tue, 31 Jul 2012 16:49:31 +0000 Subject: [PATCH] - removed MD5 related classes as we will not support it after all. --- .../include/graphics/md5/ArbProgram.h | 160 -- .../include/graphics/md5/DataManager.h | 120 - .../include/graphics/md5/DataManager.inl | 188 -- .../include/graphics/md5/GlErrors.h | 46 - .../shared_lib/include/graphics/md5/Image.h | 568 ----- .../shared_lib/include/graphics/md5/Mathlib.h | 450 ---- .../include/graphics/md5/Mathlib.inl | 2179 ----------------- .../include/graphics/md5/Md5Model.h | 548 ----- .../include/graphics/md5/ShaderManager.h | 190 -- .../include/graphics/md5/TextureManager.h | 92 - .../include/graphics/md5/md5Texture.h | 218 -- .../shared_lib/include/graphics/md5/md5util.h | 56 - .../sources/graphics/md5/ArbProgram.cpp | 281 --- .../sources/graphics/md5/GlErrors.cpp | 71 - .../shared_lib/sources/graphics/md5/Image.cpp | 1535 ------------ .../sources/graphics/md5/Md5Model.cpp | 1954 --------------- .../sources/graphics/md5/ShaderManager.cpp | 473 ---- .../sources/graphics/md5/md5Texture.cpp | 536 ---- .../sources/graphics/md5/md5util.cpp | 591 ----- 19 files changed, 10256 deletions(-) delete mode 100644 source/shared_lib/include/graphics/md5/ArbProgram.h delete mode 100644 source/shared_lib/include/graphics/md5/DataManager.h delete mode 100644 source/shared_lib/include/graphics/md5/DataManager.inl delete mode 100644 source/shared_lib/include/graphics/md5/GlErrors.h delete mode 100644 source/shared_lib/include/graphics/md5/Image.h delete mode 100644 source/shared_lib/include/graphics/md5/Mathlib.h delete mode 100644 source/shared_lib/include/graphics/md5/Mathlib.inl delete mode 100644 source/shared_lib/include/graphics/md5/Md5Model.h delete mode 100644 source/shared_lib/include/graphics/md5/ShaderManager.h delete mode 100644 source/shared_lib/include/graphics/md5/TextureManager.h delete mode 100644 source/shared_lib/include/graphics/md5/md5Texture.h delete mode 100644 source/shared_lib/include/graphics/md5/md5util.h delete mode 100644 source/shared_lib/sources/graphics/md5/ArbProgram.cpp delete mode 100644 source/shared_lib/sources/graphics/md5/GlErrors.cpp delete mode 100644 source/shared_lib/sources/graphics/md5/Image.cpp delete mode 100644 source/shared_lib/sources/graphics/md5/Md5Model.cpp delete mode 100644 source/shared_lib/sources/graphics/md5/ShaderManager.cpp delete mode 100644 source/shared_lib/sources/graphics/md5/md5Texture.cpp delete mode 100644 source/shared_lib/sources/graphics/md5/md5util.cpp diff --git a/source/shared_lib/include/graphics/md5/ArbProgram.h b/source/shared_lib/include/graphics/md5/ArbProgram.h deleted file mode 100644 index 77a97132..00000000 --- a/source/shared_lib/include/graphics/md5/ArbProgram.h +++ /dev/null @@ -1,160 +0,0 @@ -// ============================================================== -// This file is part of MegaGlest (www.glest.org) -// -// ArbProgram.h -- Copyright (c) 2007 David Henry -// changed for use with MegaGlest: Copyright (C) 2011- by Mark Vejvoda -// -// This code is licensed under the MIT license: -// http://www.opensource.org/licenses/mit-license.php -// -// Open Source Initiative OSI - The MIT License (MIT):Licensing -// -// The MIT License (MIT) -// Copyright (c) -// -// 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.// -// -// Definitions of ARB program related classes. -// -///////////////////////////////////////////////////////////////////////////// -#ifndef __ARB_PROGRAM_H__ -#define __ARB_PROGRAM_H__ - -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#endif // _WIN32 - -#include -#include -#include - -namespace Shared { namespace Graphics { namespace md5 { - -using std::string; - -///////////////////////////////////////////////////////////////////////////// -// ARB Program class diagram: -// -// +---------- (abs) -// | ArbProgram | -// +--------------+ -// ^ -// | -// +-------------+-------------+ -// | | -// +------------------+ +--------------------+ -// | ArbVertexProgram | | ArbFragmentProgram | -// +------------------+ +--------------------+ -// -///////////////////////////////////////////////////////////////////////////// - -// Global functions for initializing ARB program extensions and query for -// vertex and fragment program support on the host. -GLboolean hasArbVertexProgramSupport(); -GLboolean hasArbFragmentProgramSupport(); - -void initArbProgramHandling(); - -///////////////////////////////////////////////////////////////////////////// -// -// class ArbProgram -- ARB Program abstract object. Can be a vertex program -// or a fragment program. -// -///////////////////////////////////////////////////////////////////////////// -class ArbProgram -{ -protected: - // Constructor - ArbProgram (const string &filename); - -public: - // Destructor - virtual ~ArbProgram (); - -public: - // Accessors - const string &name () const { return _name; } - const string &code () const { return _code; } - GLuint handle () const { return _handle; } - bool fail () const { return _fail; } - - virtual GLenum programType () const = 0; - -public: - // Public interface - void use () const; - void unuse () const; - -protected: - // Internal functions - void printProgramString (int errPos); - void load () - throw (std::runtime_error); - void loadProgramFile (const string &filename) - throw (std::runtime_error); - -protected: - // Member variables - string _name; - string _code; - GLuint _handle; - GLboolean _fail; -}; - -///////////////////////////////////////////////////////////////////////////// -// -// class ArbVertexProgram -- ARB vertex program object. -// -///////////////////////////////////////////////////////////////////////////// -class ArbVertexProgram : public ArbProgram -{ -public: - // Constructor - ArbVertexProgram (const string &filename); - -public: - // Return the program enum type - virtual GLenum programType () const { - return GL_VERTEX_PROGRAM_ARB; - } -}; - - -///////////////////////////////////////////////////////////////////////////// -// -// class ArbFragmentProgram -- ARB fragment program object. -// -///////////////////////////////////////////////////////////////////////////// -class ArbFragmentProgram : public ArbProgram -{ -public: - // Constructor - ArbFragmentProgram (const string &filename); - -public: - // Return the program enum type - virtual GLenum programType () const { - return GL_FRAGMENT_PROGRAM_ARB; - } -}; - -}}} //end namespace - -#endif // __ARB_PROGRAM_H__ diff --git a/source/shared_lib/include/graphics/md5/DataManager.h b/source/shared_lib/include/graphics/md5/DataManager.h deleted file mode 100644 index 1f12a9dd..00000000 --- a/source/shared_lib/include/graphics/md5/DataManager.h +++ /dev/null @@ -1,120 +0,0 @@ -// ============================================================== -// This file is part of MegaGlest (www.glest.org) -// -// DataManager.h -- Copyright (c) 2006 David Henry -// changed for use with MegaGlest: Copyright (C) 2011- by Mark Vejvoda -// -// This code is licensed under the MIT license: -// http://www.opensource.org/licenses/mit-license.php -// -// Open Source Initiative OSI - The MIT License (MIT):Licensing -// -// The MIT License (MIT) -// Copyright (c) -// -// 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.// -// -// Definitions of a data manager class. -// -///////////////////////////////////////////////////////////////////////////// -#ifndef __DATAMANAGER_H__ -#define __DATAMANAGER_H__ - -#include -#include -#include - -using std::string; -using std::map; - -namespace Shared { namespace Graphics { namespace md5 { - -///////////////////////////////////////////////////////////////////////////// -// -// class DataManagerException - Exception class for DataManager classes. -// This acts like a standard runtime_error exception but -// know the name of the resource which caused the exception. -// -///////////////////////////////////////////////////////////////////////////// -class DataManagerException : public std::runtime_error { -public: - // Constructors - DataManagerException (const string &error) - : std::runtime_error (error) { } - DataManagerException (const string &error, const string &name) - : std::runtime_error (error), _which (name) { } - virtual ~DataManagerException () throw () { } - -public: - // Public interface - virtual const char *which () const throw () { - return _which.c_str (); - } - -private: - // Member variables - string _which; -}; - -///////////////////////////////////////////////////////////////////////////// -// -// class DataManager -- a data manager which can register/unregister -// generic objects. Destroy all registred objects at death. -// -// The data manager is a singleton. -// -///////////////////////////////////////////////////////////////////////////// -template -class DataManager { -protected: - // Constructor/destructor - DataManager (); - virtual ~DataManager (); - -public: - // Public interface - T *request (const string &name); - - void registerObject (const string &name, T *object) - throw (DataManagerException); - void unregisterObject (const string &name, bool deleteObject = false); - - void purge (); - -private: - // Member variables - typedef map DataMap; - DataMap _registry; - -public: - // Singleton related functions - static C *getInstance (); - static void kill (); - -private: - // The unique instance of this class - static C *_singleton; -}; - -// Include inline function definitions -#include "DataManager.inl" - -}}} //end namespace - -#endif // __DATAMANAGER_H__ diff --git a/source/shared_lib/include/graphics/md5/DataManager.inl b/source/shared_lib/include/graphics/md5/DataManager.inl deleted file mode 100644 index df34f4cd..00000000 --- a/source/shared_lib/include/graphics/md5/DataManager.inl +++ /dev/null @@ -1,188 +0,0 @@ -// ============================================================== -// This file is part of MegaGlest (www.glest.org) -// -// DataManager.inl -- Copyright (c) 2006 David Henry -// changed for use with MegaGlest: Copyright (C) 2011- by Mark Vejvoda -// -// This code is licensed under the MIT license: -// http://www.opensource.org/licenses/mit-license.php -// -// Open Source Initiative OSI - The MIT License (MIT):Licensing -// -// The MIT License (MIT) -// Copyright (c) -// -// 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.// -// -// Implementation of the data manager. -// -///////////////////////////////////////////////////////////////////////////// - -#include "DataManager.h" - -///////////////////////////////////////////////////////////////////////////// -// -// class DataManager implementation. -// -///////////////////////////////////////////////////////////////////////////// - -// Singleton initialization. At first, there is no object created. -template -C *DataManager::_singleton = NULL; - -// -------------------------------------------------------------------------- -// DataManager::DataManager -// -// Constructor. -// -------------------------------------------------------------------------- - -template -inline -DataManager::DataManager () { -} - -// -------------------------------------------------------------------------- -// DataManager::~DataManager -// -// Destructor. Purge all registred objects. -// -------------------------------------------------------------------------- -template -inline -DataManager::~DataManager () { - purge (); -} - -// -------------------------------------------------------------------------- -// DataManager::request -// -// Retrieve an object from the registry. Return NULL if there if the -// requested object has not been found in the registry. -// -------------------------------------------------------------------------- -template -inline T * -DataManager::request (const string &name) { - typename DataMap::iterator itor; - itor = _registry.find (name); - - if (itor != _registry.end ()) - { - // The object has been found - return itor->second; - } - else - { - return NULL; - } -} - - -// -------------------------------------------------------------------------- -// DataManager::registerObject -// -// Register an object. If kOverWrite is set, then it will overwrite -// the already existing object. If kOverWrite is combined -// with kDelete, then it will also delete the previous object from memory. -// -------------------------------------------------------------------------- -template -inline void -DataManager::registerObject (const string &name, T *object) - throw (DataManagerException) { - std::pair res; - - // Register the object as a new entry - res = _registry.insert (typename DataMap::value_type (name, object)); - - // Throw an exception if the insertion failed - if (!res.second) - throw DataManagerException ("Name collision", name); -} - -// -------------------------------------------------------------------------- -// DataManager::unregisterObject -// -// Unregister an object given its name. If deleteObject is true, -// then it delete the object, otherwise it just remove the object -// from the registry whitout freeing it from memory. -// -------------------------------------------------------------------------- -template -inline void -DataManager::unregisterObject (const string &name, bool deleteObject) { - typename DataMap::iterator itor; - itor = _registry.find (name); - - if (itor != _registry.end ()) - { - if (deleteObject) - delete itor->second; - - _registry.erase (itor); - } -} - -// -------------------------------------------------------------------------- -// DataManager::purge -// -// Destroy all registred objects and clear the registry. -// -------------------------------------------------------------------------- -template -inline void -DataManager::purge () { - // Not exception safe! - for (typename DataMap::iterator itor = _registry.begin (); - itor != _registry.end (); ++itor) - { - // Destroy object - delete itor->second; - } - - _registry.clear (); -} - -// -------------------------------------------------------------------------- -// DataManager::getInstance -// -// Return a pointer of the unique instance of this class. If there is no -// object build yet, create it. -// NOTE: This is the only way to get access to the data manager since -// constructor is private. -// -------------------------------------------------------------------------- -template -inline C * -DataManager::getInstance () { - if (_singleton == NULL) - _singleton = new C; - - return _singleton; -} - -// -------------------------------------------------------------------------- -// DataManager::kill -// -// Destroy the data manager, i.e. delete the unique instance of -// this class. -// NOTE: this function must be called before exiting in order to -// properly destroy all registred objects. -// -------------------------------------------------------------------------- - -template -inline void -DataManager::kill () { - delete _singleton; - _singleton = NULL; -} diff --git a/source/shared_lib/include/graphics/md5/GlErrors.h b/source/shared_lib/include/graphics/md5/GlErrors.h deleted file mode 100644 index e8ca3947..00000000 --- a/source/shared_lib/include/graphics/md5/GlErrors.h +++ /dev/null @@ -1,46 +0,0 @@ -// ============================================================== -// This file is part of MegaGlest (www.glest.org) -// -// GlErrors.h -- Copyright (c) 2006-2007 David Henry -// changed for use with MegaGlest: Copyright (C) 2011- by Mark Vejvoda -// -// This code is licensed under the MIT license: -// http://www.opensource.org/licenses/mit-license.php -// -// Open Source Initiative OSI - The MIT License (MIT):Licensing -// -// The MIT License (MIT) -// Copyright (c) -// -// 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.// -// -// OpenGL error management. -// -///////////////////////////////////////////////////////////////////////////// - -#ifndef __GLERRORS_H__ -#define __GLERRORS_H__ - -namespace Shared { namespace Graphics { namespace md5 { - -GLenum checkOpenGLErrors (const char *file, int line); - -}}} //end namespace - -#endif // __GLERRORS_H__ diff --git a/source/shared_lib/include/graphics/md5/Image.h b/source/shared_lib/include/graphics/md5/Image.h deleted file mode 100644 index 267bfd5b..00000000 --- a/source/shared_lib/include/graphics/md5/Image.h +++ /dev/null @@ -1,568 +0,0 @@ -// ============================================================== -// This file is part of MegaGlest (www.glest.org) -// -// Image.h -- Copyright (c) 2006 David Henry -// changed for use with MegaGlest: Copyright (C) 2011- by Mark Vejvoda -// -// This code is licensed under the MIT license: -// http://www.opensource.org/licenses/mit-license.php -// -// Open Source Initiative OSI - The MIT License (MIT):Licensing -// -// The MIT License (MIT) -// Copyright (c) -// -// 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.// -// -// Declaration of DDS, TGA, PCX, JPEG and PNG image loader classes. -// -///////////////////////////////////////////////////////////////////////////// -#ifndef __IMAGE_H__ -#define __IMAGE_H__ - -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#include -#endif // _WIN32 - -#include - -#if !defined(_WIN32) || defined(__MINGW32__) -#include -#endif - -#include -#include -#include -#include -#include - -extern "C" { -#include -} - -using std::cout; -using std::endl; -using std::string; - -#if defined(_WIN32) -using std::tr1::shared_ptr; -#endif - -namespace Shared { namespace Graphics { namespace md5 { - -#ifndef _WIN32 -//using boost::shared_ptr; -using std::tr1::shared_ptr; -#endif - -///////////////////////////////////////////////////////////////////////////// -// Image class diagram: -// -// +------- (abs) +---------------+ -// | Image | | runtime_error | -// +---------+ +---------------+ -// ^ ^ -// | +------------+ | -// +---| ImageDDS | +----------------+ -// | +------------+ | ImageException | -// | +----------------+ -// | +------------+ -// +---| ImageTGA | -// | +------------+ -// | +---------------+ -// | +------------+ | ImageBuffer | -// +---| ImagePCX | +---------------+ -// | +------------+ -// | -// | +------------+ -// +---| ImageJPEG | +----------------+ -// | +------------+ | ImageFactory | -// | +----------------+ -// | +------------+ -// +---| ImagePNG | -// +------------+ -// -///////////////////////////////////////////////////////////////////////////// - - -///////////////////////////////////////////////////////////////////////////// -// -// class ImageException - Exception class for ImageBuffer and Image -// loaders. This acts like a standard runtime_error exception but -// know which file has failed to be loaded. -// -///////////////////////////////////////////////////////////////////////////// -class ImageException : public std::runtime_error { -public: - // Constructors - ImageException (const string &error) - : std::runtime_error (error) { } - ImageException (const string &error, const string &filename) - : std::runtime_error (error), _which (filename) { } - virtual ~ImageException () throw () { } - -public: - // Public interface - virtual const char *which () const throw () { - return _which.c_str (); - } - -private: - // Member variables - string _which; -}; - -///////////////////////////////////////////////////////////////////////////// -// -// class ImageBuffer - An image file loader class. Load a whole file -// into a memory buffer. -// -///////////////////////////////////////////////////////////////////////////// -class ImageBuffer { -public: - // Constructors/destructor - ImageBuffer (const string &filename); - - ImageBuffer (const ImageBuffer &that) - : _filename (that._filename), _data (NULL), _length (that._length) - { - _data = new GLubyte[_length]; - memcpy (_data, that._data, _length); - } - - ~ImageBuffer (); - -private: - // Disable default constructor - ImageBuffer (); - -public: - // Accessors - const string &filename () const { return _filename; } - const GLubyte *data () const { return _data; } - size_t length () const { return _length; } - - ImageBuffer &operator= (const ImageBuffer &rhs) - { - this->~ImageBuffer (); - new (this) ImageBuffer (rhs); - return *this; - } - -private: - // Member variables - string _filename; - - GLubyte *_data; - size_t _length; -}; - -///////////////////////////////////////////////////////////////////////////// -// -// class Image - A generic image loader class for creating OpenGL -// textures from. All other specific image loader are derived from it. -// -///////////////////////////////////////////////////////////////////////////// -class Image { -protected: - // Default constructor - Image () - : _width (0), _height (0), _numMipmaps (0), - _format (0), _components (0), _pixels (NULL), - _standardCoordSystem (true) { } - -private: - // Disable copy constructor. - Image (const Image &img); - -public: - // Constructors/destructor - Image (const string &name, GLsizei w, GLsizei h, GLint numMipMaps, - GLenum format, GLint components, const GLubyte *pixels, - bool stdCoordSystem); - - virtual ~Image(); - -public: - // Return true if we're working with S3 - // compressed textures (DDS files) - bool isCompressed () const; - bool isPowerOfTwo () const; - - // Accessors - GLsizei width () const { return _width; } - GLsizei height () const { return _height; } - GLint numMipmaps () const { return _numMipmaps; } - GLenum format () const { return _format; } - GLint components () const { return _components; } - const GLubyte *pixels () const { return _pixels; } - const string &name () const { return _name; } - bool stdCoordSystem () const { return _standardCoordSystem; } - -protected: - // Member variables - GLsizei _width; - GLsizei _height; - GLint _numMipmaps; - - // OpenGL texture format and internal - // format (components) - GLenum _format; - GLint _components; - - // Image data - GLubyte *_pixels; - - string _name; - - // Is the picture in standard OpenGL 2D coordinate - // system? (starts lower-left corner) - bool _standardCoordSystem; -}; - - -// Definition of type aliases -typedef shared_ptr ImagePtr; - -///////////////////////////////////////////////////////////////////////////// -// -// class ImageDDS - A DirectDraw Surface (DDS) image loader class. -// Support only DXT1, DXT3 and DXT5 formats, since OpenGL doesn't -// support others. GL_EXT_texture_compression_s3tc must be supported. -// -// NOTE: Because DirectX uses the upper left corner as origin of the -// picture when OpenGL uses the lower left corner, the texture generated -// from it will be rendered upside-down. -// -///////////////////////////////////////////////////////////////////////////// -class ImageDDS : public Image { -public: - // Constructor - ImageDDS (const ImageBuffer &ibuff); - -private: - // Internal data structures and - // member variables - struct DDPixelFormat - { - GLuint size; - GLuint flags; - GLuint fourCC; - GLuint bpp; - GLuint redMask; - GLuint greenMask; - GLuint blueMask; - GLuint alphaMask; - }; - - struct DDSCaps - { - GLuint caps; - GLuint caps2; - GLuint caps3; - GLuint caps4; - }; - - struct DDColorKey - { - GLuint lowVal; - GLuint highVal; - }; - - struct DDSurfaceDesc - { - GLuint size; - GLuint flags; - GLuint height; - GLuint width; - GLuint pitch; - GLuint depth; - GLuint mipMapLevels; - GLuint alphaBitDepth; - GLuint reserved; - GLuint surface; - - DDColorKey ckDestOverlay; - DDColorKey ckDestBlt; - DDColorKey ckSrcOverlay; - DDColorKey ckSrcBlt; - - DDPixelFormat format; - DDSCaps caps; - - GLuint textureStage; - }; - - const DDSurfaceDesc *_ddsd; -}; - -///////////////////////////////////////////////////////////////////////////// -// -// class glImageTGA - A TrueVision TARGA (TGA) image loader class. -// Support 24-32 bits BGR files; 16 bits RGB; 8 bits indexed (BGR -// palette); 8 and 16 bits grayscale; all compressed and uncompressed. -// Compressed TGA images use RLE algorithm. -// -///////////////////////////////////////////////////////////////////////////// -class ImageTGA : public Image { -public: - // Constructor - ImageTGA (const ImageBuffer &ibuff); - -private: - // Internal functions - void getTextureInfo (); - - void readTGA8bits (const GLubyte *data, const GLubyte *colormap); - void readTGA16bits (const GLubyte *data); - void readTGA24bits (const GLubyte *data); - void readTGA32bits (const GLubyte *data); - void readTGAgray8bits (const GLubyte *data); - void readTGAgray16bits (const GLubyte *data); - - void readTGA8bitsRLE (const GLubyte *data, const GLubyte *colormap); - void readTGA16bitsRLE (const GLubyte *data); - void readTGA24bitsRLE (const GLubyte *data); - void readTGA32bitsRLE (const GLubyte *data); - void readTGAgray8bitsRLE (const GLubyte *data); - void readTGAgray16bitsRLE (const GLubyte *data); - -private: - // Member variables -#pragma pack(push, 1) - // tga header - struct TGA_Header - { - GLubyte id_lenght; // size of image id - GLubyte colormap_type; // 1 is has a colormap - GLubyte image_type; // compression type - - short cm_first_entry; // colormap origin - short cm_length; // colormap length - GLubyte cm_size; // colormap size - - short x_origin; // bottom left x coord origin - short y_origin; // bottom left y coord origin - - short width; // picture width (in pixels) - short height; // picture height (in pixels) - - GLubyte pixel_depth; // bits per pixel: 8, 16, 24 or 32 - GLubyte image_descriptor; // 24 bits = 0x00; 32 bits = 0x80 - - }; -#pragma pack(pop) - - const TGA_Header *_header; - - // NOTE: - // 16 bits images are stored in RGB - // 8-24-32 images are stored in BGR(A) - - // RGBA/BGRA component table access -- usefull for - // switching from bgra to rgba at load time. - static int rgbaTable[4]; // bgra to rgba: 2, 1, 0, 3 - static int bgraTable[4]; // bgra to bgra: 0, 1, 2, 3 -}; - -///////////////////////////////////////////////////////////////////////////// -// -// class ImagePCX - A Zsoft PCX image loader class. -// -///////////////////////////////////////////////////////////////////////////// -class ImagePCX : public Image { -public: - // Constructor - ImagePCX (const ImageBuffer &ibuff); - -private: - // Internal functions - void readPCX1bit (const GLubyte *data); - void readPCX4bits (const GLubyte *data); - void readPCX8bits (const GLubyte *data, - const GLubyte *palette); - void readPCX24bits (const GLubyte *data); - -private: -#pragma pack(push, 1) - // pcx header - struct PCX_Header - { - GLubyte manufacturer; - GLubyte version; - GLubyte encoding; - GLubyte bitsPerPixel; - - GLushort xmin, ymin; - GLushort xmax, ymax; - GLushort horzRes, vertRes; - - GLubyte palette[48]; - GLubyte reserved; - GLubyte numColorPlanes; - - GLushort bytesPerScanLine; - GLushort paletteType; - GLushort horzSize, vertSize; - - GLubyte padding[54]; - }; -#pragma pack(pop) - - const PCX_Header *_header; - - // RGBA/BGRA component table access -- usefull for - // switching from bgra to rgba at load time. - static int rgbTable[3]; // bgra to rgba: 0, 1, 2 - static int bgrTable[3]; // bgra to bgra: 2, 1, 0 -}; - -///////////////////////////////////////////////////////////////////////////// -// -// class ImageJPEG - A JPEG image loader class using libjpeg. -// -///////////////////////////////////////////////////////////////////////////// -class ImageJPEG : public Image { -public: - // Constructor - ImageJPEG (const ImageBuffer &ibuff); - -private: - // Error manager, using C's setjmp/longjmp - struct my_error_mgr - { - jpeg_error_mgr pub; // "public" fields - jmp_buf setjmp_buffer; // for return to caller - - string errorMsg; // last error message - }; - - typedef my_error_mgr *my_error_ptr; - -private: - // libjpeg's callback functions for reading data - static void initSource_callback (j_decompress_ptr cinfo); - static boolean fillInputBuffer_callback (j_decompress_ptr cinfo); - static void skipInputData_callback (j_decompress_ptr cinfo, - long num_bytes); - static void termSource_callback (j_decompress_ptr cinfo); - - // libjpeg's callback functions for error handling - static void errorExit_callback (j_common_ptr cinfo); - static void outputMessage_callback (j_common_ptr cinfo); -}; - -///////////////////////////////////////////////////////////////////////////// -// -// class ImagePNG - A Portable Network Graphic (PNG) image loader -// class using libpng and zlib. -// -///////////////////////////////////////////////////////////////////////////// -class ImagePNG : public Image { -public: - // Constructor - ImagePNG (const ImageBuffer &ibuff); - -private: - // Internal functions - void getTextureInfo (int color_type); - - // libpng's callback functions for reading data - // and error handling - static void read_callback (png_structp png_ptr, - png_bytep data, png_size_t length); - static void error_callback (png_structp png_ptr, - png_const_charp error_msg); - static void warning_callback (png_structp png_ptr, - png_const_charp warning_msg); - -public: - // Data source manager. Contains an image buffer and - // an offset position into file's data - struct my_source_mgr - { - // Constructors - my_source_mgr () - : pibuff (NULL), offset (0) { } - my_source_mgr (const ImageBuffer &ibuff) - : pibuff (&ibuff), offset (0) { } - - // Public member variables - const ImageBuffer *pibuff; - size_t offset; - }; - - typedef my_source_mgr *my_source_ptr; - -private: - // Member variables - string errorMsg; -}; - -///////////////////////////////////////////////////////////////////////////// -// -// class ImageFactory - An Image Factory Class. -// -///////////////////////////////////////////////////////////////////////////// -class ImageFactory { -public: - // Public interface - static Image *createImage (const ImageBuffer &ibuff) - { - string ext; - Image *result; - - // Extract file extension - const string &filename = ibuff.filename (); - ext.assign (filename, filename.find_last_of ('.') + 1, string::npos); - - if (ext.compare ("dds") == 0) - { - result = new ImageDDS (ibuff); - } - else if (ext.compare ("tga") == 0) - { - result = new ImageTGA (ibuff); - } - else if (ext.compare ("pcx") == 0) - { - result = new ImagePCX (ibuff); - } - else if (ext.compare ("jpg") == 0) - { - result = new ImageJPEG (ibuff); - } - else if (ext.compare ("png") == 0) - { - result = new ImagePNG (ibuff); - } - else - { - throw ImageException ("Unhandled image file format", filename); - } - - return result; - } -}; - -}}} //end namespace - -#endif // __IMAGE_H__ diff --git a/source/shared_lib/include/graphics/md5/Mathlib.h b/source/shared_lib/include/graphics/md5/Mathlib.h deleted file mode 100644 index e6390f8b..00000000 --- a/source/shared_lib/include/graphics/md5/Mathlib.h +++ /dev/null @@ -1,450 +0,0 @@ -// ============================================================== -// This file is part of MegaGlest (www.glest.org) -// -// Mathlib.h -- Copyright (c) 2005-2006 David Henry -// changed for use with MegaGlest: Copyright (C) 2011- by Mark Vejvoda -// -// This code is licensed under the MIT license: -// http://www.opensource.org/licenses/mit-license.php -// -// Open Source Initiative OSI - The MIT License (MIT):Licensing -// -// The MIT License (MIT) -// Copyright (c) -// -// 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.// -// -// Declarations for 3D maths object and functions to use with OpenGL. -// -// Provide vector, matrix and quaternion operations. -// -///////////////////////////////////////////////////////////////////////////// -#ifndef __MATHLIB_H__ -#define __MATHLIB_H__ - -#include - -namespace Shared { namespace Graphics { namespace md5 { - -// Forward declarations -template class Vector3; -template class Matrix4x4; -template class Quaternion; - -// Type definitions -enum Axis { - kXaxis, kYaxis, kZaxis -}; - -// Declare a global constant for pi and a few multiples. -const float kPi = 3.14159265358979323846f; -const float k2Pi = kPi * 2.0f; -const float kPiOver2 = kPi / 2.0f; -const float k1OverPi = 1.0f / kPi; -const float k1Over2Pi = 1.0f / k2Pi; -const float kPiOver180 = kPi / 180.0f; -const float k180OverPi = 180.0f / kPi; - -// "Wrap" an angle in range -pi...pi by adding the correct multiple -// of 2 pi -template -Real wrapPi (Real theta); - -// "Safe" inverse trig functions -template -Real safeAcos (Real x); - -// Set the Euler angle triple to its "canonical" value -template -void canonizeEulerAngles (Real &roll, Real &pitch, Real &yaw); - -// Convert between degrees and radians -template -inline Real degToRad (Real deg) { return deg * kPiOver180; } - -template -inline Real radToDeg (Real rad) { return rad * k180OverPi; } - -// Convert between "field of view" and "zoom". -// The FOV angle is specified in radians. -template -inline Real fovToZoom (Real fov) { return 1.0f / std::tan (fov * 0.5f); } - -template -inline Real zoomToFov (Real zoom) { return 2.0f * std::atan (1.0f / zoom); } - - -///////////////////////////////////////////////////////////////////////////// -// -// class Vector3 - A simple 3D vector class. -// -///////////////////////////////////////////////////////////////////////////// - -template -class Vector3 -{ -public: - // Constructors - Vector3 () { } - Vector3 (Real x, Real y, Real z) - : _x (x), _y (y), _z (z) { } - -public: - // Vector comparison - bool operator== (const Vector3 &v) const; - bool operator!= (const Vector3 &v) const; - - // Vector negation - Vector3 operator- () const; - - // Vector operations - Vector3 operator+ (const Vector3 &v) const; - Vector3 operator- (const Vector3 &v) const; - Vector3 operator* (Real s) const; - Vector3 operator/ (Real s) const; - - // Combined assignment operators to conform to - // C notation convention - Vector3 &operator+= (const Vector3 &v); - Vector3 &operator-= (const Vector3 &v); - Vector3 &operator*= (Real s); - Vector3 &operator/= (Real s); - - // Accessor. This allows to use the vector object - // like an array of Real. For example: - // Vector3 v (...); - // float f = v[1]; // access to _y - operator const Real *() { return _v; } - -public: - // Other vector operations - bool isZero (); - void normalize (); - -public: - // Member variables - union - { - struct - { - Real _x, _y, _z; - }; - - Real _v[3]; - }; -}; - - -// Predefined Vector3 types -typedef Vector3 Vector3f; -typedef Vector3 Vector3d; - -// We provide a global constant zero vector -static const Vector3f kZeroVectorf (0.0f, 0.0f, 0.0f); -static const Vector3d kZeroVectord (0.0, 0.0, 0.0); - - -// -// Nonmember Vector3 functions -// - -template -Vector3 operator* (Real k, Vector3 v); - -template -Real VectorMag (const Vector3 &v); - -template -Real DotProduct (const Vector3 &a, const Vector3 &b); - -template -Vector3 CrossProduct (const Vector3 &a, const Vector3 &b); - -template -Vector3 ComputeNormal (const Vector3 &p1, - const Vector3 &p2, const Vector3 &p3); - -template -Real Distance (const Vector3 &a, const Vector3 &b); - -template -Real DistanceSquared (const Vector3 &a, const Vector3 &b); - - -///////////////////////////////////////////////////////////////////////////// -// -// class Matrix4x4 - Implement a 4x4 Matrix class that can represent -// any 3D affine transformation. -// -///////////////////////////////////////////////////////////////////////////// - -template -class Matrix4x4 -{ -public: - // Constructor - Initialize the last (never used) row of the matrix - // so that we can do any operation on matrices on the 3x4 portion - // and forget that line which will (and should) never change. - Matrix4x4 () - : _h14 (0.0f), _h24 (0.0f), _h34 (0.0f), _tw (1.0f) { } - - // Note that we don't define the copy constructor and let the compiler - // doing it itself because such initialization is not necessary - // since the source matrix has its last row already initialized... - -public: - // Public interface - void identity (); - void transpose (); - void invert (); - void setTranslation (const Vector3 &v); - - void transform (Vector3 &v) const; - void rotate (Vector3 &v) const; - void inverseRotate (Vector3 &v) const; - void inverseTranslate (Vector3 &v) const; - - void fromQuaternion (const Quaternion &q); - - // Matrix <-> Euler conversions; XYZ rotation order; angles in radians - void fromEulerAngles (Real x, Real y, Real z); - void toEulerAngles (Real &x, Real &y, Real &z) const; - - // Return a base vector from the matrix - Vector3 rightVector () const; - Vector3 upVector () const; - Vector3 forwardVector () const; - Vector3 translationVector () const; - - // Accessor. This allows to use the matrix object - // like an array of Real. For example: - // Matrix4x4 mat; - // float f = mat[4]; // access to _m21 - operator const Real *() { return _m; } - -public: - // Member variables - - // The values of the matrix. Basically the upper 3x3 portion - // contains a linear transformation, and the last column is the - // translation portion. Here data is transposed, see the Mathlib.inl - // for more details. - union - { - struct - { - Real _m11, _m12, _m13, _h14; - Real _m21, _m22, _m23, _h24; - Real _m31, _m32, _m33, _h34; - Real _tx, _ty, _tz, _tw; - }; - - // Access to raw packed matrix data (usefull for - // glLoadMatrixf () and glMultMatrixf ()) - Real _m[16]; - }; -}; - - -// Predefined Matrix4x4 types -typedef Matrix4x4 Matrix4x4f; -typedef Matrix4x4 Matrix4x4d; - - -// -// Nonmember Matrix4x4 functions -// - -// Matrix concatenation -template -Matrix4x4 operator* (const Matrix4x4 &a, const Matrix4x4 &b); - -template -Matrix4x4 &operator*= (Matrix4x4 &a, const Matrix4x4 &b); - -// Vector transformation -template -Vector3 operator* (const Matrix4x4 &m, const Vector3 &p); - -// Transpose matrix -template -Matrix4x4 Transpose (const Matrix4x4 &m); - -// Invert matrix -template -Matrix4x4 Invert (const Matrix4x4 &m); - -// -// Matrix-builder functions -// - -template Matrix4x4 RotationMatrix (Axis axis, Real theta); -template Matrix4x4 RotationMatrix (const Vector3 &axis, Real theta); -template Matrix4x4 TranslationMatrix (Real x, Real y, Real z); -template Matrix4x4 TranslationMatrix (const Vector3 &v); -template Matrix4x4 ScaleMatrix (const Vector3 &s); -template Matrix4x4 ScaleAlongAxisMatrix (const Vector3 &axis, Real k); -template Matrix4x4 ShearMatrix (Axis axis, Real s, Real t); -template Matrix4x4 ProjectionMatrix (const Vector3 &n); -template Matrix4x4 ReflectionMatrix (Axis axis, Real k); -template Matrix4x4 AxisReflectionMatrix (const Vector3 &n); - -template -Matrix4x4 LookAtMatrix (const Vector3 &camPos, - const Vector3 &target, const Vector3 &camUp); -template -Matrix4x4 FrustumMatrix (Real l, Real r, Real b, Real t, Real n, Real f); -template -Matrix4x4 PerspectiveMatrix (Real fovY, Real aspect, Real n, Real f); -template -Matrix4x4 OrthoMatrix (Real l, Real r, Real b, Real t, Real n, Real f); -template -Matrix4x4 OrthoNormalMatrix (const Vector3 &xdir, - const Vector3 &ydir, const Vector3 &zdir); - - -///////////////////////////////////////////////////////////////////////////// -// -// class Quaternion - Implement a quaternion, for purposes of -// representing an angular displacement (orientation) in 3D. -// -///////////////////////////////////////////////////////////////////////////// - -template -class Quaternion -{ -public: - // Constructors - Quaternion () { } - Quaternion (Real w, Real x, Real y, Real z) - : _w (w), _x (x), _y (y), _z (z) { } - -public: - // Public interface - void identity (); - void normalize (); - void computeW (); - void rotate (Vector3 &v) const; - - void fromMatrix (const Matrix4x4 &m); - - // Quaternion <-> Euler conversions; XYZ rotation order; angles in radians - void fromEulerAngles (Real x, Real y, Real z); - void toEulerAngles (Real &x, Real &y, Real &z) const; - - Real rotationAngle () const; - Vector3 rotationAxis () const; - - // Quaternion operations - Quaternion operator+ (const Quaternion &q) const; - Quaternion &operator+= (const Quaternion &q); - - Quaternion operator- (const Quaternion &q) const; - Quaternion &operator-= (const Quaternion &q); - - Quaternion operator* (const Quaternion &q) const; - Quaternion &operator*= (const Quaternion &q); - - Quaternion operator* (Real k) const; - Quaternion &operator*= (Real k); - - Quaternion operator* (const Vector3 &v) const; - Quaternion &operator*= (const Vector3 &v); - - Quaternion operator/ (Real k) const; - Quaternion &operator/= (Real k); - - Quaternion operator~ () const; // Quaternion conjugate - Quaternion operator- () const; // Quaternion negation - -public: - // Member variables - - // The 4 values of the quaternion. Normally, it will not - // be necessary to manipulate these directly. However, - // we leave them public, since prohibiting direct access - // makes some operations, such as file I/O, unnecessarily - // complicated. - - union - { - struct - { - Real _w, _x, _y, _z; - }; - - Real _q[4]; - }; -}; - - -// Predefined Quaternion types -typedef Quaternion Quaternionf; -typedef Quaternion Quaterniond; - -// A global "identity" quaternion constant -static const Quaternionf kQuaternionIdentityf (1.0f, 0.0f, 0.0f, 0.0f); -static const Quaterniond kQuaternionIdentityd (1.0f, 0.0f, 0.0f, 0.0f); - - -// -// Nonmember Matrix4x functions -// - -template -Quaternion operator* (Real k, const Quaternion &q); - -template -Real DotProduct (const Quaternion &a, const Quaternion &b); - -template -Quaternion Conjugate (const Quaternion &q); - -template -Quaternion Inverse (const Quaternion &q); - -template -Quaternion RotationQuaternion (Axis axis, Real theta); - -template -Quaternion RotationQuaternion (const Vector3 &axis, Real theta); - -template -Quaternion Log (const Quaternion &q); -template -Quaternion Exp (const Quaternion &q); -template -Quaternion Pow (const Quaternion &q, Real exponent); - -template -Quaternion Slerp (const Quaternion &q0, const Quaternion &q1, Real t); -template -Quaternion Squad (const Quaternion &q0, const Quaternion &qa, - const Quaternion &qb, const Quaternion &q1, Real t); -template -inline void Intermediate (const Quaternion &qprev, const Quaternion &qcurr, - const Quaternion &qnext, Quaternion &qa, - Quaternion &qb); - -// Include inline function definitions -#include "Mathlib.inl" - -}}} //end namespace - -#endif // __MATHLIB_H__ diff --git a/source/shared_lib/include/graphics/md5/Mathlib.inl b/source/shared_lib/include/graphics/md5/Mathlib.inl deleted file mode 100644 index 1c0fdbbe..00000000 --- a/source/shared_lib/include/graphics/md5/Mathlib.inl +++ /dev/null @@ -1,2179 +0,0 @@ -// ============================================================== -// This file is part of MegaGlest (www.glest.org) -// -// Mathlib.inl -- Copyright (c) 2005-2006 David Henry -// changed for use with MegaGlest: Copyright (C) 2011- by Mark Vejvoda// -// ------------------------------------------------------------------- -// Portions Copyright (c) Dante Treglia II and Mark A. DeLoura, 2000. -// Portions Copyright (c) Fletcher Dunn and Ian Parberry, 2002. -// ------------------------------------------------------------------- -// -// This code is licensed under the MIT license: -// http://www.opensource.org/licenses/mit-license.php -// -// Open Source Initiative OSI - The MIT License (MIT):Licensing -// -// The MIT License (MIT) -// Copyright (c) -// -// 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.// -// -// Implementation of a math library to use with OpenGL. -// -// Provide vector, matrix and quaternion operations. -// -///////////////////////////////////////////////////////////////////////////// - -#include - -///////////////////////////////////////////////////////////////////////////// -// -// Global functions -// -///////////////////////////////////////////////////////////////////////////// -// -------------------------------------------------------------------------- -// wrapPi -// -// "Wrap" an angle in range -pi...pi by adding the correct multiple -// of 2 pi -// -------------------------------------------------------------------------- - -template -inline Real -wrapPi (Real theta) -{ - theta += kPi; - theta -= std::floor (theta * k1Over2Pi) * k2Pi; - theta -= kPi; - return theta; -} - - -// -------------------------------------------------------------------------- -// safeAcos -// -// Same as acos(x), but if x is out of range, it is "clamped" to the nearest -// valid value. The value returned is in range 0...pi, the same as the -// standard C acos() function -// -------------------------------------------------------------------------- - -template -inline Real -safeAcos (Real x) -{ - // Check limit conditions - if (x <= -1.0) - return kPi; - - if (x >= 1.0) - return 0.0; - - // value is in the domain - use standard C function - return std::acos (x); -} - - -// -------------------------------------------------------------------------- -// canonizeEulerAngles -// -// Set the Euler angle triple to its "canonical" value. This does not change -// the meaning of the Euler angles as a representation of Orientation in 3D, -// but if the angles are for other purposes such as angular velocities, etc, -// then the operation might not be valid. -// -------------------------------------------------------------------------- - -template -inline void -canonizeEulerAngles (Real &roll, Real &pitch, Real &yaw) -{ - // First, wrap pitch in range -pi ... pi - pitch = wrapPi (pitch); - - // Now, check for "the back side" of the matrix, pitch outside - // the canonical range of -pi/2 ... pi/2 - if (pitch < -kPiOver2) - { - roll += kPi; - pitch = -kPi - pitch; - yaw += kPi; - } - else if (pitch > kPiOver2) - { - roll += kPi; - pitch = kPi - pitch; - yaw += kPi; - } - - // OK, now check for the Gimbal lock case (within a slight - // tolerance) - - if (std::fabs (pitch) > kPiOver2 - 1e-4) - { - // We are in gimbal lock. Assign all rotation - // about the vertical axis to heading - yaw += roll; - roll = 0.0; - } - else - { - // Not in gimbal lock. Wrap the bank angle in - // canonical range - roll = wrapPi (roll); - } - - // Wrap heading in canonical range - yaw = wrapPi (yaw); -} - - -///////////////////////////////////////////////////////////////////////////// -// -// class Vector3 implementation. -// -///////////////////////////////////////////////////////////////////////////// - -// -------------------------------------------------------------------------- -// Vector3::isZero -// -// Return true if is zero vector. -// -------------------------------------------------------------------------- - -template -inline bool -Vector3::isZero () -{ - return (_x == 0.0) && (_y == 0.0) && (_z == 0.0); -} - - -// -------------------------------------------------------------------------- -// Vector3::normalize -// -// Set vector length to 1. -// -------------------------------------------------------------------------- - -template -inline void -Vector3::normalize() -{ - Real magSq = (_x * _x) + (_y * _y) + (_z * _z); - - if (magSq > 0.0) - { - // check for divide-by-zero - Real oneOverMag = 1.0 / std::sqrt (magSq); - _x *= oneOverMag; - _y *= oneOverMag; - _z *= oneOverMag; - } -} - - -// -------------------------------------------------------------------------- -// Vector3 operators -// -// Operator overloading for basic vector operations. -// -------------------------------------------------------------------------- - -template -inline bool -Vector3::operator== (const Vector3 &v) const -{ - return ((_x == v._x) && (_y == v._y) && (_z == v._z)); -} - -template -inline bool -Vector3::operator!= (const Vector3 &v) const -{ - return ((_x != v._x) || (_y != v._y) || (_z != v._z)); -} - -template -inline Vector3 -Vector3::operator- () const -{ - return Vector3 (-_x, -_y, -_z); -} - -template -inline Vector3 -Vector3::operator+ (const Vector3 &v) const -{ - return Vector3 (_x + v._x, _y + v._y, _z + v._z); -} - -template -inline Vector3 -Vector3::operator- (const Vector3 &v) const -{ - return Vector3 (_x - v._x, _y - v._y, _z - v._z); -} - -template -inline Vector3 -Vector3::operator* (Real s) const -{ - return Vector3 (_x * s, _y * s, _z * s); -} - -template -inline Vector3 -Vector3::operator/ (Real s) const -{ - Real oneOverS = 1.0 / s; // Note: no check for divide by zero - return Vector3 (_x * oneOverS, _y * oneOverS, _z * oneOverS); -} - -template -inline Vector3 & -Vector3::operator+= (const Vector3 &v) -{ - _x += v._x; _y += v._y; _z += v._z; - return *this; -} - -template -inline Vector3 & -Vector3::operator-= (const Vector3 &v) -{ - _x -= v._x; _y -= v._y; _z -= v._z; - return *this; -} - -template -inline Vector3 & -Vector3::operator*= (Real s) -{ - _x *= s; _y *= s; _z *= s; - return *this; -} - -template -inline Vector3 & -Vector3::operator/= (Real s) -{ - Real oneOverS = 1.0 / s; // Note: no check for divide by zero! - _x *= oneOverS; _y *= oneOverS ; _z *= oneOverS; - return *this; -} - - -// -------------------------------------------------------------------------- -// -// Nonmember Vector3 functions -// -// -------------------------------------------------------------------------- - -// Scalar on the left multiplication, for symmetry -template -inline Vector3 -operator* (Real k, Vector3 v) -{ - return Vector3 (k * v._x, k * v._y, k * v._z); -} - -// Compute vector lenght -template -inline Real -VectorMag (const Vector3 &v) -{ - return std::sqrt ((v._x * v._x) + (v._y * v._y) + (v._z * v._z)); -} - -// Vector3 dot product -template -inline Real -DotProduct (const Vector3 &a, const Vector3 &b) -{ - return ((a._x * b._x) + (a._y * b._y) + (a._z * b._z)); -} - -// Vector3 cross product -template -inline Vector3 -CrossProduct (const Vector3 &a, const Vector3 &b) -{ - return Vector3 ( - (a._y * b._z) - (a._z * b._y), - (a._z * b._x) - (a._x * b._z), - (a._x * b._y) - (a._y * b._x) - ); -} - -// Compute normal plane given three points -template -inline Vector3 -ComputeNormal (const Vector3 &p1, const Vector3 &p2, const Vector3 &p3) -{ - Vector3 vec1 (p1 - p2); - Vector3 vec2 (p1 - p3); - - Vector3 result (CrossProduct (vec1, vec2)); - result.normalize (); - - return result; -} - -// Compute distance between two points -template -inline Real -Distance (const Vector3 &a, const Vector3 &b) -{ - Real dx = a._x - b._x; - Real dy = a._y - b._y; - Real dz = a._z - b._z; - return std::sqrt ((dx * dx) + (dy * dy) + (dz * dz)); -} - -// Compute squared distance between two points. -// Useful when comparing distances, since we don't need -// to square the result. -template -inline Real -DistanceSquared (const Vector3 &a, const Vector3 &b) -{ - Real dx = a._x - b._x; - Real dy = a._y - b._y; - Real dz = a._z - b._z; - return ((dx * dx) + (dy * dy) + (dz * dz)); -} - - -///////////////////////////////////////////////////////////////////////////// -// -// class Matrix4x4 implementation. -// -// -------------------------------------------------------------------------- -// -// MATRIX ORGANIZATION -// -// The purpose of this class is so that a user might perform transformations -// without fiddling with plus or minus signs or transposing the matrix -// until the output "looks right". But of course, the specifics of the -// internal representation is important. Not only for the implementation -// in this file to be correct, but occasionally direct access to the -// matrix variables is necessary, or beneficial for optimization. Thus, -// we document our matrix conventions here. -// -// Strict adherance to linear algebra rules dictates that the -// multiplication of a 4x4 matrix by a 3D vector is actually undefined. -// To circumvent this, we can consider the input and output vectors as -// having an assumed fourth coordinate of 1. Also, since the rightmost -// column is [ 0 0 0 1 ], we can simplificate calculations ignoring -// this last column. This is shown below: -// -// | m11 m12 m13 0 | | x | | x'| -// | m21 m22 m23 0 | | y | = | y'| -// | m31 m32 m33 0 | | z | | z'| -// | tx ty tz 1 | | 1 | | 1 | -// -// We use row vectors to represent the right, up and forward vectors -// in the 4x4 matrix. OpenGL uses column vectors, but the elements of -// an OpenGL matrix are ordered in columns so that m[i][j] is in row j -// and column i. This is the reverse of the standard C convention in -// which m[i][j] is in row i and column j. The matrix should be -// transposed before being sent to OpenGL. -// -// | m11 m21 m31 tx | | m0 m4 m8 m12 | | m0 m1 m2 m3 | -// | m12 m22 m32 ty | | m1 m5 m9 m13 | | m4 m5 m6 m7 | -// | m13 m23 m33 tz | | m2 m6 m10 m14 | | m8 m9 m10 m11 | -// | 0 0 0 tw | | m3 m7 m11 m15 | | m12 m13 m14 m15 | -// -// OpenGL style OpenGL matrix standard C -// arrangement convention -// -// Fortunately, accessing to the raw matrix data via the _m[] array gives -// us the transpose matrix; i.e. in OpenGL form, so that we can directly use -// it with glLoadMatrix{fd}() or glMultMatrix{fd}(). -// -// Also, since the rightmost column (in standard C form) should always -// be [ 0 0 0 1 ], and sice these values (_h14, _h24, _h34 and _tw) are -// initialized in constructors, we don't need to modify them in our -// matrix operations, so we don't perform useless calculations... -// -// The right-hand rule is used to define "positive" rotation. -// -// +y +x' -// | | -// | | -// |______ +x +y' ______| -// / / -// / / -// +z +z' -// -// initial position Positive rotation of -// pi/2 around z-axis -// -///////////////////////////////////////////////////////////////////////////// - - -// -------------------------------------------------------------------------- -// Matrix4x4::identity -// -// Set matrix to identity. -// -------------------------------------------------------------------------- - -template -inline void -Matrix4x4::identity () -{ - _m11 = 1.0; _m21 = 0.0; _m31 = 0.0; _tx = 0.0; - _m12 = 0.0; _m22 = 1.0; _m32 = 0.0; _ty = 0.0; - _m13 = 0.0; _m23 = 0.0; _m33 = 1.0; _tz = 0.0; - _h14 = 0.0; _h24 = 0.0; _h34 = 0.0; _tw = 1.0; -} - - -// -------------------------------------------------------------------------- -// Matrix4x4::transpose -// -// Transpose the current matrix. -// -------------------------------------------------------------------------- - -template -inline void -Matrix4x4::transpose () -{ - *this = Transpose (*this); -} - - -// -------------------------------------------------------------------------- -// Matrix4x4::invert -// -// Invert the current matrix. -// -------------------------------------------------------------------------- - -template -inline void -Matrix4x4::invert () -{ - *this = Invert (*this); -} - - -// -------------------------------------------------------------------------- -// Matrix4x4::setTranslation -// -// Set the translation portion of the matrix. -// -------------------------------------------------------------------------- - -template -inline void -Matrix4x4::setTranslation (const Vector3 &v) -{ - _tx = v._x; _ty = v._y; _tz = v._z; -} - - -// -------------------------------------------------------------------------- -// Matrix4x4::transform -// -// Transform a point by the matrix. -// -------------------------------------------------------------------------- - -template -inline void -Matrix4x4::transform (Vector3 &v) const -{ - // Grind through the linear algebra. - v = Vector3 ( - (v._x * _m11) + (v._y * _m21) + (v._z * _m31) + _tx, - (v._x * _m12) + (v._y * _m22) + (v._z * _m32) + _ty, - (v._x * _m13) + (v._y * _m23) + (v._z * _m33) + _tz - ); -} - - -// -------------------------------------------------------------------------- -// Matrix4x4::rotate -// -// Rotate a point by the 3x3 upper left portion of the matrix. -// -------------------------------------------------------------------------- - -template -inline void -Matrix4x4::rotate (Vector3 &v) const -{ - v = Vector3 ( - (v._x * _m11) + (v._y * _m21) + (v._z * _m31), - (v._x * _m12) + (v._y * _m22) + (v._z * _m32), - (v._x * _m13) + (v._y * _m23) + (v._z * _m33) - ); -} - - -// -------------------------------------------------------------------------- -// Matrix4x4::inverseRotate -// -// Rotate a point by the inverse 3x3 upper left portion of the matrix. -// -------------------------------------------------------------------------- - -template -inline void -Matrix4x4::inverseRotate (Vector3 &v) const -{ - v = Vector3 ( - (v._x * _m11) + (v._y * _m12) + (v._z * _m13), - (v._x * _m21) + (v._y * _m22) + (v._z * _m23), - (v._x * _m31) + (v._y * _m32) + (v._z * _m33) - ); -} - - -// -------------------------------------------------------------------------- -// Matrix4x4::inverseRotate -// -// Translate a point by the inverse matrix. -// -------------------------------------------------------------------------- - -template -inline void -Matrix4x4::inverseTranslate (Vector3 &v) const -{ - v._x -= _tx; - v._y -= _ty; - v._z -= _tz; -} - - -// -------------------------------------------------------------------------- -// Matrix4x4::fromQuaternion -// -// Convert a quaternion to a matrix. -// -------------------------------------------------------------------------- - -template -inline void -Matrix4x4::fromQuaternion (const Quaternion &q) -{ - // Compute a few values to optimize common subexpressions - Real ww = 2.0 * q._w; - Real xx = 2.0 * q._x; - Real yy = 2.0 * q._y; - Real zz = 2.0 * q._z; - - // Set the matrix elements. There is still a little more - // opportunity for optimization due to the many common - // subexpressions. We'll let the compiler handle that... - _m11 = 1.0 - (yy * q._y) - (zz * q._z); - _m12 = (xx * q._y) + (ww * q._z); - _m13 = (xx * q._z) - (ww * q._y); - - _m21 = (xx * q._y) - (ww * q._z); - _m22 = 1.0 - (xx * q._x) - (zz * q._z); - _m23 = (yy * q._z) + (ww * q._x); - - _m31 = (xx * q._z) + (ww * q._y); - _m32 = (yy * q._z) - (ww * q._x); - _m33 = 1.0 - (xx * q._x) - (yy * q._y); - - // Reset the translation portion - _tx = _ty = _tz = 0.0; -} - - -// -------------------------------------------------------------------------- -// Matrix4x4::fromEulerAngles -// -// Setup a rotation matrix, given three X-Y-Z rotation angles. The -// rotations are performed first on x-axis, then y-axis and finaly z-axis. -// -------------------------------------------------------------------------- - -template -inline void -Matrix4x4::fromEulerAngles (Real x, Real y, Real z) -{ - // Fetch sine and cosine of angles - Real cx = std::cos (x); - Real sx = std::sin (x); - Real cy = std::cos (y); - Real sy = std::sin (y); - Real cz = std::cos (z); - Real sz = std::sin (z); - - Real sxsy = sx * sy; - Real cxsy = cx * sy; - - // Fill in the matrix elements - _m11 = (cy * cz); - _m12 = (sxsy * cz) + (cx * sz); - _m13 = -(cxsy * cz) + (sx * sz); - - _m21 = -(cy * sz); - _m22 = -(sxsy * sz) + (cx * cz); - _m23 = (cxsy * sz) + (sx * cz); - - _m31 = (sy); - _m32 = -(sx * cy); - _m33 = (cx * cy); - - // Reset the translation portion - _tx = _ty = _tz = 0.0; -} - - -// -------------------------------------------------------------------------- -// Matrix4x4::toEulerAngles -// -// Setup the euler angles in radians, given a rotation matrix. The rotation -// matrix could have been obtained from euler angles given the expression: -// M = X.Y.Z -// where X, Y and Z are rotation matrices about X, Y and Z axes. -// This is the "opposite" of the fromEulerAngles function. -// -------------------------------------------------------------------------- - -template -inline void -Matrix4x4::toEulerAngles (Real &x, Real &y, Real &z) const -{ - // Compute Y-axis angle - y = std::asin (_m31); - - // Compute cos and one over cos for optimization - Real cy = std::cos (y); - Real oneOverCosY = 1.0 / cy; - - if (std::fabs (cy) > 0.001) - { - // No gimball lock - x = std::atan2 (-_m32 * oneOverCosY, _m33 * oneOverCosY); - z = std::atan2 (-_m21 * oneOverCosY, _m11 * oneOverCosY); - } - else - { - // Gimbal lock case - x = 0.0; - z = std::atan2 (_m12, _m22); - } -} - - -// -------------------------------------------------------------------------- -// Matrix4x4::rightVector -// Matrix4x4::upVector -// Matrix4x4::forwardVector -// Matrix4x4::translationVector -// -// Return a base vector from the matrix. -// -------------------------------------------------------------------------- - -template -inline Vector3 -Matrix4x4::rightVector () const -{ - return Vector3 (_m11, _m12, _m13); -} - -template -inline Vector3 -Matrix4x4::upVector () const -{ - return Vector3 (_m21, _m22, _m23); -} - -template -inline Vector3 -Matrix4x4::forwardVector () const -{ - return Vector3 (_m31, _m32, _m33); -} - -template -inline Vector3 -Matrix4x4::translationVector () const -{ - return Vector3 (_tx, _ty, _tz); -} - - -// -------------------------------------------------------------------------- -// -// Nonmember Matrix4x4 functions -// -// -------------------------------------------------------------------------- - - -// -------------------------------------------------------------------------- -// Matrix4x4 * Matrix4x4 -// -// Matrix concatenation. -// -// We also provide a *= operator, as per C convention. -// -------------------------------------------------------------------------- - -template -inline Matrix4x4 -operator* (const Matrix4x4 &a, const Matrix4x4 &b) -{ - Matrix4x4 res; - - // Compute the left 4x3 (linear transformation) portion - res._m11 = (a._m11 * b._m11) + (a._m21 * b._m12) + (a._m31 * b._m13); - res._m12 = (a._m12 * b._m11) + (a._m22 * b._m12) + (a._m32 * b._m13); - res._m13 = (a._m13 * b._m11) + (a._m23 * b._m12) + (a._m33 * b._m13); - - res._m21 = (a._m11 * b._m21) + (a._m21 * b._m22) + (a._m31 * b._m23); - res._m22 = (a._m12 * b._m21) + (a._m22 * b._m22) + (a._m32 * b._m23); - res._m23 = (a._m13 * b._m21) + (a._m23 * b._m22) + (a._m33 * b._m23); - - res._m31 = (a._m11 * b._m31) + (a._m21 * b._m32) + (a._m31 * b._m33); - res._m32 = (a._m12 * b._m31) + (a._m22 * b._m32) + (a._m32 * b._m33); - res._m33 = (a._m13 * b._m31) + (a._m23 * b._m32) + (a._m33 * b._m33); - - // Compute the translation portion - res._tx = (a._m11 * b._tx) + (a._m21 * b._ty) + (a._m31 * b._tz) + a._tx; - res._ty = (a._m12 * b._tx) + (a._m22 * b._ty) + (a._m32 * b._tz) + a._ty; - res._tz = (a._m13 * b._tx) + (a._m23 * b._ty) + (a._m33 * b._tz) + a._tz; - - return res; -} - -template -inline Matrix4x4 & -operator*= (Matrix4x4 &a, const Matrix4x4 &b) -{ - a = a * b; - return a; -} - - -// -------------------------------------------------------------------------- -// Matrix4x4 * Vector3 -// -// Transform a point by a matrix. This makes using the vector class look -// like it does with linear algebra notation on paper. -// -------------------------------------------------------------------------- - -template -inline Vector3 -operator* (const Matrix4x4 &m, const Vector3 &p) -{ - Vector3 res (p); - m.transform (res); - return res; -} - - -// -------------------------------------------------------------------------- -// Transpose -// -// Return the transpose matrix. -// -------------------------------------------------------------------------- - -template -inline Matrix4x4 -Transpose (const Matrix4x4 &m) -{ - Matrix4x4 res; - - res._m11 = m._m11; res._m21 = m._m12; res._m31 = m._m13; res._tx = m._h14; - res._m12 = m._m21; res._m22 = m._m22; res._m32 = m._m23; res._ty = m._h24; - res._m13 = m._m31; res._m23 = m._m32; res._m33 = m._m33; res._tz = m._h34; - res._h14 = m._tx; res._h24 = m._ty; res._h34 = m._tz; res._tw = m._tw; - - return res; -} - - -// -------------------------------------------------------------------------- -// Determinant -// -// Compute the determinant of the 3x3 portion of the matrix. -// -------------------------------------------------------------------------- - -template -inline static Real -Determinant3x3 (const Matrix4x4 &m) -{ - return m._m11 * ((m._m22 * m._m33) - (m._m23 * m._m32)) - + m._m12 * ((m._m23 * m._m31) - (m._m21 * m._m33)) - + m._m13 * ((m._m21 * m._m32) - (m._m22 * m._m31)); -} - - -// -------------------------------------------------------------------------- -// Invert -// -// Compute the inverse of a matrix. We use the classical adjoint divided -// by the determinant method. -// -------------------------------------------------------------------------- - -template -inline Matrix4x4 -Invert (const Matrix4x4 &m) -{ - // Compute the determinant of the 3x3 portion - Real det = Determinant3x3 (m); - - // If we're singular, then the determinant is zero and there's - // no inverse - assert (std::fabs (det) > 0.000001); - - // Compute one over the determinant, so we divide once and - // can *multiply* per element - Real oneOverDet = 1.0 / det; - - // Compute the 3x3 portion of the inverse, by - // dividing the adjoint by the determinant - Matrix4x4 res; - - res._m11 = ((m._m22 * m._m33) - (m._m23 * m._m32)) * oneOverDet; - res._m12 = ((m._m13 * m._m32) - (m._m12 * m._m33)) * oneOverDet; - res._m13 = ((m._m12 * m._m23) - (m._m13 * m._m22)) * oneOverDet; - - res._m21 = ((m._m23 * m._m31) - (m._m21 * m._m33)) * oneOverDet; - res._m22 = ((m._m11 * m._m33) - (m._m13 * m._m31)) * oneOverDet; - res._m23 = ((m._m13 * m._m21) - (m._m11 * m._m23)) * oneOverDet; - - res._m31 = ((m._m21 * m._m32) - (m._m22 * m._m31)) * oneOverDet; - res._m32 = ((m._m12 * m._m31) - (m._m11 * m._m32)) * oneOverDet; - res._m33 = ((m._m11 * m._m22) - (m._m12 * m._m21)) * oneOverDet; - - // Compute the translation portion of the inverse - res._tx = -((m._tx * res._m11) + (m._ty * res._m21) + (m._tz * res._m31)); - res._ty = -((m._tx * res._m12) + (m._ty * res._m22) + (m._tz * res._m32)); - res._tz = -((m._tx * res._m13) + (m._ty * res._m23) + (m._tz * res._m33)); - - // Return it. - return res; -} - - -// -------------------------------------------------------------------------- -// RotationMatrix -// -// Setup the matrix to perform a rotation about one of the three cardinal -// X-Y-Z axes. -// -// The axis of rotation is specified by the 1-based "axis" index. -// -// theta is the amount of rotation, in radians. The right-hand rule is -// used to define "positive" rotation. -// -// The translation portion is reset. -// -------------------------------------------------------------------------- - -template -inline Matrix4x4 -RotationMatrix (Axis axis, Real theta) -{ - Matrix4x4 res; - - // Get sin and cosine of rotation angle - Real s = std::sin (theta); - Real c = std::cos (theta); - - // Check which axis they are rotating about - switch (axis) - { - case kXaxis: // Rotate about the x-axis - res._m11 = 1.0; res._m21 = 0.0; res._m31 = 0.0; - res._m12 = 0.0; res._m22 = c; res._m32 = -s; - res._m13 = 0.0; res._m23 = s; res._m33 = c; - break; - - case kYaxis: // Rotate about the y-axis - res._m11 = c; res._m21 = 0.0; res._m31 = s; - res._m12 = 0.0; res._m22 = 1.0; res._m32 = 0.0; - res._m13 = -s; res._m23 = 0.0; res._m33 = c; - break; - - case kZaxis: // Rotate about the z-axis - res._m11 = c; res._m21 = -s; res._m31 = 0.0; - res._m12 = s; res._m22 = c; res._m32 = 0.0; - res._m13 = 0.0; res._m23 = 0.0; res._m33 = 1.0; - break; - - default: - // bogus axis index - assert (false); - } - - // Reset the translation portion - res._tx = res._ty = res._tz = 0.0; - - return res; -} - - -//--------------------------------------------------------------------------- -// AxisRotationMatrix -// -// Setup the matrix to perform a rotation about an arbitrary axis. -// The axis of rotation must pass through the origin. -// -// axis defines the axis of rotation, and must be a unit vector. -// -// theta is the amount of rotation, in radians. The right-hand rule is -// used to define "positive" rotation. -// -// The translation portion is reset. -// -------------------------------------------------------------------------- - -template -inline Matrix4x4 -RotationMatrix (const Vector3 &axis, Real theta) -{ - Matrix4x4 res; - - // Quick sanity check to make sure they passed in a unit vector - // to specify the axis - assert (std::fabs (DotProduct (axis, axis) - 1.0) < 0.001); - - // Get sin and cosine of rotation angle - Real s = std::sin (theta); - Real c = std::cos (theta); - - // Compute 1 - cos(theta) and some common subexpressions - Real a = 1.0 - c; - Real ax = a * axis._x; - Real ay = a * axis._y; - Real az = a * axis._z; - - // Set the matrix elements. There is still a little more - // opportunity for optimization due to the many common - // subexpressions. We'll let the compiler handle that... - res._m11 = (ax * axis._x) + c; - res._m12 = (ax * axis._y) + (axis._z * s); - res._m13 = (ax * axis._z) - (axis._y * s); - - res._m21 = (ay * axis._x) - (axis._z * s); - res._m22 = (ay * axis._y) + c; - res._m23 = (ay * axis._z) + (axis._x * s); - - res._m31 = (az * axis._x) + (axis._y * s); - res._m32 = (az * axis._y) - (axis._x * s); - res._m33 = (az * axis._z) + c; - - // Reset the translation portion - res._tx = res._ty = res._tz = 0.0; - - return res; -} - - -// -------------------------------------------------------------------------- -// TranslationMatrix -// -// Build a translation matrix given a translation vector. -// -------------------------------------------------------------------------- - -template -inline Matrix4x4 -TranslationMatrix (Real x, Real y, Real z) -{ - return TranslationMatrix (Vector3 (x, y, z)); -} - -template -inline Matrix4x4 -TranslationMatrix (const Vector3 &v) -{ - Matrix4x4 res; - - res._m11 = 1.0; res._m21 = 0.0; res._m31 = 0.0; res._tx = v._x; - res._m12 = 0.0; res._m22 = 1.0; res._m32 = 0.0; res._ty = v._y; - res._m13 = 0.0; res._m23 = 0.0; res._m33 = 1.0; res._tz = v._z; - - return res; -} - - -// -------------------------------------------------------------------------- -// ScaleMatrix -// -// Setup the matrix to perform scale on each axis. For uniform scale by k, -// use a vector of the form Vector3( k, k, k ). -// -// The translation portion is reset. -// -------------------------------------------------------------------------- - -template -inline Matrix4x4 -ScaleMatrix (const Vector3 &s) -{ - Matrix4x4 res; - - // Set the matrix elements. Pretty straightforward - res._m11 = s._x; res._m21 = 0.0; res._m31 = 0.0; - res._m12 = 0.0; res._m22 = s._y; res._m32 = 0.0; - res._m13 = 0.0; res._m23 = 0.0; res._m33 = s._z; - - // Reset the translation portion - res._tx = res._ty = res._tz = 0.0; - - return res; -} - - -// -------------------------------------------------------------------------- -// ScaleAlongAxisMatrix -// -// Setup the matrix to perform scale along an arbitrary axis. -// -// The axis is specified using a unit vector. -// -// The translation portion is reset. -// -------------------------------------------------------------------------- - -template -inline Matrix4x4 -ScaleAlongAxisMatrix (const Vector3 &axis, Real k) -{ - Matrix4x4 res; - - // Quick sanity check to make sure they passed in a unit vector - // to specify the axis - assert (std::fabs (DotProduct (axis, axis) - 1.0) < 0.001); - - // Compute k-1 and some common subexpressions - Real a = k - 1.0; - Real ax = a * axis._x; - Real ay = a * axis._y; - Real az = a * axis._z; - - // Fill in the matrix elements. We'll do the common - // subexpression optimization ourselves here, since diagonally - // opposite matrix elements are equal - res._m11 = (ax * axis._x) + 1.0; - res._m22 = (ay * axis._y) + 1.0; - res._m32 = (az * axis._z) + 1.0; - - res._m12 = res._m21 = (ax * axis._y); - res._m13 = res._m31 = (ax * axis._z); - res._m23 = res._m32 = (ay * axis._z); - - // Reset the translation portion - res._tx = res._ty = res._tz = 0.0; - - return res; -} - - -// -------------------------------------------------------------------------- -// ShearMatrix -// -// Setup the matrix to perform a shear -// -// The type of shear is specified by the 1-based "axis" index. The effect -// of transforming a point by the matrix is described by the pseudocode -// below: -// -// xAxis => y += s * x, z += t * x -// yAxis => x += s * y, z += t * y -// zAxis => x += s * z, y += t * z -// -// The translation portion is reset. -// -------------------------------------------------------------------------- - -template -inline Matrix4x4 -ShearMatrix (Axis axis, Real s, Real t) -{ - Matrix4x4 res; - - // Check which type of shear they want - switch (axis) - { - case kXaxis: // Shear y and z using x - res._m11 = 1.0; res._m21 = 0.0; res._m31 = 0.0; - res._m12 = s; res._m22 = 1.0; res._m32 = 0.0; - res._m13 = t; res._m23 = 0.0; res._m33 = 1.0; - break; - - case kYaxis: // Shear x and z using y - res._m11 = 1.0; res._m21 = s; res._m31 = 0.0; - res._m12 = 0.0; res._m22 = 1.0; res._m32 = 0.0; - res._m13 = 0.0; res._m23 = t; res._m33 = 1.0; - break; - - case kZaxis: // Shear x and y using z - res._m11 = 1.0; res._m21 = 0.0; res._m31 = s; - res._m12 = 0.0; res._m22 = 1.0; res._m32 = t; - res._m13 = 0.0; res._m23 = 0.0; res._m33 = 1.0; - break; - - default: - // bogus axis index - assert (false); - } - - // Reset the translation portion - res._tx = res._ty = res._tz = 0.0; - - return res; -} - - -// -------------------------------------------------------------------------- -// ProjectionMatrix -// -// Setup the matrix to perform a projection onto a plane passing -// through the origin. The plane is perpendicular to the -// unit vector n. -// -------------------------------------------------------------------------- - -template -inline Matrix4x4 -ProjectionMatrix (const Vector3 &n) -{ - Matrix4x4 res; - - // Quick sanity check to make sure they passed in a unit vector - // to specify the axis - assert (std::fabs (DotProduct (n, n) - 1.0) < 0.001); - - // Fill in the matrix elements. We'll do the common - // subexpression optimization ourselves here, since diagonally - // opposite matrix elements are equal - res._m11 = 1.0 - (n._x * n._x); - res._m22 = 1.0 - (n._y * n._y); - res._m33 = 1.0 - (n._z * n._z); - - res._m12 = res._m21 = -(n._x * n._y); - res._m13 = res._m31 = -(n._x * n._z); - res._m23 = res._m32 = -(n._y * n._z); - - // Reset the translation portion - res._tx = res._ty = res._tz = 0.0; - - return res; -} - - -// -------------------------------------------------------------------------- -// ReflectionMatrix -// -// Setup the matrix to perform a reflection about a plane parallel -// to a cardinal plane. -// -// axis is a 1-based index which specifies the plane to project about: -// -// xAxis => reflect about the plane x=k -// yAxis => reflect about the plane y=k -// zAxis => reflect about the plane z=k -// -// The translation is set appropriately, since translation must occur if -// k != 0 -// -------------------------------------------------------------------------- - -template -inline Matrix4x4 -ReflectionMatrix (Axis axis, Real k) -{ - Matrix4x4 res; - - // Check which plane they want to reflect about - switch (axis) - { - case kXaxis: // Reflect about the plane x=k - res._m11 = -1.0; res._m21 = 0.0; res._m31 = 0.0; res._tx = 2.0 * k; - res._m12 = 0.0; res._m22 = 1.0; res._m32 = 0.0; res._ty = 0.0; - res._m13 = 0.0; res._m23 = 0.0; res._m33 = 1.0; res._tz = 0.0; - break; - - case kYaxis: // Reflect about the plane y=k - res._m11 = 1.0; res._m21 = 0.0; res._m31 = 0.0; res._tx = 0.0; - res._m12 = 0.0; res._m22 = -1.0; res._m32 = 0.0; res._ty = 2.0 * k; - res._m13 = 0.0; res._m23 = 0.0; res._m33 = 1.0; res._tz = 0.0; - break; - - case kZaxis: // Reflect about the plane z=k - res._m11 = 1.0; res._m21 = 0.0; res._m31 = 0.0; res._tx = 0.0; - res._m12 = 0.0; res._m22 = 1.0; res._m32 = 0.0; res._ty = 0.0; - res._m13 = 0.0; res._m23 = 0.0; res._m33 = -1.0; res._tz = 2.0 * k; - break; - - default: - // bogus axis index - assert (false); - } - - return res; -} - - -// -------------------------------------------------------------------------- -// AxisReflectionMatrix -// -// Setup the matrix to perform a reflection about an arbitrary plane -// through the origin. The unit vector n is perpendicular to the plane. -// -// The translation portion is reset. -// -------------------------------------------------------------------------- - -template -inline Matrix4x4 -AxisReflectionMatrix (const Vector3 &n) -{ - Matrix4x4 res; - - // Quick sanity check to make sure they passed in a unit vector - // to specify the axis - assert (std::fabs (DotProduct (n, n) - 1.0) < 0.001); - - // Compute common subexpressions - Real ax = -2.0 * n._x; - Real ay = -2.0 * n._y; - Real az = -2.0 * n._z; - - // Fill in the matrix elements. We'll do the common - // subexpression optimization ourselves here, since diagonally - // opposite matrix elements are equal - res._m11 = 1.0 + (ax * n._x); - res._m22 = 1.0 + (ay * n._y); - res._m32 = 1.0 + (az * n._z); - - res._m12 = res._m21 = (ax * n._y); - res._m13 = res._m31 = (ax * n._z); - res._m23 = res._m32 = (ay * n._z); - - // Reset the translation portion - res._tx = res._ty = res._tz = 0.00; - - return res; -} - - -// -------------------------------------------------------------------------- -// LookAtMatrix -// -// Setup the matrix to perform a "Look At" transformation like a first -// person camera. -// -------------------------------------------------------------------------- -template -inline Matrix4x4 -LookAtMatrix (const Vector3 &camPos, const Vector3 &target, - const Vector3 &camUp) -{ - Matrix4x4 rot, trans; - - Vector3 forward (camPos - target); - forward.normalize (); - - Vector3 right (CrossProduct (camUp, forward)); - Vector3 up (CrossProduct (forward, right)); - - right.normalize (); - up.normalize (); - - rot._m11 = right._x; - rot._m21 = right._y; - rot._m31 = right._z; - - rot._m12 = up._x; - rot._m22 = up._y; - rot._m32 = up._z; - - rot._m13 = forward._x; - rot._m23 = forward._y; - rot._m33 = forward._z; - - rot._tx = 0.0; - rot._ty = 0.0; - rot._tz = 0.0; - - trans = TranslationMatrix (-camPos); - - return (rot * trans); -} - - -// -------------------------------------------------------------------------- -// FrustumMatrix -// -// Setup a frustum matrix given the left, right, bottom, top, near, and far -// values for the frustum boundaries. -// -------------------------------------------------------------------------- - -template -inline Matrix4x4 -FrustumMatrix (Real l, Real r, Real b, Real t, Real n, Real f) -{ - assert (n >= 0.0); - assert (f >= 0.0); - - Matrix4x4 res; - - Real width = r - l; - Real height = t - b; - Real depth = f - n; - - res._m[0] = (2 * n) / width; - res._m[1] = 0.0; - res._m[2] = 0.0; - res._m[3] = 0.0; - - res._m[4] = 0.0; - res._m[5] = (2 * n) / height; - res._m[6] = 0.0; - res._m[7] = 0.0; - - res._m[8] = (r + l) / width; - res._m[9] = (t + b) / height; - res._m[10]= -(f + n) / depth; - res._m[11]= -1.0; - - res._m[12]= 0.0; - res._m[13]= 0.0; - res._m[14]= -(2 * f * n) / depth; - res._m[15]= 0.0; - - return res; -} - - -// -------------------------------------------------------------------------- -// PerspectiveMatrix -// -// Setup a perspective matrix given the field-of-view in the Y direction -// in degrees, the aspect ratio of Y/X, and near and far plane distances. -// -------------------------------------------------------------------------- - -template -inline Matrix4x4 -PerspectiveMatrix (Real fovY, Real aspect, Real n, Real f) -{ - Matrix4x4 res; - - Real angle; - Real cot; - - angle = fovY / 2.0; - angle = degToRad (angle); - - cot = std::cos (angle) / std::sin (angle); - - res._m[0] = cot / aspect; - res._m[1] = 0.0; - res._m[2] = 0.0; - res._m[3] = 0.0; - - res._m[4] = 0.0; - res._m[5] = cot; - res._m[6] = 0.0; - res._m[7] = 0.0; - - res._m[8] = 0.0; - res._m[9] = 0.0; - res._m[10]= -(f + n) / (f - n); - res._m[11]= -1.0; - - res._m[12]= 0.0; - res._m[13]= 0.0; - res._m[14]= -(2 * f * n) / (f - n); - res._m[15]= 0.0; - - return res; -} - - -// -------------------------------------------------------------------------- -// OrthoMatrix -// -// Setup an orthographic Matrix4x4 given the left, right, bottom, top, near, -// and far values for the frustum boundaries. -// -------------------------------------------------------------------------- - -template -inline Matrix4x4 -OrthoMatrix (Real l, Real r, Real b, Real t, Real n, Real f) -{ - Matrix4x4 res; - - Real width = r - l; - Real height = t - b; - Real depth = f - n; - - res._m[0] = 2.0 / width; - res._m[1] = 0.0; - res._m[2] = 0.0; - res._m[3] = 0.0; - - res._m[4] = 0.0; - res._m[5] = 2.0 / height; - res._m[6] = 0.0; - res._m[7] = 0.0; - - res._m[8] = 0.0; - res._m[9] = 0.0; - res._m[10]= -2.0 / depth; - res._m[11]= 0.0; - - res._m[12]= -(r + l) / width; - res._m[13]= -(t + b) / height; - res._m[14]= -(f + n) / depth; - res._m[15]= 1.0; - - return res; -} - - -// -------------------------------------------------------------------------- -// OrthoNormalMatrix -// -// Setup an orientation matrix using 3 basis normalized vectors. -// -------------------------------------------------------------------------- - -template -inline Matrix4x4 -OrthoNormalMatrix (const Vector3 &xdir, const Vector3 &ydir, - const Vector3 &zdir) -{ - Matrix4x4 res; - - res._m[0] = xdir._x; res._m[4] = ydir._x; res._m[8] = zdir._x; res._m[12] = 0.0; - res._m[1] = xdir._y; res._m[5] = ydir._y; res._m[9] = zdir._y; res._m[13] = 0.0; - res._m[2] = xdir._z; res._m[6] = ydir._z; res._m[10]= zdir._z; res._m[14] = 0.0; - res._m[3] = 0.0; res._m[7] = 0.0; res._m[11]= 0.0; res._m[15] = 1.0; - - return res; -} - - -///////////////////////////////////////////////////////////////////////////// -// -// class Quaternion implementation. -// -///////////////////////////////////////////////////////////////////////////// - -// -------------------------------------------------------------------------- -// Quaternion::identity -// -// Set to identity -// -------------------------------------------------------------------------- - -template -inline void -Quaternion::identity () -{ - _w = 1.0; _x = _y = _z = 0.0; -} - - -// -------------------------------------------------------------------------- -// Quaternion::normalize -// -// "Normalize" a quaternion. Note that normally, quaternions -// are always normalized (within limits of numerical precision). -// -// This function is provided primarily to combat floating point "error -// creep", which can occur when many successive quaternion operations -// are applied. -// -------------------------------------------------------------------------- - -template -inline void -Quaternion::normalize () -{ - // Compute magnitude of the quaternion - Real mag = std::sqrt ((_w * _w) + (_x * _x) + (_y * _y) + (_z * _z)); - - // Check for bogus length, to protect against divide by zero - if (mag > 0.0) - { - // Normalize it - Real oneOverMag = 1.0 / mag; - - _w *= oneOverMag; - _x *= oneOverMag; - _y *= oneOverMag; - _z *= oneOverMag; - } -} - - -// -------------------------------------------------------------------------- -// Quaternion::computeW -// -// Compute the W component of a unit quaternion given its x,y,z components. -// -------------------------------------------------------------------------- - -template -inline void -Quaternion::computeW () -{ - Real t = 1.0 - (_x * _x) - (_y * _y) - (_z * _z); - - if (t < 0.0) - _w = 0.0; - else - _w = -std::sqrt (t); -} - - -// -------------------------------------------------------------------------- -// Quaternion::rotate -// -// Rotate a point by quaternion. v' = q.p.q*, where p = <0, v>. -// -------------------------------------------------------------------------- - -template -inline void -Quaternion::rotate (Vector3 &v) const -{ - Quaternion qf = *this * v * ~(*this); - v._x = qf._x; - v._y = qf._y; - v._z = qf._z; -} - - -// -------------------------------------------------------------------------- -// Quaternion::fromMatrix -// -// Setup the quaternion to perform a rotation, given the angular displacement -// in matrix form. -// -------------------------------------------------------------------------- - -template -inline void -Quaternion::fromMatrix (const Matrix4x4 &m) -{ - Real trace = m._m11 + m._m22 + m._m33 + 1.0; - - if (trace > 0.0001) - { - Real s = 0.5 / std::sqrt (trace); - _w = 0.25 / s; - _x = (m._m23 - m._m32) * s; - _y = (m._m31 - m._m13) * s; - _z = (m._m12 - m._m21) * s; - } - else - { - if ((m._m11 > m._m22) && (m._m11 > m._m33)) - { - Real s = 0.5 / std::sqrt (1.0 + m._m11 - m._m22 - m._m33); - _x = 0.25 / s; - _y = (m._m21 + m._m12) * s; - _z = (m._m31 + m._m13) * s; - _w = (m._m32 - m._m23) * s; - } - else if (m._m22 > m._m33) - { - Real s = 0.5 / std::sqrt (1.0 + m._m22 - m._m11 - m._m33); - _x = (m._m21 + m._m12) * s; - _y = 0.25 / s; - _z = (m._m32 + m._m23) * s; - _w = (m._m31 - m._m13) * s; - } - else - { - Real s = 0.5 / std::sqrt (1.0 + m._m33 - m._m11 - m._m22); - _x = (m._m31 + m._m13) * s; - _y = (m._m32 + m._m23) * s; - _z = 0.25 / s; - _w = (m._m21 - m._m12) * s; - } - } -} - - -// -------------------------------------------------------------------------- -// Quaternion::fromEulerAngles -// -// Setup the quaternion to perform an object->inertial rotation, given the -// orientation in XYZ-Euler angles format. x,y,z parameters must be in -// radians. -// -------------------------------------------------------------------------- - -template -inline void -Quaternion::fromEulerAngles (Real x, Real y, Real z) -{ - // Compute sine and cosine of the half angles - Real sr = std::sin (x * 0.5); - Real cr = std::cos (x * 0.5); - Real sp = std::sin (y * 0.5); - Real cp = std::cos (y * 0.5); - Real sy = std::sin (z * 0.5); - Real cy = std::cos (z * 0.5); - - // Compute values - _w = (cy * cp * cr) + (sy * sp * sr); - _x = -(sy * sp * cr) + (cy * cp * sr); - _y = (cy * sp * cr) + (sy * cp * sr); - _z = -(cy * sp * sr) + (sy * cp * cr); -} - - -// -------------------------------------------------------------------------- -// Quaternion::toEulerAngles -// -// Setup the Euler angles, given an object->inertial rotation quaternion. -// Returned x,y,z are in radians. -// -------------------------------------------------------------------------- - -template -inline void -Quaternion::toEulerAngles (Real &x, Real &y, Real &z) const -{ - // Compute Y-axis angle - y = std::asin (2.0 * ((_x * _z) + (_w * _y))); - - // Compute cos and one over cos for optimization - Real cy = std::cos (y); - Real oneOverCosY = 1.0 / cy; - - if (std::fabs (cy) > 0.001) - { - // No gimball lock - x = std::atan2 (2.0 * ((_w * _x) - (_y * _z)) * oneOverCosY, - (1.0 - 2.0 * (_x*_x + _y*_y)) * oneOverCosY); - z = std::atan2 (2.0 * ((_w * _z) - (_x * _y)) * oneOverCosY, - (1.0 - 2.0 * (_y*_y + _z*_z)) * oneOverCosY); - } - else - { - // Gimbal lock case - x = 0.0; - z = std::atan2 (2.0 * ((_x * _y) + (_w * _z)), - 1.0 - 2.0 * (_x*_x + _z*_z)); - } -} - - -// -------------------------------------------------------------------------- -// Quaternion::getRotationAngle -// -// Return the rotation angle theta (in radians). -// -------------------------------------------------------------------------- - -template -inline Real -Quaternion::rotationAngle () const -{ - // Compute the half angle. Remember that w = cos(theta / 2) - Real thetaOver2 = safeAcos (_w); - - // Return the rotation angle - return thetaOver2 * 2.0; -} - - -// -------------------------------------------------------------------------- -// Quaternion::getRotationAxis -// -// Return the rotation axis. -// -------------------------------------------------------------------------- - -template -inline Vector3 -Quaternion::rotationAxis () const -{ - // Compute sin^2(theta/2). Remember that w = cos(theta/2), - // and sin^2(x) + cos^2(x) = 1 - Real sinThetaOver2Sq = 1.0 - (_w * _w); - - // Protect against numerical imprecision - if (sinThetaOver2Sq <= 0.0) - { - // Identity quaternion, or numerical imprecision. Just - // return any valid vector, since it doesn't matter - - return Vector3 (1.0, 0.0, 0.0); - } - - // Compute 1 / sin(theta/2) - Real oneOverSinThetaOver2 = 1.0 / std::sqrt (sinThetaOver2Sq); - - // Return axis of rotation - return Vector3 ( - _x * oneOverSinThetaOver2, - _y * oneOverSinThetaOver2, - _z * oneOverSinThetaOver2 - ); -} - - -// -------------------------------------------------------------------------- -// Quaternion operators -// -// Operator overloading for basic quaternion operations. -// -------------------------------------------------------------------------- - -template -inline Quaternion -Quaternion::operator+ (const Quaternion &q) const -{ - return Quaternion (_w + q._w, _x + q._x, _y + q._y, _z + q._z); -} - -template -inline Quaternion & -Quaternion::operator+= (const Quaternion &q) -{ - _w += q._w; _x += q._x; _y += q._y; _z += q._z; - return *this; -} - -template -inline Quaternion -Quaternion::operator- (const Quaternion &q) const -{ - return Quaternion (_w - q._w, _x - q._x, _y - q._y, _z - q._z); -} - -template -inline Quaternion & -Quaternion::operator-= (const Quaternion &q) -{ - _w -= q._w; _x -= q._x; _y -= q._y; _z -= q._z; - return *this; -} - -// Quaternion multiplication. The order of multiplication, from left -// to right, corresponds to the order of concatenated rotations. -// NOTE: Quaternion multiplication is NOT commutative, p * q != q * p -template -inline Quaternion -Quaternion::operator* (const Quaternion &q) const -{ - // We use the Grassman product formula: - // pq = - return Quaternion ( - (_w * q._w) - (_x * q._x) - (_y * q._y) - (_z * q._z), - (_x * q._w) + (_w * q._x) + (_y * q._z) - (_z * q._y), - (_y * q._w) + (_w * q._y) + (_z * q._x) - (_x * q._z), - (_z * q._w) + (_w * q._z) + (_x * q._y) - (_y * q._x) - ); -} - -template -inline Quaternion & -Quaternion::operator*= (const Quaternion &q) -{ - *this = *this * q; - return *this; -} - -template -inline Quaternion -Quaternion::operator* (const Vector3 &v) const -{ - // q * v = q * p where p = <0,v> - // Thus, we can simplify the operations. - return Quaternion ( - - (_x * v._x) - (_y * v._y) - (_z * v._z), - (_w * v._x) + (_y * v._z) - (_z * v._y), - (_w * v._y) + (_z * v._x) - (_x * v._z), - (_w * v._z) + (_x * v._y) - (_y * v._x) - ); -} - -template -inline Quaternion & -Quaternion::operator*= (const Vector3 &v) -{ - *this = *this * v; - return *this; -} - -template -inline Quaternion -Quaternion::operator* (Real k) const -{ - return Quaternion (_w * k, _x * k, _y * k, _z * k); -} - -template -inline Quaternion & -Quaternion::operator*= (Real k) -{ - _w *= k; _x *= k; _y *= k; _z *= k; - return *this; -} - -template -inline Quaternion -Quaternion::operator/ (Real k) const -{ - Real oneOverK = 1.0 / k; - return Quaternion (_w * oneOverK, _x * oneOverK, _y * oneOverK, _z * oneOverK); -} - -template -inline Quaternion & -Quaternion::operator/= (Real k) -{ - Real oneOverK = 1.0 / k; - _w *= oneOverK; _x *= oneOverK; _y *= oneOverK; _z *= oneOverK; - return *this; -} - -// Quaternion conjugate -template -inline Quaternion -Quaternion::operator~ () const -{ - return Quaternion (_w, -_x, -_y, -_z); -} - - -// Quaternion negation -template -inline Quaternion -Quaternion::operator- () const -{ - return Quaternion (-_w, -_x, -_y, -_z); -} - - -// -------------------------------------------------------------------------- -// -// Nonmember Quaternion functions -// -// -------------------------------------------------------------------------- - -// Scalar on left multiplication -template -inline Quaternion -operator* (Real k, const Quaternion &q) -{ - return Quaternion (q._w * k, q._x * k, q._y * k, q._z * k); -} - -// Quaternion dot product -template -inline Real -DotProduct (const Quaternion &a, const Quaternion &b) -{ - return ((a._w * b._w) + (a._x * b._x) + (a._y * b._y) + (a._z * b._z)); -} - -// Compute the quaternion conjugate. This is the quaternian -// with the opposite rotation as the original quaternion. -template -inline Quaternion -Conjugate (const Quaternion &q) -{ - return Quaternion (q._w, -q._x, -q._y, -q._z); -} - - -// Compute the inverse quaternion (for unit quaternion only). -template -inline Quaternion -Inverse (const Quaternion &q) -{ - // Assume this is a unit quaternion! No check for this! - Quaternion res (q._w, -q._x, -q._y, -q._z); - res.normalize (); - return res; -} - - -// -------------------------------------------------------------------------- -// RotationQuaternion -// -// Setup the quaternion to rotate about the specified axis. theta must -// be in radians. -// -------------------------------------------------------------------------- - -template -inline Quaternion -RotationQuaternion (Axis axis, Real theta) -{ - Quaternion res; - - // Compute the half angle - Real thetaOver2 = theta * 0.5; - - // Set the values - switch (axis) - { - case kXaxis: - res._w = std::cos (thetaOver2); - res._x = std::sin (thetaOver2); - res._y = 0.0; - res._z = 0.0; - break; - - case kYaxis: - res._w = std::cos (thetaOver2); - res._x = 0.0; - res._y = std::sin (thetaOver2); - res._z = 0.0; - break; - - case kZaxis: - res._w = std::cos (thetaOver2); - res._x = 0.0; - res._y = 0.0; - res._z = std::sin (thetaOver2); - break; - - default: - // Bad axis - assert (false); - } - - return res; -} - -template -inline Quaternion -RotationQuaternion (const Vector3 &axis, Real theta) -{ - Quaternion res; - - // The axis of rotation must be normalized - assert (std::fabs (DotProduct (axis, axis) - 1.0) < 0.001); - - // Compute the half angle and its sin - Real thetaOver2 = theta * 0.5; - Real sinThetaOver2 = std::sin (thetaOver2); - - // Set the values - res._w = std::cos (thetaOver2); - res._x = axis._x * sinThetaOver2; - res._y = axis._y * sinThetaOver2; - res._z = axis._z * sinThetaOver2; - - return res; -} - - -// -------------------------------------------------------------------------- -// Log -// -// Unit quaternion logarithm. log(q) = log(cos(theta) + n*sin(theta)) -// -------------------------------------------------------------------------- - -template -inline Quaternion -Log (const Quaternion &q) -{ - Quaternion res; - res._w = 0.0; - - if (std::fabs (q._w) < 1.0) - { - Real theta = std::acos (q._w); - Real sin_theta = std::sin (theta); - - if (std::fabs (sin_theta) > 0.00001) - { - Real thetaOverSinTheta = theta / sin_theta; - res._x = q._x * thetaOverSinTheta; - res._y = q._y * thetaOverSinTheta; - res._z = q._z * thetaOverSinTheta; - return res; - } - } - - res._x = q._x; - res._y = q._y; - res._z = q._z; - - return res; -} - - -// -------------------------------------------------------------------------- -// Exp -// -// Quaternion exponential. -// -------------------------------------------------------------------------- - -template -inline Quaternion -Exp (const Quaternion &q) -{ - Real theta = std::sqrt (DotProduct (q, q)); - Real sin_theta = std::sin (theta); - - Quaternion res; - res._w = std::cos (theta); - - if (std::fabs (sin_theta) > 0.00001) - { - Real sinThetaOverTheta = sin_theta / theta; - res._x = q._x * sinThetaOverTheta; - res._y = q._y * sinThetaOverTheta; - res._z = q._z * sinThetaOverTheta; - } - else - { - res._x = q._x; - res._y = q._y; - res._z = q._z; - } - - return res; -} - - -// -------------------------------------------------------------------------- -// Pow -// -// Quaternion exponentiation. -// -------------------------------------------------------------------------- - -template -inline Quaternion -Pow (const Quaternion &q, Real exponent) -{ - // Check for the case of an identity quaternion. - // This will protect against divide by zero - if (std::fabs (q._w) > 0.9999) - return q; - - // Extract the half angle alpha (alpha = theta/2) - Real alpha = std::acos (q._w); - - // Compute new alpha value - Real newAlpha = alpha * exponent; - - // Compute new quaternion - Vector3 n (q._x, q._y, q._z); - n *= std::sin (newAlpha) / std::sin (alpha); - - return Quaternion (std::cos (newAlpha), n); -} - - -// -------------------------------------------------------------------------- -// Slerp -// -// Spherical linear interpolation. -// -------------------------------------------------------------------------- - -template -inline Quaternion -Slerp (const Quaternion &q0, const Quaternion &q1, Real t) -{ - // Check for out-of range parameter and return edge points if so - if (t <= 0.0) return q0; - if (t >= 1.0) return q1; - - // Compute "cosine of angle between quaternions" using dot product - Real cosOmega = DotProduct (q0, q1); - - // If negative dot, use -q1. Two quaternions q and -q - // represent the same rotation, but may produce - // different slerp. We chose q or -q to rotate using - // the acute angle. - Real q1w = q1._w; - Real q1x = q1._x; - Real q1y = q1._y; - Real q1z = q1._z; - - if (cosOmega < 0.0) - { - q1w = -q1w; - q1x = -q1x; - q1y = -q1y; - q1z = -q1z; - cosOmega = -cosOmega; - } - - // We should have two unit quaternions, so dot should be <= 1.0 - assert (cosOmega < 1.1); - - // Compute interpolation fraction, checking for quaternions - // almost exactly the same - Real k0, k1; - - if (cosOmega > 0.9999) - { - // Very close - just use linear interpolation, - // which will protect againt a divide by zero - - k0 = 1.0 - t; - k1 = t; - } - else - { - // Compute the sin of the angle using the - // trig identity sin^2(omega) + cos^2(omega) = 1 - Real sinOmega = std::sqrt (1.0 - (cosOmega * cosOmega)); - - // Compute the angle from its sin and cosine - Real omega = std::atan2 (sinOmega, cosOmega); - - // Compute inverse of denominator, so we only have - // to divide once - Real oneOverSinOmega = 1.0 / sinOmega; - - // Compute interpolation parameters - k0 = std::sin ((1.0 - t) * omega) * oneOverSinOmega; - k1 = std::sin (t * omega) * oneOverSinOmega; - } - - // Interpolate and return new quaternion - return Quaternion ( - (k0 * q0._w) + (k1 * q1w), - (k0 * q0._x) + (k1 * q1x), - (k0 * q0._y) + (k1 * q1y), - (k0 * q0._z) + (k1 * q1z) - ); -} - - -// -------------------------------------------------------------------------- -// Squad -// -// Spherical cubic interpolation. -// squad = slerp (slerp (q0, q1, t), slerp (qa, qb, t), 2t(1 - t)). -// -------------------------------------------------------------------------- - -template -inline Quaternion -Squad (const Quaternion &q0, const Quaternion &qa, - const Quaternion &qb, const Quaternion &q1, Real t) -{ - Real slerp_t = 2.0 * t * (1.0 - t); - - Quaternion slerp_q0 = Slerp (q0, q1, t); - Quaternion slerp_q1 = Slerp (qa, qb, t); - - return Slerp (slerp_q0, slerp_q1, slerp_t); -} - - -// -------------------------------------------------------------------------- -// Intermediate -// -// Compute intermediate quaternions for building spline segments. -// -------------------------------------------------------------------------- - -template -inline void -Intermediate (const Quaternion &qprev, const Quaternion &qcurr, - const Quaternion &qnext, Quaternion &qa, Quaternion &qb) -{ - // We should have unit quaternions - assert (DotProduct (qprev, qprev) <= 1.0001); - assert (DotProduct (qcurr, qcurr) <= 1.0001); - - Quaternion inv_prev = Conjugate (qprev); - Quaternion inv_curr = Conjugate (qcurr); - - Quaternion p0 = inv_prev * qcurr; - Quaternion p1 = inv_curr * qnext; - - Quaternion arg = (Log (p0) - Log (p1)) * 0.25; - - qa = qcurr * Exp ( arg); - qb = qcurr * Exp (-arg); -} diff --git a/source/shared_lib/include/graphics/md5/Md5Model.h b/source/shared_lib/include/graphics/md5/Md5Model.h deleted file mode 100644 index f4ded72b..00000000 --- a/source/shared_lib/include/graphics/md5/Md5Model.h +++ /dev/null @@ -1,548 +0,0 @@ -// ============================================================== -// This file is part of MegaGlest (www.glest.org) -// -// Md5Model.h -- Copyright (c) 2006 David Henry -// changed for use with MegaGlest: Copyright (C) 2011- by Mark Vejvoda -// -// This code is licensed under the MIT license: -// http://www.opensource.org/licenses/mit-license.php -// -// Open Source Initiative OSI - The MIT License (MIT):Licensing -// -// The MIT License (MIT) -// Copyright (c) -// -// 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.// -// -// Declarations for MD5 Model Classes (object, mesh, animation and -// skeleton). -// -///////////////////////////////////////////////////////////////////////////// -#ifndef __MD5_H__ -#define __MD5_H__ - -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#include -#endif // _WIN32 - -#include -#include -#include -#include -#include - -#if !defined(_WIN32) || defined(__MINGW32__) -#include -#endif - -#include - -#include "Mathlib.h" -#include "md5Texture.h" - -namespace Shared { namespace Graphics { namespace md5 { - -using std::string; -using std::vector; -using std::map; - -#if defined(_WIN32) -using std::tr1::shared_ptr; -#endif - -// Forward declarations -class Md5Skeleton; -class Md5Mesh; -class Md5Model; -class Md5Animation; -class Md5Object; -class ShaderProgram; -class ArbVertexProgram; -class ArbFragmentProgram;; - -// MD5 Constants -extern const int kMd5Version; - -// We can use a specific render path, depending on -// which shader/program we want to use... -enum render_path_e - { - R_normal, - R_ARBfp_diffuse, - R_ARBfp_diffuse_specular, - R_ARBfp_ds_parallax, - R_shader - }; - -// Tangent uniform's location -//extern GLint tangentLoc; - -// ARB program's tangent location -#define TANGENT_LOC 6 - -// OpenGL vector types -typedef GLfloat vec2_t[2]; -typedef GLfloat vec3_t[3]; -typedef GLfloat vec4_t[4]; - -struct Md5Joint_t -{ - string name; - int parent; - - Vector3f pos; - Quaternionf orient; -}; - - -struct Md5Vertex_t -{ - float st[2]; // Texture coordinates - - int startWeight; // Start index weights - int countWeight; // Number of weights -}; - - -struct Md5Triangle_t -{ - int index[3]; // Vertex indices -}; - - -struct Md5Weight_t -{ - int joint; // Joint index - float bias; - - Vector3f pos; - Vector3f norm; - Vector3f tan; -}; - - -struct BoundingBox_t -{ - Vector3f min; - Vector3f max; -}; - - -struct OBBox_t -{ - Matrix4x4f world; - - Vector3f center; - Vector3f extent; -}; - - -///////////////////////////////////////////////////////////////////////////// -// -// class Md5Exception - Exception class for MD5 loader classes. -// This acts like a standard runtime_error exception but -// know which file or mesh has failed to be loaded. -// -///////////////////////////////////////////////////////////////////////////// - -class Md5Exception : public std::runtime_error -{ -public: - // Constructors - Md5Exception (const string &error) - : std::runtime_error (error) { } - Md5Exception (const string &error, const string &name) - : std::runtime_error (error), _which (name) { } - virtual ~Md5Exception () throw () { } - -public: - // Public interface - virtual const char *which () const throw () { - return _which.c_str (); - } - -private: - // Member variables - string _which; -}; - - -///////////////////////////////////////////////////////////////////////////// -// -// class Md5Skeleton - Skeleton model data class. -// -///////////////////////////////////////////////////////////////////////////// - -class Md5Skeleton -{ -public: - // Constructors/Destructor - Md5Skeleton () { } - Md5Skeleton (std::ifstream &file, int numJoints) - throw (Md5Exception); - ~Md5Skeleton (); - -private: - // Internal types - typedef shared_ptr Md5JointPtr; - -public: - // Public interface - void draw (const Matrix4x4f &modelView, bool labelJoints); - - void setNumJoints (int numJoints); - void addJoint (Md5Joint_t *thisJoint); - - Md5Skeleton *clone () const; - - // Accessors - int numJoints () const { return _joints.size (); } - Md5Joint_t *joint (int index) const { return _joints[index].get (); } - -private: - // Member variables - vector _joints; -}; - - -///////////////////////////////////////////////////////////////////////////// -// -// class Md5Mesh - Mesh data class. -// -///////////////////////////////////////////////////////////////////////////// - -class Md5Mesh -{ -public: - // Public internal types - enum - { - kHide, // Skip mesh - kNoDraw, // Don't draw but prepare vertices - kShow, // Draw mesh - }; - - typedef shared_ptr Md5VertexPtr; - typedef shared_ptr Md5TrianglePtr; - typedef shared_ptr Md5WeightPtr; - -public: - // Constructor/Destructor - Md5Mesh (std::ifstream &ifs) - throw (Md5Exception); - ~Md5Mesh (); - -public: - // Public interface - void setupVertexArrays (Md5Skeleton *skel); - void computeWeightNormals (Md5Skeleton *skel); - void computeWeightTangents (Md5Skeleton *skel); - void computeBoundingBox (Md5Skeleton *skel); - void renderVertexArrays () const; - void drawNormals () const; - - // Hide/NoDraw/Show state - void setState (int state) { _renderState = state; } - - // Texture setters - void setDecalMap (const Texture2D *tex) { _decal = tex; } - void setSpecularMap (const Texture2D *tex) { _specMap = tex; } - void setNormalMap (const Texture2D *tex) { _normalMap = tex; } - void setHeightMap (const Texture2D *tex) { _heightMap = tex; } - - // Accessors - const string &name () const { return _name; } - const BoundingBox_t &boundingBox () const { return _boundingBox; } - - // Mesh render state - bool hiden () const { return (_renderState == kHide); } - bool noDraw () const { return (_renderState == kNoDraw); } - bool show () const { return (_renderState == kShow); } - -private: - // Internal functions - void preRenderVertexArrays () const; - void postRenderVertexArrays () const; - void allocVertexArrays (); - void setupTexCoordArray (); - void setupTexture (const Texture2D *tex, GLenum texUnit) const; - void resetReversedTexture(const Texture2D *tex, GLenum texUnit) const; - -private: - // Member variables - string _name; - string _shader; - int _renderState; - - BoundingBox_t _boundingBox; - - int _numVerts; - int _numTris; - int _numWeights; - - // Original mesh data - vector _verts; - vector _tris; - vector _weights; - - // Final mesh data; vertex arrays for fast rendering - vector _vertexArray; - vector _normalArray; - vector _tangentArray; - vector _texCoordArray; - vector _vertIndices; - - // Textures - const Texture2D *_decal; - const Texture2D *_specMap; - const Texture2D *_normalMap; - const Texture2D *_heightMap; -}; - - -///////////////////////////////////////////////////////////////////////////// -// -// class Md5Model - MD5 Mesh Model class. -// -///////////////////////////////////////////////////////////////////////////// - -class Md5Model -{ -public: - // Constructor/Destructor - Md5Model (const string &filename) - throw (Md5Exception); - ~Md5Model (); - -public: - // Internal type definitions - typedef shared_ptr Md5SkeletonPtr; - typedef shared_ptr Md5MeshPtr; - typedef shared_ptr Md5AnimationPtr; - typedef map AnimMap; - -public: - // Public interface - void prepare (Md5Skeleton *skel); - void drawModel () const; - bool addAnim (const string &filename); - - // Setters - void setMeshRenderState (const string &name, int state); - void setMeshDecalMap (const string &name, const Texture2D *tex); - void setMeshSpecularMap (const string &name, const Texture2D *tex); - void setMeshNormalMap (const string &name, const Texture2D *tex); - void setMeshHeightMap (const string &name, const Texture2D *tex); - - // Accessors - const Md5Animation *anim (const string &name) const; - int numJoints () const { return _numJoints; } - const Md5Skeleton *baseSkeleton () const { return _baseSkeleton.get (); } - const AnimMap &anims () const { return _animList; } - const BoundingBox_t &bindPoseBoundingBox () const { return _bindPoseBox; } - - static render_path_e renderPath; - static ShaderProgram *shader; - static ArbVertexProgram *vp; - static ArbFragmentProgram *fp; - static GLint tangentLoc; - static bool bDrawNormals; - -private: - // Internal functions - void computeBindPoseBoundingBox (); - - // Check if an animation is valid for this model, - // i.e. anim's skeleton matches with model's skeleton - bool validityCheck (Md5Animation *anim) const; - - // Access to a mesh, given its name - Md5Mesh *getMeshByName (const string &name) const; - -private: - // Member variables - int _numJoints; - int _numMeshes; - - Md5SkeletonPtr _baseSkeleton; - - vector _meshes; - AnimMap _animList; - - BoundingBox_t _bindPoseBox; -}; - - -///////////////////////////////////////////////////////////////////////////// -// -// class Md5Animation - MD5 model animation class. -// -///////////////////////////////////////////////////////////////////////////// - -class Md5Animation -{ -public: - // Constructor/Destructor - Md5Animation (const string &filename) - throw (Md5Exception); - ~Md5Animation (); - -private: - // Internal type - struct JointInfo - { - string name; - int parent; - - // NOTE: this structure is stored in - // little-endian format - union JointFlags - { - short value; - - struct - { - bool tx: 1; - bool ty: 1; - bool tz: 1; - - bool qx: 1; - bool qy: 1; - bool qz: 1; - }; - } flags; - - int startIndex; - }; - - struct BaseFrameJoint - { - Vector3f pos; - Quaternionf orient; - }; - - typedef shared_ptr Md5SkeletonPtr; - typedef shared_ptr BoundingBoxPtr; - -public: - // Public interface - void interpolate (int frameA, int frameB, - float interp, Md5Skeleton *out) const; - - // Accessors - int maxFrame () const { return _numFrames - 1; } - int frameRate () const { return _frameRate; } - const string &name () const { return _name; } - - Md5Skeleton *frame (int frame) const { - return _skelframes[frame].get (); - } - - const BoundingBox_t *frameBounds (int frame) const { - return _bboxes[frame].get (); - } - -private: - // Internal functions - void buildFrameSkeleton (vector &jointInfos, - vector &baseFrame, - vector &animFrameData); - -private: - // Member variables - int _numFrames; - int _frameRate; - - string _name; - - // Store each frame as a skeleton - vector _skelframes; - - // Bounding boxes for each frame - vector _bboxes; -}; - - -///////////////////////////////////////////////////////////////////////////// -// -// class Md5Object - MD5 object class. -// -///////////////////////////////////////////////////////////////////////////// - -class Md5Object -{ -public: - // Public internal types/enums - enum - { - kDrawModel = 1, - kDrawSkeleton = 2, - kDrawJointLabels = 4, - }; - -public: - // Contructor/Destructor - Md5Object (Md5Model *model); - virtual ~Md5Object (); - -public: - // Public interface - void animate (double dt); - void computeBoundingBox (); - void prepare (bool softwareTransformation); - void render () const; - - // Setters - void setMd5Model (Md5Model *model); - void setAnim (const string &name); - void setModelViewMatrix (const Matrix4x4f &mat) { _modelView = mat; } - void setRenderFlags (int flags) { _renderFlags = flags; } - - // Accessors - int renderFlags () const { return _renderFlags; } - const Md5Model *getModelPtr () const { return _model; } - const string currAnimName () const { return _currAnimName; } - const OBBox_t &boundingBox () const { return _bbox; } - -protected: - // Member variables; - Md5Model *_model; - Md5Skeleton *_animatedSkeleton; - - Matrix4x4f _modelView; - bool _softwareTransformation; - - const Md5Animation *_currAnim; - string _currAnimName; - unsigned int _currFrame; - unsigned int _nextFrame; - - double _last_time; - double _max_time; - - int _renderFlags; - - OBBox_t _bbox; -}; - -}}} //end namespace - -#endif // __MD5_H__ diff --git a/source/shared_lib/include/graphics/md5/ShaderManager.h b/source/shared_lib/include/graphics/md5/ShaderManager.h deleted file mode 100644 index 92172b41..00000000 --- a/source/shared_lib/include/graphics/md5/ShaderManager.h +++ /dev/null @@ -1,190 +0,0 @@ -// ============================================================== -// This file is part of MegaGlest (www.glest.org) -// -// Shader.h -- Copyright (c) 2006 David Henry -// changed for use with MegaGlest: Copyright (C) 2011- by Mark Vejvoda -// -// This code is licensed under the MIT license: -// http://www.opensource.org/licenses/mit-license.php -// -// Open Source Initiative OSI - The MIT License (MIT):Licensing -// -// The MIT License (MIT) -// Copyright (c) -// -// 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.// -// -// Definitions of GLSL shader related classes. -// -///////////////////////////////////////////////////////////////////////////// -#ifndef __SHADER_H__ -#define __SHADER_H__ - -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#endif // _WIN32 - -#include -#include -#include - -namespace Shared { namespace Graphics { namespace md5 { - -using std::string; - -///////////////////////////////////////////////////////////////////////////// -// Shader class diagram: -// -// +-------- (abs) +---------------+ -// | Shader | | ShaderProgram | -// +----------+ +---------------+ -// ^ -// | -// +----------+----------+ -// | | -// +--------------+ +----------------+ -// | VertexShader | | FragmentShader | -// +--------------+ +----------------+ -// -///////////////////////////////////////////////////////////////////////////// - -// Global functions for initializing GLSL extensions and query for -// shader support on the host. -GLboolean hasShaderSupport(); -void initShaderHandling(); - -///////////////////////////////////////////////////////////////////////////// -// -// class Shader -- GLSL abstract shader object. Can be a vertex shader -// or a fragment shader. -// -///////////////////////////////////////////////////////////////////////////// -class Shader { -protected: - // Constructor - Shader (const string &filename); - -public: - // Destructor - virtual ~Shader (); - -public: - // Accessors - const string &name () const { return _name; } - const string &code () const { return _code; } - GLuint handle () const { return _handle; } - bool fail () const { return (_compiled == GL_FALSE); } - - virtual GLenum shaderType () const = 0; - -public: - // Public interface - void printInfoLog () const; - -protected: - // Internal functions - void compile () - throw (std::runtime_error); - void loadShaderFile (const string &filename) - throw (std::runtime_error); - -protected: - // Member variables - string _name; - string _code; - GLuint _handle; - GLint _compiled; -}; - -///////////////////////////////////////////////////////////////////////////// -// -// class VertexShader -- GLSL vertex shader object. -// -///////////////////////////////////////////////////////////////////////////// -class VertexShader : public Shader { -public: - // Constructor - VertexShader (const string &filename); - -public: - // Return the shader enum type - virtual GLenum shaderType () const { - if (GLEW_VERSION_2_0) - return GL_VERTEX_SHADER; - else - return GL_VERTEX_SHADER_ARB; - } -}; - - -///////////////////////////////////////////////////////////////////////////// -// -// class FragmentShader -- GLSL fragment shader object. -// -///////////////////////////////////////////////////////////////////////////// -class FragmentShader : public Shader { -public: - // Constructor - FragmentShader (const string &filename); - -public: - // Return the shader enum type - virtual GLenum shaderType () const { - if (GLEW_VERSION_2_0) - return GL_FRAGMENT_SHADER; - else - return GL_FRAGMENT_SHADER_ARB; - } -}; - -///////////////////////////////////////////////////////////////////////////// -// -// class ShaderProgram -- GLSL shader program object. -// -///////////////////////////////////////////////////////////////////////////// -class ShaderProgram { -public: - // Constructor/destructor - ShaderProgram (const string &name, - const VertexShader &vertexShader, - const FragmentShader &fragmentShader); - ~ShaderProgram (); - -public: - // Public interface - void use () const; - void unuse () const; - void printInfoLog () const; - - // Accessors - const string &name () const { return _name; } - GLuint handle () const { return _handle; } - bool fail () const { return (_linked == GL_FALSE); } - -private: - // Member variables - string _name; - GLuint _handle; - GLint _linked; -}; - -}}} //end namespace - -#endif // __SHADER_H__ diff --git a/source/shared_lib/include/graphics/md5/TextureManager.h b/source/shared_lib/include/graphics/md5/TextureManager.h deleted file mode 100644 index 7a81cc2f..00000000 --- a/source/shared_lib/include/graphics/md5/TextureManager.h +++ /dev/null @@ -1,92 +0,0 @@ -// ============================================================== -// This file is part of MegaGlest (www.glest.org) -// -// TextureManager.h -- Copyright (c) 2006 David Henry -// changed for use with MegaGlest: Copyright (C) 2011- by Mark Vejvoda -// -// This code is licensed under the MIT license: -// http://www.opensource.org/licenses/mit-license.php -// -// Open Source Initiative OSI - The MIT License (MIT):Licensing -// -// The MIT License (MIT) -// Copyright (c) -// -// 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.// -// -// Definitions of a texture manager class. -// -///////////////////////////////////////////////////////////////////////////// -#ifndef __TEXTUREMANAGER_H__ -#define __TEXTUREMANAGER_H__ - -#include "DataManager.h" -#include "md5Texture.h" - -namespace Shared { namespace Graphics { namespace md5 { - -///////////////////////////////////////////////////////////////////////////// -// -// class Texture2DManager -- a texture manager which can register/unregister -// Texture2D objects. Destroy all registred textures at death. -// -// The texture manager is a singleton. -// -///////////////////////////////////////////////////////////////////////////// -class Texture2DManager : - public DataManager { - friend class DataManager; - -public: - // Public interface - - // Load and register a texture. If the texture has already been - // loaded previously, return it instead of loading it. - Texture2D *load (const string &filename) - { - // Look for the texture in the registry - Texture2D *tex = request (filename); - - // If not found, load the texture - if (tex == NULL) - { - tex = new Texture2D (filename); - - // If the texture creation failed, delete the - // unusable object and return NULL - if (tex->fail ()) - { - delete tex; - tex = NULL; - } - else - { - // The texture has been successfully loaded, - // register it. - registerObject (tex->name (), tex); - } - } - - return tex; - } -}; - -}}} //end namespace - -#endif // __TEXTUREMANAGER_H__ diff --git a/source/shared_lib/include/graphics/md5/md5Texture.h b/source/shared_lib/include/graphics/md5/md5Texture.h deleted file mode 100644 index 05fbbe8b..00000000 --- a/source/shared_lib/include/graphics/md5/md5Texture.h +++ /dev/null @@ -1,218 +0,0 @@ -// ============================================================== -// This file is part of MegaGlest (www.glest.org) -// -// Texture.h -- Copyright (c) 2006 David Henry -// changed for use with MegaGlest: Copyright (C) 2011- by Mark Vejvoda -// -// This code is licensed under the MIT license: -// http://www.opensource.org/licenses/mit-license.php -// -// Open Source Initiative OSI - The MIT License (MIT):Licensing -// -// The MIT License (MIT) -// Copyright (c) -// -// 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.// -// -// Definition of an OpenGL texture classes. -// -///////////////////////////////////////////////////////////////////////////// -#ifndef __TEXTURE_H__ -#define __TEXTURE_H__ - -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#endif // _WIN32 - -#include -#include -#include -#include -#include -#include - -#include "Image.h" - -namespace Shared { namespace Graphics { namespace md5 { - -using std::string; -using std::vector; -using std::map; -using std::auto_ptr; - -///////////////////////////////////////////////////////////////////////////// -// Texture class diagram: -// -// +--------- (abs) -// | Texture | -// +-----------+ -// ^ -// | -// +---------------------+----------------------+ -// | | | -// +-----------+ +------------------+ +----------------+ -// | Texture2D | | TextureRectangle | | TextureCubeMap | -// +-----------+ +------------------+ +----------------+ -// -///////////////////////////////////////////////////////////////////////////// - - -///////////////////////////////////////////////////////////////////////////// -// -// class Texture -- OpenGL texture base class. This is an abstract -// class for more specialized OpenGL texture classes. -// -///////////////////////////////////////////////////////////////////////////// -class Texture { -public: - // Constructor/destructor - Texture (); - virtual ~Texture (); - -public: - // Constants - enum { - //Default behaviour - kDefault = 0, - - // Use texture compression - kCompress = (1 << 0), - }; - - typedef int TextureFlags; - -public: - // Public interface - void bind () const; - void bind (GLenum texUnit) const; - bool fail () const { return _fail; } - bool stdCoordSystem () const { return _standardCoordSystem; } - - // Accessors - const string &name () const { return _name; } - const GLuint handle () const { return _handle; } - - virtual GLenum target () const = 0; - -private: - // Copy operations are not allowed for textures, because - // when the source texture is destroyed, it releases - // its texture handle and so dest texture's handle is - // not valid anymore. - Texture (const Texture &); - Texture &operator= (const Texture &); - -protected: - // Internal functions - GLubyte *loadImageFile (const string &filename); - GLint getCompressionFormat (GLint internalFormat); - GLint getInternalFormat (GLint components); - -protected: - // Member variables - string _name; - GLuint _handle; - - TextureFlags _flags; - bool _standardCoordSystem; - bool _fail; -}; - - -///////////////////////////////////////////////////////////////////////////// -// -// class Texture2D -- OpenGL texture 2D object. -// -///////////////////////////////////////////////////////////////////////////// -class Texture2D : public Texture { -public: - // Constructors - Texture2D (const string &filename, TextureFlags flags = kDefault); - Texture2D (const Image *img, TextureFlags flags = kDefault); - -protected: - // Default constructor is not public - Texture2D (); - - // Internal functions - virtual void create (const Image *img, TextureFlags flags); - -public: - // Accessors - virtual GLenum target () const { return GL_TEXTURE_2D; } -}; - -///////////////////////////////////////////////////////////////////////////// -// -// class TextureRectangle -- OpenGL texture rectangle object. -// -///////////////////////////////////////////////////////////////////////////// -class TextureRectangle : public Texture { -public: - // Constructors - TextureRectangle (const string &filename, TextureFlags flags = kDefault); - TextureRectangle (const Image *img, TextureFlags flags = kDefault); - -protected: - // Internal functions - virtual void create (const Image *img, TextureFlags flags); - -public: - // Accessors - virtual GLenum target () const { return GL_TEXTURE_RECTANGLE_ARB; } - - GLint width () const { return _width; } - GLint height () const { return _height; } - -protected: - // Member variables - GLint _width; - GLint _height; -}; - -///////////////////////////////////////////////////////////////////////////// -// -// class TextureCubeMap -- OpenGL texture cube map object. -// The order of images to pass to constructors is: -// - positive x, negative x, -// - positive y, negative y, -// - positive z, negative z. -// -///////////////////////////////////////////////////////////////////////////// -class TextureCubeMap : public Texture { -public: - // Constructors - TextureCubeMap (const string &basename, const vector &files, - TextureFlags flags = kDefault); - TextureCubeMap (const string &basename, const vector &faces, - TextureFlags flags = kDefault); - -protected: - // Internal function - virtual void create (const vector &faces, TextureFlags flags); - -public: - // Accessors - virtual GLenum target () const { return GL_TEXTURE_CUBE_MAP_ARB; } -}; - -}}} //end namespace - -#endif // __TEXTURE_H__ diff --git a/source/shared_lib/include/graphics/md5/md5util.h b/source/shared_lib/include/graphics/md5/md5util.h deleted file mode 100644 index ff66f1f0..00000000 --- a/source/shared_lib/include/graphics/md5/md5util.h +++ /dev/null @@ -1,56 +0,0 @@ -// ============================================================== -// This file is part of MegaGlest (www.glest.org) -// -// Copyright (C) 2011- by Mark Vejvoda -// -// This code is licensed under the MIT license: -// http://www.opensource.org/licenses/mit-license.php -// -// Open Source Initiative OSI - The MIT License (MIT):Licensing -// -// The MIT License (MIT) -// Copyright (c) -// -// 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.// -// -// ============================================================== - -#ifndef __MD5Loader_H__ -#define __MD5Loader_H__ - -//#include "Mathlib.h" - -namespace Shared { namespace Graphics { namespace md5 { - -class Md5Object; - -//class Real; -template -class Matrix4x4; -typedef Matrix4x4 Matrix4x4f; - -void initMD5OpenGL(string shaderPath); -void cleanupMD5OpenGL(); - -Md5Object * getMD5ObjectFromLoaderScript(const string &filename); -void renderMD5Object(Md5Object *object, double anim, Matrix4x4f *modelViewMatrix=NULL); - -}}} //end namespace - -#endif // __MD5Loader_H__ diff --git a/source/shared_lib/sources/graphics/md5/ArbProgram.cpp b/source/shared_lib/sources/graphics/md5/ArbProgram.cpp deleted file mode 100644 index e2bc390a..00000000 --- a/source/shared_lib/sources/graphics/md5/ArbProgram.cpp +++ /dev/null @@ -1,281 +0,0 @@ -// ============================================================== -// This file is part of MegaGlest (www.glest.org) -// -// ArbProgram.cpp -- Copyright (c) 2007 David Henry -// changed for use with MegaGlest: Copyright (C) 2011- by Mark Vejvoda -// -// This code is licensed under the MIT license: -// http://www.opensource.org/licenses/mit-license.php -// -// Open Source Initiative OSI - The MIT License (MIT):Licensing -// -// The MIT License (MIT) -// Copyright (c) -// -// 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.// -// -// Implementation of ARB program related classes. -// -///////////////////////////////////////////////////////////////////////////// - -#include -#include - -#include "ArbProgram.h" - -namespace Shared { namespace Graphics { namespace md5 { - -using std::cout; -using std::cerr; -using std::endl; - -///////////////////////////////////////////////////////////////////////////// -// -// Global ARB program related functions. -// -///////////////////////////////////////////////////////////////////////////// - -static GLboolean ArbVpCapable = GL_FALSE; -static GLboolean ArbFpCapable = GL_FALSE; - -// -------------------------------------------------------------------------- -// hasArbVertexProgramSupport -// hasArbFragmentProgramSupport -// -// Return true if the host has ARB program support (vertex or fragment). -// -------------------------------------------------------------------------- - -GLboolean hasArbVertexProgramSupport () { - return ArbVpCapable; -} - -GLboolean hasArbFragmentProgramSupport () { - return ArbFpCapable; -} - -// -------------------------------------------------------------------------- -// initArbProgramHandling -// -// Initialize variables and extensions needed for using ARB Programs. -// This function should be called before any shader usage (at application -// initialization for example). -// -------------------------------------------------------------------------- - -void initArbProgramHandling () { - // Check for extensions needed for ARB program support on host - ArbVpCapable = glewIsSupported ("GL_ARB_vertex_program"); - ArbFpCapable = glewIsSupported ("GL_ARB_fragment_program"); - - if (!hasArbVertexProgramSupport ()) - cerr << "* missing GL_ARB_vertex_program extension" << endl; - - if (!hasArbFragmentProgramSupport ()) - cerr << "* missing GL_ARB_fragment_program extension" << endl; -} - -///////////////////////////////////////////////////////////////////////////// -// -// class ArbProgram implementation. -// -///////////////////////////////////////////////////////////////////////////// - -// -------------------------------------------------------------------------- -// ArbProgram::ArbProgram -// -// Constructor. -// -------------------------------------------------------------------------- - -ArbProgram::ArbProgram (const string &filename) - : _name (filename), _handle (0), _fail (true) { -} - -// -------------------------------------------------------------------------- -// ArbProgram::~ArbProgram -// -// Destructor. Destroy the program handle. -// -------------------------------------------------------------------------- - -ArbProgram::~ArbProgram () { - if (glIsProgramARB (_handle)) - glDeleteProgramsARB (1, &_handle); -} - -// ------------------------------------------------------------------------- -// ArbProgram::use -// ArbProgram::unuse -// -// Bind/unbind the program. -// ------------------------------------------------------------------------- - -void ArbProgram::use () const { - const GLenum target = programType (); - - glEnable (target); - glBindProgramARB (target, _handle); -} - -void ArbProgram::unuse () const { - const GLenum target = programType (); - - glBindProgramARB (target, 0); - glDisable (target); -} - -// ------------------------------------------------------------------------- -// ArbProgram::printProgramString -// -// Print the ARB program string until a given position. This is -// usefull for printing code until error position. -// ------------------------------------------------------------------------- - -void ArbProgram::printProgramString (int errPos) { - int i = 0; - - cerr << endl << " > "; - for (i = 0; i < (errPos + 1) && _code[i]; i++) { - cerr.put (_code[i]); - if (_code[i] == '\n') - cerr << " > "; - } - cerr << " <---" << endl << endl; -} - -// ------------------------------------------------------------------------- -// ArbProgram::load -// -// Create and load the program. -// ------------------------------------------------------------------------- - -void ArbProgram::load () throw (std::runtime_error) { - const GLchar *code = _code.c_str (); - const GLenum target = programType (); - - // Generate a program object handle - glGenProgramsARB (1, &_handle); - - // Make the "current" program object progid - glBindProgramARB (target, _handle); - - // Specify the program for the current object - glProgramStringARB (target, GL_PROGRAM_FORMAT_ASCII_ARB, - _code.size (), code); - - // Check for errors and warnings... - if (GL_INVALID_OPERATION == glGetError ()) { - const GLubyte *errString; - GLint errPos; - - // Find the error position - glGetIntegerv (GL_PROGRAM_ERROR_POSITION_ARB, &errPos); - - // Print implementation-dependent program - // errors and warnings string - errString = glGetString (GL_PROGRAM_ERROR_STRING_ARB); - - cerr << "Error in " << ((GL_VERTEX_PROGRAM_ARB == target) ? - "vertex" : "fragment"); - cerr << " program at position: " << errPos << endl << errString; - - printProgramString (errPos); - - _fail = true; - throw std::runtime_error ("Compilation failed"); - } -} - -// ------------------------------------------------------------------------- -// ArbProgram::loadProgramFile -// -// Load program's code from file. The code is stored into the -// _code string member variable. -// ------------------------------------------------------------------------- - -void ArbProgram::loadProgramFile (const string &filename) throw (std::runtime_error) { - // Open the file - std::ifstream ifs (filename.c_str (), std::ios::in | std::ios::binary); - - if (ifs.fail ()) - throw std::runtime_error ("Couldn't open prog file: " + filename); - - // Read whole file into string - _code.assign (std::istreambuf_iterator(ifs), - std::istreambuf_iterator()); - - // Close file - ifs.close (); -} - - -///////////////////////////////////////////////////////////////////////////// -// -// class ArbVertexProgram implementation. -// -///////////////////////////////////////////////////////////////////////////// - -// -------------------------------------------------------------------------- -// ArbVertexProgram::ArbVertexProgram -// -// Constructor. Read vertex program code from file and load it. -// -------------------------------------------------------------------------- - -ArbVertexProgram::ArbVertexProgram (const string &filename) : ArbProgram (filename) { - try { - // Load program code from file - loadProgramFile (filename); - - // load the program from code buffer - load (); - - cout << "* Vertex program \"" << _name << "\" loaded" << endl; - } - catch (std::runtime_error &err) { - cerr << "Error: Faild to create vertex program from " << _name; - cerr << endl << "Reason: " << err.what () << endl; - } -} - -///////////////////////////////////////////////////////////////////////////// -// -// class ArbFragmentProgram implementation. -// -///////////////////////////////////////////////////////////////////////////// - -// -------------------------------------------------------------------------- -// ArbFragmentProgram::ArbFragmentProgram -// -// Constructor. Read fragment program code from file and load it. -// -------------------------------------------------------------------------- - -ArbFragmentProgram::ArbFragmentProgram (const string &filename) : ArbProgram (filename) { - try { - // Load program code from file - loadProgramFile (filename); - - // load the program from code buffer - load (); - - cout << "* Fragment program \"" << _name << "\" loaded" << endl; - } - catch (std::runtime_error &err) { - cerr << "Error: Faild to create fragment program from " << _name; - cerr << endl << "Reason: " << err.what () << endl; - } -} - -}}} //end namespace diff --git a/source/shared_lib/sources/graphics/md5/GlErrors.cpp b/source/shared_lib/sources/graphics/md5/GlErrors.cpp deleted file mode 100644 index ef26d046..00000000 --- a/source/shared_lib/sources/graphics/md5/GlErrors.cpp +++ /dev/null @@ -1,71 +0,0 @@ -// ============================================================== -// This file is part of MegaGlest (www.glest.org) -// -// GlErrors.cpp -- Copyright (c) 2006-2007 David Henry -// changed for use with MegaGlest: Copyright (C) 2011- by Mark Vejvoda -// -// This code is licensed under the MIT license: -// http://www.opensource.org/licenses/mit-license.php -// -// Open Source Initiative OSI - The MIT License (MIT):Licensing -// -// The MIT License (MIT) -// Copyright (c) -// -// 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.// -// -// OpenGL error management. -// -///////////////////////////////////////////////////////////////////////////// - -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#endif // _WIN32 - -#include - -#include -#include "GlErrors.h" - -namespace Shared { namespace Graphics { namespace md5 { - -using std::cerr; -using std::endl; - -// ------------------------------------------------------------------------- -// checkOpenGLErrors -// -// Print the last OpenGL error code. @file is the filename where the -// function has been called, @line is the line number. You should use -// this function like this: -// checkOpenGLErrors (__FILE__, __LINE__); -// ------------------------------------------------------------------------- - -GLenum checkOpenGLErrors (const char *file, int line) { - GLenum errCode = glGetError (); - - if (errCode != GL_NO_ERROR) - cerr << "(GL) " << file << " (" << line << "): " - << gluErrorString (errCode) << endl; - - return errCode; -} - -}}} //end namespace diff --git a/source/shared_lib/sources/graphics/md5/Image.cpp b/source/shared_lib/sources/graphics/md5/Image.cpp deleted file mode 100644 index 7bab626f..00000000 --- a/source/shared_lib/sources/graphics/md5/Image.cpp +++ /dev/null @@ -1,1535 +0,0 @@ -// ============================================================== -// This file is part of MegaGlest (www.glest.org) -// -// Image.cpp -- Copyright (c) 2006 David Henry -// changed for use with MegaGlest: Copyright (C) 2011- by Mark Vejvoda -// -// This code is licensed under the MIT license: -// http://www.opensource.org/licenses/mit-license.php -// -// Open Source Initiative OSI - The MIT License (MIT):Licensing -// -// The MIT License (MIT) -// Copyright (c) -// -// 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.// -// -// Implementation of image loader classes for DDS, TGA, PCX, JPEG -// and PNG image formats. -// -///////////////////////////////////////////////////////////////////////////// - -#include "Image.h" - -namespace Shared { namespace Graphics { namespace md5 { - -///////////////////////////////////////////////////////////////////////////// -// -// class ImageBuffer implementation. -// -///////////////////////////////////////////////////////////////////////////// - -// -------------------------------------------------------------------------- -// ImageBuffer::ImageBuffer -// -// Constructor. Load a file into memory buffer. -// -------------------------------------------------------------------------- -ImageBuffer::ImageBuffer (const string &filename) - : _filename (filename), _data (NULL), _length (0) { - // Open file - std::ifstream ifs (filename.c_str(), std::ios::in | std::ios::binary); - - if (ifs.fail ()) - throw ImageException ("Couldn't open image file: " + filename, filename); - - // Get file length - ifs.seekg (0, std::ios::end); - _length = ifs.tellg (); - ifs.seekg (0, std::ios::beg); - - try { - // Allocate memory for holding file data - _data = new GLubyte[_length]; - - // Read whole file data - ifs.read (reinterpret_cast (_data), _length); - ifs.close (); - } - catch (...) - { - delete [] _data; - throw; - } -} - -// -------------------------------------------------------------------------- -// ImageBuffer::~ImageBuffer -// -// Destructor. Free memory buffer. -// -------------------------------------------------------------------------- -ImageBuffer::~ImageBuffer () { - delete [] _data; - _data = NULL; -} - -///////////////////////////////////////////////////////////////////////////// -// -// class Image implementation. -// -///////////////////////////////////////////////////////////////////////////// - -// -------------------------------------------------------------------------- -// Image::Image -// -// Constructors. Create an image from a pixel buffer. It allows to -// create an image from an other source of data than an ImageBuffer. -// This is also the copy constructor to use if you want pixel data -// to be copied, since the Image(const Image&) constructor is protected. -// -------------------------------------------------------------------------- - -Image::Image (const string &name, GLsizei w, GLsizei h, GLint numMipMaps, - GLenum format, GLint components, const GLubyte *pixels, - bool stdCoordSystem) - : _width (w), _height (h), _numMipmaps (numMipMaps), - _format (format), _components (components), _name (name), - _standardCoordSystem (stdCoordSystem) { - // NOTE: pixels should be a valid pointer. w, h and components - // have to be non-zero positive values. - - long size = _width * _height * _components; - - if (size <= 0) - throw std::invalid_argument - ("Image::Image: Invalid width, height or component value"); - - if (!pixels) - throw std::invalid_argument - ("Image::Image: Invalid pixel data source"); - - // allocate memory for pixel data - _pixels = new GLubyte[size]; - - // Copy pixel data from buffer - memcpy (_pixels, pixels, size); -} - -// -------------------------------------------------------------------------- -// Image::~Image -// -// Destructor. Delete all memory allocated for this object, i.e. pixel -// data. -// -------------------------------------------------------------------------- -Image::~Image () { - delete [] _pixels; - _pixels = NULL; -} - -// -------------------------------------------------------------------------- -// Image::isCompressed -// -// Check if the image is using S3TC compression (this is the case for -// DDS image only). -// -------------------------------------------------------------------------- -bool Image::isCompressed () const { - switch (_format) - { - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - return true; - - default: - return false; - } -} - -// -------------------------------------------------------------------------- -// Image::isPowerOfTwo -// -// Check if the image dimensions are powers of two. -// -------------------------------------------------------------------------- -bool Image::isPowerOfTwo () const { - GLsizei m; - for (m = 1; m < _width; m *= 2) - ; - - if (m != _width) - return false; - - for (m = 1; m < _height; m *= 2) - ; - - if (m != _height) - return false; - - return true; -} - -///////////////////////////////////////////////////////////////////////////// -// -// class ImageDDS implementation. -// -///////////////////////////////////////////////////////////////////////////// - -// FourCC auto generation with templates -template -struct MakeFourCC { - enum { - Val =(((ch3 << 24) & 0xFF000000) | - ((ch2 << 16) & 0x00FF0000) | - ((ch1 << 8) & 0x0000FF00) | - (ch0 & 0x000000FF)) - }; -}; - -const unsigned int FOURCC_DXT1 = MakeFourCC<'D', 'X', 'T', '1'>::Val; -const unsigned int FOURCC_DXT3 = MakeFourCC<'D', 'X', 'T', '3'>::Val; -const unsigned int FOURCC_DXT5 = MakeFourCC<'D', 'X', 'T', '5'>::Val; - -// -------------------------------------------------------------------------- -// ImageDDS::ImageDDS -// -// Constructor. Read a DDS image from memory. -// -------------------------------------------------------------------------- -ImageDDS::ImageDDS (const ImageBuffer &ibuff) - : _ddsd (NULL) { - _name = ibuff.filename (); - - // DDS images use the GDI+ coordinate system (starts upper-left corner) - _standardCoordSystem = false; - - // There are extensions required for handling compressed DDS - // images as textures - if (!GLEW_ARB_texture_compression) - throw ImageException ("missing GL_ARB_texture_compression" - " extension", _name); - - if (!GLEW_EXT_texture_compression_s3tc) - throw ImageException ("missing GL_EXT_texture_compression_s3tc" - " extension", _name); - - try { - // Get pointer on file data - const GLubyte *data_ptr = ibuff.data (); - int bufferSize = ibuff.length (); - - // Check if is a valid DDS file - string magic; - magic.assign (reinterpret_cast(data_ptr), 4); - if (magic.compare (0, 4, "DDS ") != 0) - throw ImageException ("Not a valid DDS file", _name); - - // Eat 4 bytes magic number - data_ptr += 4; - bufferSize -= 4; - - // Read the surface descriptor and init some member variables - _ddsd = reinterpret_cast(data_ptr); - data_ptr += sizeof (DDSurfaceDesc); - bufferSize -= sizeof (DDSurfaceDesc); - - _width = _ddsd->width; - _height = _ddsd->height; - _numMipmaps = _ddsd->mipMapLevels; - - switch (_ddsd->format.fourCC) - { - case FOURCC_DXT1: - // DXT1's compression ratio is 8:1 - _format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; - _components = 3; - break; - - case FOURCC_DXT3: - // DXT3's compression ratio is 4:1 - _format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; - _components = 4; - break; - - case FOURCC_DXT5: - // DXT5's compression ratio is 4:1 - _format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; - _components = 4; - break; - - default: - // Bad fourCC, unsupported or bad format - throw ImageException ("Unsupported DXT format", _name); - } - - // Read pixel data with mipmaps - _pixels = new GLubyte[bufferSize]; - memcpy (_pixels, data_ptr, bufferSize); - } - catch (...) - { - delete [] _pixels; - throw; - } -} - -///////////////////////////////////////////////////////////////////////////// -// -// class ImageTGA implementation. -// -///////////////////////////////////////////////////////////////////////////// - -// Pixel's component table access -int ImageTGA::rgbaTable[4] = { 2, 1, 0, 3 }; -int ImageTGA::bgraTable[4] = { 0, 1, 2, 3 }; - -// -------------------------------------------------------------------------- -// ImageTGA::ImageTGA -// -// Constructor. Read a TGA image from memory. -// -------------------------------------------------------------------------- -ImageTGA::ImageTGA (const ImageBuffer &ibuff) - : _header (NULL) { - const GLubyte *colormap = NULL; - const GLubyte *data_ptr; - - try - { - _name = ibuff.filename (); - data_ptr = ibuff.data (); - _standardCoordSystem = true; - - // Read TGA header - _header = reinterpret_cast(data_ptr); - data_ptr += sizeof (TGA_Header) + _header->id_lenght; - - // Get image information - getTextureInfo (); - - // Memory allocation for pixel data - _pixels = new GLubyte[_width * _height * _components]; - - // Read color map, if present - if (_header->colormap_type) - { - // NOTE: color map is stored in BGR - colormap = data_ptr; - data_ptr += _header->cm_length * (_header->cm_size >> 3); - } - - // Decode image data - switch (_header->image_type) - { - case 0: - // No data - break; - - case 1: - // Uncompressed 8 bits color index - readTGA8bits (data_ptr, colormap); - break; - - case 2: - // Uncompressed 16-24-32 bits - switch (_header->pixel_depth) - { - case 16: - readTGA16bits (data_ptr); - break; - - case 24: - readTGA24bits (data_ptr); - break; - - case 32: - readTGA32bits (data_ptr); - break; - } - - break; - - case 3: - // Uncompressed 8 or 16 bits grayscale - if (_header->pixel_depth == 8) - readTGAgray8bits (data_ptr); - else // 16 bits - readTGAgray16bits (data_ptr); - - break; - - case 9: - // RLE compressed 8 bits color index - readTGA8bitsRLE (data_ptr, colormap); - break; - - case 10: - // RLE compressed 16-24-32 bits - switch (_header->pixel_depth) - { - case 16: - readTGA16bitsRLE (data_ptr); - break; - - case 24: - readTGA24bitsRLE (data_ptr); - break; - - case 32: - readTGA32bitsRLE (data_ptr); - break; - } - - break; - - case 11: - // RLE compressed 8 or 16 bits grayscale - if (_header->pixel_depth == 8) - readTGAgray8bitsRLE (data_ptr); - else // 16 bits - readTGAgray16bitsRLE (data_ptr); - - break; - - default: - // Image type is not correct, free memory and quit - throw ImageException ("Unknown TGA image type", _name); - } - } - catch (...) - { - delete [] _pixels; - throw; - } -} - -// -------------------------------------------------------------------------- -// ImageTGA::getTextureInfo -// -// Extract OpenGL texture informations from TGA header. -// -------------------------------------------------------------------------- -void ImageTGA::getTextureInfo () { - _width = _header->width; - _height = _header->height; - - switch (_header->image_type) - { - case 3: // grayscale 8 bits - case 11: // grayscale 8 bits (RLE) - { - if (_header->pixel_depth == 8) - { - _format = GL_LUMINANCE; - _components = 1; - } - else // 16 bits - { - _format = GL_LUMINANCE_ALPHA; - _components = 2; - } - - break; - } - - case 1: // 8 bits color index - case 2: // BGR 16-24-32 bits - case 9: // 8 bits color index (RLE) - case 10: // BGR 16-24-32 bits (RLE) - { - // 8 bits and 16 bits images will be converted to 24 bits - if (_header->pixel_depth <= 24) - { - _format = GLEW_EXT_bgra ? GL_BGR : GL_RGB; - _components = 3; - } - else // 32 bits - { - _format = GLEW_EXT_bgra ? GL_BGRA : GL_RGBA; - _components = 4; - } - - break; - } - } -} - -// -------------------------------------------------------------------------- -// ImageTGA::readTGA8bits -// -// Read 8 bits pixel data from TGA file. -// -------------------------------------------------------------------------- -void ImageTGA::readTGA8bits (const GLubyte *data, const GLubyte *colormap) { - const GLubyte *pData = data; - int *compTable = GLEW_EXT_bgra ? bgraTable : rgbaTable; - - for (int i = 0; i < _width * _height; ++i) - { - // Read index color byte - GLubyte color = *(pData++); - - // Convert to BGR/RGB 24 bits - _pixels[(i * 3) + compTable[0]] = colormap[(color * 3) + 0]; - _pixels[(i * 3) + compTable[1]] = colormap[(color * 3) + 1]; - _pixels[(i * 3) + compTable[2]] = colormap[(color * 3) + 2]; - } -} - - -// -------------------------------------------------------------------------- -// ImageTGA::readTGA16bits -// -// Read 16 bits pixel data from TGA file. -// -------------------------------------------------------------------------- -void ImageTGA::readTGA16bits (const GLubyte *data) { - const GLubyte *pData = data; - int *compTable = GLEW_EXT_bgra ? bgraTable : rgbaTable; - - for (int i = 0; i < _width * _height; ++i, pData += 2) { - // Read color word - unsigned short color = pData[0] + (pData[1] << 8); - - // convert to BGR/RGB 24 bits - _pixels[(i * 3) + compTable[2]] = (((color & 0x7C00) >> 10) << 3); - _pixels[(i * 3) + compTable[1]] = (((color & 0x03E0) >> 5) << 3); - _pixels[(i * 3) + compTable[0]] = (((color & 0x001F) >> 0) << 3); - } -} - -// -------------------------------------------------------------------------- -// ImageTGA::readTGA24bits -// -// Read 24 bits pixel data from TGA file. -// -------------------------------------------------------------------------- -void ImageTGA::readTGA24bits (const GLubyte *data) { - if (GLEW_EXT_bgra) - { - memcpy (_pixels, data, _width * _height * 3); - } - else - { - const GLubyte *pData = data; - - for (int i = 0; i < _width * _height; ++i) - { - // Read RGB 24 bits pixel - _pixels[(i * 3) + rgbaTable[0]] = *(pData++); - _pixels[(i * 3) + rgbaTable[1]] = *(pData++); - _pixels[(i * 3) + rgbaTable[2]] = *(pData++); - } - } -} - -// -------------------------------------------------------------------------- -// ImageTGA::readTGA32bits -// -// Read 32 bits pixel data from TGA file. -// -------------------------------------------------------------------------- -void ImageTGA::readTGA32bits (const GLubyte *data) { - if (GLEW_EXT_bgra) - { - memcpy (_pixels, data, _width * _height * 4); - } - else - { - const GLubyte *pData = data; - - for (int i = 0; i < _width * _height; ++i) - { - // Read RGB 32 bits pixel - _pixels[(i * 4) + rgbaTable[0]] = *(pData++); - _pixels[(i * 4) + rgbaTable[1]] = *(pData++); - _pixels[(i * 4) + rgbaTable[2]] = *(pData++); - _pixels[(i * 4) + rgbaTable[3]] = *(pData++); - } - } -} - - -// -------------------------------------------------------------------------- -// ImageTGA::readTGAgray8bits -// -// Read grey 8 bits pixel data from TGA file. -// -------------------------------------------------------------------------- -void ImageTGA::readTGAgray8bits (const GLubyte *data) { - memcpy (_pixels, data, _width * _height); -} - -// -------------------------------------------------------------------------- -// ImageTGA::readTGAgray16bits -// -// Read grey 16 bits pixel data from TGA file. -// -------------------------------------------------------------------------- - -void -ImageTGA::readTGAgray16bits (const GLubyte *data) -{ - memcpy (_pixels, data, _width * _height * 2); -} - - -// -------------------------------------------------------------------------- -// ImageTGA::readTGA8bitsRLE -// -// Read 8 bits pixel data from TGA file with RLE compression. -// -------------------------------------------------------------------------- - -void -ImageTGA::readTGA8bitsRLE (const GLubyte *data, const GLubyte *colormap) -{ - GLubyte *ptr = _pixels; - const GLubyte *pData = data; - int *compTable = GLEW_EXT_bgra ? bgraTable : rgbaTable; - - while (ptr < _pixels + (_width * _height) * 3) - { - // Read first byte - GLubyte packet_header = *(pData++); - int size = 1 + (packet_header & 0x7f); - - if (packet_header & 0x80) - { - // Run-length packet - GLubyte color = *(pData++); - - for (int i = 0; i < size; ++i, ptr += 3) - { - ptr[0] = colormap[(color * 3) + compTable[0]]; - ptr[1] = colormap[(color * 3) + compTable[1]]; - ptr[2] = colormap[(color * 3) + compTable[2]]; - } - } - else - { - // Non run-length packet - for (int i = 0; i < size; ++i, ptr += 3) - { - GLubyte color = *(pData++); - - ptr[0] = colormap[(color * 3) + compTable[0]]; - ptr[1] = colormap[(color * 3) + compTable[1]]; - ptr[2] = colormap[(color * 3) + compTable[2]]; - } - } - } -} - - -// -------------------------------------------------------------------------- -// ImageTGA::readTGA16bitsRLE -// -// Read 16 bits pixel data from TGA file with RLE compression. -// -------------------------------------------------------------------------- - -void -ImageTGA::readTGA16bitsRLE (const GLubyte *data) -{ - const GLubyte *pData = data; - GLubyte *ptr = _pixels; - int *compTable = GLEW_EXT_bgra ? bgraTable : rgbaTable; - - while (ptr < _pixels + (_width * _height) * 3) - { - // Read first byte - GLubyte packet_header = *(pData++); - int size = 1 + (packet_header & 0x7f); - - if (packet_header & 0x80) - { - // Run-length packet - unsigned short color = pData[0] + (pData[1] << 8); - pData += 2; - - for (int i = 0; i < size; ++i, ptr += 3) - { - ptr[compTable[2]] = (((color & 0x7C00) >> 10) << 3); - ptr[compTable[1]] = (((color & 0x03E0) >> 5) << 3); - ptr[compTable[0]] = (((color & 0x001F) >> 0) << 3); - } - } - else - { - // Non run-length packet - for (int i = 0; i < size; ++i, ptr += 3) - { - unsigned short color = pData[0] + (pData[1] << 8); - pData += 2; - - ptr[compTable[2]] = (((color & 0x7C00) >> 10) << 3); - ptr[compTable[1]] = (((color & 0x03E0) >> 5) << 3); - ptr[compTable[0]] = (((color & 0x001F) >> 0) << 3); - } - } - } -} - - -// -------------------------------------------------------------------------- -// ImageTGA::readTGA24bitsRLE -// -// Read 24 bits pixel data from TGA file with RLE compression. -// -------------------------------------------------------------------------- - -void -ImageTGA::readTGA24bitsRLE (const GLubyte *data) -{ - const GLubyte *pData = data; - GLubyte *ptr = _pixels; - int *compTable = GLEW_EXT_bgra ? bgraTable : rgbaTable; - - while (ptr < _pixels + (_width * _height) * 3) - { - // Read first byte - GLubyte packet_header = *(pData++); - int size = 1 + (packet_header & 0x7f); - - if (packet_header & 0x80) - { - // Run-length packet - for (int i = 0; i < size; ++i, ptr += 3) - { - ptr[0] = pData[compTable[0]]; - ptr[1] = pData[compTable[1]]; - ptr[2] = pData[compTable[2]]; - } - - pData += 3; - } - else - { - // Non run-length packet - for (int i = 0; i < size; ++i, ptr += 3) - { - ptr[0] = pData[compTable[0]]; - ptr[1] = pData[compTable[1]]; - ptr[2] = pData[compTable[2]]; - pData += 3; - } - } - } -} - - -// -------------------------------------------------------------------------- -// ImageTGA::readTGA32bitsRLE -// -// Read 32 bits pixel data from TGA file with RLE compression. -// -------------------------------------------------------------------------- - -void -ImageTGA::readTGA32bitsRLE (const GLubyte *data) -{ - const GLubyte *pData = data; - GLubyte *ptr = _pixels; - int *compTable = GLEW_EXT_bgra ? bgraTable : rgbaTable; - - while (ptr < _pixels + (_width * _height) * 4) - { - // Read first byte - GLubyte packet_header = *(pData++); - int size = 1 + (packet_header & 0x7f); - - if (packet_header & 0x80) - { - // Run-length packet */ - for (int i = 0; i < size; ++i, ptr += 4) - { - ptr[0] = pData[compTable[0]]; - ptr[1] = pData[compTable[1]]; - ptr[2] = pData[compTable[2]]; - ptr[3] = pData[compTable[3]]; - } - - pData += 4; - } - else - { - // Non run-length packet - for (int i = 0; i < size; ++i, ptr += 4) - { - ptr[0] = pData[compTable[0]]; - ptr[1] = pData[compTable[1]]; - ptr[2] = pData[compTable[2]]; - ptr[3] = pData[compTable[3]]; - pData += 4; - } - } - } -} - - -// -------------------------------------------------------------------------- -// ImageTGA::readTGAgray8bitsRLE -// -// Read grey 8 bits pixel data from TGA file with RLE compression. -// -------------------------------------------------------------------------- - -void -ImageTGA::readTGAgray8bitsRLE (const GLubyte *data) -{ - const GLubyte *pData = data; - GLubyte *ptr = _pixels; - - while (ptr < _pixels + (_width * _height)) - { - // Read first byte - GLubyte packet_header = *(pData++); - int size = 1 + (packet_header & 0x7f); - - if (packet_header & 0x80) - { - // Run-length packet - GLubyte color = *(pData++); - - memset (ptr, color, size); - ptr += size; - } - else - { - // Non run-length packet - memcpy (ptr, pData, size); - ptr += size; - pData += size; - } - } -} - - -// -------------------------------------------------------------------------- -// ImageTGA::readTGAgray16bitsRLE -// -// Read grey 16 bits pixel data from TGA file with RLE compression. -// -------------------------------------------------------------------------- - -void -ImageTGA::readTGAgray16bitsRLE (const GLubyte *data) -{ - const GLubyte *pData = data; - GLubyte *ptr = _pixels; - - while (ptr < _pixels + (_width * _height) * 2) - { - // Read first byte - GLubyte packet_header = *(pData++); - int size = 1 + (packet_header & 0x7f); - - if (packet_header & 0x80) - { - // Run-length packet - GLubyte color = *(pData++); - GLubyte alpha = *(pData++); - - for (int i = 0; i < size; ++i, ptr += 2) - { - ptr[0] = color; - ptr[1] = alpha; - } - } - else - { - // Non run-length packet - memcpy (ptr, pData, size * 2); - ptr += size * 2; - pData += size * 2; - } - } -} - - -///////////////////////////////////////////////////////////////////////////// -// -// class ImagePCX implementation. -// -///////////////////////////////////////////////////////////////////////////// - -// Pixel's component table access -int ImagePCX::rgbTable[3] = { 0, 1, 2 }; -int ImagePCX::bgrTable[3] = { 2, 1, 0 }; - - -// -------------------------------------------------------------------------- -// ImagePCX::ImagePCX -// -// Constructor. Read a PCX image from memory. -// -------------------------------------------------------------------------- - -ImagePCX::ImagePCX (const ImageBuffer &ibuff) - : _header (NULL) -{ - const GLubyte *data_ptr; - - try - { - _name = ibuff.filename (); - _standardCoordSystem = true; - - // Get pointer on file data - data_ptr = ibuff.data (); - - // Read PCX header - _header = reinterpret_cast(data_ptr); - data_ptr += sizeof (PCX_Header); - - // Check if is valid PCX file - if (_header->manufacturer != 0x0a) - throw ImageException ("Bad version number", _name); - - // Initialize image variables - _width = _header->xmax - _header->xmin + 1; - _height = _header->ymax - _header->ymin + 1; - _format = GLEW_EXT_bgra ? GL_BGR : GL_RGB; - _components = 3; - _pixels = new GLubyte[_width * _height * _components]; - - int bitcount = _header->bitsPerPixel * _header->numColorPlanes; - int palette_pos = ibuff.length () - 768; - - // Read image data - switch (bitcount) - { - case 1: - // 1 bit color index - readPCX1bit (data_ptr); - break; - - case 4: - // 4 bits color index - readPCX4bits (data_ptr); - break; - - case 8: - // 8 bits color index - readPCX8bits (data_ptr, ibuff.data () + palette_pos); - break; - - case 24: - // 24 bits - readPCX24bits (data_ptr); - break; - - default: - // Unsupported - throw ImageException ("Unhandled PCX format (bad bitcount)", _name); - } - } - catch (...) - { - delete [] _pixels; - throw; - } -} - - -// -------------------------------------------------------------------------- -// ImagePCX::readPCX1bit -// -// Read 1 bit PCX image. -// -------------------------------------------------------------------------- - -void -ImagePCX::readPCX1bit (const GLubyte *data) -{ - int rle_count = 0, rle_value = 0; - const GLubyte *pData = data; - GLubyte *ptr = _pixels; - int *compTable = GLEW_EXT_bgra ? bgrTable : rgbTable; - - for (int y = 0; y < _height; ++y) - { - ptr = &_pixels[(_height - (y + 1)) * _width * 3]; - int bytes = _header->bytesPerScanLine; - - // Decode line number y - while (bytes--) - { - if (rle_count == 0) - { - if ( (rle_value = *(pData++)) < 0xc0) - { - rle_count = 1; - } - else - { - rle_count = rle_value - 0xc0; - rle_value = *(pData++); - } - } - - rle_count--; - - // Fill height pixels chunk - for (int i = 7; i >= 0; --i, ptr += 3) - { - int colorIndex = ((rle_value & (1 << i)) > 0); - - ptr[0] = _header->palette[colorIndex * 3 + compTable[0]]; - ptr[1] = _header->palette[colorIndex * 3 + compTable[1]]; - ptr[2] = _header->palette[colorIndex * 3 + compTable[2]]; - } - } - } -} - - -// -------------------------------------------------------------------------- -// ImagePCX::readPCX4bits -// -// Read 4 bits PCX image. -// -------------------------------------------------------------------------- - -void -ImagePCX::readPCX4bits (const GLubyte *data) -{ - const GLubyte *pData = data; - GLubyte *colorIndex = NULL; - GLubyte *line = NULL; - GLubyte *ptr; - int rle_count = 0, rle_value = 0; - int *compTable = GLEW_EXT_bgra ? bgrTable : rgbTable; - - try - { - // Memory allocation for temporary buffers - colorIndex = new GLubyte[_width]; - line = new GLubyte[_header->bytesPerScanLine]; - } - catch (std::bad_alloc &err) - { - delete [] colorIndex; - delete [] line; - throw; - } - - for (int y = 0; y < _height; ++y) - { - ptr = &_pixels[(_height - (y + 1)) * _width * 3]; - memset (colorIndex, 0, _width); - - for (int c = 0; c < 4; ++c) - { - GLubyte *pLine = line; - int bytes = _header->bytesPerScanLine; - - // Decode line number y - while (bytes--) - { - if (rle_count == 0) - { - if ( (rle_value = *(pData++)) < 0xc0) - { - rle_count = 1; - } - else - { - rle_count = rle_value - 0xc0; - rle_value = *(pData++); - } - } - - rle_count--; - *(pLine++) = rle_value; - } - - // Compute line's color indexes - for (int x = 0; x < _width; ++x) - { - if (line[x / 8] & (128 >> (x % 8))) - colorIndex[x] += (1 << c); - } - } - - // Decode scanline. color index => rgb - for (int x = 0; x < _width; ++x, ptr += 3) - { - ptr[0] = _header->palette[colorIndex[x] * 3 + compTable[0]]; - ptr[1] = _header->palette[colorIndex[x] * 3 + compTable[1]]; - ptr[2] = _header->palette[colorIndex[x] * 3 + compTable[2]]; - } - } - - // Release memory - delete [] colorIndex; - delete [] line; -} - - -// -------------------------------------------------------------------------- -// ImagePCX::readPCX8bits -// -// Read 8 bits PCX image. -// -------------------------------------------------------------------------- - -void -ImagePCX::readPCX8bits (const GLubyte *data, const GLubyte *palette) -{ - const GLubyte *pData = data; - int rle_count = 0, rle_value = 0; - GLubyte *ptr; - int *compTable = GLEW_EXT_bgra ? bgrTable : rgbTable; - - // Palette should be preceded by a value of 0x0c (12)... - GLubyte magic = palette[-1]; - if (magic != 0x0c) - { - // ... but sometimes it is not - std::cerr << "Warning: PCX palette should start with " - << "a value of 0x0c (12)!" << std::endl; - } - - // Read pixel data - for (int y = 0; y < _height; ++y) - { - ptr = &_pixels[(_height - (y + 1)) * _width * 3]; - int bytes = _header->bytesPerScanLine; - - // Decode line number y - while (bytes--) - { - if (rle_count == 0) - { - if( (rle_value = *(pData++)) < 0xc0) - { - rle_count = 1; - } - else - { - rle_count = rle_value - 0xc0; - rle_value = *(pData++); - } - } - - rle_count--; - - ptr[0] = palette[rle_value * 3 + compTable[0]]; - ptr[1] = palette[rle_value * 3 + compTable[1]]; - ptr[2] = palette[rle_value * 3 + compTable[2]]; - ptr += 3; - } - } -} - - -// -------------------------------------------------------------------------- -// ImagePCX::readPCX24bits -// -// Read 24 bits PCX image. -// -------------------------------------------------------------------------- - -void -ImagePCX::readPCX24bits (const GLubyte *data) -{ - const GLubyte *pData = data; - GLubyte *ptr; - int rle_count = 0, rle_value = 0; - int *compTable = GLEW_EXT_bgra ? bgrTable : rgbTable; - - for (int y = 0; y < _height; ++y) - { - // For each color plane - for (int c = 0; c < 3; ++c) - { - ptr = &_pixels[(_height - (y + 1)) * _width * 3]; - int bytes = _header->bytesPerScanLine; - - // Decode line number y - while (bytes--) - { - if (rle_count == 0) - { - if( (rle_value = *(pData++)) < 0xc0) - { - rle_count = 1; - } - else - { - rle_count = rle_value - 0xc0; - rle_value = *(pData++); - } - } - - rle_count--; - ptr[compTable[c]] = static_cast(rle_value); - ptr += 3; - } - } - } -} - - -///////////////////////////////////////////////////////////////////////////// -// -// class ImageJPEG implementation. -// -///////////////////////////////////////////////////////////////////////////// - -// -------------------------------------------------------------------------- -// ImageJPEG::ImageJPEG -// -// Constructor. Read a JPEG image from memory, using libjpeg. -// -------------------------------------------------------------------------- - -ImageJPEG::ImageJPEG (const ImageBuffer &ibuff) -{ - jpeg_decompress_struct cinfo; - my_error_mgr jerr; - jpeg_source_mgr jsrc; - JSAMPROW j; - - try - { - _name = ibuff.filename (); - _standardCoordSystem = true; - - // Create and configure decompress object - jpeg_create_decompress (&cinfo); - cinfo.err = jpeg_std_error (&jerr.pub); - cinfo.src = &jsrc; - - // Configure error manager - jerr.pub.error_exit = errorExit_callback; - jerr.pub.output_message = outputMessage_callback; - - if (setjmp (jerr.setjmp_buffer)) - throw ImageException (jerr.errorMsg, _name); - - // Configure source manager - jsrc.next_input_byte = ibuff.data (); - jsrc.bytes_in_buffer = ibuff.length (); - - jsrc.init_source = initSource_callback; - jsrc.fill_input_buffer = fillInputBuffer_callback; - jsrc.skip_input_data = skipInputData_callback; - jsrc.resync_to_restart = jpeg_resync_to_restart; - jsrc.term_source = termSource_callback; - - // Read file's header and prepare for decompression - jpeg_read_header (&cinfo, TRUE); - jpeg_start_decompress (&cinfo); - - // Initialize image's member variables - _width = cinfo.image_width; - _height = cinfo.image_height; - _components = cinfo.num_components; - _format = (cinfo.num_components == 1) ? GL_LUMINANCE : GL_RGB; - _pixels = new GLubyte[_width * _height * _components]; - - // Read scanlines - for (int i = 0; i < _height; ++i) - { - //j = &_pixels[_width * i * _components]; - j = (_pixels + ((_height - (i + 1)) * _width * _components)); - jpeg_read_scanlines (&cinfo, &j, 1); - } - - // Finish decompression and release memory - jpeg_finish_decompress (&cinfo); - jpeg_destroy_decompress (&cinfo); - } - catch (...) - { - delete [] _pixels; - jpeg_destroy_decompress (&cinfo); - - throw; - } -} - - -// -------------------------------------------------------------------------- -// ImageJPEG::initSource_callback -// ImageJPEG::fillInputBuffer_callback -// ImageJPEG::skipInputData_callback -// ImageJPEG::termSource_callback -// -// Callback functions used by libjpeg for reading data from memory. -// -------------------------------------------------------------------------- - -void -ImageJPEG::initSource_callback (j_decompress_ptr cinfo) -{ - // Nothing to do here -} - - -boolean -ImageJPEG::fillInputBuffer_callback (j_decompress_ptr cinfo) -{ - JOCTET eoi_buffer[2] = { 0xFF, JPEG_EOI }; - struct jpeg_source_mgr *jsrc = cinfo->src; - - // Create a fake EOI marker - jsrc->next_input_byte = eoi_buffer; - jsrc->bytes_in_buffer = 2; - - return TRUE; -} - - -void -ImageJPEG::skipInputData_callback (j_decompress_ptr cinfo, long num_bytes) -{ - struct jpeg_source_mgr *jsrc = cinfo->src; - - if (num_bytes > 0) - { - while (num_bytes > static_cast(jsrc->bytes_in_buffer)) - { - num_bytes -= static_cast(jsrc->bytes_in_buffer); - fillInputBuffer_callback (cinfo); - } - - jsrc->next_input_byte += num_bytes; - jsrc->bytes_in_buffer -= num_bytes; - } -} - - -void -ImageJPEG::termSource_callback (j_decompress_ptr cinfo) -{ - // Nothing to do here -} - - -// -------------------------------------------------------------------------- -// ImageJPEG::errorExit -// ImageJPEG::outputMessage -// -// Callback functions used by libjpeg for error handling. -// -------------------------------------------------------------------------- - -void -ImageJPEG::errorExit_callback (j_common_ptr cinfo) -{ - my_error_ptr jerr = reinterpret_cast(cinfo->err); - - // Create the error message - char message[JMSG_LENGTH_MAX]; - (*cinfo->err->format_message) (cinfo, message); - jerr->errorMsg.assign (message); - - // Return control to the setjmp point - longjmp (jerr->setjmp_buffer, 1); -} - - -void -ImageJPEG::outputMessage_callback (j_common_ptr cinfo) -{ - my_error_ptr jerr = reinterpret_cast(cinfo->err); - - // Create the error message - char message[JMSG_LENGTH_MAX]; - (*cinfo->err->format_message) (cinfo, message); - jerr->errorMsg.assign (message); - - // Send it to stderr, adding a newline - std::cerr << "libjpeg: " << jerr->errorMsg << std::endl; -} - - -///////////////////////////////////////////////////////////////////////////// -// -// class ImagePNG implementation. -// -///////////////////////////////////////////////////////////////////////////// - -// -------------------------------------------------------------------------- -// ImagePNG::ImagePNG -// -// Constructor. Read a PNG image from memory, using libpng. -// -------------------------------------------------------------------------- - -ImagePNG::ImagePNG (const ImageBuffer &ibuff) -{ - png_structp png_ptr = NULL; - png_infop info_ptr = NULL; - png_bytep *row_pointers = NULL; - int bit_depth, color_type; - my_source_mgr src_mgr (ibuff); - - try - { - _name = ibuff.filename (); - _standardCoordSystem = true; - - png_byte sig[8]; - memcpy (sig, reinterpret_cast(ibuff.data ()), 8); - - // Check for valid magic number - if (!png_sig_cmp (sig, 0, 8)) - throw ImageException ("Not a valid PNG file", _name); - - // Create PNG read struct - png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, &errorMsg, - error_callback, warning_callback); - if (!png_ptr) - throw ImageException ("Failed to create png read struct", _name); - - if (setjmp (png_jmpbuf (png_ptr))) - throw ImageException (errorMsg, _name); - - // Create PNG info struct - info_ptr = png_create_info_struct (png_ptr); - if (!info_ptr) - throw ImageException ("Failed to create png info struct", _name); - - // Set "read" callback function and give source of data - png_set_read_fn (png_ptr, &src_mgr, read_callback); - - // Read png info - png_read_info (png_ptr, info_ptr); - - // Get some usefull information from header - bit_depth = png_get_bit_depth (png_ptr, info_ptr); - color_type = png_get_color_type (png_ptr, info_ptr); - - // Convert index color images to RGB images - if (color_type == PNG_COLOR_TYPE_PALETTE) - png_set_palette_to_rgb (png_ptr); - - // Convert 1-2-4 bits grayscale images to 8 bits - // grayscale. - if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) - png_set_expand_gray_1_2_4_to_8(png_ptr); - - if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) - png_set_tRNS_to_alpha (png_ptr); - - if (bit_depth == 16) - png_set_strip_16 (png_ptr); - else if (bit_depth < 8) - png_set_packing (png_ptr); - - // Update info structure to apply transformations - png_read_update_info (png_ptr, info_ptr); - - // Get updated information - png_get_IHDR (png_ptr, info_ptr, - reinterpret_cast(&_width), - reinterpret_cast(&_height), - &bit_depth, &color_type, - NULL, NULL, NULL); - - // Get image format and components per pixel - getTextureInfo (color_type); - - // Memory allocation for storing pixel data - _pixels = new GLubyte[_width * _height * _components]; - - // Pointer array. Each one points at the begening of a row. - row_pointers = new png_bytep[_height]; - - for (int i = 0; i < _height; ++i) - { - row_pointers[i] = (png_bytep)(_pixels + - ((_height - (i + 1)) * _width * _components)); - } - - // Read pixel data using row pointers - png_read_image (png_ptr, row_pointers); - - // Finish decompression and release memory - png_read_end (png_ptr, NULL); - png_destroy_read_struct (&png_ptr, &info_ptr, NULL); - - delete [] row_pointers; - } - catch (...) - { - delete [] _pixels; - delete [] row_pointers; - - if (png_ptr) - png_destroy_read_struct (&png_ptr, &info_ptr, NULL); - - throw; - } -} - - -// -------------------------------------------------------------------------- -// ImagePNG::getTextureInfo -// -// Extract OpenGL texture informations from PNG info. -// -------------------------------------------------------------------------- - -void -ImagePNG::getTextureInfo (int color_type) -{ - switch (color_type) - { - case PNG_COLOR_TYPE_GRAY: - _format = GL_LUMINANCE; - _components = 1; - break; - - case PNG_COLOR_TYPE_GRAY_ALPHA: - _format = GL_LUMINANCE_ALPHA; - _components = 2; - break; - - case PNG_COLOR_TYPE_RGB: - _format = GL_RGB; - _components = 3; - break; - - case PNG_COLOR_TYPE_RGB_ALPHA: - _format = GL_RGBA; - _components = 4; - break; - - default: - // Badness - throw ImageException ("Bad PNG color type", _name); - } -} - - -// -------------------------------------------------------------------------- -// ImagePNG::read_callback -// ImagePNG::error_callback -// ImagePNG::warning_callback -// -// Callback functions used by libpng for reading data from memory -// and error handling. -// -------------------------------------------------------------------------- - -void -ImagePNG::read_callback (png_structp png_ptr, png_bytep data, png_size_t length) -{ - my_source_ptr src = static_cast(png_get_io_ptr(png_ptr)); - - // Copy data from image buffer - memcpy (data, src->pibuff->data () + src->offset, length); - - // Advance in the file - src->offset += length; -} - - -void -ImagePNG::error_callback (png_structp png_ptr, png_const_charp error_msg) -{ - static_cast(png_get_error_ptr(png_ptr))->assign (error_msg); - - longjmp (png_jmpbuf (png_ptr), 1); -} - - -void -ImagePNG::warning_callback (png_structp png_ptr, png_const_charp warning_msg) -{ - std::cerr << "libpng: " << warning_msg << std::endl; -} - -}}} //end namespace diff --git a/source/shared_lib/sources/graphics/md5/Md5Model.cpp b/source/shared_lib/sources/graphics/md5/Md5Model.cpp deleted file mode 100644 index 7e1d7fde..00000000 --- a/source/shared_lib/sources/graphics/md5/Md5Model.cpp +++ /dev/null @@ -1,1954 +0,0 @@ -// ============================================================== -// This file is part of MegaGlest (www.glest.org) -// -// Md5Model.h -- Copyright (c) 2006-2007 David Henry -// changed for use with MegaGlest: Copyright (C) 2011- by Mark Vejvoda -// -// This code is licensed under the MIT license: -// http://www.opensource.org/licenses/mit-license.php -// -// Open Source Initiative OSI - The MIT License (MIT):Licensing -// -// The MIT License (MIT) -// Copyright (c) -// -// 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.// -// -// Implementation of MD5 Model classes. -// -///////////////////////////////////////////////////////////////////////////// - -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#endif // _WIN32 - -#include -#include -#include -#include -#include - -#include "md5Texture.h" -#include "ArbProgram.h" -#include "ShaderManager.h" -#include "Md5Model.h" - -namespace Shared { namespace Graphics { namespace md5 { - - -using std::cout; -using std::cerr; -using std::endl; - -///////////////////////////////////////////////////////////////////////////// -// -// global stuff -// -///////////////////////////////////////////////////////////////////////////// - -render_path_e Md5Model::renderPath; -ShaderProgram *Md5Model::shader=NULL; -ArbVertexProgram *Md5Model::vp=NULL; -ArbFragmentProgram *Md5Model::fp=NULL; -// Tangent uniform's location -GLint Md5Model::tangentLoc = -1; -bool Md5Model::bDrawNormals = false; - -const int kMd5Version = 10; - -// Sort functor for joints -struct SortByDepth : - public std::binary_function -{ - bool operator() (const Md5Joint_t &j1, const Md5Joint_t &j2) const { - return (j1.pos._z < j2.pos._z); - } -}; - -///////////////////////////////////////////////////////////////////////////// -// -// class Md5Skeleton implementation. -// -///////////////////////////////////////////////////////////////////////////// - -// -------------------------------------------------------------------------- -// Md5Skeleton::Md5Skeleton -// -// Constructor. Load skeleton data from a <.md5mesh> file. -// -------------------------------------------------------------------------- -Md5Skeleton::Md5Skeleton (std::ifstream &ifs, int numJoints) - throw (Md5Exception) { - string token, buffer; - - if (!ifs.is_open()) - throw Md5Exception ("Input stream not opened!", "skeleton"); - - // Read all joints - for (int i = 0; i < numJoints; ++i) - { - // NOTE: hope there isn't any comment between - // two lines of joints data... - Md5JointPtr j (new Md5Joint_t); - - ifs >> j->name; - ifs >> j->parent; - ifs >> token; // "(" - ifs >> j->pos._x; - ifs >> j->pos._y; - ifs >> j->pos._z; - ifs >> token; // ")" - ifs >> token; // "(" - ifs >> j->orient._x; - ifs >> j->orient._y; - ifs >> j->orient._z; - ifs >> token; // ")" - - // Eat up rest of the line - std::getline (ifs, buffer); - - // Compute orient quaternion's w value - j->orient.computeW (); - - // Add joint to joints vector - _joints.push_back (j); - } -} - -// -------------------------------------------------------------------------- -// Md5Skeleton::~Md5Skeleton -// -// Destructor. Free all data allocated for skeleton's joints. -// -------------------------------------------------------------------------- -Md5Skeleton::~Md5Skeleton () { -} - -// -------------------------------------------------------------------------- -// Md5Skeleton::draw -// -// Draw skeleton's bones and joints. -// -------------------------------------------------------------------------- -void Md5Skeleton::draw (const Matrix4x4f &modelView, bool labelJoints) { - // Draw each joint - glPointSize (5.0f); - glColor3f (1.0f, 0.0f, 0.0f); - glBegin (GL_POINTS); - for (unsigned int i = 0; i < _joints.size (); ++i) - glVertex3fv (_joints[i]->pos); - glEnd (); - glPointSize (1.0f); - - // Draw each bone - glColor3f (0.0f, 1.0f, 0.0f); - glBegin (GL_LINES); - for (unsigned int i = 0; i < _joints.size (); ++i) - { - if (_joints[i]->parent != -1) - { - glVertex3fv (_joints[ _joints[i]->parent ]->pos); - glVertex3fv (_joints[i]->pos); - } - } - glEnd (); - - // Label each joint - /* - if (labelJoints && font) - { - vector jointlist (_joints.size ()); - - // Copy joint's position and name - for (unsigned int i = 0; i < _joints.size (); ++i) - jointlist.push_back (*_joints[i]); - - // Sort joints about depth because of alpha blending - std::sort (jointlist.begin (), jointlist.end (), SortByDepth ()); - - glActiveTexture (GL_TEXTURE0); - glMatrixMode (GL_TEXTURE); - glLoadIdentity (); - - GLfloat mat[16]; - glMatrixMode (GL_MODELVIEW); - glGetFloatv (GL_MODELVIEW_MATRIX, mat); - - glPushMatrix (); - // Setup billboard matrix - mat[0] = 1.0f; mat[1] = 0.0f; mat[2] = 0.0f; - mat[4] = 0.0f; mat[5] = 1.0f; mat[6] = 0.0f; - mat[8] = 0.0f; mat[9] = 0.0f; mat[10]= 1.0f; - - glLoadMatrixf (mat); - - glPushAttrib (GL_POLYGON_BIT); - glFrontFace (GL_CCW); - glPolygonMode (GL_FRONT, GL_FILL); - glColor3f (1.0f, 1.0f, 1.0f); - - glLoadIdentity (); - glScalef (0.1f, 0.1f, 0.1f); - - for (unsigned int i = 0; i < _joints.size (); ++i) - { - glPushMatrix (); - // Move to joint's position - glTranslatef (jointlist[i].pos._x * 10.0f, - jointlist[i].pos._y * 10.0f, - jointlist[i].pos._z * 10.0f); - - font->printText (jointlist[i].name.c_str ()); - glPopMatrix(); - } - - // GL_POLYGON_BIT - glPopAttrib (); - glPopMatrix (); - } - */ -} - -// -------------------------------------------------------------------------- -// Md5Skeleton::setNumJoints -// -// Reserve memory to hold numJoints joints. -// -------------------------------------------------------------------------- -void Md5Skeleton::setNumJoints (int numJoints) { - _joints.reserve (numJoints); -} - -// -------------------------------------------------------------------------- -// Md5Skeleton::addJoint -// -// Add a joint to the skeleton. -// -------------------------------------------------------------------------- -void Md5Skeleton::addJoint (Md5Joint_t *thisJoint) { - _joints.push_back (Md5JointPtr (thisJoint)); -} - -// -------------------------------------------------------------------------- -// Md5Skeleton::clone -// -// Dupplicate the skeleton. -// -------------------------------------------------------------------------- -Md5Skeleton* Md5Skeleton::clone () const { - Md5Skeleton *cpy = new Md5Skeleton; - cpy->setNumJoints (_joints.size ()); - - for (size_t i = 0; i < _joints.size (); ++i) - cpy->addJoint (new Md5Joint_t (*_joints[i].get ())); - - return cpy; -} - -///////////////////////////////////////////////////////////////////////////// -// -// class Md5Mesh implementation. -// -///////////////////////////////////////////////////////////////////////////// - -// -------------------------------------------------------------------------- -// Md5Mesh::Md5Mesh -// -// Constructor. Load mesh data from a <.md5mesh> file. -// -------------------------------------------------------------------------- -Md5Mesh::Md5Mesh (std::ifstream &ifs) - throw (Md5Exception) - : _renderState (kShow), _numVerts (0), _numTris (0), _numWeights (0), - _decal (NULL), _specMap (NULL), _normalMap (NULL), _heightMap (NULL) { - string token, buffer; - - if (!ifs.is_open()) - throw Md5Exception ("Input stream not opened!", "mesh"); - - do - { - // Read first token line from file - ifs >> token; - - if (token == "shader") - { - ifs >> _shader; - - // Remove quote marks from the shader string - _shader = _shader.substr (_shader.find_first_of ('\"') + 1, - _shader.find_last_of ('\"') - 1); - - // Get mesh name from shader string - _name = _shader.c_str() + _shader.find_last_of ('/') + 1; - } - else if (token == "numverts") - { - ifs >> _numVerts; - _verts.reserve (_numVerts); - } - else if (token == "numtris") - { - ifs >> _numTris; - _tris.reserve (_numTris); - } - else if (token == "numweights") - { - ifs >> _numWeights; - _weights.reserve (_numWeights); - } - else if (token == "vert") - { - Md5VertexPtr vert (new Md5Vertex_t); - - // Read vertex data - ifs >> token; // index - ifs >> token; // "(" - ifs >> vert->st[0]; - ifs >> vert->st[1]; - ifs >> token; // ")" - ifs >> vert->startWeight; - ifs >> vert->countWeight; - - _verts.push_back (vert); - } - else if (token == "tri") - { - Md5TrianglePtr tri (new Md5Triangle_t); - - // Read triangle data - ifs >> token; // index - ifs >> tri->index[0]; - ifs >> tri->index[1]; - ifs >> tri->index[2]; - - _tris.push_back (tri); - } - else if (token == "weight") - { - Md5WeightPtr weight (new Md5Weight_t); - - // Read weight data - ifs >> token; // index - ifs >> weight->joint; - ifs >> weight->bias; - ifs >> token; // "(" - ifs >> weight->pos._x; - ifs >> weight->pos._y; - ifs >> weight->pos._z; - ifs >> token; // ")" - - _weights.push_back (weight); - } - - // Eat up rest of the line - std::getline (ifs, buffer); - - } - while ((token != "}") && !ifs.eof ()); - - // Memory allocation for vertex arrays - allocVertexArrays (); - - // Setup texture coordinates array - setupTexCoordArray (); -} - -// -------------------------------------------------------------------------- -// Md5Mesh::~Md5Mesh -// -// Destructor. Free all data allocated for the mesh, i.e. vertices, -// triangles, weights and vertex arrays. -// -------------------------------------------------------------------------- -Md5Mesh::~Md5Mesh () { -} - -// -------------------------------------------------------------------------- -// Md5Mesh::setupVertexArray -// -// Compute vertices' position, normal and tangent. -// -------------------------------------------------------------------------- -void Md5Mesh::setupVertexArrays (Md5Skeleton *skel) { - for (int i = 0; i < _numVerts; ++i) - { - Vector3f finalVertex = kZeroVectorf; - Vector3f finalNormal = kZeroVectorf; - Vector3f finalTangent = kZeroVectorf; - - // Calculate final vertex to draw with weights - for (int j = 0; j < _verts[i]->countWeight; ++j) - { - const Md5Weight_t *pWeight - = _weights[_verts[i]->startWeight + j].get (); - const Md5Joint_t *pJoint - = skel->joint (pWeight->joint); - - // Calculate transformed vertex for this weight - Vector3f wv = pWeight->pos; - pJoint->orient.rotate (wv); - - // The sum of all pWeight->bias should be 1.0 - finalVertex += (pJoint->pos + wv) * pWeight->bias; - - // Calculate transformed normal for this weight - Vector3f wn = pWeight->norm; - pJoint->orient.rotate (wn); - - finalNormal += wn * pWeight->bias; - - // Calculate transformed tangent for this weight - Vector3f wt = pWeight->tan; - pJoint->orient.rotate (wt); - - finalTangent += wt * pWeight->bias; - } - - // We can omit to normalize normal and tangent, - // because they should have been already normalized - // when they were computed. We can gain some time - // avoiding some heavy calculus. - - //finalNormal.normalize (); - //finalTangent.normalize (); - - { - // Fill in the vertex arrays with the freshly vertex, normal - // and tangent computed. - - GLfloat *vertexPointer = &_vertexArray[i * 3]; - GLfloat *normalPointer = &_normalArray[i * 3]; - GLfloat *tangentPointer = &_tangentArray[i * 3]; - - vertexPointer[0] = finalVertex._x; - vertexPointer[1] = finalVertex._y; - vertexPointer[2] = finalVertex._z; - - normalPointer[0] = finalNormal._x; - normalPointer[1] = finalNormal._y; - normalPointer[2] = finalNormal._z; - - tangentPointer[0] = finalTangent._x; - tangentPointer[1] = finalTangent._y; - tangentPointer[2] = finalTangent._z; - } - } -} - - -// -------------------------------------------------------------------------- -// Md5Mesh::computeWeightNormals -// -// der_ton said: -// -// * First you have to get the bind-pose model-space normals by calculating -// them from the model geometry in bind-pose. -// -// * Then you calculate the weight's normal (which is in bone-space) by -// invert-transforming the normal by the bone-space matrix. -// -// * So afterwards when animating, you'll transform the weight normal with -// the animated bone-space matrix and add them all up and you'll get -// back your animated vertex normal. -// -------------------------------------------------------------------------- - -void -Md5Mesh::computeWeightNormals (Md5Skeleton *skel) -{ - vector bindposeVerts (_numVerts); - vector bindposeNorms (_numVerts); - - for (int i = 0; i < _numVerts; ++i) - { - // Zero out final vertex position and final vertex normal - bindposeVerts[i] = kZeroVectorf; - bindposeNorms[i] = kZeroVectorf; - - for (int j = 0; j < _verts[i]->countWeight; ++j) - { - const Md5Weight_t *pWeight - = _weights[_verts[i]->startWeight + j].get (); - const Md5Joint_t *pJoint - = skel->joint (pWeight->joint); - - // Calculate transformed vertex for this weight - Vector3f wv = pWeight->pos; - pJoint->orient.rotate (wv); - - bindposeVerts[i] += (pJoint->pos + wv) * pWeight->bias; - } - } - - // Compute triangle normals - for (int i = 0; i < _numTris; ++i) - { - const Md5Triangle_t *pTri = _tris[i].get (); - - Vector3f triNorm (-ComputeNormal (bindposeVerts[pTri->index[0]], - bindposeVerts[pTri->index[1]], bindposeVerts[pTri->index[2]])); - - for (int j = 0; j < 3; ++j) - bindposeNorms[pTri->index[j]] += triNorm; - } - - // "Average" the surface normals, by normalizing them - for (int i = 0; i < _numVerts; ++i) - bindposeNorms[i].normalize (); - - // - // At this stage we have all vertex normals computed - // for the model geometry in bind-pos - // - - // Zero out all weight normals - for (int i = 0; i < _numWeights; ++i) - _weights[i]->norm = kZeroVectorf; - - // Compute weight normals by invert-transforming the normal - // by the bone-space matrix - for (int i = 0; i < _numVerts; ++i) - { - for (int j = 0; j < _verts[i]->countWeight; ++j) - { - Md5Weight_t *pWeight - = _weights[_verts[i]->startWeight + j].get (); - const Md5Joint_t *pJoint - = skel->joint (pWeight->joint); - - Vector3f wn = bindposeNorms[i]; - - // Compute inverse quaternion rotation - Quaternionf invRot = Inverse (pJoint->orient); - invRot.rotate (wn); - - pWeight->norm += wn; - } - } - - // Normalize all weight normals - for (int i = 0; i < _numWeights; ++i) - _weights[i]->norm.normalize (); -} - - -// -------------------------------------------------------------------------- -// Md5Mesh::computeWeightTangents -// -// Compute per-vertex tangent vectors and then, calculate the weight -// tangent. -// -------------------------------------------------------------------------- - -void -Md5Mesh::computeWeightTangents (Md5Skeleton *skel) -{ - vector bindposeVerts (_numVerts); - vector bindposeNorms (_numVerts); - vector bindposeTans (_numVerts); - - vector sTan (_numVerts); - vector tTan (_numVerts); - - // Zero out all weight tangents (thank you Valgrind) - for (int i = 0; i < _numWeights; ++i) - _weights[i]->tan = kZeroVectorf; - - // Compute bind-pose vertices and normals - for (int i = 0; i < _numVerts; ++i) - { - // Zero out final vertex position, normal and tangent - bindposeVerts[i] = kZeroVectorf; - bindposeNorms[i] = kZeroVectorf; - bindposeTans[i] = kZeroVectorf; - - // Zero s-tangents and t-tangents - sTan[i] = kZeroVectorf; - tTan[i] = kZeroVectorf; - - for (int j = 0; j < _verts[i]->countWeight; ++j) - { - const Md5Weight_t *pWeight - = _weights[_verts[i]->startWeight + j].get (); - const Md5Joint_t *pJoint - = skel->joint (pWeight->joint); - - // Calculate transformed vertex for this weight - Vector3f wv = pWeight->pos; - pJoint->orient.rotate (wv); - - bindposeVerts[i] += (pJoint->pos + wv) * pWeight->bias; - - // Calculate transformed normal for this weight - Vector3f wn = pWeight->norm; - pJoint->orient.rotate (wn); - - bindposeNorms[i] += wn * pWeight->bias; - } - } - - // Calculate s-tangeants and t-tangeants at triangle level - for (int i = 0; i < _numTris; ++i) - { - const Md5Triangle_t *pTri = _tris[i].get (); - - const Vector3f &v0 = bindposeVerts[pTri->index[0]]; - const Vector3f &v1 = bindposeVerts[pTri->index[1]]; - const Vector3f &v2 = bindposeVerts[pTri->index[2]]; - - const vec2_t &w0 = _verts[pTri->index[0]]->st; - const vec2_t &w1 = _verts[pTri->index[1]]->st; - const vec2_t &w2 = _verts[pTri->index[2]]->st; - - float x1 = v1._x - v0._x; - float x2 = v2._x - v0._x; - float y1 = v1._y - v0._y; - float y2 = v2._y - v0._y; - float z1 = v1._z - v0._z; - float z2 = v2._z - v0._z; - - float s1 = w1[0] - w0[0]; - float s2 = w2[0] - w0[0]; - float t1 = w1[1] - w0[1]; - float t2 = w2[1] - w0[1]; - - float r = (s1 * t2) - (s2 * t1); - - if (r == 0.0f) - // Prevent division by zero - r = 1.0f; - - float oneOverR = 1.0f / r; - - Vector3f sDir ((t2 * x1 - t1 * x2) * oneOverR, - (t2 * y1 - t1 * y2) * oneOverR, - (t2 * z1 - t1 * z2) * oneOverR); - Vector3f tDir ((s1 * x2 - s2 * x1) * oneOverR, - (s1 * y2 - s2 * y1) * oneOverR, - (s1 * z2 - s2 * z1) * oneOverR); - - for (int j = 0; j < 3; ++j) - { - sTan[pTri->index[j]] += sDir; - tTan[pTri->index[j]] += tDir; - } - } - - // Calculate vertex tangent - for (int i = 0; i < _numVerts; ++i) - { - const Vector3f &n = bindposeNorms[i]; - const Vector3f &t = sTan[i]; - - // Gram-Schmidt orthogonalize - bindposeTans[i] = (t - n * DotProduct (n, t)); - bindposeTans[i].normalize (); - - // Calculate handedness - if (DotProduct (CrossProduct (n, t), tTan[i]) < 0.0f) - bindposeTans[i] = -bindposeTans[i]; - - // Compute weight tangent - for (int j = 0; j < _verts[i]->countWeight; ++j) - { - Md5Weight_t *pWeight - = _weights[_verts[i]->startWeight + j].get (); - const Md5Joint_t *pJoint - = skel->joint (pWeight->joint); - - Vector3f wt = bindposeTans[i]; - - // Compute inverse quaternion rotation - Quaternionf invRot = Inverse (pJoint->orient); - invRot.rotate (wt); - - pWeight->tan += wt; - } - } - - // Normalize all weight tangents - for (int i = 0; i < _numWeights; ++i) - _weights[i]->tan.normalize (); -} - - -// -------------------------------------------------------------------------- -// Md5Mesh::computeBoundingBox -// -// Compute mesh bounding box for a given skeleton. -// -------------------------------------------------------------------------- - -void Md5Mesh::computeBoundingBox (Md5Skeleton *skel) { - Vector3f maxValue(-99999.0f, -99999.0f, -99999.0f); - Vector3f minValue( 99999.0f, 99999.0f, 99999.0f); - - for (int i = 0; i < _numVerts; ++i) { - Vector3f finalVertex = kZeroVectorf; - - // Calculate final vertex to draw with weights - for (int j = 0; j < _verts[i]->countWeight; ++j) { - const Md5Weight_t *pWeight - = _weights[_verts[i]->startWeight + j].get (); - const Md5Joint_t *pJoint - = skel->joint (pWeight->joint); - - // Calculate transformed vertex for this weight - Vector3f wv = pWeight->pos; - pJoint->orient.rotate (wv); - - // The sum of all pWeight->bias should be 1.0 - finalVertex += (pJoint->pos + wv) * pWeight->bias; - } - - if (finalVertex._x > maxValue._x) - maxValue._x = finalVertex._x; - - if (finalVertex._x < minValue._x) - minValue._x = finalVertex._x; - - if (finalVertex._y > maxValue._y) - maxValue._y = finalVertex._y; - - if (finalVertex._y < minValue._y) - minValue._y = finalVertex._y; - - if (finalVertex._z > maxValue._z) - maxValue._z = finalVertex._z; - - if (finalVertex._z < minValue._z) - minValue._z = finalVertex._z; - } - - _boundingBox.min = minValue; - _boundingBox.max = maxValue; -} - -// -------------------------------------------------------------------------- -// Md5Mesh::preRenderVertexArrays -// -// Pre-rendering preparation. Setup some render-path dependent stuff, -// like tangent arrays for ARB programs and shaders. -// -------------------------------------------------------------------------- - -void -Md5Mesh::preRenderVertexArrays () const -{ - switch (Md5Model::renderPath) - { - case R_normal: - break; - - case R_ARBfp_diffuse: - case R_ARBfp_diffuse_specular: - case R_ARBfp_ds_parallax: - { - Md5Model::vp->use (); - Md5Model::fp->use (); - - glEnableVertexAttribArrayARB (TANGENT_LOC); - glVertexAttribPointerARB (TANGENT_LOC, 3, GL_FLOAT, GL_FALSE, - 0, &_tangentArray.front ()); - break; - } - - case R_shader: - { - if (Md5Model::tangentLoc == -1) - break; - - Md5Model::shader->use (); - - if (GLEW_VERSION_2_0) - { - glEnableVertexAttribArray (Md5Model::tangentLoc); - glVertexAttribPointer (Md5Model::tangentLoc, 3, GL_FLOAT, - GL_FALSE, 0, &_tangentArray.front ()); - } - else - { - glEnableVertexAttribArrayARB (Md5Model::tangentLoc); - glVertexAttribPointerARB (Md5Model::tangentLoc, 3, GL_FLOAT, - GL_FALSE, 0, &_tangentArray.front ()); - } - break; - } - } -} - - -// -------------------------------------------------------------------------- -// Md5Mesh::postRenderVertexArrays -// -// Post-rendering operations. Render-path dependent cleaning up after -// mesh rendering, like disabling tangent arrays for ARB programs and -// shaders. -// -------------------------------------------------------------------------- - -void -Md5Mesh::postRenderVertexArrays () const -{ - switch (Md5Model::renderPath) - { - case R_normal: - break; - - case R_ARBfp_diffuse: - case R_ARBfp_diffuse_specular: - case R_ARBfp_ds_parallax: - { - Md5Model::vp->unuse (); - Md5Model::fp->unuse (); - - glDisableVertexAttribArrayARB (TANGENT_LOC); - break; - } - - case R_shader: - { - if (Md5Model::tangentLoc == -1) - break; - - Md5Model::shader->unuse (); - - if (GLEW_VERSION_2_0) - glDisableVertexAttribArray (Md5Model::tangentLoc); - else - glDisableVertexAttribArrayARB (Md5Model::tangentLoc); - - break; - } - } -} - - -// -------------------------------------------------------------------------- -// Md5Mesh::renderVertexArray -// -// Render mesh with vertex array. -// -------------------------------------------------------------------------- - -void Md5Mesh::renderVertexArrays () const { - // Ensable shader/program's stuff - preRenderVertexArrays (); - - glEnableClientState (GL_VERTEX_ARRAY); - glEnableClientState (GL_NORMAL_ARRAY); - glEnableClientState (GL_TEXTURE_COORD_ARRAY); - - // Upload mesh data to OpenGL - glVertexPointer (3, GL_FLOAT, 0, &_vertexArray.front ()); - glNormalPointer (GL_FLOAT, 0, &_normalArray.front ()); - glTexCoordPointer (2, GL_FLOAT, 0, &_texCoordArray.front ()); - - // Bind to mesh's textures - setupTexture(_heightMap, GL_TEXTURE3); - setupTexture(_normalMap, GL_TEXTURE2); - setupTexture(_specMap, GL_TEXTURE1); - setupTexture(_decal, GL_TEXTURE0); - - // Draw the mesh - glDrawElements (GL_TRIANGLES, _numTris * 3, - GL_UNSIGNED_INT, &_vertIndices.front ()); - - resetReversedTexture(_heightMap, GL_TEXTURE3); - resetReversedTexture(_normalMap, GL_TEXTURE2); - resetReversedTexture(_specMap, GL_TEXTURE1); - resetReversedTexture(_decal, GL_TEXTURE0); - - - glDisableClientState (GL_TEXTURE_COORD_ARRAY); - glDisableClientState (GL_NORMAL_ARRAY); - glDisableClientState (GL_VERTEX_ARRAY); - - // Disable shader/program's stuff - postRenderVertexArrays (); -} - - -// -------------------------------------------------------------------------- -// Md5Mesh::drawNormals -// -// Draw mesh's vertex normals and tangents. -// -------------------------------------------------------------------------- - -void -Md5Mesh::drawNormals () const -{ - Vector3f thisVertex, thisNormal, thisTangent; - - glPushAttrib (GL_ENABLE_BIT); - glDisable (GL_LIGHTING); - glDisable (GL_TEXTURE_2D); - - // Blue - glColor3f (0.0, 0.0, 1.0); - - // Draw normals - glBegin (GL_LINES); - for (int i = 0; i < _numVerts * 3; i += 3) - { - thisVertex._x = _vertexArray[i + 0]; - thisVertex._y = _vertexArray[i + 1]; - thisVertex._z = _vertexArray[i + 2]; - - thisNormal._x = _normalArray[i + 0]; - thisNormal._y = _normalArray[i + 1]; - thisNormal._z = _normalArray[i + 2]; - - Vector3f normVec (thisVertex + thisNormal); - - glVertex3fv (thisVertex); - glVertex3fv (normVec); - } - glEnd (); - - // Magenta - glColor3f (1.0, 0.0, 1.0); - - // Draw tangents - glBegin (GL_LINES); - for (int i = 0; i < _numVerts * 3; i += 3) - { - thisVertex._x = _vertexArray[i + 0]; - thisVertex._y = _vertexArray[i + 1]; - thisVertex._z = _vertexArray[i + 2]; - - thisTangent._x = _tangentArray[i + 0]; - thisTangent._y = _tangentArray[i + 1]; - thisTangent._z = _tangentArray[i + 2]; - - Vector3f tanVec (thisVertex + thisTangent); - - glVertex3fv (thisVertex); - glVertex3fv (tanVec); - } - glEnd (); - - // GL_ENABLE_BIT - glPopAttrib (); -} - - -// -------------------------------------------------------------------------- -// Md5Mesh::allocVertexArrays -// -// Allocate memory for vertex arrays. NOTE: we need to have triangle -// data first! (_tris) -// -------------------------------------------------------------------------- - -void -Md5Mesh::allocVertexArrays () -{ - _vertexArray.reserve (_numVerts * 3); - _normalArray.reserve (_numVerts * 3); - _tangentArray.reserve (_numVerts * 3); - _texCoordArray.reserve (_numVerts * 2); - _vertIndices.reserve (_numTris * 3); - - // We can already initialize the vertex index array (we won't have - // to do it each time we want to draw) - for (int i = 0; i < _numTris; ++i) - { - for (int j = 0; j < 3; ++j) - _vertIndices.push_back (_tris[i]->index[j]); - } -} - - -// -------------------------------------------------------------------------- -// Md5Mesh::setupTexCoordArray -// -// Compute texture coordinate array. -// -------------------------------------------------------------------------- - -void -Md5Mesh::setupTexCoordArray () -{ - for (int i = 0, j = 0; i < _numVerts; ++i, j += 2) - { - // j = i * 2; - _texCoordArray[j + 0] = _verts[i]->st[0]; - _texCoordArray[j + 1] = _verts[i]->st[1]; - } -} - - -// -------------------------------------------------------------------------- -// Md5Mesh::setupTexture -// -// Setup texture 'tex' for the given texture unit. -// -------------------------------------------------------------------------- - -void Md5Mesh::setupTexture(const Texture2D *tex, GLenum texUnit) const { - if(!tex) { - // Disable texture and return - glActiveTexture (texUnit); - glBindTexture (GL_TEXTURE_2D, 0); - } - else { - tex->bind (texUnit); - - // Doom 3 doesn't use the OpenGL standard coordinate system - // for images, i.e. image data "starts" at the upper-left - // corner instead of the lower-left corner. - - // We must reverse the t component if the texture - // has been built with OpenGL's coord. system - if (tex->stdCoordSystem ()) { - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glScalef(1.0f, -1.0f, 1.0f); - glTranslatef(0.0f, -1.0f, 0.0f); - glMatrixMode(GL_MODELVIEW); - } - } -} - -void Md5Mesh::resetReversedTexture(const Texture2D *tex, GLenum texUnit) const { - if(tex) { - tex->bind(texUnit); - - // Doom 3 doesn't use the OpenGL standard coordinate system - // for images, i.e. image data "starts" at the upper-left - // corner instead of the lower-left corner. - - // We must UNDO the reversing of the t component if the texture - // has been built with OpenGL's coord. system - if(tex->stdCoordSystem ()) { - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glTranslatef(0.0f, 0.0f, 0.0f); - glScalef(1.0f, 1.0f, 1.0f); - glMatrixMode(GL_MODELVIEW); - } - } -} - -///////////////////////////////////////////////////////////////////////////// -// -// class Md5Model implementation. -// -///////////////////////////////////////////////////////////////////////////// - -// -------------------------------------------------------------------------- -// Md5Model::Md5Model -// -// Constructor. Load MD5 mesh from file. -// -------------------------------------------------------------------------- - -Md5Model::Md5Model (const string &filename) - throw (Md5Exception) - : _numJoints (0), _numMeshes (0) -{ - // Open file - std::ifstream ifs (filename.c_str(), std::ios::in); - - if (ifs.fail ()) - throw Md5Exception ("Couldn't open md5model file: " + filename, filename); - - while (!ifs.eof ()) - { - string token, buffer; - int version = 0; - - // Read next token - ifs >> token; - - if (token == "//") - { - // This is the begining of a comment - // Eat up rest of the line - std::getline (ifs, buffer); - } - else if (token == "MD5Version") - { - ifs >> version; - - if (version != kMd5Version) - throw Md5Exception ("Bad ifs version", filename); - } - else if (token == "numJoints") - { - ifs >> _numJoints; - } - else if (token == "numMeshes") - { - ifs >> _numMeshes; - _meshes.reserve (_numMeshes); - } - else if (token == "joints") - { - // Base skeleton data - ifs >> token; // "{" - - Md5Skeleton *skel = new Md5Skeleton (ifs, _numJoints); - _baseSkeleton = Md5SkeletonPtr (skel); - - ifs >> token; // "}" - } - else if (token == "mesh") - { - ifs >> token; // "{" - - // Create and load a new model mesh - Md5MeshPtr mesh = Md5MeshPtr (new Md5Mesh (ifs)); - - // Compute bounding box in bind-pose - mesh->computeBoundingBox (_baseSkeleton.get ()); - - // Compute weight normals - mesh->computeWeightNormals (_baseSkeleton.get ()); - - // Compute weight tangents - mesh->computeWeightTangents (_baseSkeleton.get ()); - - _meshes.push_back (mesh); - } - } - - ifs.close (); - - // Compute the bounding box in bind-pose - computeBindPoseBoundingBox (); -} - - -// -------------------------------------------------------------------------- -// Md5Model::~Md5Model -// -// Destructor. Free all data allocated for the model. -// -------------------------------------------------------------------------- - -Md5Model::~Md5Model () -{ -} - - -// -------------------------------------------------------------------------- -// Md5Model::drawModel -// -// Draw each mesh of the model. -// -------------------------------------------------------------------------- - -void -Md5Model::drawModel () const -{ - for (int i = 0; i < _numMeshes; ++i) - { - if (_meshes[i]->show ()) - { - _meshes[i]->renderVertexArrays (); - - if (Md5Model::bDrawNormals) - _meshes[i]->drawNormals (); - } - } -} - - -// -------------------------------------------------------------------------- -// Md5Model::prepare -// -// Prepare each mesh of the model for drawing, i.e. compute final vertex -// positions, normals and other vertex's related data. -// -------------------------------------------------------------------------- - -void Md5Model::prepare (Md5Skeleton *skel) { - for (int i = 0; i < _numMeshes; ++i) { - if (!_meshes[i]->hiden ()) { - // Prepare for drawing with interpolated skeleton - _meshes[i]->setupVertexArrays(skel); - } - } -} - - -// -------------------------------------------------------------------------- -// Md5Model::addAnim -// -// Load a MD5 animation and add it to the animation list. Return true if -// the animation has been loaded successfully. -// -------------------------------------------------------------------------- - -bool -Md5Model::addAnim (const string &filename) -{ - Md5Animation *pAnim = new Md5Animation (filename); - - // Check for compatibility - if (!validityCheck (pAnim)) - { - cerr << filename << " isn't a valid animation" - << " for this model!" << endl; - delete pAnim; - return false; - } - - const string name (pAnim->name ()); - - // If there is already an animation with same name, - // delete it - AnimMap::iterator itor = _animList.find (name); - if (itor != _animList.end()) - _animList.erase (itor); - - // Insert the new animation - _animList.insert (AnimMap::value_type (name, Md5AnimationPtr (pAnim))); - - return true; -} - - -// -------------------------------------------------------------------------- -// Md5Model::setMeshRenderState -// Md5Model::setMeshDecalMap -// Md5Model::setMeshSpecularMap -// Md5Model::setMeshNormalMap -// Md5Model::setMeshHeightMap -// -// Setup mesh's state or texture. -// -------------------------------------------------------------------------- - -void -Md5Model::setMeshRenderState (const string &name, int state) -{ - if (Md5Mesh *mesh = getMeshByName (name)) - mesh->setState (state); -} - - -void -Md5Model::setMeshDecalMap (const string &name, const Texture2D *tex) -{ - if (Md5Mesh *mesh = getMeshByName (name)) - mesh->setDecalMap (tex); -} - - -void -Md5Model::setMeshSpecularMap (const string &name, const Texture2D *tex) -{ - if (Md5Mesh *mesh = getMeshByName (name)) - mesh->setSpecularMap (tex); -} - - -void -Md5Model::setMeshNormalMap (const string &name, const Texture2D *tex) -{ - if (Md5Mesh *mesh = getMeshByName (name)) - mesh->setNormalMap (tex); -} - - -void -Md5Model::setMeshHeightMap (const string &name, const Texture2D *tex) -{ - if (Md5Mesh *mesh = getMeshByName (name)) - mesh->setHeightMap (tex); -} - - -// -------------------------------------------------------------------------- -// Md5Model::anim -// -// Accessor. Return animation from list. -// -------------------------------------------------------------------------- - -const Md5Animation* -Md5Model::anim (const string &name) const -{ - AnimMap::const_iterator itor = _animList.find (name); - if (itor != _animList.end ()) - return itor->second.get (); - - return NULL; -} - - -// -------------------------------------------------------------------------- -// Md5Model::computeBindPoseBoundingBox -// -// Compute model's bounding box in bind-pose. -// -------------------------------------------------------------------------- - -void Md5Model::computeBindPoseBoundingBox() { - Vector3f maxValue(-99999.0f, -99999.0f, -99999.0f); - Vector3f minValue( 99999.0f, 99999.0f, 99999.0f); - - // Get the min and the max from all mesh bounding boxes - for (int i = 0; i < _numMeshes; ++i) { - const BoundingBox_t &meshBox = _meshes[i]->boundingBox (); - - if (meshBox.max._x > maxValue._x) - maxValue._x = meshBox.max._x; - - if (meshBox.min._x < minValue._x) - minValue._x = meshBox.min._x; - - if (meshBox.max._y > maxValue._y) - maxValue._y = meshBox.max._y; - - if (meshBox.min._y < minValue._y) - minValue._y = meshBox.min._y; - - if (meshBox.max._z > maxValue._z) - maxValue._z = meshBox.max._z; - - if (meshBox.min._z < minValue._z) - minValue._z = meshBox.min._z; - } - - _bindPoseBox.min = minValue; - _bindPoseBox.max = maxValue; -} - - -// -------------------------------------------------------------------------- -// Md5Model::validityCheck -// -// Check if an animation is valid for this model or not. A valid -// animation must have a skeleton with the same number of joints with -// model's skeleton and for each skeleton joint, name and parent Id must -// match. -// -------------------------------------------------------------------------- - -bool -Md5Model::validityCheck (Md5Animation *anim) const -{ - if (!anim) - return false; - - if (_numJoints != anim->frame (0)->numJoints()) - return false; - - for (int i = 0; i < _numJoints; ++i) - { - const Md5Joint_t *modelJoint = _baseSkeleton->joint (i); - const Md5Joint_t *animJoint = anim->frame (0)->joint (i); - - if (modelJoint->name != animJoint->name) - return false; - - if (modelJoint->parent != animJoint->parent) - return false; - } - - return true; -} - - -// -------------------------------------------------------------------------- -// Md5Model::getMeshByName -// -// Get pointer to a mesh given its name. Return NULL if there is no mesh -// with such a name. -// -------------------------------------------------------------------------- - -Md5Mesh* -Md5Model::getMeshByName (const string &name) const -{ - for (int i = 0; i < _numMeshes; ++i) - { - if (_meshes[i]->name () == name) - return _meshes[i].get (); - } - - return NULL; -} - - -///////////////////////////////////////////////////////////////////////////// -// -// class Md5Animation implementation. -// -///////////////////////////////////////////////////////////////////////////// - -// -------------------------------------------------------------------------- -// Md5Animation::Md5Animation -// -// Constructor. Load MD5 animation from <.md5anim> file. -// -------------------------------------------------------------------------- - -Md5Animation::Md5Animation (const string &filename) - throw (Md5Exception) - : _numFrames (0), _frameRate (0) -{ - vector jointInfos; - vector baseFrame; - vector animFrameData; - int numJoints = 0; - int numAnimatedComponents = 0; - - // Open file - std::ifstream ifs (filename.c_str(), std::ios::in); - - if (ifs.fail()) - throw Md5Exception ("Couldn't open md5anim file: " + filename, filename); - - while (!ifs.eof ()) - { - string token, buffer; - int version = 0;; - int i = 0; - - // Read next token - ifs >> token; - - if (token == "//") - { - // This is the begining of a comment - // Eat up rest of the line - std::getline (ifs, buffer); - } - else if (token == "MD5Version") - { - ifs >> version; - - if (version != kMd5Version) - throw Md5Exception ("Bad file version", filename); - } - else if (token == "numFrames") - { - ifs >> _numFrames; - _skelframes.reserve (_numFrames); - _bboxes.reserve (_numFrames); - } - else if (token == "numJoints") - { - ifs >> numJoints; - jointInfos.reserve (numJoints); - baseFrame.reserve (numJoints); - } - else if (token == "frameRate") - { - ifs >> _frameRate; - } - else if (token == "numAnimatedComponents") - { - ifs >> numAnimatedComponents; - animFrameData.reserve (numAnimatedComponents); - } - else if (token == "hierarchy") - { - // Read all joint infos - ifs >> token; // "{" - - // Read all joint infos - for (i = 0; i < numJoints; ++i) - { - JointInfo jinfo; - - ifs >> jinfo.name; - ifs >> jinfo.parent; - ifs >> jinfo.flags.value; - ifs >> jinfo.startIndex; - - jointInfos.push_back (jinfo); - - // Eat up rest of the line - std::getline (ifs, buffer); - } - - ifs >> token; // "}" - } - else if (token == "bounds") - { - ifs >> token; // "{" - - // Read frame bounds - for (int i = 0; i < _numFrames; ++i) - { - BoundingBoxPtr bbox (new BoundingBox_t); - - ifs >> token; // "(" - ifs >> bbox->min._x; - ifs >> bbox->min._y; - ifs >> bbox->min._z; - ifs >> token; // ")" - ifs >> token; // "(" - ifs >> bbox->max._x; - ifs >> bbox->max._y; - ifs >> bbox->max._z; - ifs >> token; // ")" - - _bboxes.push_back (bbox); - } - - ifs >> token; // "}" - } - else if (token == "baseframe") - { - // We should have an opening bracket for the baseframe joint list - ifs >> token; // "{" - - // Read baseframe data - for (i = 0; i < numJoints; ++i) - { - BaseFrameJoint bfj; - - ifs >> token; // "(" - ifs >> bfj.pos._x; - ifs >> bfj.pos._y; - ifs >> bfj.pos._z; - ifs >> token; // ")" - ifs >> token; // "(" - ifs >> bfj.orient._x; - ifs >> bfj.orient._y; - ifs >> bfj.orient._z; - ifs >> token; // ")" - - baseFrame.push_back (bfj); - - // Eat up rest of the line - std::getline (ifs, buffer); - } - - ifs >> token; // "}" - } - else if (token == "frame") - { - int frameIndex; - ifs >> frameIndex; - ifs >> token; // "{" - - animFrameData.clear (); - - // Read all frame data - float afvalue; - for (i = 0; i < numAnimatedComponents; ++i) - { - // NOTE about coding style: beeuuarg *vomit* - ifs >> afvalue; - animFrameData.push_back (afvalue); - } - - ifs >> token; // "}" - - // Build skeleton for this frame - buildFrameSkeleton (jointInfos, baseFrame, animFrameData); - } - } - - ifs.close (); - - // Extract animation's name - string szfile = filename; - string::size_type start = szfile.find_last_of ('/'); - string::size_type end = szfile.find_last_of (".md5anim"); - _name = szfile.substr (start + 1, end - start - 8); -} - - -// -------------------------------------------------------------------------- -// Md5Animation::~Md5Animation -// -// Destructor. Free all data allocated for the animation. -// -------------------------------------------------------------------------- - -Md5Animation::~Md5Animation () -{ -} - - -// -------------------------------------------------------------------------- -// Md5Animation::buildFrameSkeleton -// -// Build a skeleton for a particular frame. The skeleton is transformed -// by the given modelview matrix so that it is possible to obtain the -// skeleton in absolute coordinates. -// -------------------------------------------------------------------------- - -void -Md5Animation::buildFrameSkeleton (vector &jointInfos, - vector &baseFrame, - vector &animFrameData) -{ - // Allocate memory for this frame - Md5SkeletonPtr skelframe (new Md5Skeleton); - _skelframes.push_back (skelframe); - - skelframe->setNumJoints (jointInfos.size ()); - - // Setup all joints for this frame - for (unsigned int i = 0; i < jointInfos.size (); ++i) - { - BaseFrameJoint *baseJoint = &baseFrame[i]; - Vector3f animatedPos = baseJoint->pos; - Quaternionf animatedOrient = baseJoint->orient; - int j = 0; - - if (jointInfos[i].flags.tx) // Tx - { - animatedPos._x = animFrameData[jointInfos[i].startIndex + j]; - ++j; - } - - if (jointInfos[i].flags.ty) // Ty - { - animatedPos._y = animFrameData[jointInfos[i].startIndex + j]; - ++j; - } - - if (jointInfos[i].flags.tz) // Tz - { - animatedPos._z = animFrameData[jointInfos[i].startIndex + j]; - ++j; - } - - if (jointInfos[i].flags.qx) // Qx - { - animatedOrient._x = animFrameData[jointInfos[i].startIndex + j]; - ++j; - } - - if (jointInfos[i].flags.qy) // Qy - { - animatedOrient._y = animFrameData[jointInfos[i].startIndex + j]; - ++j; - } - - if (jointInfos[i].flags.qz) // Qz - { - animatedOrient._z = animFrameData[jointInfos[i].startIndex + j]; - ++j; - } - - // Compute orient quaternion's w value - animatedOrient.computeW (); - - // NOTE: we assume that this joint's parent has - // already been calculated, i.e. joint's ID should - // never be smaller than its parent ID. - Md5Joint_t *thisJoint = new Md5Joint_t; - skelframe->addJoint (thisJoint); - - int parent = jointInfos[i].parent; - thisJoint->parent = parent; - thisJoint->name = jointInfos[i].name; - - // has parent? - if (thisJoint->parent < 0) - { - thisJoint->pos = animatedPos; - thisJoint->orient = animatedOrient; - } - else - { - const Md5Joint_t *parentJoint = skelframe->joint (parent); - - parentJoint->orient.rotate (animatedPos); - thisJoint->pos = animatedPos + parentJoint->pos; - - thisJoint->orient = parentJoint->orient * animatedOrient; - thisJoint->orient.normalize (); - } - } -} - - -// -------------------------------------------------------------------------- -// Md5Animation::interpolate -// -// Build an interpolated skeleton given two frame indexes and an -// interpolation percentage. 'out' must be non-null. -// -------------------------------------------------------------------------- - -void -Md5Animation::interpolate (int frameA, int frameB, - float interp, Md5Skeleton *out) const -{ - for (int i = 0; i < out->numJoints (); ++i) - { - const Md5Joint_t *pJointA = _skelframes[frameA]->joint (i); - const Md5Joint_t *pJointB = _skelframes[frameB]->joint (i); - Md5Joint_t *pFinalJoint = out->joint (i); - - pFinalJoint->parent = pJointA->parent; - pFinalJoint->pos = pJointA->pos + interp * (pJointB->pos - pJointA->pos); - pFinalJoint->orient = Slerp (pJointA->orient, pJointB->orient, interp); - } -} - - -///////////////////////////////////////////////////////////////////////////// -// -// class Md5Object implementation. -// -///////////////////////////////////////////////////////////////////////////// - -// -------------------------------------------------------------------------- -// Md5Object::Md5Object -// -// Constructor. -// -------------------------------------------------------------------------- - -Md5Object::Md5Object (Md5Model *model) - : _model (NULL), _animatedSkeleton (NULL), _softwareTransformation (false), - _currAnim (NULL), _currFrame (0), _nextFrame (1), _last_time (0.0), - _max_time (0.0), _renderFlags (kDrawModel) -{ - setMd5Model (model); -} - - -// -------------------------------------------------------------------------- -// Md5Object::~Md5Object -// -// Destructor. Free all data allocated for the object. -// -------------------------------------------------------------------------- - -Md5Object::~Md5Object () -{ - delete _animatedSkeleton; -} - - -// -------------------------------------------------------------------------- -// Md5Object::setMd5Model -// -// Attach MD5 Model to Object. -// -------------------------------------------------------------------------- - -void -Md5Object::setMd5Model (Md5Model *model) -{ - if (_model != model) - { - _model = model; // Link to the model - - // Delete previous skeletons because the new - // model is different and its skeleton can hold - // more joints. - delete _animatedSkeleton; - - // Copy skeleton joints name - _animatedSkeleton = _model->baseSkeleton ()->clone (); - - // Reset animation - _currAnim = NULL; - _currAnimName.clear (); - } -} - - -// -------------------------------------------------------------------------- -// Md5Object::setAnim -// -// Set the current animation to play. -// -------------------------------------------------------------------------- - -void -Md5Object::setAnim (const string &name) -{ - if (_model) - { - // Retrieve animation from model's animation list - if ((_currAnim = _model->anim (name))) - { - _currAnimName = _currAnim->name (); - - // Compute max frame time and reset _last_time - _max_time = 1.0 / static_cast(_currAnim->frameRate ()); - _last_time = 0.0; - - // Reset current and next frames - _currFrame = 0; - _nextFrame = (_currAnim->maxFrame () > 0) ? 1 : 0; - } - else - { - delete _animatedSkeleton; - _currAnimName.clear (); - - // Rebuild animated skeleton with model's base skeleton - _animatedSkeleton = _model->baseSkeleton ()->clone (); - } - } -} - - -// -------------------------------------------------------------------------- -// Md5Object::animate -// -// Compute current and next frames for model's animation. -// -------------------------------------------------------------------------- - -void -Md5Object::animate (double dt) -{ - // Animate only if there is an animation... - if (_currAnim) - { - _last_time += dt; - - // Move to next frame? - if (_last_time >= _max_time) - { - _currFrame++; - _nextFrame++; - _last_time = 0.0f; - - unsigned int maxFrame = _currAnim->maxFrame (); - - if (_currFrame > maxFrame) - _currFrame = 0; - - if (_nextFrame > maxFrame) - _nextFrame = 0; - } - } -} - - -// -------------------------------------------------------------------------- -// Md5Object::computeBoundingBox -// -// Compute object's oriented bounding box. -// -------------------------------------------------------------------------- - -void -Md5Object::computeBoundingBox () -{ - BoundingBox_t bbox; - - if (_currAnim) - { - // Interpolate frames' bounding box in order - // to get animated AABB in object space - const BoundingBox_t *boxA, *boxB; - boxA = _currAnim->frameBounds (_currFrame); - boxB = _currAnim->frameBounds (_nextFrame); - - float interp = _last_time * _currAnim->frameRate (); - - bbox.min = boxA->min + (boxB->min - boxA->min) * interp; - bbox.max = boxA->max + (boxB->max - boxA->max) * interp; - } - else - { - // Get bind-pose model's bouding box - bbox = _model->bindPoseBoundingBox (); - } - - // Compute oriented bounding box - _bbox.world = _modelView; - _bbox.center = Vector3f ((bbox.max._x + bbox.min._x) * 0.5f, - (bbox.max._y + bbox.min._y) * 0.5f, - (bbox.max._z + bbox.min._z) * 0.5f); - _bbox.extent = Vector3f (bbox.max._x - _bbox.center._x, - bbox.max._y - _bbox.center._y, - bbox.max._z - _bbox.center._z); -} - - -// -------------------------------------------------------------------------- -// Md5Object::prepare -// -// Prepare object to be drawn. Interpolate skeleton frames if the -// object is animated, or copy model's base skeleton to current -// skeleton if not. -// Apply model view transformation if asked. -// -------------------------------------------------------------------------- - -void Md5Object::prepare(bool softwareTransformation) { - _softwareTransformation = softwareTransformation; - - if (_renderFlags & kDrawModel) - { - if (_currAnim) - { - // Interpolate current and next frame skeletons - float interp = _last_time * _currAnim->frameRate (); - _currAnim->interpolate (_currFrame, _nextFrame, - interp, _animatedSkeleton); - } - else - { - // If there is no animated skeleton, fall to - // model's base skeleton - delete _animatedSkeleton; - - _animatedSkeleton = _model->baseSkeleton()->clone (); - } - - if (_softwareTransformation || _renderFlags & kDrawJointLabels) - { - // Force software transformation if joint labels have - // to be drawn - _softwareTransformation = true; - - Quaternionf rot; - rot.fromMatrix (_modelView); - - // Applly Model-View transformation for each joint - for (int i = 0; i < _animatedSkeleton->numJoints (); ++i) - { - Md5Joint_t *thisJoint = _animatedSkeleton->joint (i); - - thisJoint->pos = _modelView * thisJoint->pos; - thisJoint->orient = rot * thisJoint->orient; - } - } - - // Setup vertex arrays - _model->prepare (_animatedSkeleton); - } -} - -// -------------------------------------------------------------------------- -// Md5Object::render -// -// Draw the object. -// -------------------------------------------------------------------------- - -void Md5Object::render () const { - glPushMatrix (); - //glTranslatef( 0.0f, -60.0f, 0.0f ); - //glRotatef( -90.0, 1.0, 0.0, 0.0 ); - //glRotatef( -90.0, 0.0, 0.0, 1.0 ); - //glTranslatef( 0.0f, -60.0f, 0.0f ); - - //!glRotatef( -20.0, 1.0, 0.0, 0.0 ); - //!glRotatef( -20.0, 0.0, 1.0, 0.0 ); - - //glRotatef( 50.0, 1.0, 0.0, 0.0 ); - //glTranslatef( 5.0f, -2.0f, -3.0f ); - - //!glTranslatef(-1.4f, -1.4f, -7.5f); - - //glRotatef( 90.0, 0.0, 0.0, 1.0 ); - //glRotatef( -25.0, 0.0, 1.0, 0.0 ); - - //glRotatef( -20.0, 1.0, 0.0, 0.0 ); - //glScalef(1.0/20.0f, 1.0/20.0f, 1.0f); - - if (!_softwareTransformation) { - glMultMatrixf (_modelView._m); - } - glPushAttrib (GL_POLYGON_BIT | GL_ENABLE_BIT); - glFrontFace (GL_CW); - - if (_renderFlags & kDrawModel) { - _model->drawModel (); - } - if (_renderFlags & kDrawSkeleton) { - glDisable (GL_TEXTURE_2D); - glDisable (GL_LIGHTING); - - _animatedSkeleton->draw (_modelView,_renderFlags & kDrawJointLabels); - } - - // GL_POLYGON_BIT | GL_ENABLE_BIT - glPopAttrib (); - glPopMatrix (); -} - -}}} //end namespace diff --git a/source/shared_lib/sources/graphics/md5/ShaderManager.cpp b/source/shared_lib/sources/graphics/md5/ShaderManager.cpp deleted file mode 100644 index ff91cd20..00000000 --- a/source/shared_lib/sources/graphics/md5/ShaderManager.cpp +++ /dev/null @@ -1,473 +0,0 @@ -// ============================================================== -// This file is part of MegaGlest (www.glest.org) -// -// Shader.cpp -- Copyright (c) 2006-2007 David Henry -// changed for use with MegaGlest: Copyright (C) 2011- by Mark Vejvoda -// -// This code is licensed under the MIT license: -// http://www.opensource.org/licenses/mit-license.php -// -// Open Source Initiative OSI - The MIT License (MIT):Licensing -// -// The MIT License (MIT) -// Copyright (c) -// -// 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.// -// -// Implementation of GLSL shader related classes. -// -///////////////////////////////////////////////////////////////////////////// - -#include -#include - -#include "ShaderManager.h" -#include "GlErrors.h" - -namespace Shared { namespace Graphics { namespace md5 { - -using std::cout; -using std::cerr; -using std::endl; - - -///////////////////////////////////////////////////////////////////////////// -// -// Global shader related functions. -// -///////////////////////////////////////////////////////////////////////////// - -static GLboolean GLSLCapable = GL_FALSE; - -// -------------------------------------------------------------------------- -// hasShaderSupport -// -// Return true if the host has GLSL, so that we can use shaders. -// -------------------------------------------------------------------------- -GLboolean hasShaderSupport () { - return GLSLCapable; -} - -// -------------------------------------------------------------------------- -// checkExtensionPresence -// -// Check if an extension is present on the host OpenGL implementation. -// Increment @missing if the extension is missing. -// -------------------------------------------------------------------------- -static void checkExtensionPresence (const string &name, int &missing) { - if (!glewIsSupported (name.c_str ())) - { - cerr << "* missing " << name << " extension" << endl; - missing++; - } -} - -// -------------------------------------------------------------------------- -// initShaderHandling -// -// Initialize variables and extensions needed for using GLSL. This -// function should be called before any shader usage (at application -// initialization for example). -// -------------------------------------------------------------------------- -void initShaderHandling () { - int missing = 0; - - // Check for extensions needed for GLSL support on host - checkExtensionPresence ("GL_ARB_shader_objects", missing); - checkExtensionPresence ("GL_ARB_shading_language_100", missing); - checkExtensionPresence ("GL_ARB_vertex_shader", missing); - checkExtensionPresence ("GL_ARB_fragment_shader", missing); - - // Disable GLSL if one extension is missing - if (missing > 0) - GLSLCapable = GL_FALSE; - else - GLSLCapable = GL_TRUE; -} - - -///////////////////////////////////////////////////////////////////////////// -// -// class Shader implementation. -// -///////////////////////////////////////////////////////////////////////////// - -// -------------------------------------------------------------------------- -// Shader::Shader -// -// Constructor. -// -------------------------------------------------------------------------- -Shader::Shader (const string &filename) - : _name (filename), _handle (0), _compiled (0) { -} - -// -------------------------------------------------------------------------- -// Shader::~Shader -// -// Destructor. Destroy the shader handle. -// -------------------------------------------------------------------------- -Shader::~Shader () { - if (GLEW_VERSION_2_0) - { - if (glIsShader (_handle)) - glDeleteShader (_handle); - } - else - { - GLint type; - glGetObjectParameterivARB (_handle, GL_OBJECT_TYPE_ARB, &type); - - if (GL_SHADER_OBJECT_ARB == type) - glDeleteObjectARB (_handle); - } -} - -// ------------------------------------------------------------------------- -// Shader::printInfoLog -// -// Print log info about a vertex or a fragment shader. -// ------------------------------------------------------------------------- -void Shader::printInfoLog () const { - GLint infologLength = 0; - - // First check for previous OpenGL errors... - checkOpenGLErrors (__FILE__, __LINE__); - - // Get log's length - if (GLEW_VERSION_2_0) - glGetShaderiv (_handle, GL_INFO_LOG_LENGTH, &infologLength); - else - glGetObjectParameterivARB (_handle, GL_OBJECT_INFO_LOG_LENGTH_ARB, - &infologLength); - - // If log is empty, quit - if (infologLength <= 1) - return; - - try - { - GLchar *infoLog = new GLchar[infologLength]; - - // Get the log... - if (GLEW_VERSION_2_0) - glGetShaderInfoLog (_handle, infologLength, NULL, infoLog); - else - glGetInfoLogARB (_handle, infologLength, NULL, infoLog); - - // ...and print it to standard output - cout << "Shader \"" << _name << "\" InfoLog (" - << infologLength << "):" << endl << infoLog << endl; - - delete [] infoLog; - } - catch (std::bad_alloc &err) - { - cerr << "Error: memory allocation failed for shader info log" - << endl << " Reason: " << err.what () << endl; - } -} - -// ------------------------------------------------------------------------- -// Shader::compile -// -// Create and compile the shader. -// ------------------------------------------------------------------------- -void Shader::compile () - throw (std::runtime_error) { - const GLchar *code = _code.c_str (); - - if (GLEW_VERSION_2_0) - { - // Create a shader object - _handle = glCreateShader (shaderType ()); - - // Upload shader code to OpenGL - glShaderSource (_handle, 1, &code, NULL); - - // Compile shader - glCompileShader (_handle); - glGetShaderiv (_handle, GL_COMPILE_STATUS, &_compiled); - printInfoLog (); - - // Check for success - if (GL_FALSE == _compiled) - throw std::runtime_error ("Compilation failed"); - } - else - { - // Create a shader object - _handle = glCreateShaderObjectARB (shaderType ()); - - // Upload shader code to OpenGL - glShaderSourceARB (_handle, 1, &code, NULL); - - // Compile shader - glCompileShaderARB (_handle); - glGetObjectParameterivARB (_handle, GL_OBJECT_COMPILE_STATUS_ARB, &_compiled); - printInfoLog (); - - // Check for success - if (GL_FALSE == _compiled) - throw std::runtime_error ("Compilation failed"); - } -} - -// ------------------------------------------------------------------------- -// Shader::loadShaderFile -// -// Load shader's GLSL code from file. The code is stored into the -// _code string member variable. -// ------------------------------------------------------------------------- -void Shader::loadShaderFile (const string &filename) throw (std::runtime_error) { - // Open the file - std::ifstream ifs (filename.c_str (), std::ios::in | std::ios::binary); - - if (ifs.fail ()) - throw std::runtime_error ("Couldn't open shader file: " + filename); - - // Read whole file into string - _code.assign (std::istreambuf_iterator(ifs), - std::istreambuf_iterator()); - - // Close file - ifs.close (); -} - - -///////////////////////////////////////////////////////////////////////////// -// -// class VertexShader implementation. -// -///////////////////////////////////////////////////////////////////////////// - -// -------------------------------------------------------------------------- -// VertexShader::VertexShader -// -// Constructor. Read vertex shader code from file and compile it. -// -------------------------------------------------------------------------- -VertexShader::VertexShader (const string &filename) - : Shader (filename) { - try - { - // Load shader code from file - loadShaderFile (filename); - - // Compile the shader - compile (); - - cout << "* Vertex shader \"" << _name << "\" compiled" << endl; - } - catch (std::runtime_error &err) - { - cerr << "Error: Faild to create vertex shader from " << _name << endl; - cerr << "Reason: " << err.what () << endl; - } -} - -///////////////////////////////////////////////////////////////////////////// -// -// class FragmentShader implementation. -// -///////////////////////////////////////////////////////////////////////////// - -// -------------------------------------------------------------------------- -// FragmentShader::FragmentShader -// -// Constructor. Read fragment shader code from file and compile it. -// -------------------------------------------------------------------------- -FragmentShader::FragmentShader (const string &filename) - : Shader (filename) { - try - { - // Load shader code from file - loadShaderFile (filename); - - // Compile the shader - compile (); - - cout << "* Fragment shader \"" << _name << "\" compiled" << endl; - } - catch (std::runtime_error &err) - { - cerr << "Error: Faild to create fragment shader from " << _name << endl; - cerr << "Reason: " << err.what () << endl; - } -} -///////////////////////////////////////////////////////////////////////////// -// -// class ShaderProgram implementation. -// -///////////////////////////////////////////////////////////////////////////// - -// -------------------------------------------------------------------------- -// ShaderProgram::ShaderProgram -// -// Constructor. Link vertex and fragment shader. If the vertex shader -// or the fragment shader is invalid (has failed to compile), the -// shader program creation is aborted. -// -------------------------------------------------------------------------- - -ShaderProgram::ShaderProgram (const string &filename, - const VertexShader &vertexShader, - const FragmentShader &fragmentShader) - : _name (filename), _handle (0), _linked (0) { - try { - if (vertexShader.fail ()) - throw std::runtime_error ("Invalid vertex shader"); - - if (fragmentShader.fail ()) - throw std::runtime_error ("Invalid fragment shader"); - - if (GLEW_VERSION_2_0) - { - // Create program and attach vertex and fragment shaders - _handle = glCreateProgram (); - glAttachShader (_handle, vertexShader.handle ()); - glAttachShader (_handle, fragmentShader.handle ()); - - // Perform link stage - glLinkProgram (_handle); - glGetProgramiv (_handle, GL_LINK_STATUS, &_linked); - - // Validate program - glValidateProgram (_handle); - printInfoLog (); - - // Check for success - if (GL_FALSE == _linked) - throw std::runtime_error ("Link stage failed"); - } - else - { - // Create program and attach vertex and fragment shaders - _handle = glCreateProgramObjectARB (); - glAttachObjectARB (_handle, vertexShader.handle ()); - glAttachObjectARB (_handle, fragmentShader.handle ()); - - // Perform link stage - glLinkProgramARB (_handle); - glGetObjectParameterivARB (_handle, GL_OBJECT_LINK_STATUS_ARB, &_linked); - - // Validate program - glValidateProgramARB (_handle); - printInfoLog (); - - // Check for success - if (GL_FALSE == _linked) - throw std::runtime_error ("Link stage failed"); - } - - cout << "* Shader \"" << _name << "\" successfully linked" << endl; - } - catch (std::runtime_error &err) - { - cerr << "Error: Faild to create shader " << _name << endl; - cerr << "Reason: " << err.what () << endl; - } -} - -// -------------------------------------------------------------------------- -// ShaderProgram::~ShaderProgram -// -// Destructor. Destroy the shader program handle. -// -------------------------------------------------------------------------- -ShaderProgram::~ShaderProgram () { - if (GLEW_VERSION_2_0) - { - if (glIsProgram (_handle)) - glDeleteProgram (_handle); - } - else - { - GLint type; - glGetObjectParameterivARB (_handle, GL_OBJECT_TYPE_ARB, &type); - - if (GL_PROGRAM_OBJECT_ARB == type) - glDeleteObjectARB (_handle); - } -} - - -// ------------------------------------------------------------------------- -// ShaderProgram::use -// ShaderProgram::unuse -// -// Bind/unbind the shader. -// ------------------------------------------------------------------------- -void ShaderProgram::use () const { - if (GLEW_VERSION_2_0) - glUseProgram (_handle); - else - glUseProgramObjectARB (_handle); -} - -void ShaderProgram::unuse () const { - if (GLEW_VERSION_2_0) - glUseProgram (0); - else - glUseProgramObjectARB (0); -} - -// ------------------------------------------------------------------------- -// ShaderProgram::printInfoLog -// -// Print log info about a shader program. -// ------------------------------------------------------------------------- -void ShaderProgram::printInfoLog () const { - GLint infologLength = 0; - - // First check for previous OpenGL errors... - checkOpenGLErrors (__FILE__, __LINE__); - - // Get log's length - if (GLEW_VERSION_2_0) - glGetProgramiv (_handle, GL_INFO_LOG_LENGTH, &infologLength); - else - glGetObjectParameterivARB (_handle, GL_OBJECT_INFO_LOG_LENGTH_ARB, - &infologLength); - - - // If log is empty, quit - if (infologLength <= 1) - return; - - try - { - GLchar *infoLog = new GLchar[infologLength]; - - // Get the log... - if (GLEW_VERSION_2_0) - glGetProgramInfoLog (_handle, infologLength, NULL, infoLog); - else - glGetInfoLogARB (_handle, infologLength, NULL, infoLog); - - // ...and print it to standard output - cout << "Program \"" << _name << "\" InfoLog (" - << infologLength << "):" << endl << infoLog << endl; - - delete [] infoLog; - } - catch (std::bad_alloc &err) - { - cerr << "Error: memory allocation failed for shader program " - << "info log" << endl << " Reason: " << err.what () << endl; - } -} - -}}} //end namespace diff --git a/source/shared_lib/sources/graphics/md5/md5Texture.cpp b/source/shared_lib/sources/graphics/md5/md5Texture.cpp deleted file mode 100644 index 95f14104..00000000 --- a/source/shared_lib/sources/graphics/md5/md5Texture.cpp +++ /dev/null @@ -1,536 +0,0 @@ -// ============================================================== -// This file is part of MegaGlest (www.glest.org) -// -// Texture.cpp -- Copyright (c) 2006 David Henry -// changed for use with MegaGlest: Copyright (C) 2011- by Mark Vejvoda -// -// This code is licensed under the MIT license: -// http://www.opensource.org/licenses/mit-license.php -// -// Open Source Initiative OSI - The MIT License (MIT):Licensing -// -// The MIT License (MIT) -// Copyright (c) -// -// 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.// -// -// Implementation of an OpenGL texture classes. -// -///////////////////////////////////////////////////////////////////////////// - -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#endif // _WIN32 - -#include -#include -#include - -#include "GlErrors.h" -#include "md5Texture.h" -#include "Image.h" - -namespace Shared { namespace Graphics { namespace md5 { - -using std::cout; -using std::cerr; -using std::endl; -using std::max; - -///////////////////////////////////////////////////////////////////////////// -// -// class Texture implementation. -// -///////////////////////////////////////////////////////////////////////////// - -// -------------------------------------------------------------------------- -// Texture::Texture -// -// Constructor. -// -------------------------------------------------------------------------- -Texture::Texture () - : _handle (0), _flags (kDefault), - _standardCoordSystem (true), _fail (true) { - // Inhibit possible previous OpenGL error - checkOpenGLErrors (__FILE__, __LINE__); -} - -// -------------------------------------------------------------------------- -// Texture::~Texture -// -// Destructor. Delete texture object. -// -------------------------------------------------------------------------- -Texture::~Texture () { - // Delete texture object - if (glIsTexture(_handle)) - glDeleteTextures (1, &_handle); -} - -// -------------------------------------------------------------------------- -// Texture::bind -// -// Bind texture to the active texture unit. -// -------------------------------------------------------------------------- -void Texture::bind () const { - glBindTexture (target (), _handle); -} - -void Texture::bind (GLenum texUnit) const { - glActiveTexture (texUnit); - glBindTexture (target (), _handle); -} - - -// -------------------------------------------------------------------------- -// Texture::getCompressionFormat -// -// Return the corresponding format for a compressed image given -// image's internal format (pixel components). -// -------------------------------------------------------------------------- -GLint Texture::getCompressionFormat (GLint internalFormat) { - if (!GLEW_EXT_texture_compression_s3tc || - !GLEW_ARB_texture_compression) - // No compression possible on this target machine - return internalFormat; - - switch (internalFormat) - { - case 1: - return GL_COMPRESSED_LUMINANCE; - - case 2: - return GL_COMPRESSED_LUMINANCE_ALPHA; - - case 3: - return GL_COMPRESSED_RGB; - - case 4: - return GL_COMPRESSED_RGBA; - - default: - // Error! - throw std::invalid_argument ("Texture::getCompressionFormat: " - "Bad internal format"); - } -} - - -// -------------------------------------------------------------------------- -// Texture::getInternalFormat -// -// Return texture's internal format depending to whether compression -// is used or not. -// -------------------------------------------------------------------------- -GLint Texture::getInternalFormat (GLint components) { - if (_flags & kCompress) - return getCompressionFormat (components); - else - return components; -} - -///////////////////////////////////////////////////////////////////////////// -// -// class Texture2D implementation. -// -///////////////////////////////////////////////////////////////////////////// - -// -------------------------------------------------------------------------- -// Texture2D::Texture2D -// -// Constructors. Try to load a texture 2D. Don't throw any exception -// if it fails to create the texture; the program can still run whithout -// textures. -// -------------------------------------------------------------------------- -Texture2D::Texture2D () : Texture () { -} - -Texture2D::Texture2D (const string &filename, TextureFlags flags) { - try - { - // Load image file into a buffer - ImageBuffer ibuff (filename); - auto_ptr img (ImageFactory::createImage (ibuff)); - - // Create texture from image buffer - create (img.get (), flags); - } - catch (std::exception &err) - { - cerr << "Error: Couldn't create texture 2D from " << filename - << endl << "Reason: " << err.what () << endl; - } -} - - -Texture2D::Texture2D (const Image *img, TextureFlags flags) -{ - try - { - // Create texture from image buffer - create (img, flags); - } - catch (std::exception &err) - { - cerr << "Error: Couldn't create texture 2D from " << img->name () - << endl << "Reason: " << err.what () << endl; - } -} - - -// -------------------------------------------------------------------------- -// Texture2D::create -// -// Create a texture 2D from an image. -// -------------------------------------------------------------------------- - -void -Texture2D::create (const Image *img, TextureFlags flags) -{ - if (!img->pixels ()) - throw std::runtime_error ("Invalid image data"); - - // Fill texture's vars - _name = img->name (); - _flags = flags; - _standardCoordSystem = img->stdCoordSystem (); - - // Generate a texture name - glGenTextures (1, &_handle); - glBindTexture (target (), _handle); - - // Setup texture filters - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - if (img->isCompressed ()) - { - // Image use S3 compression. Only S3TC DXT1, DXT3 - // and DXT5 formats are supported. - GLsizei mipWidth = img->width (); - GLsizei mipHeight = img->height (); - int offset = 0; - int blockSize = (img->format () == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) ? 8 : 16; - - // Upload mipmaps to video memory - for (GLint mipLevel = 0; mipLevel < img->numMipmaps (); ++mipLevel) - { - GLsizei mipSize = ((mipWidth + 3) / 4) * ((mipHeight + 3) / 4) * blockSize; - - glCompressedTexImage2D (GL_TEXTURE_2D, mipLevel, img->format (), - mipWidth, mipHeight, 0, mipSize, - img->pixels () + offset); - - mipWidth = max (mipWidth >> 1, 1); - mipHeight = max (mipHeight >> 1, 1); - - offset += mipSize; - } - } - else - { - // Build the texture and generate mipmaps - if (GLEW_SGIS_generate_mipmap && img->isPowerOfTwo ()) - { - // Hardware mipmap generation - glTexParameteri (GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); - glHint (GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST); - - glTexImage2D (GL_TEXTURE_2D, 0, getInternalFormat (img->components ()), - img->width (), img->height (), 0, img->format (), - GL_UNSIGNED_BYTE, img->pixels ()); - } - else - { - // No hardware mipmap generation support, fall back to the - // good old gluBuild2DMipmaps function - gluBuild2DMipmaps (GL_TEXTURE_2D, getInternalFormat (img->components ()), - img->width (), img->height (), img->format (), - GL_UNSIGNED_BYTE, img->pixels ()); - } - } - - // Does texture creation succeeded? - if (GL_NO_ERROR == checkOpenGLErrors (__FILE__, __LINE__)) - _fail = false; -} - - -///////////////////////////////////////////////////////////////////////////// -// -// class TextureRectangle implementation. -// -///////////////////////////////////////////////////////////////////////////// - -// -------------------------------------------------------------------------- -// TextureRectangle::TextureRectangle -// -// Constructors. Try to load a texture rectangle. Don't throw any -// exception if it fails to create the texture; the program can still -// run whithout textures. -// -------------------------------------------------------------------------- - -TextureRectangle::TextureRectangle (const string &filename, TextureFlags flags) - : _width (0), _height (0) -{ - try - { - // Check if is not a DDS image - if (filename.find (".dds") != string::npos) - throw ImageException ("Compressed textures are not supported for" - " texture rectangles!", filename); - - // Load image file into a buffer - ImageBuffer ibuff (filename); - auto_ptr img (ImageFactory::createImage (ibuff)); - - // Create texture from image buffer - create (img.get (), flags); - } - catch (std::exception &err) - { - cerr << "Error: Couldn't create texture rectangle from " - << filename << endl << "Reason: " << err.what () << endl; - } -} - - -TextureRectangle::TextureRectangle (const Image *img, TextureFlags flags) - : _width (0), _height (0) -{ - try - { - // Check if is not a compressed DDS image - if (img->isCompressed ()) - throw ImageException ("Compressed textures are not supported for" - " texture rectangles!", img->name ()); - - // Create texture from image buffer - create (img, flags); - } - catch (std::exception &err) - { - cerr << "Error: Couldn't create texture rectangle from " - << img->name () << endl << "Reason: " << err.what () << endl; - } -} - - -// -------------------------------------------------------------------------- -// TextureRectangle::create -// -// Create a texture rectangle from an image. No mipmap -// filtering is permitted for texture rectangles. -// -------------------------------------------------------------------------- - -void -TextureRectangle::create (const Image *img, TextureFlags flags) -{ - if (!img->pixels ()) - throw std::runtime_error ("Invalid image data"); - - // Get image info - _standardCoordSystem = img->stdCoordSystem (); - _width = img->width (); - _height = img->height (); - _name = img->name (); - _flags = flags; - - // Generate a texture name - glGenTextures (1, &_handle); - glBindTexture (target (), _handle); - - // Setup texture filters - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - // Create texture from image - glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, - getInternalFormat (img->components ()), - img->width (), img->height (), 0, img->format (), - GL_UNSIGNED_BYTE, img->pixels ()); - - // Does texture creation succeeded? - if (GL_NO_ERROR == checkOpenGLErrors (__FILE__, __LINE__)) - _fail = false; -} - - -///////////////////////////////////////////////////////////////////////////// -// -// class TextureCubeMap implementation. -// -///////////////////////////////////////////////////////////////////////////// - -// -------------------------------------------------------------------------- -// TextureCubeMap::TextureCubeMap -// -// Constructors. Try to load a texture cube map. Don't throw any -// exception if it fails to create the texture; the program can still -// run whithout textures. -// -------------------------------------------------------------------------- - -TextureCubeMap::TextureCubeMap (const string &basename, const vector &files, - TextureFlags flags) -{ - try - { - _name = basename; - - vector faces; - faces.reserve(6); - - // Load images - for (int i = 0; i < 6; ++i) - { - ImageBuffer ibuff (files[i]); - faces.push_back (ImagePtr (ImageFactory::createImage (ibuff))); - } - - // Create texture from faces - create (faces, flags); - } - catch (ImageException &err) - { - cerr << "Error: Couldn't create texture cube map from " << basename << endl; - cerr << "Reason: " << err.what () << " (" << err.which () << ")" << endl; - } - catch (std::exception &err) - { - cerr << "Error: Couldn't create texture cube map from " << basename << endl; - cerr << "Reason: " << err.what () << endl; - } -} - - -TextureCubeMap::TextureCubeMap (const string &basename, const vector &faces, - TextureFlags flags) -{ - try - { - _name = basename; - - // Create texture from image buffer - create (faces, flags); - } - catch (ImageException &err) - { - cerr << "Error: Couldn't create texture cube map from " << basename << endl; - cerr << "Reason: " << err.what () << " (" << err.which () << ")" << endl; - } - catch (std::exception &err) - { - cerr << "Error: Couldn't create texture cube map from " << basename << endl; - cerr << "Reason: " << err.what () << endl; - } -} - - -// -------------------------------------------------------------------------- -// TextureCubeMap::create -// -// Create a cube map texture from images. -// -------------------------------------------------------------------------- - -void -TextureCubeMap::create (const vector &faces, TextureFlags flags) -{ - // Create a list of image buffers and associate a target - // for each one - typedef map TexTarget; - typedef TexTarget::value_type TexPair; - TexTarget texImages; - - texImages.insert (TexPair (faces[0].get(), GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB)); - texImages.insert (TexPair (faces[1].get(), GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB)); - texImages.insert (TexPair (faces[2].get(), GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB)); - texImages.insert (TexPair (faces[3].get(), GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB)); - texImages.insert (TexPair (faces[4].get(), GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB)); - texImages.insert (TexPair (faces[5].get(), GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)); - - _standardCoordSystem = faces[0]->stdCoordSystem (); - _flags = flags; - - // Generate a texture name - glGenTextures (1, &_handle); - glBindTexture (GL_TEXTURE_CUBE_MAP_ARB, _handle); - - // Setup texture filters - glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - - - // Load each side of the cube - for (TexTarget::iterator itor = texImages.begin (); - itor != texImages.end (); ++itor) - { - // Get image data - const Image *img = itor->first; - - if (!img->pixels ()) - throw std::runtime_error ("Invalid image data"); - - if (img->isCompressed ()) - { - // Image use S3 compression - GLsizei mipWidth = img->width (); - GLsizei mipHeight = img->height (); - int offset = 0; - int blockSize = - (img->format () == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) ? 8 : 16; - - // Upload mipmaps to video memory - for (GLint mipLevel = 0; mipLevel < img->numMipmaps (); ++mipLevel) - { - GLsizei mipSize = ((mipWidth + 3) / 4) * - ((mipHeight + 3) / 4) * blockSize; - - glCompressedTexImage2D (itor->second, mipLevel, img->format (), - mipWidth, mipHeight, 0, mipSize, - img->pixels () + offset); - - mipWidth = max (mipWidth >> 1, 1); - mipHeight = max (mipHeight >> 1, 1); - - offset += mipSize; - } - } - else - { - // No hardware mipmap generation support for texture cube - // maps, use gluBuild2DMipmaps function instead - gluBuild2DMipmaps (itor->second, getInternalFormat (img->components ()), - img->width (), img->height (), img->format (), - GL_UNSIGNED_BYTE, img->pixels ()); - } - } - - // Does texture creation succeeded? - if (GL_NO_ERROR == checkOpenGLErrors (__FILE__, __LINE__)) - _fail = false; -} - -}}} //end namespace diff --git a/source/shared_lib/sources/graphics/md5/md5util.cpp b/source/shared_lib/sources/graphics/md5/md5util.cpp deleted file mode 100644 index cb13811b..00000000 --- a/source/shared_lib/sources/graphics/md5/md5util.cpp +++ /dev/null @@ -1,591 +0,0 @@ -// ============================================================== -// This file is part of MegaGlest (www.glest.org) -// -// Copyright (C) 2011- by Mark Vejvoda -// -// This code is licensed under the MIT license: -// http://www.opensource.org/licenses/mit-license.php -// -// Open Source Initiative OSI - The MIT License (MIT):Licensing -// -// The MIT License (MIT) -// Copyright (c) -// -// 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.// -// -// ============================================================== - -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#endif - -#include -#include -#include -#include -#include -#include - -#include "GlErrors.h" -#include "Mathlib.h" -#include "Md5Model.h" -#include "TextureManager.h" -#include "ArbProgram.h" -#include "ShaderManager.h" -#include "md5util.h" - -namespace Shared { namespace Graphics { namespace md5 { - - -using std::cout; -using std::cerr; -using std::endl; -using std::string; -using std::vector; - -// All vertex and fragment programs -ArbVertexProgram *vp_bump = NULL; -ArbVertexProgram *vp_bump_parallax = NULL; - -ArbFragmentProgram *fp_diffuse = NULL; -ArbFragmentProgram *fp_diffuse_specular = NULL; -ArbFragmentProgram *fp_ds_parallax = NULL; - -// Tangent uniform's location -GLint tangentLoc = -1; - -int renderFlags = Md5Object::kDrawModel; - -bool bAnimate = true; -bool bTextured = true; -bool bCullFace = true; -bool bBounds = false; -bool bParallax = false; -bool bLight = true; -bool bSmooth = true; -bool bWireframe = false; -bool bDrawNormals = false; - -vector animations; - -// Camera -Vector3f rot, eye; - -// ------------------------------------------------------------------------- -// cleanupMD5OpenGL -// -// Application cleanup. -// ------------------------------------------------------------------------- -void cleanupMD5OpenGL() { - //delete model; - //delete object; - //delete font; - //delete shader; - - delete Md5Model::shader; - Md5Model::shader=NULL; - delete vp_bump; - delete vp_bump_parallax; - delete fp_diffuse; - delete fp_diffuse_specular; - delete fp_ds_parallax; - - Texture2DManager::kill (); -} - -// ------------------------------------------------------------------------- -// initShader -// -// Shader's uniform variables initialization. -// ------------------------------------------------------------------------- -void initShader () { - if (NULL == Md5Model::shader) - return; - - Md5Model::shader->use(); - - if (GLEW_VERSION_2_0) { - GLuint prog = Md5Model::shader->handle (); - - // Set uniform parameters - glUniform1i (glGetUniformLocation (prog, "decalMap"), 0); - glUniform1i (glGetUniformLocation (prog, "glossMap"), 1); - glUniform1i (glGetUniformLocation (prog, "normalMap"), 2); - glUniform1i (glGetUniformLocation (prog, "heightMap"), 3); - glUniform1i (glGetUniformLocation (prog, "parallaxMapping"), bParallax); - - // Get attribute location - Md5Model::tangentLoc = glGetAttribLocation (prog, "tangent"); - } - else { - GLhandleARB prog = Md5Model::shader->handle(); - - // Set uniform parameters - glUniform1iARB (glGetUniformLocationARB (prog, "decalMap"), 0); - glUniform1iARB (glGetUniformLocationARB (prog, "glossMap"), 1); - glUniform1iARB (glGetUniformLocationARB (prog, "normalMap"), 2); - glUniform1iARB (glGetUniformLocationARB (prog, "heightMap"), 3); - glUniform1iARB (glGetUniformLocationARB (prog, "parallaxMapping"), bParallax); - - // Get attribute location - Md5Model::tangentLoc = glGetAttribLocationARB (prog, "tangent"); - } - - Md5Model::shader->unuse(); - - // Warn ff we fail to get tangent location... We'll can still use - // the shader, but without tangents - if(Md5Model::tangentLoc == -1) - cerr << "Warning! No \"tangent\" uniform found in shader!" << endl; -} - -// ------------------------------------------------------------------------- -// announceRenderPath -// -// Print info about a render path. -// ------------------------------------------------------------------------- -void announceRenderPath (render_path_e path) { - cout << "Render path: "; - switch (path) - { - case R_normal: - cout << "no bump mapping (fixed pipeline)" << endl; - break; - - case R_ARBfp_diffuse: - cout << "bump mapping, diffuse only " - << "(ARB vp & fp)" << endl; - break; - - case R_ARBfp_diffuse_specular: - cout << "bump mapping, diffuse and specular " - << "(ARB vp & fp)" << endl; - break; - - case R_ARBfp_ds_parallax: - cout << "bump mapping with parallax " - << "(ARB fp & fp)" << endl; - break; - - case R_shader: - cout << "bump mapping with parallax " - << "(GLSL)" << endl; - break; - } -} - -// ------------------------------------------------------------------------- -// initMD5OpenGL -// -// OpenGL initialization. -// ------------------------------------------------------------------------- -void initMD5OpenGL(string shaderPath) { - //glClearColor (0.5f, 0.5f, 0.5f, 0.0f); - //glShadeModel (GL_SMOOTH); - //glCullFace (GL_BACK); - //glEnable (GL_DEPTH_TEST); - - // Initialize GLEW - GLenum err = glewInit (); - if(GLEW_OK != err) { - // Problem: glewInit failed, something is seriously wrong. - cerr << "Error: " << glewGetErrorString (err) << endl; - cleanupMD5OpenGL(); - } - - // Print some infos about user's OpenGL implementation - cout << "OpenGL Version String: " << glGetString (GL_VERSION) << endl; - cout << "GLU Version String: " << gluGetString (GLU_VERSION) << endl; - cout << "GLEW Version String: " << glewGetString (GLEW_VERSION) << endl; - - // Initialize ARB vertex/fragment program support - initArbProgramHandling(); - - // Initialize GLSL shader support - initShaderHandling(); - - if(hasArbVertexProgramSupport () && - hasArbFragmentProgramSupport ()) { - // Load ARB programs - vp_bump = new ArbVertexProgram(shaderPath + "bump.vp"); - vp_bump_parallax = new ArbVertexProgram(shaderPath + "bumpparallax.vp"); - - fp_diffuse = new ArbFragmentProgram(shaderPath + "bumpd.fp"); - fp_diffuse_specular = new ArbFragmentProgram(shaderPath + "bumpds.fp"); - fp_ds_parallax = new ArbFragmentProgram(shaderPath + "bumpdsp.fp"); - - // Current ARB programs will be bump mapping with diffuse - // and specular components - Md5Model::vp = vp_bump; - Md5Model::fp = fp_diffuse_specular; - } - - if(hasShaderSupport ()) { - // Load shader - VertexShader vs(shaderPath + "bump.vert"); - FragmentShader fs(shaderPath + "bump.frag"); - Md5Model::shader = new ShaderProgram(shaderPath + "bump mapping", vs, fs); - - // Initialize shader's uniforms - initShader(); - } - - // Announce avalaible render paths, select the best - cout << endl << "Available render paths:" << endl; - - cout << " [F3] - No bump mapping (fixed pipeline)" << endl; - Md5Model::renderPath = R_normal; - - if (vp_bump && fp_diffuse) { - cout << " [F4] - Bump mapping, diffuse only " - << "(ARB vp & fp)" << endl; - Md5Model::renderPath = R_ARBfp_diffuse; - } - - if (vp_bump && fp_diffuse_specular) { - cout << " [F5] - Bump mapping, diffuse and specular " - << "(ARB vp & fp)" << endl; - Md5Model::renderPath = R_ARBfp_diffuse_specular; - } - - if (vp_bump_parallax && fp_ds_parallax) { - cout << " [F6] - Bump mapping with parallax " - << "(ARB vp & fp)" << endl; - } - - if (Md5Model::shader) { - cout << " [F7] - Bump mapping with parallax " - << "(GLSL)" << endl; - Md5Model::renderPath = R_shader; - } - - // Announce which path has been chosen by default - cout << endl; - announceRenderPath(Md5Model::renderPath); - - checkOpenGLErrors (__FILE__, __LINE__); -} - -// ------------------------------------------------------------------------- -// extractFromQuotes -// -// Extract a string from quotes. -// ------------------------------------------------------------------------- -inline const string extractFromQuotes (const string &str) { - string::size_type start = str.find_first_of ('\"') + 1; - string::size_type end = str.find_first_of ('\"', start) - 2; - return str.substr (start, end); -} - -// ------------------------------------------------------------------------- -// getMD5ObjectFromLoaderScript -// -// Parse a script file for loading md5mesh and animations. -// ------------------------------------------------------------------------- -Md5Object * getMD5ObjectFromLoaderScript(const string &filename) { - // Open the file to parse - std::ifstream file (filename.c_str(), std::ios::in); - - if (file.fail ()) { - cerr << "Couldn't open " << filename << endl; - cleanupMD5OpenGL(); - } - - // Get texture manager - Texture2DManager *texMgr = Texture2DManager::getInstance(); - - Md5Model *model = NULL; - Md5Object *object = NULL; - - while (!file.eof ()) { - string token, buffer; - string meshFile, animFile, textureFile; - string meshName, animName; - - // Peek next token - file >> token; - - if (token == "model") { - std::getline (file, buffer); - meshFile = extractFromQuotes (buffer); - - // Delete previous model and object if existing - delete model; - delete object; - - // Load mesh model - model = new Md5Model(meshFile); - object = new Md5Object(model); - } - else if (token == "anim") { - std::getline (file, buffer); - animFile = extractFromQuotes (buffer); - - try { - // Load animation - if (model) { - model->addAnim(animFile); - } - } - catch (Md5Exception &err) { - cerr << "Failed to load animation " - << animFile << endl; - cerr << "Reason: " << err.what () - << " (" << err.which () << ")" << endl; - } - } - else if (token == "hide") { - std::getline (file, buffer); - meshName = extractFromQuotes (buffer); - - // Set mesh's render state - if (model) { - model->setMeshRenderState (meshName, Md5Mesh::kHide); - } - } - else if ((token == "decalMap") || - (token == "specularMap") || - (token == "normalMap") || - (token == "heightMap")) { - // Get the next token and extract the mesh name - file >> buffer; - long start = buffer.find_first_of ('\"') + 1; - long end = buffer.find_first_of ('\"', start) - 1; - meshName = buffer.substr (start, end); - - // Get the rest of line and extract texture's filename - std::getline (file, buffer); - textureFile = extractFromQuotes (buffer); - - // If the model has been loaded, setup - // the texture to the desired mesh - if (model) { - Texture2D *tex = texMgr->load (textureFile); - if (tex->fail ()) - cerr << "failed to load " << textureFile << endl; - - if (token == "decalMap") - model->setMeshDecalMap (meshName, tex); - else if (token == "specularMap") - model->setMeshSpecularMap (meshName, tex); - else if (token == "normalMap") - model->setMeshNormalMap (meshName, tex); - else if (token == "heightMap") - model->setMeshHeightMap (meshName, tex); - } - } - else if (token == "setAnim") { - std::getline (file, buffer); - animName = extractFromQuotes (buffer); - - // Set object's default animation - object->setAnim (animName); - } - } - - file.close (); - - if (!model || !object) - throw Md5Exception ("No mesh found!", filename); - - return object; -} - -// ------------------------------------------------------------------------- -// setupLight -// -// Setup light position and enable light0. -// ------------------------------------------------------------------------- -void setupLight(GLfloat x, GLfloat y, GLfloat z) { - GLfloat lightPos[4]; - lightPos[0] = x; - lightPos[1] = y; - lightPos[2] = z; - lightPos[3] = 1.0f; - - glDisable (GL_LIGHTING); - glDisable (GL_LIGHT0); - - if (bLight) - { - glPushMatrix (); - glLoadIdentity (); - glLightfv (GL_LIGHT0, GL_POSITION, lightPos); - glPopMatrix (); - - glEnable (GL_LIGHTING); - glEnable (GL_LIGHT0); - } -} - - -// ------------------------------------------------------------------------- -// drawObb -// -// Draw an Oriented Bouding Box. -// ------------------------------------------------------------------------- -void drawObb(const OBBox_t &obb) { - Vector3f corners[8]; - - corners[0] = Vector3f (-obb.extent._x, -obb.extent._y, -obb.extent._z); - corners[1] = Vector3f ( obb.extent._x, -obb.extent._y, -obb.extent._z); - corners[2] = Vector3f ( obb.extent._x, obb.extent._y, -obb.extent._z); - corners[3] = Vector3f (-obb.extent._x, obb.extent._y, -obb.extent._z); - corners[4] = Vector3f (-obb.extent._x, -obb.extent._y, obb.extent._z); - corners[5] = Vector3f ( obb.extent._x, -obb.extent._y, obb.extent._z); - corners[6] = Vector3f ( obb.extent._x, obb.extent._y, obb.extent._z); - corners[7] = Vector3f (-obb.extent._x, obb.extent._y, obb.extent._z); - - glPushAttrib (GL_ENABLE_BIT); - glDisable (GL_TEXTURE_2D); - glDisable (GL_LIGHTING); - - for (int i = 0; i < 8; ++i) { - corners[i] += obb.center; - obb.world.transform (corners[i]); - } - - GLuint indices[24] = - { - 0, 1, 1, 2, 2, 3, 3, 0, - 4, 5, 5, 6, 6, 7, 7, 4, - 0, 4, 1, 5, 2, 6, 3, 7 - }; - - glColor3f (1.0, 0.0, 0.0); - - glEnableClientState (GL_VERTEX_ARRAY); - glVertexPointer (3, GL_FLOAT, 0, corners); - glDrawElements (GL_LINES, 24, GL_UNSIGNED_INT, indices); - glDisableClientState (GL_VERTEX_ARRAY); - - // GL_ENABLE_BIT - glPopAttrib(); -} - -// ------------------------------------------------------------------------- -// drawAxes -// -// Draw the X, Y and Z axes at the center of world. -// ------------------------------------------------------------------------- -void drawAxes(const Matrix4x4f &modelView) { - // Setup world model view matrix - glLoadIdentity (); - glMultMatrixf (modelView._m); - - // Draw the three axes - glBegin (GL_LINES); - // X-axis in red - glColor3f (1.0f, 0.0f, 0.0f); - glVertex3fv (kZeroVectorf._v); - glVertex3fv (kZeroVectorf + Vector3f (10.0f, 0.0f, 0.0)); - - // Y-axis in green - glColor3f (0.0f, 1.0f, 0.0f); - glVertex3fv (kZeroVectorf._v); - glVertex3fv (kZeroVectorf + Vector3f (0.0f, 10.0f, 0.0)); - - // Z-axis in blue - glColor3f (0.0f, 0.0f, 1.0f); - glVertex3fv (kZeroVectorf._v); - glVertex3fv (kZeroVectorf + Vector3f (0.0f, 0.0f, 10.0)); - glEnd (); -} - -// ------------------------------------------------------------------------- -// renderMD5Object -// -// Render the 3D part of the scene. -// ------------------------------------------------------------------------- -void renderMD5Object(Md5Object *object, double anim, Matrix4x4f *modelViewMatrix) { - if(!object) { - return; - } - - // Clear the window - //glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glMatrixMode (GL_MODELVIEW); - glLoadIdentity (); - - // Camera rotation - Matrix4x4f camera; - -#if 0 - camera.identity (); - - glTranslated (-eye._x, -eye._y, -eye._z); - glRotated (rot._x, 1.0f, 0.0f, 0.0f); - glRotated (rot._y, 0.0f, 1.0f, 0.0f); - glRotated (rot._z, 0.0f, 0.0f, 1.0f); -#else - camera.fromEulerAngles (degToRad (rot._x), - degToRad (rot._y), - degToRad (rot._z)); - camera.setTranslation (-eye); -#endif - - Matrix4x4f axisRotation - = RotationMatrix (kXaxis, -kPiOver2) - * RotationMatrix (kZaxis, -kPiOver2); - - Matrix4x4f final = camera * axisRotation; - //glMultMatrixf (final._m); - if(modelViewMatrix) { - final = *modelViewMatrix; - } - - // Setup scene lighting - setupLight (0.0f, 20.0f, 100.0f); - - // Enable/disable texture mapping (fixed pipeline) - if (bTextured) - glEnable (GL_TEXTURE_2D); - else - glDisable (GL_TEXTURE_2D); - - // Enable/disable backface culling - if (bCullFace) - glEnable (GL_CULL_FACE); - else - glDisable (GL_CULL_FACE); - - // Setup polygon mode and shade model - glPolygonMode (GL_FRONT_AND_BACK, bWireframe ? GL_LINE : GL_FILL); - glShadeModel (bSmooth ? GL_SMOOTH : GL_FLAT); - - // Draw object - object->setModelViewMatrix (final); - object->setRenderFlags (renderFlags); - //object->animate (bAnimate ? timer.deltaTime () : 0.0f); - object->animate (anim); - object->computeBoundingBox (); - object->prepare (false); - object->render (); - - if (bBounds) - drawObb (object->boundingBox ()); - - glDisable (GL_LIGHTING); - glDisable (GL_TEXTURE_2D); - - drawAxes (final); -} - -}}} //end namespace