/* =========================================================================== maya2q3 - export .md3 files from maya Copyright (C) 2005 HermitWorks Entertainment Corporation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. =========================================================================== */ #ifndef INC__q3shader_h_ #define INC__q3shader_h_ namespace shader { class ShaderContext { public: ShaderContext( void ); void SetTime( unsigned int msecs ) { m_time = msecs; } unsigned int GetTime( void ) const { return m_time; } void SetShowDetail( bool value ) { m_showDetail = value; } bool GetShowDetail( void ) const { return m_showDetail; } private: unsigned int m_time; bool m_showDetail; }; class Shader { public: enum { MaxDeforms = 3, MaxStages = 8, MaxImageAnims = 8, MaxTexMods = 4, }; Shader( const char *name ); //loads a shader from its text description, //first token must be the opening curly brace void Parse( const char *text ); //sets a shader up to be the default texture shader void SetToTexture( const char *texName ); void LoadGLResources( void ); void UnloadGLResources( void ); //sets up the GL to start rendering with this shader //returns the number of stages to render size_t BeginShader( const ShaderContext &ctx ); //starts a stage //returns true to render, false to skip the stage bool BeginStage( const ShaderContext &ctx, size_t idx ); //ends the current stage //don't call if BeginStage returned false void EndStage( const ShaderContext &ctx ); //resets the GL to its original state void EndShader( const ShaderContext &ctx ); const q3::qname& GetName( void ) const { return m_name; } DECLARE_ENUM( SurfaceFlags ) None = 0, NoDraw = 1, Transparent = 2, END_ENUM( SurfaceFlags ); SurfaceFlags GetSurfaceFlags( void ) const { return m_surfFlags; } bool DoesNeedNormal( void ) const { return m_needNorm; } bool DoesNeedTexCoord( void ) const { return m_needTexCoord; } struct StageInfo { size_t numImages; struct ImageInfo { q3::qname name; unsigned int width; unsigned int height; } images[MaxImageAnims]; bool mipmap; GLenum wrapClampMode; //loads an image into the GL, //caller is responsible for destroying the image GLuint LoadImage( size_t index ) const; }; size_t GetStageCount( void ) const; StageInfo GetStageInfo( size_t index ) const; bool HasTransparency( void ) const; static const char* FindShaderInFile( const char *fileText, const char *shaderName ); static void GetShadersInFile( const char *fileText, std::vector< q3::qname > &retList ); static void GetDefaultableTextures( const char *dirName, std::vector< q3::qname > &retList ); private: DECLARE_ENUM( WaveFunc ) None, Sin, Square, Triangle, SawTooth, InvSawTooth, Noise END_ENUM( WaveFunc ); DECLARE_ENUM( CullMode ) Back, Front, None END_ENUM( CullMode ); DECLARE_ENUM( Deformation ) None, Wave, Normals, Bulge, Move, AutoSprite, AutoSprite2 END_ENUM( Deformation ); DECLARE_ENUM( TexGen ) Bad, Identity, Texture, EnvMap, Vector END_ENUM( TexGen ); DECLARE_ENUM( TexMod ) None = 0, Transform = 0x00000001, Turbulent = 0x00000002, Scroll = 0x00000003, Scale = 0x00000004, Stretch = 0x00000005, Rotate = 0x00000006, EntityTranslate = 0x00000007, Type_Bits = 0x000000FF, Combine_0 = 0x00000100, //convert into a matrix and store in slot N Combine_1 = 0x00000200, Combine_2 = 0x00000300, Combine_3 = 0x00000400, Combine_Forward = 0x00008000, //combine into the next mod's matrix Combine_Bits = 0x0000FF00, END_ENUM_WITH_TYPE( TexMod, int ); DECLARE_ENUM( RgbGen ) Bad, IdentityLighting, Identity, Entity, InvEntity, ExactVertex, Vertex, InvVertex, Wave, DiffuseLit, Const END_ENUM( RgbGen ); DECLARE_ENUM( AlphaGen ) Identity, Skip, Entity, InvEntity, Vertex, InvVertex, Specular, Wave, Const, Portal END_ENUM( AlphaGen ); DECLARE_ENUM( StateBits ) None = 0, SrcBlend_Zero = 0x00000001, SrcBlend_One = 0x00000002, SrcBlend_DstColor = 0x00000003, SrcBlend_InvDstColor = 0x00000004, SrcBlend_SrcAlpha = 0x00000005, SrcBlend_InvSrcAlpha = 0x00000006, SrcBlend_DstAlpha = 0x00000007, SrcBlend_InvDstAlpha = 0x00000008, SrcBlend_AlphaSat = 0x00000009, SrcBlend_Bits = 0x0000000F, DstBlend_Zero = 0x00000010, DstBlend_One = 0x00000020, DstBlend_SrcColor = 0x00000030, DstBlend_InvSrcColor = 0x00000040, DstBlend_SrcAlpha = 0x00000050, DstBlend_InvSrcAlpha = 0x00000060, DstBlend_DstAlpha = 0x00000070, DstBlend_InvDstAlpha = 0x00000080, DstBlend_Bits = 0x000000F0, DepthMask = 0x00000100, PolyLine = 0x00001000, DepthTestDisable = 0x00010000, DepthFunc_Equal = 0x00020000, TexAddr_Wrap = 0x01000000, TexAddr_Clamp = 0x02000000, TexAddr_ClampToEdge = 0x03000000, TexAddr_Bits = 0x0F000000, AlphaTest_GT_0 = 0x10000000, AlphaTest_LT_0x80 = 0x20000000, AlphaTest_GE_0x80 = 0x40000000, AlphaTest_Bits = 0x70000000, Default = DepthMask END_ENUM_WITH_TYPE( StateBits, int ); struct WaveForm { WaveFunc type; float base; float amplitude; float phase; float frequency; }; q3::qname m_name; CullMode m_cull; bool m_polyOffset; bool m_noMips; bool m_noPicMip; bool m_needNorm; bool m_needTexCoord; int m_numDeforms; struct DeformStage { Deformation type; vec3 moveVec; WaveForm wave; float spread; struct { float width, height, speed; } bulge; } m_deforms[MaxDeforms]; int m_numStages; struct ShaderStage { struct TextureBundle { int numTextures; q3::qname texNames[MaxImageAnims]; GLuint texHandles[MaxImageAnims]; unsigned int texWidths[MaxImageAnims]; unsigned int texHeights[MaxImageAnims]; float texAnimSpeed; TexGen texGen; vec3 texGenVecs[2]; int numTexMods; struct TextureMod { TexMod type; WaveForm wave; float matrix[2][2]; float translate[2]; float scale[2]; float scroll[2]; float rotateSpeed; } texMods[MaxTexMods]; } bundle; //q3 defines 2 of these, but the second seems to be internal use only struct __tag_RgbGen_ { RgbGen type; WaveForm wave; float c[3]; } rgb; struct __tag_AlphaGen_ { AlphaGen type; WaveForm wave; float a; } alpha; StateBits state; bool isDetail; GLuint program; } m_stages[MaxStages]; float m_portalRange; struct { float offset, clamp; } m_time; bool m_shaderStarted; size_t m_currPass; gl::Context m_glCtx; SurfaceFlags m_surfFlags; void InitDefault( void ); void ParseDeform( const char *&text ); WaveFunc NameToGenFunc( const char *funcname ); void ParseWaveForm( const char *&text, WaveForm &wave ); void ParseTexMod( const char *text, ShaderStage &stage ); void ParseStage( const char *&text ); typedef sstr< 1024 * 16 > shader_src; GLuint BuildShader( size_t iPass ); void OptimizeTexMods( ShaderStage::TextureBundle &texstage ); void BuildWaveEval( const WaveForm &wave, const char *timeReg, const char *ofsReg, const char *outReg, shader_src &prog ); static GLuint LoadTexture( const char *name, bool mipmap, GLenum wrapClampMode, unsigned int &width, unsigned int &height ); }; }; #endif