- added md5 code to project (but not actively used, only compiled)

This commit is contained in:
Mark Vejvoda 2011-10-18 04:32:02 +00:00
parent b30fdea0d0
commit a2ae980986
20 changed files with 9871 additions and 26 deletions

View File

@ -0,0 +1,141 @@
// ==============================================================
// 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 licenced under the MIT license.
//
// This software is provided "as is" without express or implied
// warranties. You may freely copy and compile this source into
// applications you distribute provided that the copyright text
// below is included in the resulting source code.
//
// Definitions of ARB program related classes.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef __ARB_PROGRAM_H__
#define __ARB_PROGRAM_H__
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif // _WIN32
#include <GL/glew.h>
#include <stdexcept>
#include <string>
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__

View File

@ -0,0 +1,101 @@
// ==============================================================
// 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 licenced under the MIT license.
//
// This software is provided "as is" without express or implied
// warranties. You may freely copy and compile this source into
// applications you distribute provided that the copyright text
// below is included in the resulting source code.
//
// Definitions of a data manager class.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef __DATAMANAGER_H__
#define __DATAMANAGER_H__
#include <stdexcept>
#include <string>
#include <map>
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 <typename T, typename C>
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<string, T*> 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__

View File

@ -0,0 +1,169 @@
// ==============================================================
// 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 licenced under the MIT license.
//
// This software is provided "as is" without express or implied
// warranties. You may freely copy and compile this source into
// applications you distribute provided that the copyright text
// below is included in the resulting source code.
//
// Implementation of the data manager.
//
/////////////////////////////////////////////////////////////////////////////
#include "DataManager.h"
/////////////////////////////////////////////////////////////////////////////
//
// class DataManager implementation.
//
/////////////////////////////////////////////////////////////////////////////
// Singleton initialization. At first, there is no object created.
template <typename T, typename C>
C *DataManager<T, C>::_singleton = NULL;
// --------------------------------------------------------------------------
// DataManager::DataManager
//
// Constructor.
// --------------------------------------------------------------------------
template <typename T, typename C>
inline
DataManager<T, C>::DataManager () {
}
// --------------------------------------------------------------------------
// DataManager::~DataManager
//
// Destructor. Purge all registred objects.
// --------------------------------------------------------------------------
template <typename T, typename C>
inline
DataManager<T, C>::~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 <typename T, typename C>
inline T *
DataManager<T, C>::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 <typename T, typename C>
inline void
DataManager<T, C>::registerObject (const string &name, T *object)
throw (DataManagerException) {
std::pair<typename DataMap::iterator, bool> 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 <typename T, typename C>
inline void
DataManager<T, C>::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 <typename T, typename C>
inline void
DataManager<T, C>::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 <typename T, typename C>
inline C *
DataManager<T, C>::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 <typename T, typename C>
inline void
DataManager<T, C>::kill () {
delete _singleton;
_singleton = NULL;
}

View File

@ -0,0 +1,27 @@
// ==============================================================
// 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 licenced under the MIT license.
//
// This software is provided "as is" without express or implied
// warranties. You may freely copy and compile this source into
// applications you distribute provided that the copyright text
// below is included in the resulting source code.
//
// 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__

View File

@ -0,0 +1,539 @@
// ==============================================================
// 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 licenced under the MIT license.
//
// This software is provided "as is" without express or implied
// warranties. You may freely copy and compile this source into
// applications you distribute provided that the copyright text
// below is included in the resulting source code.
//
// 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 <windows.h>
#endif // _WIN32
#include <GL/glew.h>
//#include <boost/shared_ptr.hpp>
#include <tr1/memory>
#include <stdexcept>
#include <iostream>
#include <fstream>
#include <string>
#include <png.h>
extern "C" {
#include <jpeglib.h>
}
using std::cout;
using std::endl;
using std::string;
namespace Shared { namespace Graphics { namespace md5 {
//using boost::shared_ptr;
using std::tr1::shared_ptr;
/////////////////////////////////////////////////////////////////////////////
// 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<Image> 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__

View File

@ -0,0 +1,431 @@
// ==============================================================
// 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 licenced under the MIT license.
//
// This software is provided "as is" without express or implied
// warranties. You may freely copy and compile this source into
// applications you distribute provided that the copyright text
// below is included in the resulting source code.
//
// Declarations for 3D maths object and functions to use with OpenGL.
//
// Provide vector, matrix and quaternion operations.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef __MATHLIB_H__
#define __MATHLIB_H__
#include <cmath>
namespace Shared { namespace Graphics { namespace md5 {
// Forward declarations
template <typename Real> class Vector3;
template <typename Real> class Matrix4x4;
template <typename Real> 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 <typename Real>
Real wrapPi (Real theta);
// "Safe" inverse trig functions
template <typename Real>
Real safeAcos (Real x);
// Set the Euler angle triple to its "canonical" value
template <typename Real>
void canonizeEulerAngles (Real &roll, Real &pitch, Real &yaw);
// Convert between degrees and radians
template <typename Real>
inline Real degToRad (Real deg) { return deg * kPiOver180; }
template <typename Real>
inline Real radToDeg (Real rad) { return rad * k180OverPi; }
// Convert between "field of view" and "zoom".
// The FOV angle is specified in radians.
template <typename Real>
inline Real fovToZoom (Real fov) { return 1.0f / std::tan (fov * 0.5f); }
template <typename Real>
inline Real zoomToFov (Real zoom) { return 2.0f * std::atan (1.0f / zoom); }
/////////////////////////////////////////////////////////////////////////////
//
// class Vector3<Real> - A simple 3D vector class.
//
/////////////////////////////////////////////////////////////////////////////
template <typename Real>
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<Real> &v) const;
bool operator!= (const Vector3<Real> &v) const;
// Vector negation
Vector3<Real> operator- () const;
// Vector operations
Vector3<Real> operator+ (const Vector3<Real> &v) const;
Vector3<Real> operator- (const Vector3<Real> &v) const;
Vector3<Real> operator* (Real s) const;
Vector3<Real> operator/ (Real s) const;
// Combined assignment operators to conform to
// C notation convention
Vector3<Real> &operator+= (const Vector3<Real> &v);
Vector3<Real> &operator-= (const Vector3<Real> &v);
Vector3<Real> &operator*= (Real s);
Vector3<Real> &operator/= (Real s);
// Accessor. This allows to use the vector object
// like an array of Real. For example:
// Vector3<float> 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<float> Vector3f;
typedef Vector3<double> 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 <typename Real>
Vector3<Real> operator* (Real k, Vector3<Real> v);
template <typename Real>
Real VectorMag (const Vector3<Real> &v);
template <typename Real>
Real DotProduct (const Vector3<Real> &a, const Vector3<Real> &b);
template <typename Real>
Vector3<Real> CrossProduct (const Vector3<Real> &a, const Vector3<Real> &b);
template <typename Real>
Vector3<Real> ComputeNormal (const Vector3<Real> &p1,
const Vector3<Real> &p2, const Vector3<Real> &p3);
template <typename Real>
Real Distance (const Vector3<Real> &a, const Vector3<Real> &b);
template <typename Real>
Real DistanceSquared (const Vector3<Real> &a, const Vector3<Real> &b);
/////////////////////////////////////////////////////////////////////////////
//
// class Matrix4x4<Real> - Implement a 4x4 Matrix class that can represent
// any 3D affine transformation.
//
/////////////////////////////////////////////////////////////////////////////
template <typename Real>
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<Real> &v);
void transform (Vector3<Real> &v) const;
void rotate (Vector3<Real> &v) const;
void inverseRotate (Vector3<Real> &v) const;
void inverseTranslate (Vector3<Real> &v) const;
void fromQuaternion (const Quaternion<Real> &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<Real> rightVector () const;
Vector3<Real> upVector () const;
Vector3<Real> forwardVector () const;
Vector3<Real> translationVector () const;
// Accessor. This allows to use the matrix object
// like an array of Real. For example:
// Matrix4x4<float> 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<float> Matrix4x4f;
typedef Matrix4x4<double> Matrix4x4d;
//
// Nonmember Matrix4x4 functions
//
// Matrix concatenation
template <typename Real>
Matrix4x4<Real> operator* (const Matrix4x4<Real> &a, const Matrix4x4<Real> &b);
template <typename Real>
Matrix4x4<Real> &operator*= (Matrix4x4<Real> &a, const Matrix4x4<Real> &b);
// Vector transformation
template <typename Real>
Vector3<Real> operator* (const Matrix4x4<Real> &m, const Vector3<Real> &p);
// Transpose matrix
template <typename Real>
Matrix4x4<Real> Transpose (const Matrix4x4<Real> &m);
// Invert matrix
template <typename Real>
Matrix4x4<Real> Invert (const Matrix4x4<Real> &m);
//
// Matrix-builder functions
//
template <typename Real> Matrix4x4<Real> RotationMatrix (Axis axis, Real theta);
template <typename Real> Matrix4x4<Real> RotationMatrix (const Vector3<Real> &axis, Real theta);
template <typename Real> Matrix4x4<Real> TranslationMatrix (Real x, Real y, Real z);
template <typename Real> Matrix4x4<Real> TranslationMatrix (const Vector3<Real> &v);
template <typename Real> Matrix4x4<Real> ScaleMatrix (const Vector3<Real> &s);
template <typename Real> Matrix4x4<Real> ScaleAlongAxisMatrix (const Vector3<Real> &axis, Real k);
template <typename Real> Matrix4x4<Real> ShearMatrix (Axis axis, Real s, Real t);
template <typename Real> Matrix4x4<Real> ProjectionMatrix (const Vector3<Real> &n);
template <typename Real> Matrix4x4<Real> ReflectionMatrix (Axis axis, Real k);
template <typename Real> Matrix4x4<Real> AxisReflectionMatrix (const Vector3<Real> &n);
template <typename Real>
Matrix4x4<Real> LookAtMatrix (const Vector3<Real> &camPos,
const Vector3<Real> &target, const Vector3<Real> &camUp);
template <typename Real>
Matrix4x4<Real> FrustumMatrix (Real l, Real r, Real b, Real t, Real n, Real f);
template <typename Real>
Matrix4x4<Real> PerspectiveMatrix (Real fovY, Real aspect, Real n, Real f);
template <typename Real>
Matrix4x4<Real> OrthoMatrix (Real l, Real r, Real b, Real t, Real n, Real f);
template <typename Real>
Matrix4x4<Real> OrthoNormalMatrix (const Vector3<Real> &xdir,
const Vector3<Real> &ydir, const Vector3<Real> &zdir);
/////////////////////////////////////////////////////////////////////////////
//
// class Quaternion<Real> - Implement a quaternion, for purposes of
// representing an angular displacement (orientation) in 3D.
//
/////////////////////////////////////////////////////////////////////////////
template <typename Real>
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<Real> &v) const;
void fromMatrix (const Matrix4x4<Real> &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<Real> rotationAxis () const;
// Quaternion operations
Quaternion<Real> operator+ (const Quaternion<Real> &q) const;
Quaternion<Real> &operator+= (const Quaternion<Real> &q);
Quaternion<Real> operator- (const Quaternion<Real> &q) const;
Quaternion<Real> &operator-= (const Quaternion<Real> &q);
Quaternion<Real> operator* (const Quaternion<Real> &q) const;
Quaternion<Real> &operator*= (const Quaternion<Real> &q);
Quaternion<Real> operator* (Real k) const;
Quaternion<Real> &operator*= (Real k);
Quaternion<Real> operator* (const Vector3<Real> &v) const;
Quaternion<Real> &operator*= (const Vector3<Real> &v);
Quaternion<Real> operator/ (Real k) const;
Quaternion<Real> &operator/= (Real k);
Quaternion<Real> operator~ () const; // Quaternion conjugate
Quaternion<Real> 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<float> Quaternionf;
typedef Quaternion<double> 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 <typename Real>
Quaternion<Real> operator* (Real k, const Quaternion<Real> &q);
template <typename Real>
Real DotProduct (const Quaternion<Real> &a, const Quaternion<Real> &b);
template <typename Real>
Quaternion<Real> Conjugate (const Quaternion<Real> &q);
template <typename Real>
Quaternion<Real> Inverse (const Quaternion<Real> &q);
template <typename Real>
Quaternion<Real> RotationQuaternion (Axis axis, Real theta);
template <typename Real>
Quaternion<Real> RotationQuaternion (const Vector3<Real> &axis, Real theta);
template <typename Real>
Quaternion<Real> Log (const Quaternion<Real> &q);
template <typename Real>
Quaternion<Real> Exp (const Quaternion<Real> &q);
template <typename Real>
Quaternion<Real> Pow (const Quaternion<Real> &q, Real exponent);
template <typename Real>
Quaternion<Real> Slerp (const Quaternion<Real> &q0, const Quaternion<Real> &q1, Real t);
template <typename Real>
Quaternion<Real> Squad (const Quaternion<Real> &q0, const Quaternion<Real> &qa,
const Quaternion<Real> &qb, const Quaternion<Real> &q1, Real t);
template <typename Real>
inline void Intermediate (const Quaternion<Real> &qprev, const Quaternion<Real> &qcurr,
const Quaternion<Real> &qnext, Quaternion<Real> &qa,
Quaternion<Real> &qb);
// Include inline function definitions
#include "Mathlib.inl"
}}} //end namespace
#endif // __MATHLIB_H__

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,522 @@
// ==============================================================
// 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 licenced under the MIT license.
//
// This software is provided "as is" without express or implied
// warranties. You may freely copy and compile this source into
// applications you distribute provided that the copyright text
// below is included in the resulting source code.
//
// Declarations for MD5 Model Classes (object, mesh, animation and
// skeleton).
//
/////////////////////////////////////////////////////////////////////////////
#ifndef __MD5_H__
#define __MD5_H__
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif // _WIN32
#include <string>
#include <vector>
#include <map>
#include <fstream>
#include <stdexcept>
//#include <tr1/memory>
#include <GL/gl.h>
#include "Mathlib.h"
#include "Texture.h"
namespace Shared { namespace Graphics { namespace md5 {
using std::string;
using std::vector;
using std::map;
//using std::shared_ptr;
// 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<Md5Joint_t> 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<Md5JointPtr> _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<Md5Vertex_t> Md5VertexPtr;
typedef shared_ptr<Md5Triangle_t> Md5TrianglePtr;
typedef shared_ptr<Md5Weight_t> 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<Md5VertexPtr> _verts;
vector<Md5TrianglePtr> _tris;
vector<Md5WeightPtr> _weights;
// Final mesh data; vertex arrays for fast rendering
vector<GLfloat> _vertexArray;
vector<GLfloat> _normalArray;
vector<GLfloat> _tangentArray;
vector<GLfloat> _texCoordArray;
vector<GLuint> _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<Md5Skeleton> Md5SkeletonPtr;
typedef shared_ptr<Md5Mesh> Md5MeshPtr;
typedef shared_ptr<Md5Animation> Md5AnimationPtr;
typedef map<string, Md5AnimationPtr> 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<Md5MeshPtr> _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<Md5Skeleton> Md5SkeletonPtr;
typedef shared_ptr<BoundingBox_t> 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<JointInfo> &jointInfos,
vector<BaseFrameJoint> &baseFrame,
vector<float> &animFrameData);
private:
// Member variables
int _numFrames;
int _frameRate;
string _name;
// Store each frame as a skeleton
vector<Md5SkeletonPtr> _skelframes;
// Bounding boxes for each frame
vector<BoundingBoxPtr> _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__

View File

@ -0,0 +1,171 @@
// ==============================================================
// 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 licenced under the MIT license.
//
// This software is provided "as is" without express or implied
// warranties. You may freely copy and compile this source into
// applications you distribute provided that the copyright text
// below is included in the resulting source code.
//
// Definitions of GLSL shader related classes.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef __SHADER_H__
#define __SHADER_H__
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif // _WIN32
#include <GL/glew.h>
#include <stdexcept>
#include <string>
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__

View File

@ -0,0 +1,200 @@
// ==============================================================
// 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 licenced under the MIT license.
//
// This software is provided "as is" without express or implied
// warranties. You may freely copy and compile this source into
// applications you distribute provided that the copyright text
// below is included in the resulting source code.
//
// Definition of an OpenGL texture classes.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef __TEXTURE_H__
#define __TEXTURE_H__
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif // _WIN32
#include <GL/gl.h>
#include <GL/glext.h>
#include <memory>
#include <stdexcept>
#include <string>
#include <vector>
#include <map>
#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<string> &files,
TextureFlags flags = kDefault);
TextureCubeMap (const string &basename, const vector<ImagePtr> &faces,
TextureFlags flags = kDefault);
protected:
// Internal function
virtual void create (const vector<ImagePtr> &faces, TextureFlags flags);
public:
// Accessors
virtual GLenum target () const { return GL_TEXTURE_CUBE_MAP_ARB; }
};
}}} //end namespace
#endif // __TEXTURE_H__

