00001 /********************************************************************** 00002 * glsl_shader.H: 00003 * 00004 * This class will be going through some changes within the next few days 00005 * Please e-mail karolale@umich.edu should you encounter any bugs 00006 * I'll be adding support for a separate GTexture to render TEX REF image 00007 **********************************************************************/ 00008 #ifndef GLSL_SHADER_H_IS_INCLUDED 00009 #define GLSL_SHADER_H_IS_INCLUDED 00010 00011 #include "geom/texturegl.H" 00012 00013 #include "util.H" // TexUnit 00014 #include "basic_texture.H" 00015 #include "perlin.H" //header file still included so it can use the namespace 00016 00017 /********************************************************************** 00018 * GLSLShader: 00019 * 00020 * Base class for GTextures that replace OpenGL's fixed 00021 * functionality with GLSL vertex and fragment programs. 00022 * 00023 * Derived classes should fill in two virtual methods that 00024 * return the names of the required vertex and fragment 00025 * programs; the base class provides functionality to read the 00026 * different shader files and link them into a GLSL program. 00027 * 00028 * Derived classes can also override other virtual methods 00029 * (see below) to load and activate textures, query 00030 * variable locations, and send values of uniform 00031 * variables to the program. To send values of attribute 00032 * variables to the program, use a custom StripCB. 00033 * 00034 * See glsl_toon.H for an example of using this class. 00035 * 00036 **********************************************************************/ 00037 00038 class GLSLShader : public BasicTexture { //no longer derived from Perlin 00039 public: 00040 //******** MANAGERS ******** 00041 GLSLShader(Patch* patch = 0, StripCB* cb = 0); 00042 virtual ~GLSLShader(); 00043 00044 //******** RUN-TIME TYPE ID ******** 00045 DEFINE_RTTI_METHODS3("GLSLShader", GLSLShader*, BasicTexture, CDATA_ITEM*); 00046 00047 //******** UTILITY FUNCTIONS ******** 00048 str_ptr shader_path() const { return Config::JOT_ROOT() + "nprdata/glsl/"; } 00049 00050 // Given the base name of the shader, add the full path and extension: 00051 str_ptr vp_name(Cstr_ptr& name) const { return shader_path() + name + ".vp"; } 00052 str_ptr fp_name(Cstr_ptr& name) const { return shader_path() + name + ".fp"; } 00053 00054 // Wrapper for glGetUniformLocation, with error reporting: 00055 bool get_uniform_loc(Cstr_ptr& name, GLint& loc); 00056 00057 // Optimistic convenience version of above: 00058 GLint get_uniform_loc(Cstr_ptr& name) { 00059 GLint ret = -1; 00060 get_uniform_loc(name, ret); 00061 return ret; 00062 } 00063 00064 // Load the texture (should be already allocated TEXTUREgl 00065 // with filename set as member variable). 00066 // 00067 // Note: Does not activate the texture for use in the current frame. 00068 // 00069 // This is a no-op of the texture was previously loaded. 00070 static bool load_texture(TEXTUREglptr& tex); 00071 00072 // Load (if needed) and activate the texture. 00073 static bool activate_texture(TEXTUREglptr& tex); 00074 00075 //******** VIRTUAL METHODS ******** 00076 00077 // base classes can over-ride this to maintain their own program 00078 // variable, e.g. to share a single program among all instances of 00079 // the derived class: 00080 virtual GLuint& program() { return _program; } 00081 virtual bool& did_init() { return _did_init; } 00082 00083 00084 //gets called between the compile and link of the program 00085 //it is meant to explicitly bind the vertex attribute locations 00086 //this operation is ****NOT REQUIRED**** 00087 //attributes not explicitly bound will be bound automaticly by the linker 00088 virtual bool bind_attributes(GLuint prog) { return true; }; 00089 00090 // Called in init(), subclasses can query and store the 00091 // "locations" of uniform and attribute variables here. 00092 // Base class doesn't use any variables, so it's a no-op. 00093 virtual bool get_variable_locs() { return true; } 00094 00095 // The following are called in draw(): 00096 00097 // Send values of uniform variables to the shader. 00098 virtual bool set_uniform_variables() const { return true; } 00099 00100 // Initialize textures, if any: 00101 virtual void init_textures() {} 00102 00103 // Calls glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | mask), 00104 // enables/disables face culling as needed, and sets the current color: 00105 virtual void set_gl_state(GLbitfield mask=0) const; 00106 00107 // Activate textures, if any: 00108 virtual void activate_textures() {} 00109 00110 // Calls glPopAttrib(): 00111 virtual void restore_gl_state() const; 00112 00113 00114 //******** GTexture VIRTUAL METHODS ******** 00115 00116 // Draw the patch. If Base classes over-ride the above virtual 00117 // methods correctly, they don't need to over-ride draw. 00118 // See GLSLToonShader for an example. 00119 virtual int draw(CVIEWptr& v); 00120 00121 //******** DATA_ITEM VIRTUAL METHODS ******** 00122 virtual DATA_ITEM *dup() const { return new GLSLShader; } 00123 00124 protected: 00125 GLuint _program; // GLSL program 00126 bool _did_init; // tells if init() was called before 00127 00128 BasicTexture* _tex_ref_shader; //pointer to a shader that will render the 00129 //texture reference image 00130 00131 //******** PROTECTED UTILITY METHODS ******** 00132 00133 // Loads and compiles the GLSL program: 00134 bool init(); 00135 00136 // Activate/deactivate the program: 00137 void activate_program() { use_program(program()); } 00138 void deactivate_program() const { use_program(0); } 00139 00140 // Utility to activate a GLSL program (via OpenGL v. 2.0 or 1.5): 00141 static void use_program(GLuint prog); 00142 00143 static void delete_program(GLuint& prog); 00144 static void delete_shader(GLuint shader); 00145 static void delete_shaders(CARRAY<GLuint>& shaders); 00146 static void print_shader_source(GLuint shader); 00147 static void print_info(Cstr_ptr& gtex_name, GLuint obj); 00148 static bool link_program(Cstr_ptr& gtex_name, GLuint prog); 00149 static bool compile_shader(Cstr_ptr& gtex_name, GLuint shader); 00150 static GLuint load_shader( 00151 Cstr_ptr& gtex_name, 00152 Cstr_ptr& filename, 00153 GLenum type); 00154 static bool load_shaders( 00155 Cstr_ptr& gtex_name, 00156 Cstr_list& filenames, 00157 ARRAY<GLuint>& shaders, 00158 GLenum type); 00159 00160 static char* read_file(Cstr_ptr& gtex_name, Cstr_ptr& filename, GLint& len); 00161 static bool attach_shaders(CARRAY<GLuint>& shaders, GLuint prog); 00162 00163 //******** VIRTUAL METHODS ******** 00164 00165 // The following methods give the names of the vertex and 00166 // fragment shader programs. 00167 00168 // For the usual case that there is only 1 file, subclasses 00169 // can override the following: 00170 virtual str_ptr vp_filename() { 00171 // Base class uses jot/nprdata/glsl/simple.vp by default, but 00172 // "simple" can be changed using environment variable GLSL_SHADER_NAME 00173 return vp_name(Config::get_var_str("GLSL_SHADER_NAME","simple")); 00174 } 00175 virtual str_ptr fp_filename() { 00176 // Base class uses jot/nprdata/glsl/simple.fp by default, but 00177 // "simple" can be changed using environment variable GLSL_SHADER_NAME 00178 return fp_name(Config::get_var_str("GLSL_SHADER_NAME","simple")); 00179 } 00180 00181 // Subclasses can fill in the following two methods to return 00182 // a list of file names of vertex and fragment program source 00183 // files; but usually there is only 1 file for each, in which 00184 // case it's more convenient to override the single-name 00185 // versions, above. 00186 virtual str_list vp_filenames() { 00187 str_list ret; 00188 ret += vp_filename(); // override this method for single name case 00189 return ret; 00190 } 00191 virtual str_list fp_filenames() { 00192 str_list ret; 00193 ret += fp_filename(); // override this method for single name case 00194 return ret; 00195 } 00196 00197 //virtual methods controling the texture reference shader 00198 00199 virtual void set_ref_tex_shader(); //by default this will use the smooth shader 00200 virtual void use_ref_tex_shader(); //called in the base class to use the shader 00201 //overload if the shader requires special steps 00202 //to render 00203 }; 00204 00205 /********************************************************************** 00206 * GLSLLightingShader: 00207 * 00208 * Reproduces standard OpenGL lighting via GLSL shaders, in 00209 * conjunction with lighting.vp and lighting.fp shaders in 00210 * the jot/nprdata/glsl/ directory. 00211 **********************************************************************/ 00212 class GLSLLightingShader : public GLSLShader { 00213 public: 00214 //******** MANAGERS ******** 00215 GLSLLightingShader(Patch* patch = 0); 00216 00217 //******** RUN-TIME TYPE ID ******** 00218 DEFINE_RTTI_METHODS3("GLSL Lighting", 00219 GLSLLightingShader*, BasicTexture, CDATA_ITEM*); 00220 00221 //******** GLSLShader VIRTUAL METHODS ******** 00222 00223 // using a static variable for program, so all toon shader 00224 // instances share the same program: 00225 virtual GLuint& program() { return _program; } 00226 virtual bool& did_init() { return _did_init; } 00227 00228 //******** GTexture VIRTUAL METHODS ******** 00229 00230 // Draw the patch: 00231 virtual int draw(CVIEWptr& v); 00232 00233 //******** DATA_ITEM VIRTUAL METHODS ******** 00234 virtual DATA_ITEM *dup() const { return new GLSLLightingShader; } 00235 00236 private: 00237 00238 static GLuint _program; // shared by all GLSLLightingShader instances 00239 static bool _did_init; // tells whether initialization attempt was made 00240 00241 //******** VIRTUAL METHODS ******** 00242 00243 virtual str_ptr vp_filename() { return vp_name("lighting"); } 00244 virtual str_ptr fp_filename() { return fp_name("lighting"); } 00245 }; 00246 00247 #endif // GLSL_SHADER_H_IS_INCLUDED 00248 00249 // end of file glsl_shader.H