g4tools  5.4.0
tex_rect
Go to the documentation of this file.
1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
2 // See the file tools.license for terms.
3 
4 #ifndef tools_sg_tex_rect
5 #define tools_sg_tex_rect
6 
7 // node to render an RGB tools::img_byte with ::glTexImage2D.
8 
9 //#define TOOLS_SG_TEX_RECT_DEBUG
10 
11 #include "node"
12 #include "render_action"
13 #include "pick_action"
14 #include "bbox_action"
15 #include "event_action"
16 #include "render_manager"
17 #include "gstos"
18 #include "base_tex"
19 
20 #include "../pointer"
21 #include "../num2s"
22 
23 namespace tools {
24 namespace sg {
25 
26 class tex_rect : public node, public gstos, public base_tex {
28 public:
29  virtual void* cast(const std::string& a_class) const {
30  {if(void* p = cmp_cast<tex_rect>(this,a_class)) return p;}
31  {if(void* p = base_tex::cast(a_class)) return p;}
32  return parent::cast(a_class);
33  }
34 public:
37 public:
38  virtual const desc_fields& node_desc_fields() const {
40  static const desc_fields s_v(parent::node_desc_fields(),6, //WARNING : take care of count.
47  );
48  return s_v;
49  }
50 private:
51  void add_fields(){
52  add_field(&img);
54  add_field(&expand);
55  add_field(&limit);
57  add_field(&height);
58  }
59 public:
60  virtual void render(render_action& a_action) {
61 #ifdef TOOLS_SG_TEX_RECT_DEBUG
62  a_action.out() << "tools::tex_rect::render : begin : 001 : " << std::endl;
63 #endif
64 
65  //NOTE : we draw border (show_border is true) and background even if
66  // gen_texture() failed.
67 
68  if(touched()) {
69 #ifdef TOOLS_SG_TEX_RECT_DEBUG
70  a_action.out() << "tools::tex_rect::render : touched." << std::endl;
71 #endif
72  update_sg(a_action.out());
73  reset_touched();
74  }
75  if(m_img.is_empty()) {
76 #ifdef TOOLS_SG_TEX_RECT_DEBUG
77  a_action.out() << "tools::tex_rect::render : m_img is empty." << std::endl;
78 #endif
79  return;
80  }
81 
82 #ifdef TOOLS_SG_TEX_RECT_DEBUG
83  a_action.out() << "tools::tex_rect::render : have a m_img. get_tex_id ..." << std::endl;
84 #endif
85 
86  unsigned int _id = get_tex_id(a_action.out(),a_action.render_manager(),m_img,nearest.value());
87 
88 #ifdef TOOLS_SG_TEX_RECT_DEBUG
89  a_action.out() << "tools::tex_rect::render : get_tex_id : " << _id << "." << std::endl;
90 #endif
91 
92  const state& state = a_action.state();
93 
94  //image must be 2^n,2^m in size !
95  // exa : 128x64
96 
97  f12 xyzs;
98 
99  if(show_border.value()) {
100 #ifdef TOOLS_SG_TEX_RECT_DEBUG
101  a_action.out() << "tools::tex_rect::render : show_border." << std::endl;
102 #endif
103  f12 nms;
104  _front(xyzs,nms,0.01f);
105 
106  a_action.color4f(1,0,0,1);
107  a_action.line_width(4);
108 
109  a_action.draw_vertex_array(gl::line_loop(),12,xyzs);
110 
111  //pushes back the filled polygons to avoid z-fighting with lines
112  a_action.set_polygon_offset(true);
113 
114  a_action.color4f(state.m_color);
115  a_action.line_width(state.m_line_width);
116  }
117 
118 #ifdef TOOLS_SG_TEX_RECT_DEBUG
119  a_action.out() << "tools::tex_rect::render : draw back face." << std::endl;
120 #endif
121 
122  //draw a back face pointing toward negative z :
123  {a_action.color4f(back_color.value());
124  f18 tris,nms;
125  _tris(tris,nms);
126  a_action.draw_vertex_normal_array(gl::triangles(),18,tris,nms);
127  a_action.color4f(state.m_color);}
128 
129  if(_id) {
130 #ifdef TOOLS_SG_TEX_RECT_DEBUG
131  a_action.out() << "tools::tex_rect::render : draw_vertex_normal_array_texture." << std::endl;
132 #endif
133  f12 nms;
134  _front(xyzs,nms);
135  float tcs[8];
136  set_tcs(tcs);
137  a_action.draw_vertex_normal_array_texture(gl::triangle_fan(),12,xyzs,nms,_id,tcs);
138  }
140  }
141  virtual void pick(pick_action& a_action) {
142  if(touched()) {
143  update_sg(a_action.out());
144  reset_touched();
145  }
146  if(m_img.is_empty()) return;
147  f12 xyzs,nms;
148  _front(xyzs,nms);
149  a_action.add__primitive(*this,gl::triangle_fan(),12,xyzs,true);
150  }
151 
152  virtual void bbox(bbox_action& a_action) {
153  if(touched()) {
154  update_sg(a_action.out());
155  reset_touched();
156  }
157  if(m_img.is_empty()) return;
158  f12 xyzs,nms;
159  _front(xyzs,nms);
160  a_action.add_points(12,xyzs);
161  }
162 public:
163  virtual bool intersect_value(std::ostream&,intersect_type,const line<vec3f>& a_line,std::string& a_s) const {
164  // a_line is in local world coordinate.
165 
166  const img_byte& _img = img.value();
167  if(_img.is_empty()) {a_s.clear();return false;}
168 
169  float aspect = float(_img.width())/float(_img.height());
170  float h2 = height.value()*0.5f;
171  float w2 = aspect*h2;
172 
173  plane<vec3f> plane(vec3f(w2,h2,0),vec3f(-w2,h2,0),vec3f(-w2,-h2,0));
174  vec3f p;
175  if(!plane.intersect(a_line,p)) {a_s.clear();return false;}
176 
177  float imw = (float)_img.width();
178  float imh = (float)_img.height();
179 
180  //image coordinates :
181  int ix = int((imw*p.x()/w2+imw)*0.5f);
182  int iy = int((imh*p.y()/h2+imh)*0.5f);
183 
184  //rgb of pixel :
185  std::vector<unsigned char> pixel;
186  if((ix<0)||(iy<0)||!_img.pixel(ix,iy,pixel)) {a_s.clear();return false;}
187 
188  a_s.clear();
189  for(unsigned int ipix=0;ipix<pixel.size();ipix++) {
190  if(ipix) a_s += " ";
191  if(!numas<float>(float(pixel[ipix])/255.0f,a_s)){}
192  }
193 
194  return true;
195  }
196 public:
198  :parent()
199  ,base_tex()
200  ,show_border(false)
201  ,height(1)
202  {
203  add_fields();
204  }
205  virtual ~tex_rect(){}
206 public:
207  tex_rect(const tex_rect& a_from)
208  :parent(a_from)
209  ,gstos(a_from)
210  ,base_tex(a_from)
211  ,show_border(a_from.show_border)
212  ,height(a_from.height)
213  {
214  add_fields();
215  }
216  tex_rect& operator=(const tex_rect& a_from){
217  parent::operator=(a_from);
218  gstos::operator=(a_from);
219  base_tex::operator=(a_from);
220  if(&a_from==this) return *this;
221  show_border = a_from.show_border;
222  height = a_from.height;
223  return *this;
224  }
225 public:
226 
227  //const img_byte& rendered_img() const {return m_img;}
228 
229  void rendered_size(std::ostream& a_out,unsigned int& a_w,unsigned int& a_h) {
230  update_sg(a_out);
231  reset_touched();
232  a_w = m_img.width();
233  a_h = m_img.height();
234  }
235 
236 protected:
237  //virtual //NOTE : virtual for diaporama node. (but warning with clang -g4flags).
238  void update_sg(std::ostream& a_out) {
239  clean_gstos(); //must reset for all render_manager.
240  if(height.value()<=0) {
241  m_img.make_empty();
242  return;
243  }
244  base_tex::_update_sg_(a_out);
245  }
246 protected:
247 
248  typedef float f12[12];
249  void _front(f12& front,f12& nms,float a_epsil = 0.0f) { //[12]
250  float aspect = float(img.value().width())/float(img.value().height());
251  float h2 = height*0.5f;
252  float w2 = aspect*h2;
253 
254  h2 += a_epsil;
255  w2 += a_epsil;
256 
257  front[0] = -w2;
258  front[1] = -h2;
259  front[2] = 0;
260 
261  front[3] = w2;
262  front[4] = -h2;
263  front[5] = 0;
264 
265  front[6] = w2;
266  front[7] = h2;
267  front[8] = 0;
268 
269  front[ 9] = -w2;
270  front[10] = h2;
271  front[11] = 0;
272 
273  nms[0] = 0;
274  nms[1] = 0;
275  nms[2] = 1;
276 
277  nms[3] = 0;
278  nms[4] = 0;
279  nms[5] = 1;
280 
281  nms[6] = 0;
282  nms[7] = 0;
283  nms[8] = 1;
284 
285  nms[9] = 0;
286  nms[10] = 0;
287  nms[11] = 1;
288  }
289 
290  void _back(f12& back) { //[12]
291  float aspect = float(img.value().width())/float(img.value().height());
292  float h2 = height*0.5f;
293  float w2 = aspect*h2;
294  float d2 = 0;
295 
296  back[0] = w2;back[ 1] = -h2;back[ 2] = d2;
297  back[3] = -w2;back[ 4] = -h2;back[ 5] = d2;
298  back[6] = -w2;back[ 7] = h2;back[ 8] = d2;
299  back[9] = w2;back[10] = h2;back[11] = d2;
300  }
301 
302  typedef float f18[18];
303  void _tris(f18& tris,f18& nms){
304  f12 back;
305  _back(back);
306 
307  tris[0] = back[0];
308  tris[1] = back[1];
309  tris[2] = back[2];
310 
311  tris[3] = back[3];
312  tris[4] = back[4];
313  tris[5] = back[5];
314 
315  tris[6] = back[6];
316  tris[7] = back[7];
317  tris[8] = back[8];
318  //
319  tris[9] = back[6];
320  tris[10] = back[7];
321  tris[11] = back[8];
322 
323  tris[12] = back[9];
324  tris[13] = back[10];
325  tris[14] = back[11];
326 
327  tris[15] = back[0];
328  tris[16] = back[1];
329  tris[17] = back[2];
330 
332  nms[0] = 0;
333  nms[1] = 0;
334  nms[2] = -1;
335 
336  nms[3] = 0;
337  nms[4] = 0;
338  nms[5] = -1;
339 
340  nms[6] = 0;
341  nms[7] = 0;
342  nms[8] = -1;
343  //
344  nms[9] = 0;
345  nms[10] = 0;
346  nms[11] = -1;
347 
348  nms[12] = 0;
349  nms[13] = 0;
350  nms[14] = -1;
351 
352  nms[15] = 0;
353  nms[16] = 0;
354  nms[17] = -1;
355  }
356 };
357 
358 }}
359 
360 #endif
base_tex
tools::sg::gstos
Definition: gstos:16
node
tools::sg::base_tex::_update_sg_
void _update_sg_(std::ostream &a_out)
Definition: base_tex:69
tools::sg::tex_rect::height
sf< float > height
Definition: tex_rect:36
tools::img
Definition: img:21
tools::sg::render_action::draw_vertex_array
virtual void draw_vertex_array(gl::mode_t, size_t, const float *)=0
tools::sg::base_tex::operator=
base_tex & operator=(const base_tex &a_from)
Definition: base_tex:59
tools::sg::state
Definition: state:25
tools::sg::tex_rect::f18
float f18[18]
Definition: tex_rect:302
tools::sg::base_tex::intersect_type
intersect_type
Definition: base_tex:34
tools::gl::triangles
mode_t triangles()
Definition: glprims:20
tools::sg::base_tex::set_tcs
void set_tcs(float a_tcs[8])
Definition: base_tex:204
tools::sg::base_tex::cast
virtual void * cast(const std::string &a_class) const
Definition: base_tex:23
tools::sg::tex_rect::cast
virtual void * cast(const std::string &a_class) const
Definition: tex_rect:29
pick_action
tools::plane
Definition: plane:12
tools::sg::tex_rect::_front
void _front(f12 &front, f12 &nms, float a_epsil=0.0f)
Definition: tex_rect:249
tools::sg::tex_rect::tex_rect
tex_rect()
Definition: tex_rect:197
TOOLS_NODE_NO_CAST
#define TOOLS_NODE_NO_CAST(a__class, a__sclass, a__parent)
Definition: node:328
render_action
tools::sg::state::m_GL_POLYGON_OFFSET_FILL
bool m_GL_POLYGON_OFFSET_FILL
Definition: state:250
tools::gl::triangle_fan
mode_t triangle_fan()
Definition: glprims:22
tools::plane::intersect
bool intersect(const line< VEC3 > &a_line, VEC3 &a_intersection) const
Definition: plane:63
tools::sg::gstos::clean_gstos
void clean_gstos()
Definition: gstos:89
tools::sg::node
Definition: node:28
tools::sg::bbox_action
Definition: bbox_action:15
tools::sg::tex_rect::bbox
virtual void bbox(bbox_action &a_action)
Definition: tex_rect:152
tools::sg::tex_rect::show_border
sf< bool > show_border
Definition: tex_rect:35
event_action
tools::sg::gstos::get_tex_id
unsigned int get_tex_id(std::ostream &a_out, render_manager &a_mgr, const img_byte &a_img, bool a_NEAREST)
Definition: gstos:30
tools::sg::base_tex::back_color
sf_vec< colorf, float > back_color
Definition: base_tex:29
tools::sg::tex_rect::rendered_size
void rendered_size(std::ostream &a_out, unsigned int &a_w, unsigned int &a_h)
Definition: tex_rect:229
tools::img::width
unsigned int width() const
Definition: img:214
tools::sg::base_tex::limit
sf< unsigned int > limit
Definition: base_tex:31
tools::sg::desc_fields
Definition: field_desc:148
tools::vec3::y
const T & y() const
Definition: vec3:85
tools::sg::render_action::color4f
virtual void color4f(float, float, float, float)=0
tools::sg::gstos::operator=
gstos & operator=(const gstos &a_from)
Definition: gstos:22
tools::sg::pick_action
Definition: pick_action:59
tools::sg::pick_action::add__primitive
bool add__primitive(sg::node &a_node, gl::mode_t a_mode, size_t a_floatn, const float *a_xyzs, bool a_stop=false)
Definition: pick_action:431
tools::sg::tex_rect::node_desc_fields
virtual const desc_fields & node_desc_fields() const
Definition: tex_rect:38
tools::vec3::x
const T & x() const
Definition: vec3:84
render_manager
tools::img::pixel
bool pixel(unsigned int a_i, unsigned a_j, std::vector< T > &a_pixel) const
Definition: img:223
tools::sg::tex_rect::pick
virtual void pick(pick_action &a_action)
Definition: tex_rect:141
tools::img::is_empty
bool is_empty() const
Definition: img:194
tools::sg::render_action::set_polygon_offset
virtual void set_polygon_offset(bool)=0
tools::sg::render_action::render_manager
virtual sg::render_manager & render_manager()=0
tools::sg::tex_rect::intersect_value
virtual bool intersect_value(std::ostream &, intersect_type, const line< vec3f > &a_line, std::string &a_s) const
Definition: tex_rect:163
tools::sg::primitive_visitor::add_points
bool add_points(size_t a_floatn, const float *a_xyzs, bool a_stop=false)
Definition: primitive_visitor:1405
gstos
tools::vec3f
Definition: vec3f:13
tools::sg::render_action
Definition: render_action:24
tools::sg::tex_rect::update_sg
void update_sg(std::ostream &a_out)
Definition: tex_rect:238
tools
inlined C code : ///////////////////////////////////
Definition: aida_ntuple:26
tools::sg::node::add_field
void add_field(field *a_field)
Definition: node:128
tools::gl::line_loop
mode_t line_loop()
Definition: glprims:18
TOOLS_FIELD_DESC_NODE_CLASS
#define TOOLS_FIELD_DESC_NODE_CLASS(a__class)
Definition: field:68
tools::img::make_empty
void make_empty(bool a_delete=true)
Definition: img:186
tools::sg::base_tex
Definition: base_tex:19
tools::sg::render_action::draw_vertex_normal_array
virtual void draw_vertex_normal_array(gl::mode_t, size_t, const float *, const float *)=0
tools::sg::tex_rect::f12
float f12[12]
Definition: tex_rect:248
tools::sg::bsf::value
T & value()
Definition: bsf:98
tools::sg::action::out
std::ostream & out() const
Definition: action:51
tools::img::height
unsigned int height() const
Definition: img:215
tools::sg::tex_rect::tex_rect
tex_rect(const tex_rect &a_from)
Definition: tex_rect:207
tools::line
Definition: line:13
tools::sg::state::m_line_width
float m_line_width
Definition: state:267
tools::sg::render_action::draw_vertex_normal_array_texture
virtual void draw_vertex_normal_array_texture(gl::mode_t, size_t, const float *, const float *, gstoid, const float *)=0
tools::sg::state::m_color
colorf m_color
Definition: state:259
tools::sg::base_tex::expand
sf< bool > expand
Definition: base_tex:30
tools::sg::render_action::line_width
virtual void line_width(float)=0
tools::sg::base_tex::m_img
img_byte m_img
Definition: base_tex:239
tools::sg::tex_rect::_tris
void _tris(f18 &tris, f18 &nms)
Definition: tex_rect:303
tools::sg::tex_rect::_back
void _back(f12 &back)
Definition: tex_rect:290
tools::sg::states::state
const sg::state & state() const
Definition: states:76
tools::sg::tex_rect::operator=
tex_rect & operator=(const tex_rect &a_from)
Definition: tex_rect:216
tools::sg::tex_rect
Definition: tex_rect:26
tools::sg::node::touched
virtual bool touched()
Definition: node:96
tools::sg::tex_rect::~tex_rect
virtual ~tex_rect()
Definition: tex_rect:205
tools::img::clear
void clear()
Definition: img:111
tools::sg::sf< bool >
TOOLS_ARG_FIELD_DESC
#define TOOLS_ARG_FIELD_DESC(a__field)
Definition: field:71
tools::sg::base_tex::nearest
sf< bool > nearest
Definition: base_tex:32
tools::sg::node::reset_touched
virtual void reset_touched()
Definition: node:102
bbox_action
tools::sg::tex_rect::render
virtual void render(render_action &a_action)
Definition: tex_rect:60