Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/Geant4/tools/sg/gl2ps_action 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_gl2ps_action
0005 #define tools_sg_gl2ps_action
0006 
0007 #include "gl2ps_manager"
0008 #include "../gl2ps"
0009 
0010 #include "render_action"
0011 #include "primitive_visitor"
0012 #include "../colorfs"
0013 #include "../lina/plane"
0014 
0015 #include <cstdio> //FILE
0016 
0017 namespace tools {
0018 namespace sg {
0019 
0020 class gl2ps_action : public render_action {
0021   TOOLS_ACTION(gl2ps_action,tools::sg::gl2ps_action,render_action)
0022 private:
0023   gl2ps_action& get_me() {return *this;}
0024 
0025   static unsigned int _GL2PS_POINT()    {return 2;}
0026   static unsigned int _GL2PS_LINE()     {return 3;}
0027   static unsigned int _GL2PS_TRIANGLE() {return 5;}
0028 public:
0029   virtual void draw_vertex_array(gl::mode_t a_mode,
0030                                  size_t a_floatn,
0031                                  const float* a_xyzs){
0032     m_pv.add_primitive(a_mode,a_floatn,a_xyzs);
0033   }
0034 
0035   virtual void draw_vertex_array_xy(gl::mode_t a_mode,
0036                                     size_t a_floatn,
0037                                     const float* a_xys){
0038     m_pv.add_primitive_xy(a_mode,a_floatn,a_xys);
0039   }
0040 
0041   virtual void draw_vertex_color_array(gl::mode_t a_mode,
0042                                        size_t a_floatn,
0043                                        const float* a_xyzs,
0044                                        const float* a_rgbas){
0045     m_pv.add_primitive_rgba(a_mode,a_floatn,a_xyzs,a_rgbas);
0046   }
0047 
0048   virtual void draw_vertex_normal_array(gl::mode_t a_mode,
0049                                         size_t a_floatn,
0050                                         const float* a_xyzs,
0051                                         const float* a_nms){
0052     m_pv.add_primitive_normal(a_mode,a_floatn,a_xyzs,a_nms);
0053   }
0054 
0055   virtual void draw_vertex_color_normal_array(gl::mode_t a_mode,
0056                                               size_t a_floatn,
0057                                               const float* a_xyzs,
0058                                               const float* a_rgbas,
0059                                               const float* a_nms){
0060     // We expect a_nms of size : 3*(a_floatn/3)
0061     // (then one normal per 3D point).
0062     m_pv.add_primitive_normal_rgba(a_mode,a_floatn,a_xyzs,a_nms,a_rgbas);
0063   }
0064 
0065   virtual void clear_color(float a_r,float a_g,float a_b,float /*a_a*/){
0066     //a_a ?
0067     set_background(a_r,a_g,a_b);
0068   }
0069   virtual void color4f(float a_r,float a_g,float a_b,float a_a){
0070     m_color.set_value(a_r,a_g,a_b,a_a);
0071   }
0072   virtual void line_width(float a_v){m_line_width = a_v;}
0073   virtual void point_size(float a_v) {m_point_size = a_v;}
0074   virtual void set_polygon_offset(bool a_v) {m_POLYGON_OFFSET_FILL = a_v;}
0075   virtual void normal(float a_x,float a_y,float a_z) {
0076     m_normal.set_value(a_x,a_y,a_z);
0077   }
0078 
0079   virtual void set_winding(winding_type a_v) {
0080     m_ccw = (a_v==winding_ccw?true:false);
0081   }
0082 
0083   virtual void set_shade_model(shade_type a_v) {
0084     if(a_v==shade_smooth) {}
0085     else {}
0086   }
0087 
0088   virtual void set_depth_test(bool a_on) {m_DEPTH_TEST = a_on;}
0089 
0090   virtual void set_cull_face(bool a_on) {m_CULL_FACE = a_on;}
0091   virtual void set_point_smooth(bool a_on) {m_POINT_SMOOTH = a_on;}
0092   virtual void set_line_smooth(bool a_on) {m_LINE_SMOOTH = a_on;}
0093 
0094   virtual void load_proj_matrix(const mat4f& a_mtx) {m_proj = a_mtx;}
0095   virtual void load_model_matrix(const mat4f& a_mtx) {
0096     m_model = a_mtx;
0097     set_normal_matrix();
0098   }
0099 
0100   virtual unsigned int max_lights() {return 1000;}
0101 
0102   virtual void enable_light(unsigned int,
0103                             float a_dx,float a_dy,float a_dz,
0104                             float a_r,float a_g,float a_b,float a_a,
0105                             float a_ar,float a_ag,float a_ab,float a_aa){
0106     m_light_color.set_value(a_r,a_g,a_b,a_a);
0107     m_light_ambient.set_value(a_ar,a_ag,a_ab,a_aa);
0108     m_light_direction.set_value(a_dx,a_dy,a_dz);
0109     m_light_direction.normalize();
0110     m_light_on = true;
0111   }
0112 
0113   virtual void set_lighting(bool a_on) {m_light_on = a_on;}
0114   virtual void set_blend(bool) {}
0115 
0116   virtual void restore_state(unsigned int /*a_ret_num_light*/) {
0117     const sg::state& _state = state();
0118     m_proj = _state.m_proj;
0119     m_model = _state.m_model;
0120     set_normal_matrix();
0121 
0122     m_color = _state.m_color;
0123     m_normal = _state.m_normal;
0124     
0125     m_ccw = (_state.m_winding==winding_ccw?true:false);
0126     m_POLYGON_OFFSET_FILL = _state.m_GL_POLYGON_OFFSET_FILL;
0127     m_CULL_FACE = _state.m_GL_CULL_FACE;
0128     m_POINT_SMOOTH = _state.m_GL_POINT_SMOOTH;
0129     m_LINE_SMOOTH = _state.m_GL_LINE_SMOOTH;
0130     m_point_size = _state.m_point_size;
0131     m_line_width = _state.m_line_width;
0132     m_light_on = _state.m_GL_LIGHTING;
0133     m_DEPTH_TEST = _state.m_GL_DEPTH_TEST;
0134   }
0135 
0136   /////////////////////////////////////////////////////////////////
0137   /// texture /////////////////////////////////////////////////////
0138   /////////////////////////////////////////////////////////////////
0139   virtual void draw_vertex_array_texture(gl::mode_t,size_t a_xyzn,const float* a_xyzs,
0140                                          gstoid a_id,const float* a_tcs) {
0141     img_byte img;
0142     if(!m_mgr.find(a_id,img)) return;
0143     m_pv.add_texture(m_out,a_xyzn,a_xyzs,img,a_tcs);
0144   }
0145 
0146   virtual void draw_vertex_normal_array_texture(gl::mode_t a_mode,
0147                                          size_t a_xyzn,
0148                                          const float* a_xyzs,
0149                                          const float* /*a_nms*/,
0150                                          gstoid a_id,
0151                                          const float* a_tcs) {
0152     draw_vertex_array_texture(a_mode,a_xyzn,a_xyzs,a_id,a_tcs);
0153   }
0154 
0155   /////////////////////////////////////////////////////////////////
0156   /// VBO /////////////////////////////////////////////////////////
0157   /////////////////////////////////////////////////////////////////
0158   virtual void begin_gsto(gstoid) {}
0159   virtual void draw_gsto_v(gl::mode_t,size_t,bufpos){}
0160   virtual void draw_gsto_vc(gl::mode_t,size_t,bufpos,bufpos) {}
0161   virtual void draw_gsto_vn(gl::mode_t,size_t,bufpos,bufpos) {}
0162   virtual void draw_gsto_vcn(gl::mode_t,size_t,bufpos,bufpos,bufpos) {}
0163   virtual void end_gsto() {}
0164   /////////////////////////////////////////////////////////////////
0165   /////////////////////////////////////////////////////////////////
0166   /////////////////////////////////////////////////////////////////
0167   virtual sg::render_manager& render_manager() {return m_mgr;}
0168 public:
0169   gl2ps_action(gl2ps_manager& a_mgr,std::ostream& a_out,unsigned int a_ww,unsigned int a_wh)
0170   :parent(a_out,a_ww,a_wh)
0171   ,m_mgr(a_mgr)
0172   ,m_gl2ps_context(0)
0173   ,m_FILE(0)
0174   ,m_pv(get_me())
0175   ,m_light_color(colorf_white())
0176   ,m_light_ambient(colorf_black())
0177   ,m_light_direction(vec3f(0,0,-1))
0178 
0179   ,m_ccw(true)
0180   ,m_POLYGON_OFFSET_FILL(false)
0181   ,m_CULL_FACE(true)
0182   ,m_POINT_SMOOTH(false)
0183   ,m_LINE_SMOOTH(false)
0184   ,m_point_size(1)
0185   ,m_line_width(1)
0186   ,m_light_on(false)
0187   ,m_DEPTH_TEST(true)
0188   {
0189     m_back[0] = 1;
0190     m_back[1] = 1;
0191     m_back[2] = 1;
0192 
0193     m_vp_mtx.set_identity();
0194     m_vp_mtx.mul_translate(float(m_ww)/2,float(m_wh)/2,0);
0195     m_vp_mtx.mul_scale(float(m_ww)/2,float(m_wh)/2,1);
0196 
0197     //m_zb.change_size(a_ww,a_wh);
0198 //    m_zb.clear_color_buffer(0);
0199 //    m_zb.clear_depth_buffer();
0200     m_proj.set_identity();
0201     m_model.set_identity();
0202     m_normal_matrix.set_identity();
0203   }
0204   virtual ~gl2ps_action(){
0205     close();
0206   }
0207 protected:
0208   gl2ps_action(const gl2ps_action& a_from)
0209   :parent(a_from)
0210   ,m_mgr(a_from.m_mgr)
0211   ,m_gl2ps_context(0)
0212   ,m_FILE(0)
0213 
0214   ,m_vp_mtx(a_from.m_vp_mtx)
0215   ,m_pv(a_from.m_pv)
0216   ,m_light_color(a_from.m_light_color)
0217   ,m_light_ambient(a_from.m_light_ambient)
0218   ,m_light_direction(a_from.m_light_direction)
0219   ,m_normal(a_from.m_normal)
0220 
0221   ,m_proj(a_from.m_proj)
0222   ,m_model(a_from.m_model)
0223   ,m_normal_matrix(a_from.m_normal_matrix)
0224   ,m_color(a_from.m_color)
0225   ,m_ccw(a_from.m_ccw)
0226   ,m_POLYGON_OFFSET_FILL(a_from.m_POLYGON_OFFSET_FILL)
0227   ,m_CULL_FACE(a_from.m_CULL_FACE)
0228   ,m_POINT_SMOOTH(a_from.m_POINT_SMOOTH)
0229   ,m_LINE_SMOOTH(a_from.m_LINE_SMOOTH)
0230   ,m_point_size(a_from.m_point_size)
0231   ,m_line_width(a_from.m_line_width)
0232   ,m_light_on(a_from.m_light_on)
0233   ,m_DEPTH_TEST(a_from.m_DEPTH_TEST)
0234   {
0235     m_back[0] = a_from.m_back[0];
0236     m_back[1] = a_from.m_back[1];
0237     m_back[2] = a_from.m_back[2];
0238   }
0239   gl2ps_action& operator=(const gl2ps_action& a_from){
0240     parent::operator=(a_from);
0241     if(&a_from==this) return *this;
0242     close();
0243     m_back[0] = a_from.m_back[0];
0244     m_back[1] = a_from.m_back[1];
0245     m_back[2] = a_from.m_back[2];
0246 
0247     m_vp_mtx = a_from.m_vp_mtx;
0248     m_pv = a_from.m_pv;
0249     m_light_color = a_from.m_light_color;
0250     m_light_ambient = a_from.m_light_ambient;
0251     m_light_direction = a_from.m_light_direction;
0252     m_normal = a_from.m_normal;
0253 
0254     m_proj = a_from.m_proj;
0255     m_model = a_from.m_model;
0256     m_normal_matrix = a_from.m_normal_matrix;
0257     m_color = a_from.m_color;
0258     m_ccw = a_from.m_ccw;
0259     m_POLYGON_OFFSET_FILL = a_from.m_POLYGON_OFFSET_FILL;
0260     m_CULL_FACE = a_from.m_CULL_FACE;
0261     m_POINT_SMOOTH = a_from.m_POINT_SMOOTH;
0262     m_LINE_SMOOTH = a_from.m_LINE_SMOOTH;
0263     m_point_size = a_from.m_point_size;
0264     m_line_width = a_from.m_line_width;
0265     m_light_on = a_from.m_light_on;
0266     m_DEPTH_TEST = a_from.m_DEPTH_TEST;
0267     return *this;
0268   }
0269 public:
0270   bool open(const std::string& a_name,int a_format = TOOLS_GL2PS_EPS) {
0271     return open(a_name,a_format,-1,-1);
0272   }
0273   bool open(const std::string& a_name,int a_format,int a_sort,int a_options) {
0274     close();
0275 
0276     m_gl2ps_context = ::tools_gl2psCreateContext();
0277     if(!m_gl2ps_context) {
0278       m_out << "tools::sg::gl2ps_action::open :"
0279             << " can't create gl2ps context."
0280             << std::endl;
0281       return false;
0282     }
0283     
0284     m_FILE = ::fopen(a_name.c_str(),"wb");
0285     if(!m_FILE) {
0286       m_out << "tools::sg::gl2ps_action::open :"
0287             << " can't open file " << a_name << "."
0288             << std::endl;
0289       ::tools_gl2psDeleteContext(m_gl2ps_context);
0290       m_gl2ps_context = 0;
0291       return false;
0292     }
0293 
0294     int sort = 0;
0295     if(a_sort==(-1)) {
0296       sort = TOOLS_GL2PS_BSP_SORT;
0297     } else {
0298       sort = a_sort;
0299     }
0300 
0301     int options = 0;
0302     if(a_options==(-1)) {
0303       options = TOOLS_GL2PS_SILENT
0304       | TOOLS_GL2PS_OCCLUSION_CULL
0305       | TOOLS_GL2PS_BEST_ROOT
0306       | TOOLS_GL2PS_DRAW_BACKGROUND;
0307     } else {
0308       options = a_options;
0309     }
0310     
0311     tools_GLint vp[4];
0312     vp[0] = 0;
0313     vp[1] = 0;
0314     vp[2] = m_ww;
0315     vp[3] = m_wh;
0316 
0317     int bufsize = 0;
0318     if(::tools_gl2psBeginPage(m_gl2ps_context,"","tools_sg_write_gl2ps",
0319                      vp,a_format,sort,options,
0320                      TOOLS_GL_RGBA,0, NULL,0,0,0,bufsize,
0321                      m_FILE,a_name.c_str())==TOOLS_GL2PS_ERROR) {
0322       m_out << "tools::sg::gl2ps_action::open :"
0323             << " tools_gl2psBeginPage() failed."
0324             << std::endl;
0325       ::fclose(m_FILE);
0326       m_FILE = 0;
0327       ::tools_gl2psDeleteContext(m_gl2ps_context);
0328       m_gl2ps_context = 0;
0329       return false;
0330     }
0331     
0332     ::tools_gl2psSetBackgroundColor(m_gl2ps_context,m_back[0],m_back[1],m_back[2]);
0333 
0334     m_vp_mtx.set_identity();
0335     m_vp_mtx.mul_translate(float(m_ww)/2,float(m_wh)/2,0);
0336     m_vp_mtx.mul_scale(float(m_ww)/2,float(m_wh)/2,1);
0337 
0338     return true;
0339   }
0340 
0341   bool close() {
0342     tools_GLint _status = 0;
0343     if(m_gl2ps_context) {
0344       _status = ::tools_gl2psEndPage(m_gl2ps_context);
0345     }
0346     if(m_FILE) {
0347       ::fclose(m_FILE);
0348       m_FILE = 0;
0349     }      
0350     if(m_gl2ps_context) {
0351       ::tools_gl2psDeleteContext(m_gl2ps_context);
0352       m_gl2ps_context = 0;
0353     }
0354     if (_status == TOOLS_GL2PS_OVERFLOW) return false;
0355     return true;
0356   }
0357   void set_background(float a_r,float a_g,float a_b) {
0358     m_back[0] = a_r;
0359     m_back[1] = a_g;
0360     m_back[2] = a_b;
0361   }
0362 protected:
0363   void set_normal_matrix() {
0364     mat4f tmp(m_model);
0365     tmp.no_translate();
0366     if(!tmp.invert(m_normal_matrix)) {
0367       m_out << "tools::sg::gl2ps_action::set_normal_matrix : can't invert model matrix." << std::endl;
0368     }
0369     m_normal_matrix.transpose();
0370   }
0371 
0372   bool project_point(float& a_x,float& a_y,float& a_z,float& a_w) {
0373     a_w = 1;
0374     m_model.mul_4f(a_x,a_y,a_z,a_w);
0375     m_proj.mul_4f(a_x,a_y,a_z,a_w);
0376     if(a_w==0) return false;
0377     a_x /= a_w;
0378     a_y /= a_w;
0379     a_z /= a_w;
0380     return true;
0381   }
0382 //  bool project_normal(float& a_x,float& a_y,float& a_z) {
0383 //    m_normal_matrix.mul_dir_3f(a_x,a_y,a_z);
0384 //  //m_proj.mul_dir_3f(a_x,a_y,a_z); //?
0385 //    return true;
0386 //  }
0387 
0388   static void set_vtx(tools_GL2PSvertex* a_vs,unsigned int a_index,
0389                       float a_x,float a_y,float a_z,
0390                       float a_r,float a_g,float a_b,float a_a){
0391     a_vs[a_index].xyz[0] = a_x;
0392     a_vs[a_index].xyz[1] = a_y;
0393     a_vs[a_index].xyz[2] = a_z;
0394     a_vs[a_index].rgba[0] = a_r;
0395     a_vs[a_index].rgba[1] = a_g;
0396     a_vs[a_index].rgba[2] = a_b;
0397     a_vs[a_index].rgba[3] = a_a;
0398   }
0399 
0400   class primvis : public primitive_visitor {
0401   protected:
0402     virtual bool project(float& a_x,float& a_y,float& a_z,float& a_w) {
0403       return m_this.project_point(a_x,a_y,a_z,a_w);
0404     }
0405     virtual bool add_point(float a_x,float a_y,float a_z,float) {
0406       if(!m_this.m_gl2ps_context) return false;
0407       
0408       float r = m_this.m_color[0];
0409       float g = m_this.m_color[1];
0410       float b = m_this.m_color[2];
0411       float a = m_this.m_color[3];
0412 
0413       tools_GLint offset = 0;
0414       tools_GLfloat ofactor = 0;
0415       tools_GLfloat ounits = 0;
0416       tools_GLushort pattern = 0;
0417       tools_GLint factor = 0;
0418       tools_GLfloat sz = m_this.m_point_size;
0419       tools_GLint linecap = 0;
0420       tools_GLint linejoin = 0;
0421       char boundary = 0;
0422 
0423       tools_GL2PSvertex vertices[1];
0424 
0425       m_this.m_vp_mtx.mul_3f(a_x,a_y,a_z);
0426 
0427       m_this.set_vtx(vertices,0, a_x,a_y,a_z, r,g,b,a);
0428       ::tools_gl2psAddPolyPrimitive(m_this.m_gl2ps_context,_GL2PS_POINT(),1,vertices,offset,ofactor,ounits,pattern,factor,sz,linecap,linejoin,boundary);
0429       return true;
0430     }
0431 
0432     virtual bool add_point(float a_x,float a_y,float a_z,float,
0433                            float a_r,float a_g,float a_b,float a_a) {
0434       if(!m_this.m_gl2ps_context) return false;
0435       
0436       tools_GLint offset = 0;
0437       tools_GLfloat ofactor = 0;
0438       tools_GLfloat ounits = 0;
0439       tools_GLushort pattern = 0;
0440       tools_GLint factor = 0;
0441       tools_GLfloat sz = m_this.m_point_size;
0442       tools_GLint linecap = 0;
0443       tools_GLint linejoin = 0;
0444       char boundary = 0;
0445 
0446       tools_GL2PSvertex vertices[1];
0447 
0448       m_this.m_vp_mtx.mul_3f(a_x,a_y,a_z);
0449 
0450       m_this.set_vtx(vertices,0, a_x,a_y,a_z, a_r,a_g,a_b,a_a);
0451 
0452       ::tools_gl2psAddPolyPrimitive(m_this.m_gl2ps_context,_GL2PS_POINT(),1,vertices,offset,ofactor,ounits,pattern,factor,sz,linecap,linejoin,boundary);
0453       return true;
0454     }
0455 
0456     virtual bool add_line(float a_bx,float a_by,float a_bz,float,
0457                           float a_ex,float a_ey,float a_ez,float) {
0458       if(!m_this.m_gl2ps_context) return false;
0459       
0460       float r = m_this.m_color[0];
0461       float g = m_this.m_color[1];
0462       float b = m_this.m_color[2];
0463       float a = m_this.m_color[3];
0464 
0465       tools_GLint offset = 0;
0466       tools_GLfloat ofactor = 0;
0467       tools_GLfloat ounits = 0;
0468       tools_GLushort pattern = 0;
0469       tools_GLint factor = 0;
0470       tools_GLfloat lwidth = m_this.m_line_width;
0471       tools_GLint linecap = 0;
0472       tools_GLint linejoin = 0;
0473       char boundary = 0;
0474 
0475       tools_GL2PSvertex vertices[2];
0476 
0477       m_this.m_vp_mtx.mul_3f(a_bx,a_by,a_bz);
0478       m_this.m_vp_mtx.mul_3f(a_ex,a_ey,a_ez);
0479 
0480       m_this.set_vtx(vertices,0, a_bx,a_by,a_bz, r,g,b,a);
0481       m_this.set_vtx(vertices,1, a_ex,a_ey,a_ez, r,g,b,a);
0482 
0483       ::tools_gl2psAddPolyPrimitive(m_this.m_gl2ps_context,_GL2PS_LINE(),2,vertices,offset,ofactor,ounits,pattern,factor,lwidth,linecap,linejoin,boundary);
0484 
0485       return true;
0486     }
0487 
0488     virtual bool add_line(float a_bx,float a_by,float a_bz,float,
0489                           float a_br,float a_bg,float a_bb,float a_ba,
0490                           float a_ex,float a_ey,float a_ez,float,
0491                           float a_er,float a_eg,float a_eb,float a_ea){
0492       if(!m_this.m_gl2ps_context) return false;
0493 
0494       tools_GLint offset = 0;
0495       tools_GLfloat ofactor = 0;
0496       tools_GLfloat ounits = 0;
0497       tools_GLushort pattern = 0;
0498       tools_GLint factor = 0;
0499       tools_GLfloat lwidth = m_this.m_line_width;
0500       tools_GLint linecap = 0;
0501       tools_GLint linejoin = 0;
0502       char boundary = 0;
0503 
0504       tools_GL2PSvertex vertices[2];
0505 
0506       m_this.m_vp_mtx.mul_3f(a_bx,a_by,a_bz);
0507       m_this.m_vp_mtx.mul_3f(a_ex,a_ey,a_ez);
0508 
0509       m_this.set_vtx(vertices,0, a_bx,a_by,a_bz, a_br,a_bg,a_bb,a_ba);
0510       m_this.set_vtx(vertices,1, a_ex,a_ey,a_ez, a_er,a_eg,a_eb,a_ea);
0511 
0512       //tools_gl2psAddPolyPrimitive(m_this.m_gl2ps_context,_GL2PS_LINE(),2,vertices,0,pattern,factor,lwidth,0);
0513       ::tools_gl2psAddPolyPrimitive(m_this.m_gl2ps_context,_GL2PS_LINE(),2,vertices,offset,ofactor,ounits,pattern,factor,lwidth,linecap,linejoin,boundary);
0514 
0515       return true;
0516     }
0517 
0518     virtual bool add_triangle(float a_p1x,float a_p1y,float a_p1z,float a_p1w,
0519                               float a_p2x,float a_p2y,float a_p2z,float a_p2w,
0520                               float a_p3x,float a_p3y,float a_p3z,float a_p3w){
0521       float r = m_this.m_color[0];
0522       float g = m_this.m_color[1];
0523       float b = m_this.m_color[2];
0524       float a = m_this.m_color[3];
0525       return _add_triangle(a_p1x,a_p1y,a_p1z,a_p1w,
0526                            m_this.m_normal.x(),m_this.m_normal.y(),m_this.m_normal.z(),
0527                            r,g,b,a,
0528                            a_p2x,a_p2y,a_p2z,a_p2w,
0529                            m_this.m_normal.x(),m_this.m_normal.y(),m_this.m_normal.z(),
0530                            r,g,b,a,
0531                            a_p3x,a_p3y,a_p3z,a_p3w,
0532                            m_this.m_normal.x(),m_this.m_normal.y(),m_this.m_normal.z(),
0533                            r,g,b,a);
0534     }
0535 
0536     virtual bool add_triangle(
0537       float a_p1x,float a_p1y,float a_p1z,float a_p1w,
0538       float a_r1,float a_g1,float a_b1,float a_a1,
0539       float a_p2x,float a_p2y,float a_p2z,float a_p2w,
0540       float a_r2,float a_g2,float a_b2,float a_a2,
0541       float a_p3x,float a_p3y,float a_p3z,float a_p3w,
0542       float a_r3,float a_g3,float a_b3,float a_a3){
0543 
0544       return _add_triangle(a_p1x,a_p1y,a_p1z,a_p1w,
0545                            m_this.m_normal.x(),m_this.m_normal.y(),m_this.m_normal.z(),
0546                            a_r1,a_g1,a_b1,a_a1,
0547                            a_p2x,a_p2y,a_p2z,a_p2w,
0548                            m_this.m_normal.x(),m_this.m_normal.y(),m_this.m_normal.z(),
0549                            a_r2,a_g2,a_b2,a_a2,
0550                            a_p3x,a_p3y,a_p3z,a_p3w,
0551                            m_this.m_normal.x(),m_this.m_normal.y(),m_this.m_normal.z(),
0552                            a_r3,a_g3,a_b3,a_a3);
0553     }
0554 
0555     virtual bool project_normal(float& /*a_x*/,float& /*a_y*/,float& /*a_z*/) {
0556       //return m_this.project_normal(a_x,a_y,a_z);
0557       return true;
0558     }
0559     virtual bool add_point_normal(float a_x,float a_y,float a_z,float a_w,
0560                                   float /*a_nx*/,float /*a_ny*/,float /*a_nz*/) {
0561       add_point(a_x,a_y,a_z,a_w);
0562     //m_this.m_points.add_normal(a_nx,a_ny,a_nz);
0563       return true;
0564     }
0565     virtual bool add_point_normal(float a_x,float a_y,float a_z,float a_w,
0566                                   float /*a_nx*/,float /*a_ny*/,float /*a_nz*/,
0567                                   float a_r,float a_g,float a_b,float a_a) {
0568       add_point(a_x,a_y,a_z,a_w,a_r,a_g,a_b,a_a);
0569     //m_this.m_points.add_normal(a_nx,a_ny,a_nz);
0570       return true;
0571     }
0572     virtual bool add_line_normal(float a_bx,float a_by,float a_bz,float a_bw,
0573                                  float /*a_bnx*/,float /*a_bny*/,float /*a_bnz*/,
0574                                  float a_ex,float a_ey,float a_ez,float a_ew,
0575                                  float /*a_enx*/,float /*a_eny*/,float /*a_enz*/) {
0576       add_line(a_bx,a_by,a_bz,a_bw, a_ex,a_ey,a_ez,a_ew);
0577     //m_this.m_lines.add_normal(a_bnx,a_bny,a_bnz);
0578     //m_this.m_lines.add_normal(a_enx,a_eny,a_enz);
0579       return true;
0580     }
0581     virtual bool add_line_normal(float a_bx,float a_by,float a_bz,float a_bw,
0582                                  float /*a_bnx*/,float /*a_bny*/,float /*a_bnz*/,
0583                                  float a_br,float a_bg,float a_bb,float a_ba,
0584                                  float a_ex,float a_ey,float a_ez,float a_ew,
0585                                  float /*a_enx*/,float /*a_eny*/,float /*a_enz*/,
0586                                  float a_er,float a_eg,float a_eb,float a_ea){
0587       add_line(a_bx,a_by,a_bz,a_bw, a_br,a_bg,a_bb,a_ba, a_ex,a_ey,a_ez,a_ew, a_er,a_eg,a_eb,a_ea);
0588     //m_this.m_lines.add_normal(a_bnx,a_bny,a_bnz);
0589     //m_this.m_lines.add_normal(a_enx,a_eny,a_enz);
0590       return true;
0591     }
0592     virtual bool add_triangle_normal(
0593       float a_p1x,float a_p1y,float a_p1z,float a_p1w,
0594       float a_n1x,float a_n1y,float a_n1z,
0595       float a_p2x,float a_p2y,float a_p2z,float a_p2w,
0596       float a_n2x,float a_n2y,float a_n2z,
0597       float a_p3x,float a_p3y,float a_p3z,float a_p3w,
0598       float a_n3x,float a_n3y,float a_n3z) {
0599 
0600       float r = m_this.m_color[0];
0601       float g = m_this.m_color[1];
0602       float b = m_this.m_color[2];
0603       float a = m_this.m_color[3];
0604       
0605       return _add_triangle(a_p1x,a_p1y,a_p1z,a_p1w,
0606                            a_n1x,a_n1y,a_n1z,
0607                            r,g,b,a,
0608                            a_p2x,a_p2y,a_p2z,a_p2w,
0609                            a_n2x,a_n2y,a_n2z,
0610                            r,g,b,a,
0611                            a_p3x,a_p3y,a_p3z,a_p3w,
0612                            a_n3x,a_n3y,a_n3z,
0613                            r,g,b,a);
0614     }
0615     virtual bool add_triangle_normal(
0616       float a_p1x,float a_p1y,float a_p1z,float a_p1w,
0617       float a_n1x,float a_n1y,float a_n1z,
0618       float a_r1,float a_g1,float a_b1,float a_a1,
0619       float a_p2x,float a_p2y,float a_p2z,float a_p2w,
0620       float a_n2x,float a_n2y,float a_n2z,
0621       float a_r2,float a_g2,float a_b2,float a_a2,
0622       float a_p3x,float a_p3y,float a_p3z,float a_p3w,
0623       float a_n3x,float a_n3y,float a_n3z,
0624       float a_r3,float a_g3,float a_b3,float a_a3){
0625       return _add_triangle(a_p1x,a_p1y,a_p1z,a_p1w,
0626                            a_n1x,a_n1y,a_n1z,
0627                            a_r1,a_g1,a_b1,a_a1,
0628                            a_p2x,a_p2y,a_p2z,a_p2w,
0629                            a_n2x,a_n2y,a_n2z,
0630                            a_r2,a_g2,a_b2,a_a2,
0631                            a_p3x,a_p3y,a_p3z,a_p3w,
0632                            a_n3x,a_n3y,a_n3z,
0633                            a_r3,a_g3,a_b3,a_a3);
0634     }
0635   public:
0636     primvis(gl2ps_action& a_this):m_this(a_this){}
0637     virtual ~primvis(){}
0638   public:
0639     primvis(const primvis& a_from)
0640     :primitive_visitor(a_from)
0641     ,m_this(a_from.m_this)
0642     {}
0643     primvis& operator=(const primvis& a_from){
0644       primitive_visitor::operator=(a_from);
0645       return *this;
0646     }
0647   protected:    
0648     bool _add_triangle(float a_p1x,float a_p1y,float a_p1z,float /*a_p1w*/,
0649                        float a_n1x,float a_n1y,float a_n1z,
0650                        float a_r1,float a_g1,float a_b1,float a_a1,
0651                        float a_p2x,float a_p2y,float a_p2z,float /*a_p2w*/,
0652                        float a_n2x,float a_n2y,float a_n2z,
0653                        float a_r2,float a_g2,float a_b2,float a_a2,
0654                        float a_p3x,float a_p3y,float a_p3z,float /*a_p3w*/,
0655                        float a_n3x,float a_n3y,float a_n3z,
0656                        float a_r3,float a_g3,float a_b3,float a_a3) {
0657 
0658       if(!m_this.m_gl2ps_context) return false;
0659 
0660       float p1x = a_p1x;float p1y = a_p1y;float p1z = a_p1z;//float p1w = a_p1w;
0661       float p2x = a_p2x;float p2y = a_p2y;float p2z = a_p2z;//float p2w = a_p2w;
0662       float p3x = a_p3x;float p3y = a_p3y;float p3z = a_p3z;//float p3w = a_p3w;
0663 
0664       m_this.m_vp_mtx.mul_3f(p1x,p1y,p1z);
0665       m_this.m_vp_mtx.mul_3f(p2x,p2y,p2z);
0666       m_this.m_vp_mtx.mul_3f(p3x,p3y,p3z);
0667 
0668      {plane<vec3f> pn(
0669         vec3f(p1x,p1y,p1z),
0670         vec3f(p2x,p2y,p2z),
0671         vec3f(p3x,p3y,p3z)
0672       );
0673       if(!pn.is_valid()) return true;
0674       float C = pn.normal()[2];
0675       if(m_this.m_CULL_FACE){
0676         if(m_this.m_ccw) {
0677           if(C<=0) return true;
0678         } else {
0679           if(C>=0) return true;
0680         }
0681       }}
0682 
0683       tools_GL2PSvertex vertices[3];
0684 
0685       if(m_this.m_light_on) {  // same logic as toolx/wasm/webgl.js:
0686         
0687         float nx = (a_n1x+a_n2x+a_n3x)/3.0f;
0688         float ny = (a_n1y+a_n2y+a_n3y)/3.0f;
0689         float nz = (a_n1z+a_n2z+a_n3z)/3.0f;
0690 
0691         m_this.m_normal_matrix.mul_dir_3f(nx,ny,nz);
0692         vec3f _normal(nx,ny,nz);_normal.normalize();
0693 
0694         float _dot = _normal.dot(m_this.m_light_direction);
0695 
0696         float _r = (a_r1+a_r2+a_r3)/3.0f;
0697         float _g = (a_g1+a_g2+a_g3)/3.0f;
0698         float _b = (a_b1+a_b2+a_b3)/3.0f;
0699         float _a = (a_a1+a_a2+a_a3)/3.0f;
0700         colorf a_color(_r,_g,_b,_a);
0701 
0702         colorf frag_color = a_color;
0703 
0704         if(_dot<0.0) {
0705           _dot *= -1.0;
0706 
0707           colorf _tmp = m_this.m_light_color;
0708           _tmp *= _dot;
0709           _tmp += m_this.m_light_ambient;
0710 
0711           frag_color *= _tmp;
0712 
0713         } else {
0714           frag_color *= m_this.m_light_ambient;
0715         }
0716 
0717         frag_color.clamp();
0718         frag_color.set_a(a_color.a());
0719         
0720         float r = frag_color.r();
0721         float g = frag_color.g();
0722         float b = frag_color.b();
0723         float a = frag_color.a();
0724 
0725         m_this.set_vtx(vertices,0, p1x,p1y,p1z, r,g,b,a);
0726         m_this.set_vtx(vertices,1, p2x,p2y,p2z, r,g,b,a);
0727         m_this.set_vtx(vertices,2, p3x,p3y,p3z, r,g,b,a);
0728 
0729       } else {
0730         m_this.set_vtx(vertices,0, p1x,p1y,p1z, a_r1,a_g1,a_b1,a_a1);
0731         m_this.set_vtx(vertices,1, p2x,p2y,p2z, a_r2,a_g2,a_b2,a_a2);
0732         m_this.set_vtx(vertices,2, p3x,p3y,p3z, a_r3,a_g3,a_b3,a_a3);
0733 
0734       }
0735 
0736       tools_GLint offset = 0;
0737       tools_GLfloat ofactor = 0;
0738       tools_GLfloat ounits = 0;
0739       tools_GLushort pattern = 0;
0740       tools_GLint factor = 0;
0741       tools_GLfloat lwidth = m_this.m_line_width;
0742       tools_GLint linecap = 0;
0743       tools_GLint linejoin = 0;
0744       char boundary = 0;
0745 
0746       ::tools_gl2psAddPolyPrimitive(m_this.m_gl2ps_context,_GL2PS_TRIANGLE(),3,vertices,offset,ofactor,ounits,pattern,factor,lwidth,linecap,linejoin,boundary);
0747 
0748       return true;
0749     }
0750   protected:
0751     gl2ps_action& m_this;
0752   };
0753 
0754 protected:
0755   gl2ps_manager& m_mgr;
0756   tools_GL2PScontext* m_gl2ps_context;
0757 
0758   FILE* m_FILE;
0759   float m_back[3];
0760   mat4f m_vp_mtx;
0761   primvis m_pv;
0762 
0763   colorf m_light_color;
0764   colorf m_light_ambient;
0765   vec3f m_light_direction;
0766   vec3f m_normal;
0767 
0768   // to be restored in restore_state() :
0769   mat4f m_proj;
0770   mat4f m_model;
0771   mat4f m_normal_matrix;
0772   colorf m_color;
0773   bool m_ccw;
0774   bool m_POLYGON_OFFSET_FILL;
0775   bool m_CULL_FACE;
0776   bool m_POINT_SMOOTH;
0777   bool m_LINE_SMOOTH;
0778   float m_point_size;
0779   float m_line_width;
0780   bool m_light_on;
0781   bool m_DEPTH_TEST;
0782 };
0783 
0784 inline bool gl2ps_s2format(const std::string& a_format,int& a_gl2ps_format) {
0785   if(a_format=="gl2ps_eps") {a_gl2ps_format = TOOLS_GL2PS_EPS;return true;}
0786   if(a_format=="gl2ps_ps")  {a_gl2ps_format = TOOLS_GL2PS_PS; return true;}
0787   if(a_format=="gl2ps_pdf") {a_gl2ps_format = TOOLS_GL2PS_PDF;return true;}
0788   if(a_format=="gl2ps_svg") {a_gl2ps_format = TOOLS_GL2PS_SVG;return true;}
0789   if(a_format=="gl2ps_tex") {a_gl2ps_format = TOOLS_GL2PS_TEX;return true;}
0790   if(a_format=="gl2ps_pgf") {a_gl2ps_format = TOOLS_GL2PS_PGF;return true;}
0791   a_gl2ps_format = TOOLS_GL2PS_PS;
0792   return false;
0793 }
0794 
0795 inline bool gl2ps_s2sort(const std::string& a_sort,int& a_gl2ps_sort) {
0796   if(a_sort=="NO_SORT")     {a_gl2ps_sort = TOOLS_GL2PS_NO_SORT;    return true;}
0797   if(a_sort=="SIMPLE_SORT") {a_gl2ps_sort = TOOLS_GL2PS_SIMPLE_SORT;return true;}
0798   if(a_sort=="BSP_SORT")    {a_gl2ps_sort = TOOLS_GL2PS_BSP_SORT;   return true;}
0799   a_gl2ps_sort = TOOLS_GL2PS_NO_SORT;
0800   return false;
0801 }
0802 
0803 }}
0804 
0805 #include "../words"
0806 #include "../forit"
0807 #include "../touplow"
0808 #include "../sout"
0809 
0810 namespace tools {
0811 namespace sg {
0812 
0813 inline bool gl2ps_s2options(const std::string& a_opts,int& a_gl2ps_opts) {
0814   std::vector<std::string> opts;
0815   words(a_opts,"|",false,opts);
0816   a_gl2ps_opts = 0;
0817   tools_vforit(std::string,opts,it) {
0818     touppercase(*it);
0819     const std::string& item = *it;
0820          if(item=="NONE")                 a_gl2ps_opts |= TOOLS_GL2PS_NONE;
0821     else if(item=="DRAW_BACKGROUND")      a_gl2ps_opts |= TOOLS_GL2PS_DRAW_BACKGROUND;
0822     else if(item=="SIMPLE_LINE_OFFSET")   a_gl2ps_opts |= TOOLS_GL2PS_SIMPLE_LINE_OFFSET;
0823     else if(item=="SILENT")               a_gl2ps_opts |= TOOLS_GL2PS_SILENT;
0824     else if(item=="BEST_ROOT")            a_gl2ps_opts |= TOOLS_GL2PS_BEST_ROOT;
0825     else if(item=="OCCLUSION_CULL")       a_gl2ps_opts |= TOOLS_GL2PS_OCCLUSION_CULL;
0826     else if(item=="NO_TEXT")              a_gl2ps_opts |= TOOLS_GL2PS_NO_TEXT;
0827     else if(item=="LANDSCAPE")            a_gl2ps_opts |= TOOLS_GL2PS_LANDSCAPE;
0828     else if(item=="NO_PS3_SHADING")       a_gl2ps_opts |= TOOLS_GL2PS_NO_PS3_SHADING;
0829     else if(item=="NO_PIXMAP")            a_gl2ps_opts |= TOOLS_GL2PS_NO_PIXMAP;
0830     else if(item=="USE_CURRENT_VIEWPORT") a_gl2ps_opts |= TOOLS_GL2PS_USE_CURRENT_VIEWPORT;
0831     else if(item=="COMPRESS")             a_gl2ps_opts |= TOOLS_GL2PS_COMPRESS;
0832     else if(item=="NO_BLENDING")          a_gl2ps_opts |= TOOLS_GL2PS_NO_BLENDING;
0833     else if(item=="TIGHT_BOUNDING_BOX")   a_gl2ps_opts |= TOOLS_GL2PS_TIGHT_BOUNDING_BOX;
0834     else if(item=="NO_OPENGL_CONTEXT")    a_gl2ps_opts |= TOOLS_GL2PS_NO_OPENGL_CONTEXT;
0835     else if(item=="NO_TEX_FONTSIZE")      a_gl2ps_opts |= TOOLS_GL2PS_NO_TEX_FONTSIZE;
0836     else if(item=="PORTABLE_SORT")        a_gl2ps_opts |= TOOLS_GL2PS_PORTABLE_SORT;
0837     else                                  {a_gl2ps_opts = 0;return false;}
0838   }
0839   return true;
0840 }
0841 
0842 }}
0843 
0844 
0845 #endif