// Copyright (C) 2010, Guy Barrand. All rights reserved. // See the file tools.license for terms. #ifndef tools_sg_gl2ps_action #define tools_sg_gl2ps_action #include "gl2ps_manager" #include "../gl2ps" #include "render_action" #include "primitive_visitor" #include "../colorfs" #include "../lina/plane" #include //FILE namespace tools { namespace sg { class gl2ps_action : public render_action { TOOLS_ACTION(gl2ps_action,tools::sg::gl2ps_action,render_action) private: gl2ps_action& get_me() {return *this;} static unsigned int _GL2PS_POINT() {return 2;} static unsigned int _GL2PS_LINE() {return 3;} static unsigned int _GL2PS_TRIANGLE() {return 5;} public: virtual void draw_vertex_array(gl::mode_t a_mode, size_t a_floatn, const float* a_xyzs){ m_pv.add_primitive(a_mode,a_floatn,a_xyzs); } virtual void draw_vertex_array_xy(gl::mode_t a_mode, size_t a_floatn, const float* a_xys){ m_pv.add_primitive_xy(a_mode,a_floatn,a_xys); } virtual void draw_vertex_color_array(gl::mode_t a_mode, size_t a_floatn, const float* a_xyzs, const float* a_rgbas){ m_pv.add_primitive_rgba(a_mode,a_floatn,a_xyzs,a_rgbas); } virtual void draw_vertex_normal_array(gl::mode_t a_mode, size_t a_floatn, const float* a_xyzs, const float* a_nms){ m_pv.add_primitive_normal(a_mode,a_floatn,a_xyzs,a_nms); } virtual void draw_vertex_color_normal_array(gl::mode_t a_mode, size_t a_floatn, const float* a_xyzs, const float* a_rgbas, const float* a_nms){ // We expect a_nms of size : 3*(a_floatn/3) // (then one normal per 3D point). m_pv.add_primitive_normal_rgba(a_mode,a_floatn,a_xyzs,a_nms,a_rgbas); } virtual void clear_color(float a_r,float a_g,float a_b,float /*a_a*/){ //a_a ? set_background(a_r,a_g,a_b); } virtual void color4f(float a_r,float a_g,float a_b,float a_a){ m_color.set_value(a_r,a_g,a_b,a_a); } virtual void line_width(float a_v){m_line_width = a_v;} virtual void point_size(float a_v) {m_point_size = a_v;} virtual void set_polygon_offset(bool a_v) {m_POLYGON_OFFSET_FILL = a_v;} virtual void normal(float a_x,float a_y,float a_z) { m_normal.set_value(a_x,a_y,a_z); } virtual void set_winding(winding_type a_v) { m_ccw = (a_v==winding_ccw?true:false); } virtual void set_shade_model(shade_type a_v) { if(a_v==shade_smooth) {} else {} } virtual void set_depth_test(bool a_on) {m_DEPTH_TEST = a_on;} virtual void set_cull_face(bool a_on) {m_CULL_FACE = a_on;} virtual void set_point_smooth(bool a_on) {m_POINT_SMOOTH = a_on;} virtual void set_line_smooth(bool a_on) {m_LINE_SMOOTH = a_on;} virtual void load_proj_matrix(const mat4f& a_mtx) {m_proj = a_mtx;} virtual void load_model_matrix(const mat4f& a_mtx) { m_model = a_mtx; set_normal_matrix(); } virtual unsigned int max_lights() {return 1000;} virtual void enable_light(unsigned int, float a_dx,float a_dy,float a_dz, float a_r,float a_g,float a_b,float a_a, float a_ar,float a_ag,float a_ab,float a_aa){ m_light_color.set_value(a_r,a_g,a_b,a_a); m_light_ambient.set_value(a_ar,a_ag,a_ab,a_aa); m_light_direction.set_value(a_dx,a_dy,a_dz); m_light_direction.normalize(); m_light_on = true; } virtual void set_lighting(bool a_on) {m_light_on = a_on;} virtual void set_blend(bool) {} virtual void restore_state(unsigned int /*a_ret_num_light*/) { const sg::state& _state = state(); m_proj = _state.m_proj; m_model = _state.m_model; set_normal_matrix(); m_color = _state.m_color; m_normal = _state.m_normal; m_ccw = (_state.m_winding==winding_ccw?true:false); m_POLYGON_OFFSET_FILL = _state.m_GL_POLYGON_OFFSET_FILL; m_CULL_FACE = _state.m_GL_CULL_FACE; m_POINT_SMOOTH = _state.m_GL_POINT_SMOOTH; m_LINE_SMOOTH = _state.m_GL_LINE_SMOOTH; m_point_size = _state.m_point_size; m_line_width = _state.m_line_width; m_light_on = _state.m_GL_LIGHTING; m_DEPTH_TEST = _state.m_GL_DEPTH_TEST; } ///////////////////////////////////////////////////////////////// /// texture ///////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////// virtual void draw_vertex_array_texture(gl::mode_t,size_t a_xyzn,const float* a_xyzs, gstoid a_id,const float* a_tcs) { img_byte img; if(!m_mgr.find(a_id,img)) return; m_pv.add_texture(m_out,a_xyzn,a_xyzs,img,a_tcs); } virtual void draw_vertex_normal_array_texture(gl::mode_t a_mode, size_t a_xyzn, const float* a_xyzs, const float* /*a_nms*/, gstoid a_id, const float* a_tcs) { draw_vertex_array_texture(a_mode,a_xyzn,a_xyzs,a_id,a_tcs); } ///////////////////////////////////////////////////////////////// /// VBO ///////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////// virtual void begin_gsto(gstoid) {} virtual void draw_gsto_v(gl::mode_t,size_t,bufpos){} virtual void draw_gsto_vc(gl::mode_t,size_t,bufpos,bufpos) {} virtual void draw_gsto_vn(gl::mode_t,size_t,bufpos,bufpos) {} virtual void draw_gsto_vcn(gl::mode_t,size_t,bufpos,bufpos,bufpos) {} virtual void end_gsto() {} ///////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////// virtual sg::render_manager& render_manager() {return m_mgr;} public: gl2ps_action(gl2ps_manager& a_mgr,std::ostream& a_out,unsigned int a_ww,unsigned int a_wh) :parent(a_out,a_ww,a_wh) ,m_mgr(a_mgr) ,m_gl2ps_context(0) ,m_FILE(0) ,m_pv(get_me()) ,m_light_color(colorf_white()) ,m_light_ambient(colorf_black()) ,m_light_direction(vec3f(0,0,-1)) ,m_ccw(true) ,m_POLYGON_OFFSET_FILL(false) ,m_CULL_FACE(true) ,m_POINT_SMOOTH(false) ,m_LINE_SMOOTH(false) ,m_point_size(1) ,m_line_width(1) ,m_light_on(false) ,m_DEPTH_TEST(true) { m_back[0] = 1; m_back[1] = 1; m_back[2] = 1; m_vp_mtx.set_identity(); m_vp_mtx.mul_translate(float(m_ww)/2,float(m_wh)/2,0); m_vp_mtx.mul_scale(float(m_ww)/2,float(m_wh)/2,1); m_proj.set_identity(); m_model.set_identity(); m_normal_matrix.set_identity(); } virtual ~gl2ps_action(){ close(); } protected: gl2ps_action(const gl2ps_action& a_from) :parent(a_from) ,m_mgr(a_from.m_mgr) ,m_gl2ps_context(0) ,m_FILE(0) ,m_vp_mtx(a_from.m_vp_mtx) ,m_pv(a_from.m_pv) ,m_light_color(a_from.m_light_color) ,m_light_ambient(a_from.m_light_ambient) ,m_light_direction(a_from.m_light_direction) ,m_normal(a_from.m_normal) ,m_proj(a_from.m_proj) ,m_model(a_from.m_model) ,m_normal_matrix(a_from.m_normal_matrix) ,m_color(a_from.m_color) ,m_ccw(a_from.m_ccw) ,m_POLYGON_OFFSET_FILL(a_from.m_POLYGON_OFFSET_FILL) ,m_CULL_FACE(a_from.m_CULL_FACE) ,m_POINT_SMOOTH(a_from.m_POINT_SMOOTH) ,m_LINE_SMOOTH(a_from.m_LINE_SMOOTH) ,m_point_size(a_from.m_point_size) ,m_line_width(a_from.m_line_width) ,m_light_on(a_from.m_light_on) ,m_DEPTH_TEST(a_from.m_DEPTH_TEST) { m_back[0] = a_from.m_back[0]; m_back[1] = a_from.m_back[1]; m_back[2] = a_from.m_back[2]; } gl2ps_action& operator=(const gl2ps_action& a_from){ parent::operator=(a_from); if(&a_from==this) return *this; close(); m_back[0] = a_from.m_back[0]; m_back[1] = a_from.m_back[1]; m_back[2] = a_from.m_back[2]; m_vp_mtx = a_from.m_vp_mtx; m_pv = a_from.m_pv; m_light_color = a_from.m_light_color; m_light_ambient = a_from.m_light_ambient; m_light_direction = a_from.m_light_direction; m_normal = a_from.m_normal; m_proj = a_from.m_proj; m_model = a_from.m_model; m_normal_matrix = a_from.m_normal_matrix; m_color = a_from.m_color; m_ccw = a_from.m_ccw; m_POLYGON_OFFSET_FILL = a_from.m_POLYGON_OFFSET_FILL; m_CULL_FACE = a_from.m_CULL_FACE; m_POINT_SMOOTH = a_from.m_POINT_SMOOTH; m_LINE_SMOOTH = a_from.m_LINE_SMOOTH; m_point_size = a_from.m_point_size; m_line_width = a_from.m_line_width; m_light_on = a_from.m_light_on; m_DEPTH_TEST = a_from.m_DEPTH_TEST; return *this; } public: bool open(const std::string& a_name,int a_format = TOOLS_GL2PS_EPS) { return open(a_name,a_format,-1,-1); } bool open(const std::string& a_name,int a_format,int a_sort,int a_options) { close(); m_gl2ps_context = ::tools_gl2psCreateContext(); if(!m_gl2ps_context) { m_out << "tools::sg::gl2ps_action::open :" << " can't create gl2ps context." << std::endl; return false; } m_FILE = ::fopen(a_name.c_str(),"wb"); if(!m_FILE) { m_out << "tools::sg::gl2ps_action::open :" << " can't open file " << a_name << "." << std::endl; ::tools_gl2psDeleteContext(m_gl2ps_context); m_gl2ps_context = 0; return false; } int sort = 0; if(a_sort==(-1)) { sort = TOOLS_GL2PS_BSP_SORT; } else { sort = a_sort; } int options = 0; if(a_options==(-1)) { options = TOOLS_GL2PS_SILENT | TOOLS_GL2PS_OCCLUSION_CULL | TOOLS_GL2PS_BEST_ROOT | TOOLS_GL2PS_DRAW_BACKGROUND; } else { options = a_options; } tools_GLint vp[4]; vp[0] = 0; vp[1] = 0; vp[2] = m_ww; vp[3] = m_wh; int bufsize = 0; if(::tools_gl2psBeginPage(m_gl2ps_context,"","tools_sg_write_gl2ps", vp,a_format,sort,options, TOOLS_GL_RGBA,0, NULL,0,0,0,bufsize, m_FILE,a_name.c_str())==TOOLS_GL2PS_ERROR) { m_out << "tools::sg::gl2ps_action::open :" << " tools_gl2psBeginPage() failed." << std::endl; ::fclose(m_FILE); m_FILE = 0; ::tools_gl2psDeleteContext(m_gl2ps_context); m_gl2ps_context = 0; return false; } ::tools_gl2psSetBackgroundColor(m_gl2ps_context,m_back[0],m_back[1],m_back[2]); m_vp_mtx.set_identity(); m_vp_mtx.mul_translate(float(m_ww)/2,float(m_wh)/2,0); m_vp_mtx.mul_scale(float(m_ww)/2,float(m_wh)/2,1); return true; } bool close() { tools_GLint _status = 0; if(m_gl2ps_context) { _status = ::tools_gl2psEndPage(m_gl2ps_context); } if(m_FILE) { ::fclose(m_FILE); m_FILE = 0; } if(m_gl2ps_context) { ::tools_gl2psDeleteContext(m_gl2ps_context); m_gl2ps_context = 0; } if (_status == TOOLS_GL2PS_OVERFLOW) return false; return true; } void set_background(float a_r,float a_g,float a_b) { m_back[0] = a_r; m_back[1] = a_g; m_back[2] = a_b; } protected: void set_normal_matrix() { mat4f tmp(m_model); tmp.no_translate(); if(!tmp.invert(m_normal_matrix)) { m_out << "tools::sg::gl2ps_action::set_normal_matrix : can't invert model matrix." << std::endl; } m_normal_matrix.transpose(); } bool project_point(float& a_x,float& a_y,float& a_z,float& a_w) { a_w = 1; m_model.mul_4f(a_x,a_y,a_z,a_w); m_proj.mul_4f(a_x,a_y,a_z,a_w); if(a_w==0) return false; a_x /= a_w; a_y /= a_w; a_z /= a_w; return true; } static void set_vtx(tools_GL2PSvertex* a_vs,unsigned int a_index, float a_x,float a_y,float a_z, float a_r,float a_g,float a_b,float a_a){ a_vs[a_index].xyz[0] = a_x; a_vs[a_index].xyz[1] = a_y; a_vs[a_index].xyz[2] = a_z; a_vs[a_index].rgba[0] = a_r; a_vs[a_index].rgba[1] = a_g; a_vs[a_index].rgba[2] = a_b; a_vs[a_index].rgba[3] = a_a; } class primvis : public primitive_visitor { protected: virtual bool project(float& a_x,float& a_y,float& a_z,float& a_w) { return m_this.project_point(a_x,a_y,a_z,a_w); } virtual bool add_point(float a_x,float a_y,float a_z,float) { if(!m_this.m_gl2ps_context) return false; float r = m_this.m_color[0]; float g = m_this.m_color[1]; float b = m_this.m_color[2]; float a = m_this.m_color[3]; tools_GLint offset = 0; tools_GLfloat ofactor = 0; tools_GLfloat ounits = 0; tools_GLushort pattern = 0; tools_GLint factor = 0; tools_GLfloat sz = m_this.m_point_size; tools_GLint linecap = 0; tools_GLint linejoin = 0; char boundary = 0; tools_GL2PSvertex vertices[1]; m_this.m_vp_mtx.mul_3f(a_x,a_y,a_z); m_this.set_vtx(vertices,0, a_x,a_y,a_z, r,g,b,a); ::tools_gl2psAddPolyPrimitive(m_this.m_gl2ps_context,_GL2PS_POINT(),1,vertices,offset,ofactor,ounits,pattern,factor,sz,linecap,linejoin,boundary); return true; } virtual bool add_point(float a_x,float a_y,float a_z,float, float a_r,float a_g,float a_b,float a_a) { if(!m_this.m_gl2ps_context) return false; tools_GLint offset = 0; tools_GLfloat ofactor = 0; tools_GLfloat ounits = 0; tools_GLushort pattern = 0; tools_GLint factor = 0; tools_GLfloat sz = m_this.m_point_size; tools_GLint linecap = 0; tools_GLint linejoin = 0; char boundary = 0; tools_GL2PSvertex vertices[1]; m_this.m_vp_mtx.mul_3f(a_x,a_y,a_z); m_this.set_vtx(vertices,0, a_x,a_y,a_z, a_r,a_g,a_b,a_a); ::tools_gl2psAddPolyPrimitive(m_this.m_gl2ps_context,_GL2PS_POINT(),1,vertices,offset,ofactor,ounits,pattern,factor,sz,linecap,linejoin,boundary); return true; } virtual bool add_line(float a_bx,float a_by,float a_bz,float, float a_ex,float a_ey,float a_ez,float) { if(!m_this.m_gl2ps_context) return false; float r = m_this.m_color[0]; float g = m_this.m_color[1]; float b = m_this.m_color[2]; float a = m_this.m_color[3]; tools_GLint offset = 0; tools_GLfloat ofactor = 0; tools_GLfloat ounits = 0; tools_GLushort pattern = 0; tools_GLint factor = 0; tools_GLfloat lwidth = m_this.m_line_width; tools_GLint linecap = 0; tools_GLint linejoin = 0; char boundary = 0; tools_GL2PSvertex vertices[2]; m_this.m_vp_mtx.mul_3f(a_bx,a_by,a_bz); m_this.m_vp_mtx.mul_3f(a_ex,a_ey,a_ez); m_this.set_vtx(vertices,0, a_bx,a_by,a_bz, r,g,b,a); m_this.set_vtx(vertices,1, a_ex,a_ey,a_ez, r,g,b,a); ::tools_gl2psAddPolyPrimitive(m_this.m_gl2ps_context,_GL2PS_LINE(),2,vertices,offset,ofactor,ounits,pattern,factor,lwidth,linecap,linejoin,boundary); return true; } virtual bool add_line(float a_bx,float a_by,float a_bz,float, float a_br,float a_bg,float a_bb,float a_ba, float a_ex,float a_ey,float a_ez,float, float a_er,float a_eg,float a_eb,float a_ea){ if(!m_this.m_gl2ps_context) return false; tools_GLint offset = 0; tools_GLfloat ofactor = 0; tools_GLfloat ounits = 0; tools_GLushort pattern = 0; tools_GLint factor = 0; tools_GLfloat lwidth = m_this.m_line_width; tools_GLint linecap = 0; tools_GLint linejoin = 0; char boundary = 0; tools_GL2PSvertex vertices[2]; m_this.m_vp_mtx.mul_3f(a_bx,a_by,a_bz); m_this.m_vp_mtx.mul_3f(a_ex,a_ey,a_ez); m_this.set_vtx(vertices,0, a_bx,a_by,a_bz, a_br,a_bg,a_bb,a_ba); m_this.set_vtx(vertices,1, a_ex,a_ey,a_ez, a_er,a_eg,a_eb,a_ea); ::tools_gl2psAddPolyPrimitive(m_this.m_gl2ps_context,_GL2PS_LINE(),2,vertices,offset,ofactor,ounits,pattern,factor,lwidth,linecap,linejoin,boundary); return true; } virtual bool add_triangle(float a_p1x,float a_p1y,float a_p1z,float a_p1w, float a_p2x,float a_p2y,float a_p2z,float a_p2w, float a_p3x,float a_p3y,float a_p3z,float a_p3w){ float r = m_this.m_color[0]; float g = m_this.m_color[1]; float b = m_this.m_color[2]; float a = m_this.m_color[3]; return _add_triangle(a_p1x,a_p1y,a_p1z,a_p1w, m_this.m_normal.x(),m_this.m_normal.y(),m_this.m_normal.z(), r,g,b,a, a_p2x,a_p2y,a_p2z,a_p2w, m_this.m_normal.x(),m_this.m_normal.y(),m_this.m_normal.z(), r,g,b,a, a_p3x,a_p3y,a_p3z,a_p3w, m_this.m_normal.x(),m_this.m_normal.y(),m_this.m_normal.z(), r,g,b,a); } virtual bool add_triangle( float a_p1x,float a_p1y,float a_p1z,float a_p1w, float a_r1,float a_g1,float a_b1,float a_a1, float a_p2x,float a_p2y,float a_p2z,float a_p2w, float a_r2,float a_g2,float a_b2,float a_a2, float a_p3x,float a_p3y,float a_p3z,float a_p3w, float a_r3,float a_g3,float a_b3,float a_a3){ return _add_triangle(a_p1x,a_p1y,a_p1z,a_p1w, m_this.m_normal.x(),m_this.m_normal.y(),m_this.m_normal.z(), a_r1,a_g1,a_b1,a_a1, a_p2x,a_p2y,a_p2z,a_p2w, m_this.m_normal.x(),m_this.m_normal.y(),m_this.m_normal.z(), a_r2,a_g2,a_b2,a_a2, a_p3x,a_p3y,a_p3z,a_p3w, m_this.m_normal.x(),m_this.m_normal.y(),m_this.m_normal.z(), a_r3,a_g3,a_b3,a_a3); } virtual bool project_normal(float& /*a_x*/,float& /*a_y*/,float& /*a_z*/) { return true; } virtual bool add_point_normal(float a_x,float a_y,float a_z,float a_w, float /*a_nx*/,float /*a_ny*/,float /*a_nz*/) { add_point(a_x,a_y,a_z,a_w); return true; } virtual bool add_point_normal(float a_x,float a_y,float a_z,float a_w, float /*a_nx*/,float /*a_ny*/,float /*a_nz*/, float a_r,float a_g,float a_b,float a_a) { add_point(a_x,a_y,a_z,a_w,a_r,a_g,a_b,a_a); return true; } virtual bool add_line_normal(float a_bx,float a_by,float a_bz,float a_bw, float /*a_bnx*/,float /*a_bny*/,float /*a_bnz*/, float a_ex,float a_ey,float a_ez,float a_ew, float /*a_enx*/,float /*a_eny*/,float /*a_enz*/) { add_line(a_bx,a_by,a_bz,a_bw, a_ex,a_ey,a_ez,a_ew); return true; } virtual bool add_line_normal(float a_bx,float a_by,float a_bz,float a_bw, float /*a_bnx*/,float /*a_bny*/,float /*a_bnz*/, float a_br,float a_bg,float a_bb,float a_ba, float a_ex,float a_ey,float a_ez,float a_ew, float /*a_enx*/,float /*a_eny*/,float /*a_enz*/, float a_er,float a_eg,float a_eb,float a_ea){ 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); return true; } virtual bool add_triangle_normal( float a_p1x,float a_p1y,float a_p1z,float a_p1w, float a_n1x,float a_n1y,float a_n1z, float a_p2x,float a_p2y,float a_p2z,float a_p2w, float a_n2x,float a_n2y,float a_n2z, float a_p3x,float a_p3y,float a_p3z,float a_p3w, float a_n3x,float a_n3y,float a_n3z) { float r = m_this.m_color[0]; float g = m_this.m_color[1]; float b = m_this.m_color[2]; float a = m_this.m_color[3]; return _add_triangle(a_p1x,a_p1y,a_p1z,a_p1w, a_n1x,a_n1y,a_n1z, r,g,b,a, a_p2x,a_p2y,a_p2z,a_p2w, a_n2x,a_n2y,a_n2z, r,g,b,a, a_p3x,a_p3y,a_p3z,a_p3w, a_n3x,a_n3y,a_n3z, r,g,b,a); } virtual bool add_triangle_normal( float a_p1x,float a_p1y,float a_p1z,float a_p1w, float a_n1x,float a_n1y,float a_n1z, float a_r1,float a_g1,float a_b1,float a_a1, float a_p2x,float a_p2y,float a_p2z,float a_p2w, float a_n2x,float a_n2y,float a_n2z, float a_r2,float a_g2,float a_b2,float a_a2, float a_p3x,float a_p3y,float a_p3z,float a_p3w, float a_n3x,float a_n3y,float a_n3z, float a_r3,float a_g3,float a_b3,float a_a3){ return _add_triangle(a_p1x,a_p1y,a_p1z,a_p1w, a_n1x,a_n1y,a_n1z, a_r1,a_g1,a_b1,a_a1, a_p2x,a_p2y,a_p2z,a_p2w, a_n2x,a_n2y,a_n2z, a_r2,a_g2,a_b2,a_a2, a_p3x,a_p3y,a_p3z,a_p3w, a_n3x,a_n3y,a_n3z, a_r3,a_g3,a_b3,a_a3); } public: primvis(gl2ps_action& a_this):m_this(a_this){} virtual ~primvis(){} public: primvis(const primvis& a_from) :primitive_visitor(a_from) ,m_this(a_from.m_this) {} primvis& operator=(const primvis& a_from){ primitive_visitor::operator=(a_from); return *this; } protected: bool _add_triangle(float a_p1x,float a_p1y,float a_p1z,float /*a_p1w*/, float a_n1x,float a_n1y,float a_n1z, float a_r1,float a_g1,float a_b1,float a_a1, float a_p2x,float a_p2y,float a_p2z,float /*a_p2w*/, float a_n2x,float a_n2y,float a_n2z, float a_r2,float a_g2,float a_b2,float a_a2, float a_p3x,float a_p3y,float a_p3z,float /*a_p3w*/, float a_n3x,float a_n3y,float a_n3z, float a_r3,float a_g3,float a_b3,float a_a3) { if(!m_this.m_gl2ps_context) return false; float p1x = a_p1x;float p1y = a_p1y;float p1z = a_p1z;//float p1w = a_p1w; float p2x = a_p2x;float p2y = a_p2y;float p2z = a_p2z;//float p2w = a_p2w; float p3x = a_p3x;float p3y = a_p3y;float p3z = a_p3z;//float p3w = a_p3w; m_this.m_vp_mtx.mul_3f(p1x,p1y,p1z); m_this.m_vp_mtx.mul_3f(p2x,p2y,p2z); m_this.m_vp_mtx.mul_3f(p3x,p3y,p3z); {plane pn( vec3f(p1x,p1y,p1z), vec3f(p2x,p2y,p2z), vec3f(p3x,p3y,p3z) ); if(!pn.is_valid()) return true; float C = pn.normal()[2]; if(m_this.m_CULL_FACE){ if(m_this.m_ccw) { if(C<=0) return true; } else { if(C>=0) return true; } }} tools_GL2PSvertex vertices[3]; if(m_this.m_light_on) { // same logic as toolx/wasm/webgl.js: float nx = (a_n1x+a_n2x+a_n3x)/3.0f; float ny = (a_n1y+a_n2y+a_n3y)/3.0f; float nz = (a_n1z+a_n2z+a_n3z)/3.0f; m_this.m_normal_matrix.mul_dir_3f(nx,ny,nz); vec3f _normal(nx,ny,nz);_normal.normalize(); float _dot = _normal.dot(m_this.m_light_direction); float _r = (a_r1+a_r2+a_r3)/3.0f; float _g = (a_g1+a_g2+a_g3)/3.0f; float _b = (a_b1+a_b2+a_b3)/3.0f; float _a = (a_a1+a_a2+a_a3)/3.0f; colorf a_color(_r,_g,_b,_a); colorf frag_color = a_color; if(_dot<0.0) { _dot *= -1.0; colorf _tmp = m_this.m_light_color; _tmp *= _dot; _tmp += m_this.m_light_ambient; frag_color *= _tmp; } else { frag_color *= m_this.m_light_ambient; } frag_color.clamp(); frag_color.set_a(a_color.a()); float r = frag_color.r(); float g = frag_color.g(); float b = frag_color.b(); float a = frag_color.a(); m_this.set_vtx(vertices,0, p1x,p1y,p1z, r,g,b,a); m_this.set_vtx(vertices,1, p2x,p2y,p2z, r,g,b,a); m_this.set_vtx(vertices,2, p3x,p3y,p3z, r,g,b,a); } else { m_this.set_vtx(vertices,0, p1x,p1y,p1z, a_r1,a_g1,a_b1,a_a1); m_this.set_vtx(vertices,1, p2x,p2y,p2z, a_r2,a_g2,a_b2,a_a2); m_this.set_vtx(vertices,2, p3x,p3y,p3z, a_r3,a_g3,a_b3,a_a3); } tools_GLint offset = 0; tools_GLfloat ofactor = 0; tools_GLfloat ounits = 0; tools_GLushort pattern = 0; tools_GLint factor = 0; tools_GLfloat lwidth = m_this.m_line_width; tools_GLint linecap = 0; tools_GLint linejoin = 0; char boundary = 0; ::tools_gl2psAddPolyPrimitive(m_this.m_gl2ps_context,_GL2PS_TRIANGLE(),3,vertices,offset,ofactor,ounits,pattern,factor,lwidth,linecap,linejoin,boundary); return true; } protected: gl2ps_action& m_this; }; protected: gl2ps_manager& m_mgr; tools_GL2PScontext* m_gl2ps_context; FILE* m_FILE; float m_back[3]; mat4f m_vp_mtx; primvis m_pv; colorf m_light_color; colorf m_light_ambient; vec3f m_light_direction; vec3f m_normal; // to be restored in restore_state() : mat4f m_proj; mat4f m_model; mat4f m_normal_matrix; colorf m_color; bool m_ccw; bool m_POLYGON_OFFSET_FILL; bool m_CULL_FACE; bool m_POINT_SMOOTH; bool m_LINE_SMOOTH; float m_point_size; float m_line_width; bool m_light_on; bool m_DEPTH_TEST; }; inline bool gl2ps_s2format(const std::string& a_format,int& a_gl2ps_format) { if(a_format=="gl2ps_eps") {a_gl2ps_format = TOOLS_GL2PS_EPS;return true;} if(a_format=="gl2ps_ps") {a_gl2ps_format = TOOLS_GL2PS_PS; return true;} if(a_format=="gl2ps_pdf") {a_gl2ps_format = TOOLS_GL2PS_PDF;return true;} if(a_format=="gl2ps_svg") {a_gl2ps_format = TOOLS_GL2PS_SVG;return true;} if(a_format=="gl2ps_tex") {a_gl2ps_format = TOOLS_GL2PS_TEX;return true;} if(a_format=="gl2ps_pgf") {a_gl2ps_format = TOOLS_GL2PS_PGF;return true;} a_gl2ps_format = TOOLS_GL2PS_PS; return false; } inline bool gl2ps_s2sort(const std::string& a_sort,int& a_gl2ps_sort) { if(a_sort=="NO_SORT") {a_gl2ps_sort = TOOLS_GL2PS_NO_SORT; return true;} if(a_sort=="SIMPLE_SORT") {a_gl2ps_sort = TOOLS_GL2PS_SIMPLE_SORT;return true;} if(a_sort=="BSP_SORT") {a_gl2ps_sort = TOOLS_GL2PS_BSP_SORT; return true;} a_gl2ps_sort = TOOLS_GL2PS_NO_SORT; return false; } }} #include "../tokenize" #include "../forit" #include "../touplow" #include "../sout" namespace tools { namespace sg { inline bool gl2ps_s2options(const std::string& a_opts,int& a_gl2ps_opts) { std::vector opts; words(a_opts,"|",false,opts); a_gl2ps_opts = 0; tools_vforit(std::string,opts,it) { touppercase(*it); const std::string& item = *it; if(item=="NONE") a_gl2ps_opts |= TOOLS_GL2PS_NONE; else if(item=="DRAW_BACKGROUND") a_gl2ps_opts |= TOOLS_GL2PS_DRAW_BACKGROUND; else if(item=="SIMPLE_LINE_OFFSET") a_gl2ps_opts |= TOOLS_GL2PS_SIMPLE_LINE_OFFSET; else if(item=="SILENT") a_gl2ps_opts |= TOOLS_GL2PS_SILENT; else if(item=="BEST_ROOT") a_gl2ps_opts |= TOOLS_GL2PS_BEST_ROOT; else if(item=="OCCLUSION_CULL") a_gl2ps_opts |= TOOLS_GL2PS_OCCLUSION_CULL; else if(item=="NO_TEXT") a_gl2ps_opts |= TOOLS_GL2PS_NO_TEXT; else if(item=="LANDSCAPE") a_gl2ps_opts |= TOOLS_GL2PS_LANDSCAPE; else if(item=="NO_PS3_SHADING") a_gl2ps_opts |= TOOLS_GL2PS_NO_PS3_SHADING; else if(item=="NO_PIXMAP") a_gl2ps_opts |= TOOLS_GL2PS_NO_PIXMAP; else if(item=="USE_CURRENT_VIEWPORT") a_gl2ps_opts |= TOOLS_GL2PS_USE_CURRENT_VIEWPORT; else if(item=="COMPRESS") a_gl2ps_opts |= TOOLS_GL2PS_COMPRESS; else if(item=="NO_BLENDING") a_gl2ps_opts |= TOOLS_GL2PS_NO_BLENDING; else if(item=="TIGHT_BOUNDING_BOX") a_gl2ps_opts |= TOOLS_GL2PS_TIGHT_BOUNDING_BOX; else if(item=="NO_OPENGL_CONTEXT") a_gl2ps_opts |= TOOLS_GL2PS_NO_OPENGL_CONTEXT; else if(item=="NO_TEX_FONTSIZE") a_gl2ps_opts |= TOOLS_GL2PS_NO_TEX_FONTSIZE; else if(item=="PORTABLE_SORT") a_gl2ps_opts |= TOOLS_GL2PS_PORTABLE_SORT; else {a_gl2ps_opts = 0;return false;} } return true; } }} #endif