//============ Copyright (c) Valve Corporation, All rights reserved. ============ // // cglmprogram.h // GLMgr programs (ARBVP/ARBfp) // //=============================================================================== #ifndef CGLMPROGRAM_H #define CGLMPROGRAM_H #include #pragma once // good ARB program references // http://petewarden.com/notes/archives/2005/05/fragment_progra_2.html // http://petewarden.com/notes/archives/2005/06/fragment_progra_3.html // ext links // http://www.opengl.org/registry/specs/ARB/vertex_program.txt // http://www.opengl.org/registry/specs/ARB/fragment_program.txt // http://www.opengl.org/registry/specs/EXT/gpu_program_parameters.txt //=============================================================================== // tokens not in the SDK headers //#ifndef GL_DEPTH_STENCIL_ATTACHMENT_EXT // #define GL_DEPTH_STENCIL_ATTACHMENT_EXT 0x84F9 //#endif //=============================================================================== // forward declarations class GLMContext; class CGLMShaderPair; class CGLMShaderPairCache; // CGLMProgram can contain two flavors of the same program, one in assembler, one in GLSL. // these flavors are pretty different in terms of the API's that are used to activate them - // for example, assembler programs can just get bound to the context, whereas GLSL programs // have to be linked. To some extent we try to hide that detail inside GLM. // for now, make CGLMProgram a container, it does not set policy or hold a preference as to which // flavor you want to use. GLMContext has to handle that. enum EGLMProgramType { kGLMVertexProgram, kGLMFragmentProgram, kGLMNumProgramTypes }; enum EGLMProgramLang { kGLMARB, kGLMGLSL, kGLMNumProgramLangs }; struct GLMShaderDesc { union { GLuint arb; // ARB program object name GLhandleARB glsl; // GLSL shader object handle (void*) } m_object; // these can change if shader text is edited bool m_textPresent; // is this flavor(lang) of text present in the buffer? int m_textOffset; // where is it int m_textLength; // how big bool m_compiled; // has this text been through a compile attempt bool m_valid; // and if so, was the compile successful int m_slowMark; // has it been flagged during a non native draw batch before. increment every time it's slow. int m_highWater; // vount of vec4's in the major uniform array ("vc" on vs, "pc" on ps) // written by dxabstract.... gross! }; GLenum GLMProgTypeToARBEnum( EGLMProgramType type ); // map vert/frag to ARB asm bind target GLenum GLMProgTypeToGLSLEnum( EGLMProgramType type ); // map vert/frag to ARB asm bind target class CGLMProgram { public: friend class CGLMShaderPairCache; friend class CGLMShaderPair; friend class GLMContext; // only GLMContext can make CGLMProgram objects friend class GLMTester; friend class IDirect3D9; friend class IDirect3DDevice9; //=============================== // constructor is very light, it just makes one empty program object per flavor. CGLMProgram( GLMContext *ctx, EGLMProgramType type ); ~CGLMProgram( ); void SetProgramText ( char *text ); // import text to GLM object - invalidate any prev compiled program bool CompileActiveSources ( void ); // compile only the flavors that were provided. bool Compile ( EGLMProgramLang lang ); bool CheckValidity ( EGLMProgramLang lang ); void LogSlow ( EGLMProgramLang lang ); // detailed spew when called for first time; one liner or perhaps silence after that void GetLabelIndexCombo ( char *labelOut, int labelOutMaxChars, int *indexOut, int *comboOut ); void GetComboIndexNameString ( char *stringOut, int stringOutMaxChars ); // mmmmmmmm-nnnnnnnn-filename #if GLMDEBUG bool PollForChanges( void ); // check mirror for changes. void ReloadStringFromEditable( void ); // populate m_string from editable item (react to change) bool SyncWithEditable( void ); #endif //=============================== // common stuff GLMContext *m_ctx; // link back to parent context EGLMProgramType m_type; // vertex or pixel uint m_serial; // serial number for hashing char *m_text; // copy of text passed into constructor. Can change if editable shaders is enabled. // note - it can contain multiple flavors, so use CGLMTextSectioner to scan it and locate them #if GLMDEBUG CGLMEditableTextItem *m_editable; // editable text item for debugging #endif GLMShaderDesc m_descs[ kGLMNumProgramLangs ]; uint m_samplerMask; // (1<