#ifndef _cgfxShaderCommon_h_
#define _cgfxShaderCommon_h_
#ifdef _WIN32
# pragma warning(disable: 4786)
#endif
#define M_CHECK(assertion) if (assertion) ; else throw ((cgfxShaderCommon::InternalError*)__LINE__)
#ifdef DEBUG
#define CGFX_DEBUG 1
#endif
namespace cgfxShaderCommon
{
struct InternalError
{
char* message;
};
}
#define RETURNSTAT(s, msg) \
if (!s) \
{ \
s.perror(msg); \
return s; \
}
#define lengthof(array) (sizeof(array) / sizeof(array[0]))
#if !defined(TEXTURES_BY_NAME) && !defined(TEXTURES_BY_NODE)
# define TEXTURES_BY_NODE 1
#endif
#if defined(CGFX_DEBUG) && defined(_WIN32)
# ifndef _CRTDBG_MAP_ALLOC
# define _CRTDBG_MAP_ALLOC
# endif
#endif
#include <stdlib.h>
#if defined(_WIN32)
# include <crtdbg.h>
#endif
#if defined(CGFX_DEBUG2)
# define OutputDebugString(s) fprintf(stderr, "%s", s)
# define OutputDebugStrings(s1, s2) fprintf(stderr, "%s%s\n", s1, s2);
#else
# if defined (_WIN32)
# define OutputDebugStrings(s1, s2) \
(OutputDebugString(s1), OutputDebugString(s2), OutputDebugString("\n"))
# else
# define OutputDebugString(s) ((void) 0)
# define OutputDebugStrings(s1, s2) ((void) 0)
# endif
#endif
template < typename Tarray, typename Titem >
bool
arrayContains( const Tarray& array, const Titem& item )
{
int i;
for ( i = array.length(); i > 0; --i )
if ( array[ i - 1 ] == item )
break;
return i > 0;
}
template < typename Tarray, typename Titem >
int
findOrAppend( Tarray& array, const Titem& item )
{
int i;
int n = array.length();
for ( i = 0; i < n; ++i )
if ( array[ i ] == item )
break;
if ( i == n )
array.append( item );
return i;
}
#ifndef CGFXSHADER_VERSION
#define CGFXSHADER_VERSION "4.4"
#endif
#include <maya/MObject.h>
#include <maya/MString.h>
#include <maya/MStringArray.h>
#if !defined(_WIN32) && !defined(GL_GLEXT_PROTOTYPES)
#define GL_GLEXT_PROTOTYPES
#endif
#include <maya/MGL.h>
#include <Cg/cg.h>
#if defined(_WIN32) || defined(LINUX)
#if defined(_WIN32)
#include <QtGui/qopenglext.h>
#endif
#else
typedef void (* PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture);
typedef void (* PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
typedef void (* PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index);
typedef void (* PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index);
typedef void (* PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
typedef void (* PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLvoid *pointer);
typedef void (* PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue);
typedef void (* PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
typedef void (* PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
#endif
#include <Cg/cgGL.h>
class glRegister
{
public:
enum
{
kUnknown,
kPosition,
kVertexWeight,
kNormal,
kColor,
kSecondaryColor,
kFogCoord,
kTexCoord,
kLastTexCoord = kTexCoord + 7,
kVertexAttrib,
kLastVertexAttrib = kVertexAttrib + 15,
kLast
};
};
class glStateCache
{
public:
glStateCache();
static glStateCache& instance() { return gInstance; }
inline void reset() { fRequiredRegisters = 0; fEnabledRegisters = 0; fActiveTextureUnit = -1; }
void flushState();
inline void disableAll();
inline void enablePosition();
inline void enableNormal();
inline void disableNormal();
inline void enableColor();
inline void enableSecondaryColor();
void activeTexture( int i);
inline void enableAndActivateTexCoord( int i);
void enableVertexAttrib( int i);
static int sMaxTextureUnits;
static PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTexture;
static PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointer;
static PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArray;
static PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArray;
static PFNGLVERTEXATTRIB4FARBPROC glVertexAttrib4f;
static PFNGLSECONDARYCOLORPOINTEREXTPROC glSecondaryColorPointer;
static PFNGLSECONDARYCOLOR3FEXTPROC glSecondaryColor3f;
static PFNGLMULTITEXCOORD4FARBPROC glMultiTexCoord4fARB;
private:
static glStateCache gInstance;
long fRequiredRegisters;
long fEnabledRegisters;
int fActiveTextureUnit;
};
inline void glStateCache::disableAll() { fRequiredRegisters = 0; flushState(); }
inline void glStateCache::enablePosition() { if( !(fEnabledRegisters & (1 << glRegister::kPosition))) { glEnableClientState(GL_VERTEX_ARRAY); fEnabledRegisters |= (1 << glRegister::kPosition); } fRequiredRegisters |= (1 << glRegister::kPosition); }
inline void glStateCache::enableNormal() { if( !(fEnabledRegisters & (1 << glRegister::kNormal))) { glEnableClientState(GL_NORMAL_ARRAY); fEnabledRegisters |= (1 << glRegister::kNormal); } fRequiredRegisters |= (1 << glRegister::kNormal); }
inline void glStateCache::disableNormal() { if( fEnabledRegisters & (1 << glRegister::kNormal)) { glDisableClientState(GL_NORMAL_ARRAY); fEnabledRegisters &= ~(1 << glRegister::kNormal); } fRequiredRegisters &= ~(1 << glRegister::kNormal); }
inline void glStateCache::enableColor() { if( !(fEnabledRegisters & (1 << glRegister::kColor))) { glEnableClientState(GL_COLOR_ARRAY); fEnabledRegisters |= (1 << glRegister::kColor); } fRequiredRegisters |= (1 << glRegister::kColor); }
inline void glStateCache::enableSecondaryColor() { if( !(fEnabledRegisters & (1 << glRegister::kSecondaryColor))) { glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT); fEnabledRegisters |= (1 << glRegister::kSecondaryColor); } fRequiredRegisters |= (1 << glRegister::kSecondaryColor); }
inline void glStateCache::enableAndActivateTexCoord( int i) { activeTexture( i); if( !(fEnabledRegisters & (1 << (glRegister::kTexCoord + i)))) { glEnableClientState(GL_TEXTURE_COORD_ARRAY); fEnabledRegisters |= (1 << (glRegister::kTexCoord + i)); } fRequiredRegisters |= (1 << (glRegister::kTexCoord + i)); }
#endif