00001 /********************************************************************** 00002 * ref_img_client.H 00003 **********************************************************************/ 00004 #ifndef REF_IMG_CLIENT_IS_INCLUDED 00005 #define REF_IMG_CLIENT_IS_INCLUDED 00006 00007 #include "net/data_item.H" 00008 00009 #define CVIEWptr const VIEWptr 00010 class VIEWptr; 00011 00012 /***************************************************************** 00013 * RefImageClient: 00014 * 00015 * An abstract base class that can make approprite drawing 00016 * calls for creating various types of reference images. 00017 * 00018 * (A reference image is an image read from the frame buffer 00019 * into main memory so that it can be used by the program for 00020 * some purpose.) 00021 *****************************************************************/ 00022 class RefImageClient { 00023 public: 00024 //******** ENUMS ******** 00025 enum ref_img_t { 00026 REF_IMG_NONE = 0, // Should be 00027 REF_IMG_ID = 1, // powers of 2 00028 REF_IMG_COLOR = 2, // (after the first one) 00029 REF_IMG_COLOR_2 = 4, 00030 00031 REF_IMG_ID_PRE1 = 8, // Not really distinct images. 00032 REF_IMG_ID_PRE2 = 16, // These are just additional 00033 REF_IMG_ID_PRE3 = 32, // pre-passes of REF_IMG_ID. 00034 REF_IMG_ID_PRE4 = 64, // No image should claim to be 00035 // of these types. 00036 REF_IMG_TEX_MEM = 128 00037 }; 00038 00039 //******** MANAGERS ******** 00040 RefImageClient() {} 00041 virtual ~RefImageClient() {} 00042 00043 //******** RUN-TIME TYPE ID ******** 00044 static STAT_STR_RET static_name() { RET_STAT_STR("RefImageClient"); } 00045 00046 //******** DRAWING ******** 00047 00048 virtual int draw(CVIEWptr&) = 0; 00049 00050 virtual int draw_id_ref() { return 0; } 00051 virtual int draw_id_ref_pre1() { return 0; } 00052 virtual int draw_id_ref_pre2() { return 0; } 00053 virtual int draw_id_ref_pre3() { return 0; } 00054 virtual int draw_id_ref_pre4() { return 0; } 00055 virtual int draw_color_ref() { return 0; } 00056 virtual int draw_color_ref_2() { return 0; } 00057 virtual int draw_tex_mem_ref() { return draw_color_ref(); } 00058 00059 // Answers the question: what ref images does this client need? 00060 virtual ref_img_t use_ref_image() { return REF_IMG_NONE; } 00061 00062 // The visibility reference image is used for O(1) picking 00063 // (not counting the cost of preparing the image). Only invisible 00064 // objects should do nothing for this call ... other objects that 00065 // can't or won't do picking via the visibility reference image 00066 // should draw in solid black to cover up any objects occluded by 00067 // them: 00068 virtual int draw_vis_ref() { return 0; } 00069 00070 // The ID reference image is a lot like the visibility reference 00071 // image, except for how it is used: to aid in some cases in 00072 // supporting sophisticated rendering. Thus the question of how to 00073 // draw it may depend on whether and how it will be used. Even if 00074 // it won't be used by this RefImageClient we should still draw 00075 // black (unless we're invisible), as explained above. A reasonable 00076 // default implementation is thus to draw the same way as for the 00077 // visibility reference image (e.g., invisible or solid black). 00078 // Other reference images are wholly optional: 00079 /*virtual int draw_ref_img(ref_img_t t) { 00080 return (t == REF_IMG_ID) ? draw_vis_ref() : 0; 00081 }*/ 00082 virtual int draw_ref_img(ref_img_t t) { 00083 switch (t) { 00084 case REF_IMG_ID: return draw_id_ref(); 00085 brcase REF_IMG_ID_PRE1: return draw_id_ref_pre1(); 00086 brcase REF_IMG_ID_PRE2: return draw_id_ref_pre2(); 00087 brcase REF_IMG_ID_PRE3: return draw_id_ref_pre3(); 00088 brcase REF_IMG_ID_PRE4: return draw_id_ref_pre4(); 00089 brcase REF_IMG_COLOR: return draw_color_ref(); 00090 brcase REF_IMG_COLOR_2: return draw_color_ref_2(); 00091 brcase REF_IMG_TEX_MEM: return draw_tex_mem_ref(); 00092 brdefault: return 0; 00093 } 00094 return 0; 00095 } 00096 00097 // Final pass rendering call, ignored by most, can be used to 00098 // draw strokes after visibility determination has been made: 00099 // (The return value doesn't mean anything.) 00100 virtual int draw_final(CVIEWptr &) { return 0; } 00101 }; 00102 typedef const RefImageClient CRefImageClient; 00103 00104 /***************************************************************** 00105 * RefImageClient_array: 00106 * 00107 * An ARRAY of RefImageClients with convenience methods 00108 * for passing calls to all the items in the array. 00109 * 00110 * We start with a generic templated ARRAY class RIC_array 00111 * (and a parallel LIST class RIC_list) to allow arrays to 00112 * be built for types DERIVED FROM RefImageClients. 00113 * 00114 * E.g., if 'Bcurve' is a class derived from RefImageClient, 00115 * we might like to have a Bcurve_array with these same 00116 * convenience methods, but still be able to work with 00117 * actual Bcurve* pointers. We could do so using: 00118 * 00119 * typedef RIC_array<Bcurve> Bcurve_array; 00120 * 00121 * If we wanted additional convenience methods specific to 00122 * Bcurves, we would define the Bcurve_array type through 00123 * subclassing. 00124 *****************************************************************/ 00125 template <class T> 00126 class RIC_array : public ARRAY<T*> { 00127 public: 00128 00129 //******** MANAGERS ******** 00130 00131 RIC_array(int n=0) : ARRAY<T*>(n) {} 00132 RIC_array(const ARRAY<T*>& l) : ARRAY<T*>(l) {} 00133 00134 //******** CONVENIENCE ******** 00135 00136 int draw(CVIEWptr& v) const { 00137 int ret = 0; 00138 for (int i=0; i<num(); i++) 00139 ret += (*this)[i]->draw(v); 00140 return ret; 00141 } 00142 int draw_vis_ref() const { 00143 int ret = 0; 00144 for (int i=0; i<num(); i++) 00145 ret += (*this)[i]->draw_vis_ref(); 00146 return ret; 00147 } 00148 int draw_id_ref() const { 00149 int ret = 0; 00150 for (int i=0; i<num(); i++) 00151 ret += (*this)[i]->draw_id_ref(); 00152 return ret; 00153 } 00154 int draw_id_ref_pre1() const { 00155 int ret = 0; 00156 for (int i=0; i<num(); i++) 00157 ret += (*this)[i]->draw_id_ref_pre1(); 00158 return ret; 00159 } 00160 int draw_id_ref_pre2() const { 00161 int ret = 0; 00162 for (int i=0; i<num(); i++) 00163 ret += (*this)[i]->draw_id_ref_pre2(); 00164 return ret; 00165 } 00166 int draw_id_ref_pre3() const { 00167 int ret = 0; 00168 for (int i=0; i<num(); i++) 00169 ret += (*this)[i]->draw_id_ref_pre3(); 00170 return ret; 00171 } 00172 int draw_id_ref_pre4() const { 00173 int ret = 0; 00174 for (int i=0; i<num(); i++) 00175 ret += (*this)[i]->draw_id_ref_pre4(); 00176 return ret; 00177 } 00178 00179 00180 int draw_color_ref() const { 00181 int ret = 0; 00182 for (int i=0; i<num(); i++) 00183 ret += (*this)[i]->draw_color_ref(); 00184 return ret; 00185 } 00186 int draw_color_ref_2() const { 00187 int ret = 0; 00188 for (int i=0; i<num(); i++) 00189 ret += (*this)[i]->draw_color_ref_2(); 00190 return ret; 00191 } 00192 int draw_tex_mem_ref() const { 00193 int ret = 0; 00194 for (int i=0; i<num(); i++) 00195 ret += (*this)[i]->draw_tex_mem_ref(); 00196 return ret; 00197 } 00198 int draw_ref_img(RefImageClient::ref_img_t t) const { 00199 int ret = 0; 00200 for (int i=0; i<num(); i++) 00201 ret += (*this)[i]->draw_ref_img(t); 00202 return ret; 00203 } 00204 int draw_final(CVIEWptr &v) const { 00205 int ret = 0; 00206 for (int i=0; i<num(); i++) 00207 ret += (*this)[i]->draw_final(v); 00208 return ret; 00209 } 00210 RefImageClient::ref_img_t use_ref_image() const { 00211 int ret = RefImageClient::REF_IMG_NONE; 00212 for (int i=0; i<num(); i++) 00213 ret |= (*this)[i]->use_ref_image(); 00214 return (RefImageClient::ref_img_t) ret; 00215 } 00216 00217 using ARRAY<T*>::num; 00218 }; 00219 00220 // Now we do it all over for LIST 00221 // XXX - How could we avoid this copied code? 00222 template <class T> 00223 class RIC_list : public LIST<T> { 00224 public: 00225 00226 //******** MANAGERS ******** 00227 00228 RIC_list(int n=0) : LIST<T>(n) {} 00229 RIC_list(const LIST<T>& l) : LIST<T>(l) {} 00230 00231 //******** CONVENIENCE ******** 00232 int draw(CVIEWptr& v) const { 00233 int ret = 0; 00234 for (int i=0; i<num(); i++) 00235 ret += (*this)[i]->draw(v); 00236 return ret; 00237 } 00238 int draw_vis_ref() const { 00239 int ret = 0; 00240 for (int i=0; i<num(); i++) 00241 ret += (*this)[i]->draw_vis_ref(); 00242 return ret; 00243 } 00244 int draw_id_ref() const { 00245 int ret = 0; 00246 for (int i=0; i<num(); i++) 00247 ret += (*this)[i]->draw_id_ref(); 00248 return ret; 00249 } 00250 00251 int draw_id_ref_pre1() const { 00252 int ret = 0; 00253 for (int i=0; i<num(); i++) 00254 ret += (*this)[i]->draw_id_ref_pre1(); 00255 return ret; 00256 } 00257 int draw_id_ref_pre2() const { 00258 int ret = 0; 00259 for (int i=0; i<num(); i++) 00260 ret += (*this)[i]->draw_id_ref_pre2(); 00261 return ret; 00262 } 00263 int draw_id_ref_pre3() const { 00264 int ret = 0; 00265 for (int i=0; i<num(); i++) 00266 ret += (*this)[i]->draw_id_ref_pre3(); 00267 return ret; 00268 } 00269 int draw_id_ref_pre4() const { 00270 int ret = 0; 00271 for (int i=0; i<num(); i++) 00272 ret += (*this)[i]->draw_id_ref_pre4(); 00273 return ret; 00274 } 00275 00276 int draw_color_ref() const { 00277 int ret = 0; 00278 for (int i=0; i<num(); i++) 00279 ret += (*this)[i]->draw_color_ref(); 00280 return ret; 00281 } 00282 int draw_color_ref_2() const { 00283 int ret = 0; 00284 for (int i=0; i<num(); i++) 00285 ret += (*this)[i]->draw_color_ref_2(); 00286 return ret; 00287 } 00288 int draw_tex_mem_ref() const { 00289 int ret = 0; 00290 for (int i=0; i<num(); i++) 00291 ret += (*this)[i]->draw_tex_mem_ref(); 00292 return ret; 00293 } 00294 int draw_final(CVIEWptr &v) const { 00295 int ret = 0; 00296 for (int i=0; i<num(); i++) 00297 ret += (*this)[i]->draw_final(v); 00298 return ret; 00299 } 00300 int draw_ref_img(RefImageClient::ref_img_t t) const { 00301 int ret = 0; 00302 for (int i=0; i<num(); i++) 00303 ret += (*this)[i]->draw_ref_img(t); 00304 return ret; 00305 } 00306 RefImageClient::ref_img_t use_ref_image() const { 00307 int ret = RefImageClient::REF_IMG_NONE; 00308 for (int i=0; i<num(); i++) 00309 ret |= (*this)[i]->use_ref_image(); 00310 return (RefImageClient::ref_img_t) ret; 00311 } 00312 00313 using LIST<T>::num; 00314 }; 00315 00316 // Here we define a form of the array based on 00317 // RefImageClient pointers: 00318 typedef RIC_array<RefImageClient> RefImageClient_array; 00319 00320 #endif // REF_IMG_CLIENT_IS_INCLUDED 00321 00322 /* end of file ref_img_client.H */ 00323