00001 /********************************************************************** 00002 * gtexture.H 00003 **********************************************************************/ 00004 #ifndef GTEXTURE_H_IS_INCLUDED 00005 #define GTEXTURE_H_IS_INCLUDED 00006 00007 #include "patch.H" 00008 #include "stripcb.H" 00009 00010 /********************************************************************** 00011 * GTexture: 00012 * 00013 * Base class for a procedural texture associated w/ a patch. 00014 * Simple examples include procedures that just implement Gouraud 00015 * shading or other conventional rendering styles. More inter- 00016 * esting examples include "Graftal textures," as described in: 00017 * 00018 * Michael A. Kowalski, Lee Markosian, J. D. Northrup, Lubomir 00019 * Bourdev, Ronen Barzel, Loring S. Holden and John 00020 * Hughes. Art-Based Rendering of Fur, Grass, and Trees, 00021 * Proceedings of SIGGRAPH 99, Computer Graphics Proceedings, 00022 * Annual Conference Series, pp. 433-438 (August 1999, Los 00023 * Angeles, California). Addison Wesley Longman. Edited by Alyn 00024 * Rockwood. ISBN 0-20148-560-5. 00025 **********************************************************************/ 00026 class GTexture : public DATA_ITEM, public BMESHdrawable { 00027 public: 00028 00029 //******** MANAGERS ******** 00030 00031 GTexture(Patch* p = 0, StripCB* cb=0); 00032 virtual ~GTexture() { delete _cb; } 00033 00034 //******** RUN-TIME TYPE ID ******** 00035 00036 DEFINE_RTTI_METHODS3("Textured patch", GTexture*, DATA_ITEM, CDATA_ITEM *); 00037 STAT_STR_RET type() const { return class_name(); } 00038 00039 //******** ACCESSORS ******** 00040 00041 Patch* patch() const { return _patch; } 00042 BMESH* mesh() const { return _patch ? _patch->mesh() : 0; } 00043 00044 StripCB* cb() const { return _cb; } 00045 void set_cb(StripCB* cb) { delete _cb; _cb = cb; } 00046 00047 GTexture* ctrl() const { return _ctrl; } 00048 void set_ctrl(GTexture* c) { _ctrl = c; } 00049 00050 //******** VIRTUAL METHODS ******** 00051 00052 virtual int set_color(CCOLOR&) { return 0; } 00053 virtual void changed() {} 00054 00055 // Optional list of GTextures owned by this GTexture. 00056 // E.g., HiddenLineTexture owns a SolidColorTexture and 00057 // a WireframeTexture that do all the actual work. 00058 virtual GTexture_list gtextures() const { return GTexture_list(); } 00059 00060 virtual void set_patch(Patch* p) { 00061 _patch = p; 00062 gtextures().set_patch(p); 00063 changed(); 00064 } 00065 00066 //******** FADING STUFF ******** 00067 // XXX - under construction -- documentation pending 00068 // 00069 // these methods relate to fading between GTextures when 00070 // switching: 00071 // 00072 // push_alpha() and pop_alpha() exist as an alternative to adding 00073 // an alpha parameter to the regular draw() method: 00074 virtual void push_alpha(double a) { 00075 _alphas += a; 00076 gtextures().push_alpha(a); 00077 } 00078 virtual void pop_alpha () { 00079 _alphas.pop(); 00080 gtextures().pop_alpha(); 00081 } 00082 double alpha() const { 00083 // include alpha from the patch, if any: 00084 double a = (_patch && _patch->has_transp()) ? _patch->transp() : 1.0; 00085 return a * (_alphas.empty() ? 1.0 : _alphas.last()); 00086 } 00087 00088 // The following is used for fading between GTextures when 00089 // switching. If the newly introduced GTexture knows the 00090 // outgoing one draws filled triangles of the Patch, then the 00091 // new one can draw first with alpha = 1, and the outgoing 00092 // GTexture can draw on top of it using an alpha corresponding 00093 // to how faded it is. If the outgoing GTexture doesn't draw 00094 // filled, the new one has to fade itself in. 00095 virtual bool draws_filled() const { return true; } 00096 00097 virtual void draw_with_alpha(double alpha) { 00098 push_alpha(alpha); 00099 draw(VIEW::peek()); 00100 pop_alpha(); 00101 } 00102 00103 // The next 2 methods are given default implementations for 00104 // convenience. They work for simple GTextures like smooth 00105 // shading or wireframe. Compound GTextures like hidden 00106 // line have to override these. I.e., if the implementation 00107 // of hidden line style draws solid colored triangles with 00108 // wireframe over them, then in draw_filled_tris() it 00109 // should just draw the solid colored part, and in 00110 // draw_non_filled_tris() it should draw just the wireframe 00111 // part. 00112 virtual void draw_filled_tris(double alpha) { 00113 if (draws_filled()) 00114 draw_with_alpha(alpha); 00115 } 00116 virtual void draw_non_filled_tris(double alpha) { 00117 if (!draws_filled()) 00118 draw_with_alpha(alpha); 00119 } 00120 00121 //******** I/O FUNCTIONS ******** 00122 00123 virtual int read_stream (istream &, str_list &) { return 1;} 00124 virtual int write_data (ostream &) const { return 0;}; 00125 virtual int write_stream(ostream &os) const { 00126 os << _begin_tag << class_name() << endl; 00127 write_data(os); 00128 os << _end_tag << endl; return 1; 00129 } 00130 00131 //******** DATA_ITEM VIRTUAL FUNCTIONS ******** 00132 00133 virtual DATA_ITEM *dup() const { return 0; } 00134 virtual CTAGlist &tags() const; 00135 00136 //******************************************************* 00137 // PROTECTED 00138 //******************************************************* 00139 protected: 00140 Patch* _patch; // patch that owns this 00141 StripCB* _cb; // used for rendering tri strips etc. 00142 00143 // for drawing the texture with a specified amount of 00144 // transparency thrown in: 00145 ARRAY<double> _alphas; 00146 00147 // optional (usually nil) "controlling" texture that this one 00148 // defers to: 00149 GTexture* _ctrl; 00150 00151 // for I/O: 00152 static Cstr_ptr _type_name; 00153 static Cstr_ptr _begin_tag; 00154 static Cstr_ptr _end_tag; 00155 }; 00156 00157 /***************************************************************** 00158 * GTexture_list 00159 * 00160 * Defined in patch.H, inlined convenience methods defined here. 00161 *****************************************************************/ 00162 00163 inline void 00164 GTexture_list::write_stream(ostream& os) const 00165 { 00166 for (int k=0; k<_num; k++) 00167 _array[k]->write_stream(os); 00168 } 00169 00170 inline void 00171 GTexture_list::delete_all() 00172 { 00173 while (!empty()) 00174 delete pop(); 00175 } 00176 00177 inline void 00178 GTexture_list::set_patch(Patch* p) const 00179 { 00180 for (int k=0; k<_num; k++) 00181 _array[k]->set_patch(p); 00182 } 00183 00184 inline void 00185 GTexture_list::push_alpha(double a) const 00186 { 00187 for (int k=0; k<_num; k++) 00188 _array[k]->push_alpha(a); 00189 } 00190 00191 inline void 00192 GTexture_list::pop_alpha() const 00193 { 00194 for (int k=0; k<_num; k++) 00195 _array[k]->pop_alpha(); 00196 } 00197 00198 // Given a Patch, return a particular type of texture (class G) 00199 // to render the Patch. Create the texture if needed: 00200 template <class G> 00201 inline G* 00202 get_tex(Patch* p) 00203 { 00204 return p ? G::upcast(p->get_tex(G::static_name())) : 0; 00205 } 00206 00207 #endif // GTEXTURE_H_IS_INCLUDED 00208 00209 // end of file gtexture.H