Warning, /include/Geant4/tools/sg/base_tex is written in an unsupported language. File is not indexed.
0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003
0004 #ifndef tools_sg_base_tex
0005 #define tools_sg_base_tex
0006
0007 #include "../platform"
0008 #include "../img"
0009 #include "../lina/line"
0010 #include "../lina/vec3f"
0011
0012 #include "sf_vec"
0013 #include "sf_img"
0014 #include "../colorfs"
0015
0016 namespace tools {
0017 namespace sg {
0018
0019 class base_tex {
0020 public:
0021 TOOLS_SCLASS(tools::sg::base_tex)
0022 public:
0023 virtual void* cast(const std::string& a_class) const {
0024 if(void* p = cmp_cast<base_tex>(this,a_class)) return p;
0025 return 0;
0026 }
0027 public:
0028 sf_img<byte> img;
0029 sf_vec<colorf,float> back_color;
0030 sf<bool> expand;
0031 sf<unsigned int> limit;
0032 sf<bool> nearest; //for glTexParameteri. See exlib/sg/GL_manager. default=true for astro images.
0033 public:
0034 enum intersect_type {
0035 intersect_down,
0036 intersect_move,
0037 intersect_up
0038 };
0039 virtual bool intersect_value(std::ostream&,intersect_type a_type,const line<vec3f>& a_line,std::string& a_s) const = 0;
0040 public:
0041 base_tex()
0042 :img(img_byte())
0043 ,back_color(colorf_white())
0044 ,expand(false)
0045 ,limit(device::tex_mem_limit()) //OpenGL-ES glTex limitation.
0046 ,nearest(true)
0047 ,m_img()
0048 {}
0049 virtual ~base_tex(){}
0050 public:
0051 base_tex(const base_tex& a_from)
0052 :img(a_from.img)
0053 ,back_color(a_from.back_color)
0054 ,expand(a_from.expand)
0055 ,limit(a_from.limit)
0056 ,nearest(a_from.nearest)
0057 ,m_img()
0058 {}
0059 base_tex& operator=(const base_tex& a_from){
0060 img = a_from.img;
0061 back_color = a_from.back_color;
0062 expand = a_from.expand;
0063 limit = a_from.limit;
0064 nearest = a_from.nearest;
0065 m_img.make_empty();
0066 return *this;
0067 }
0068 protected:
0069 void _update_sg_(std::ostream& a_out) {
0070 const img_byte& _img = img.value();
0071
0072 if(_img.is_empty()) {
0073 m_img.make_empty();
0074 return;
0075 }
0076
0077 unsigned int bpp = _img.bytes_per_pixel();
0078 if((bpp!=1)&&(bpp!=3)&&(bpp!=4)) {
0079 a_out << "tools::sg::tex_rect::update_sg :"
0080 << " bpp " << bpp << " not handled."
0081 << std::endl;
0082 m_img.make_empty();
0083 return;
0084 }
0085
0086 // image must be power of two in width and height.
0087
0088 const colorf& bc = back_color.value();
0089
0090 byte pixel[4];
0091 pixel[0] = bc.ruchar();
0092 pixel[1] = bc.guchar();
0093 pixel[2] = bc.buchar();
0094 pixel[3] = bc.auchar();
0095
0096 if((back_color.value().a()!=1)&&(bpp!=4)) {
0097 //transparent background.
0098
0099 //NOTE : the node must be rendered after the "behind nodes" so that
0100 // transparency be taken into account for the "behind nodes".
0101
0102 img_byte img4;
0103 if(!_img.rgb2rgba(img4,255)){
0104 a_out << "tools::sg::tex_rect::update_sg :"
0105 << " rgb2rgba failed."
0106 << std::endl;
0107 m_img.make_empty();
0108 return;
0109 }
0110
0111 if(!img4.to_texture(expand.value(),pixel,m_img)){
0112 a_out << "tools::sg::tex_rect::update_sg :"
0113 << " problem with tools::tex_rect::to_texture."
0114 << std::endl;
0115 m_img.make_empty();
0116 return;
0117 }
0118
0119 } else {
0120 if(!_img.to_texture(expand.value(),pixel,m_img)){
0121 a_out << "tools::sg::tex_rect::update_sg :"
0122 << " problem with tools::tex_rect::to_texture."
0123 << std::endl;
0124 m_img.make_empty();
0125 return;
0126 }
0127 }
0128
0129 if(limit.value()) {
0130 unsigned int tw = m_img.width();
0131 unsigned int th = m_img.height();
0132 if((tw*th*m_img.bytes_per_pixel())>limit.value()) {
0133 unsigned int fac = 2;
0134 while(true) {
0135 unsigned int pw = tw/fac;
0136 unsigned int ph = th/fac;
0137 if((pw*ph)<limit.value()) {
0138 unsigned int sx = (tw-pw)/2;
0139 unsigned int sy = (th-ph)/2;
0140
0141 img_byte part;
0142 if(!m_img.get_part(sx,sy,pw,ph,part)) {
0143 m_img.make_empty();
0144 return;
0145 }
0146 m_img = part;
0147 break;
0148 }
0149 fac *= 2;
0150 }
0151 }
0152 }
0153
0154 }
0155
0156 static void dump(std::ostream& a_out,const std::string& a_cmt,const img_byte& a_img) {
0157 if(a_cmt.size()) a_out << a_cmt << std::endl;
0158 a_out << " width " << a_img.width()
0159 << " height " << a_img.height()
0160 << " bpp " << a_img.bytes_per_pixel()
0161 << std::endl;
0162 }
0163
0164 static void dump_not_null(std::ostream& a_out,const std::string& a_cmt,const img_byte& a_img) {
0165 if(a_cmt.size()) a_out << a_cmt << std::endl;
0166 unsigned int w = a_img.width();
0167 unsigned int h = a_img.height();
0168 unsigned int n = a_img.bytes_per_pixel();
0169 a_out << "img_byte : width " << w << " height " << h << " bpp " << n << std::endl;
0170 byte* pos = (byte*)a_img.buffer();
0171 if(n==3) {
0172 byte r,g,b;
0173 for(unsigned int j=0;j<h;j++) {
0174 for(unsigned int i=0;i<w;i++) {
0175 r = *pos;pos++;
0176 g = *pos;pos++;
0177 b = *pos;pos++;
0178 if(r||g||b)
0179 a_out << " " << i << " " << j
0180 << " : " << (unsigned int)r << " " << (unsigned int)g << " " << (unsigned int)b
0181 << std::endl;
0182 }
0183 }
0184 }
0185 }
0186
0187 void set_tcs(float a_tcs[8]) {
0188 const img_byte& _img = img.value();
0189
0190 a_tcs[0] = 0;a_tcs[1] = 0;
0191 a_tcs[2] = 1;a_tcs[3] = 0;
0192 a_tcs[4] = 1;a_tcs[5] = 1;
0193 a_tcs[6] = 0;a_tcs[7] = 1;
0194
0195 float ax = 1;
0196 float bx = 0;
0197 float ay = 1;
0198 float by = 0;
0199 {unsigned int iw = _img.width();
0200 unsigned int ih = _img.height();
0201 unsigned int rw = m_img.width();
0202 unsigned int rh = m_img.height();
0203 if(rw>iw) {
0204 float part = float(iw)/float(rw);
0205 ax = part;
0206 bx = 0.5f*(1-part);
0207 }
0208 if(rh>ih) {
0209 float part = float(ih)/float(rh);
0210 ay = part;
0211 by = 0.5f*(1-part);
0212 }}
0213
0214 {unsigned int num = 12/3;
0215 for(unsigned int index=0;index<num;index++) {
0216 a_tcs[2*index] = ax*a_tcs[2*index] +bx;
0217 a_tcs[2*index+1] = ay*a_tcs[2*index+1]+by;
0218 }}
0219
0220 }
0221 protected:
0222 img_byte m_img;
0223 };
0224
0225 }}
0226
0227 #endif