View File

@ -0,0 +1,73 @@
// ==============================================================
// 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 licenced under the MIT license.
//
// This software is provided "as is" without express or implied
// warranties. You may freely copy and compile this source into
// applications you distribute provided that the copyright text
// below is included in the resulting source code.
//
// Definitions of a texture manager class.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef __TEXTUREMANAGER_H__
#define __TEXTUREMANAGER_H__
#include "DataManager.h"
#include "Texture.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<Texture2D, Texture2DManager> {
friend class DataManager<Texture2D, Texture2DManager>;
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__

View File

@ -0,0 +1,34 @@
// ==============================================================
// This file is part of MegaGlest (www.glest.org)
//
// Copyright (C) 2011- by Mark Vejvoda
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 3 of the
// License, or (at your option) any later version
// ==============================================================
#ifndef __MD5Loader_H__
#define __MD5Loader_H__
//#include "Mathlib.h"
namespace Shared { namespace Graphics { namespace md5 {
class Md5Object;
class Real;
template <typename Real>
class Matrix4x4;
typedef Matrix4x4<float> 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__

View File

@ -0,0 +1,262 @@
// ==============================================================
// 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 licenced under the MIT license.
//
// This software is provided "as is" without express or implied
// warranties. You may freely copy and compile this source into
// applications you distribute provided that the copyright text
// below is included in the resulting source code.
//
// Implementation of ARB program related classes.
//
/////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <fstream>
#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<char>(ifs),
std::istreambuf_iterator<char>());
// 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

View File

@ -0,0 +1,53 @@
// ==============================================================
// 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 licenced under the MIT license.
//
// This software is provided "as is" without express or implied
// warranties. You may freely copy and compile this source into
// applications you distribute provided that the copyright text
// below is included in the resulting source code.
//
// OpenGL error management.
//
/////////////////////////////////////////////////////////////////////////////
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif // _WIN32
#include <GL/gl.h>
#include <GL/glu.h>
#include <iostream>
#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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,454 @@
// ==============================================================
// 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 licenced under the MIT license.
//
// This software is provided "as is" without express or implied
// warranties. You may freely copy and compile this source into
// applications you distribute provided that the copyright text
// below is included in the resulting source code.
//
// Implementation of GLSL shader related classes.
//
/////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <fstream>
#include "Shader.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<char>(ifs),
std::istreambuf_iterator<char>());
// 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

View File

@ -0,0 +1,516 @@
// ==============================================================
// 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 licenced under the MIT license.
//
// This software is provided "as is" without express or implied
// warranties. You may freely copy and compile this source into
// applications you distribute provided that the copyright text
// below is included in the resulting source code.
//
// Implementation of an OpenGL texture classes.
//
/////////////////////////////////////////////////////////////////////////////
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif // _WIN32
#include <GL/glew.h>
#include <iostream>
#include <stdexcept>
#include "GlErrors.h"
#include "Texture.h"
#include "Image.h"
namespace Shared { namespace Graphics { namespace md5 {
using std::cout;
using std::cerr;
using std::endl;
/////////////////////////////////////////////////////////////////////////////
//
// 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<Image> 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 = std::max (mipWidth >> 1, 1);
mipHeight = std::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<Image> 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<string> &files,
TextureFlags flags)
{
try
{
_name = basename;
vector<ImagePtr> 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<ImagePtr> &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<ImagePtr> &faces, TextureFlags flags)
{
// Create a list of image buffers and associate a target
// for each one
typedef map<const Image*, GLenum> 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 = std::max (mipWidth >> 1, 1);
mipHeight = std::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

View File

@ -0,0 +1,569 @@
// ==============================================================
// This file is part of MegaGlest (www.glest.org)
//
// Copyright (C) 2011- by Mark Vejvoda
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 3 of the
// License, or (at your option) any later version
// ==============================================================
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
#include <iostream>
#include <iomanip>
#include <fstream>
#include <vector>
#include <string>
#include <GL/glew.h>
#include "GlErrors.h"
#include "Mathlib.h"
#include "Md5Model.h"
#include "TextureManager.h"
#include "ArbProgram.h"
#include "Shader.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<string> 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

View File

@ -1,26 +0,0 @@
Copyright (c) 2005-2008, Thomas BERNARD
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.