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