Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights reserved. 2 // See the file tools.license for terms. 3 4 #ifndef tools_sg_base_tex 5 #define tools_sg_base_tex 6 7 #include "../platform" 8 #include "../img" 9 #include "../lina/line" 10 #include "../lina/vec3f" 11 12 #include "sf_vec" 13 #include "sf_img" 14 #include "../colorfs" 15 16 namespace tools { 17 namespace sg { 18 19 class base_tex { 20 public: 21 TOOLS_SCLASS(tools::sg::base_tex) 22 public: 23 virtual void* cast(const std::string& a_class) const { 24 if(void* p = cmp_cast<base_tex>(this,a_class)) return p; 25 return 0; 26 } 27 public: 28 sf_img<byte> img; 29 sf_vec<colorf,float> back_color; 30 sf<bool> expand; 31 sf<unsigned int> limit; 32 sf<bool> nearest; //for glTexParameteri. See exlib/sg/GL_manager. default=true for astro images. 33 public: 34 enum intersect_type { 35 intersect_down, 36 intersect_move, 37 intersect_up 38 }; 39 virtual bool intersect_value(std::ostream&,intersect_type a_type,const line<vec3f>& a_line,std::string& a_s) const = 0; 40 public: 41 base_tex() 42 :img(img_byte()) 43 ,back_color(colorf_white()) 44 ,expand(false) 45 ,limit(device::tex_mem_limit()) //OpenGL-ES glTex limitation. 46 ,nearest(true) 47 ,m_img() 48 {} 49 virtual ~base_tex(){} 50 public: 51 base_tex(const base_tex& a_from) 52 :img(a_from.img) 53 ,back_color(a_from.back_color) 54 ,expand(a_from.expand) 55 ,limit(a_from.limit) 56 ,nearest(a_from.nearest) 57 ,m_img() 58 {} 59 base_tex& operator=(const base_tex& a_from){ 60 img = a_from.img; 61 back_color = a_from.back_color; 62 expand = a_from.expand; 63 limit = a_from.limit; 64 nearest = a_from.nearest; 65 m_img.make_empty(); 66 return *this; 67 } 68 protected: 69 void _update_sg_(std::ostream& a_out) { 70 //clean_texs(); //must reset for all render_manager. 71 72 const img_byte& _img = img.value(); 73 74 //::printf("debug : base_tex::_update_sg : size = %d, w = %d, h = %d, bpp %d\n", 75 // _img.size(),_img.width(),_img.height(),_img.bpp()); 76 77 78 if(_img.is_empty()) { 79 m_img.make_empty(); 80 return; 81 } 82 83 unsigned int bpp = _img.bpp(); 84 if((bpp!=1)&&(bpp!=3)&&(bpp!=4)) { 85 a_out << "tools::sg::tex_rect::update_sg :" 86 << " bpp " << bpp << " not handled." 87 << std::endl; 88 m_img.make_empty(); 89 return; 90 } 91 92 //a_out << "debug : tools::sg::tex_rect::update_sg :" 93 // << " this " << tools::p2s(this) 94 // << std::endl; 95 96 // image must be power of two in width and height. 97 98 const colorf& bc = back_color.value(); 99 //::printf("debug : back_color %g %g %g %g\n",bc.r(),bc.g(),bc.b(),bc.a()); 100 101 byte pixel[4]; 102 pixel[0] = bc.ruchar(); 103 pixel[1] = bc.guchar(); 104 pixel[2] = bc.buchar(); 105 pixel[3] = bc.auchar(); 106 107 //dump(a_out,"debug : 0000 :",_img); 108 109 if((back_color.value().a()!=1)&&(bpp!=4)) { 110 //transparent background. 111 112 //NOTE : the node must be rendered after the "behind nodes" so that 113 // transparency be taken into account for the "behind nodes". 114 115 img_byte img4; 116 if(!_img.rgb2rgba(img4,255)){ 117 a_out << "tools::sg::tex_rect::update_sg :" 118 << " rgb2rgba failed." 119 << std::endl; 120 m_img.make_empty(); 121 return; 122 } 123 124 if(!img4.to_texture(expand.value(),pixel,m_img)){ 125 a_out << "tools::sg::tex_rect::update_sg :" 126 << " problem with tools::tex_rect::to_texture." 127 << std::endl; 128 m_img.make_empty(); 129 return; 130 } 131 132 } else { 133 if(!_img.to_texture(expand.value(),pixel,m_img)){ 134 a_out << "tools::sg::tex_rect::update_sg :" 135 << " problem with tools::tex_rect::to_texture." 136 << std::endl; 137 m_img.make_empty(); 138 return; 139 } 140 } 141 142 //a_out << "debug : limit : 000 : " << limit.value() << std::endl; 143 if(limit.value()) { 144 unsigned int tw = m_img.width(); 145 unsigned int th = m_img.height(); 146 if((tw*th*m_img.bpp())>limit.value()) { 147 //a_out << "debug : trunc " << (tw*th) << std::endl; 148 unsigned int fac = 2; 149 while(true) { 150 unsigned int pw = tw/fac; 151 unsigned int ph = th/fac; 152 if((pw*ph)<limit.value()) { 153 unsigned int sx = (tw-pw)/2; 154 unsigned int sy = (th-ph)/2; 155 156 img_byte part; 157 if(!m_img.get_part(sx,sy,pw,ph,part)) { 158 m_img.make_empty(); 159 return; 160 } 161 //a_out << "debug : base_tex : img.get_part due to limit (" << limit.value() << ")." << std::endl; 162 m_img = part; 163 break; 164 } 165 fac *= 2; 166 } 167 } 168 } 169 //dump_not_null(a_out,"debug : base_tex::_update_sg_ :",m_img); 170 171 } 172 173 static void dump(std::ostream& a_out,const std::string& a_cmt,const img_byte& a_img) { 174 if(a_cmt.size()) a_out << a_cmt << std::endl; 175 a_out << " width " << a_img.width() 176 << " height " << a_img.height() 177 << " bpp " << a_img.bpp() 178 << std::endl; 179 } 180 181 static void dump_not_null(std::ostream& a_out,const std::string& a_cmt,const img_byte& a_img) { 182 if(a_cmt.size()) a_out << a_cmt << std::endl; 183 unsigned int w = a_img.width(); 184 unsigned int h = a_img.height(); 185 unsigned int n = a_img.bpp(); 186 a_out << "img_byte : width " << w << " height " << h << " bpp " << n << std::endl; 187 byte* pos = (byte*)a_img.buffer(); 188 if(n==3) { 189 byte r,g,b; 190 for(unsigned int j=0;j<h;j++) { 191 for(unsigned int i=0;i<w;i++) { 192 r = *pos;pos++; 193 g = *pos;pos++; 194 b = *pos;pos++; 195 if(r||g||b) 196 a_out << " " << i << " " << j 197 << " : " << (unsigned int)r << " " << (unsigned int)g << " " << (unsigned int)b 198 << std::endl; 199 } 200 } 201 } 202 } 203 204 void set_tcs(float a_tcs[8]) { 205 const img_byte& _img = img.value(); 206 207 a_tcs[0] = 0;a_tcs[1] = 0; 208 a_tcs[2] = 1;a_tcs[3] = 0; 209 a_tcs[4] = 1;a_tcs[5] = 1; 210 a_tcs[6] = 0;a_tcs[7] = 1; 211 212 float ax = 1; 213 float bx = 0; 214 float ay = 1; 215 float by = 0; 216 {unsigned int iw = _img.width(); 217 unsigned int ih = _img.height(); 218 unsigned int rw = m_img.width(); 219 unsigned int rh = m_img.height(); 220 if(rw>iw) { 221 float part = float(iw)/float(rw); 222 ax = part; 223 bx = 0.5f*(1-part); 224 } 225 if(rh>ih) { 226 float part = float(ih)/float(rh); 227 ay = part; 228 by = 0.5f*(1-part); 229 }} 230 231 {unsigned int num = 12/3; 232 for(unsigned int index=0;index<num;index++) { 233 a_tcs[2*index] = ax*a_tcs[2*index] +bx; 234 a_tcs[2*index+1] = ay*a_tcs[2*index+1]+by; 235 }} 236 237 } 238 protected: 239 img_byte m_img; 240 }; 241 242 }} 243 244 #endif