// Copyright (C) 2010, Guy Barrand. All rights reserved. // See the file tools.license for terms. #ifndef tools_sg_render_gstos #define tools_sg_render_gstos #include "gstos" #include "render_action" #include "gstos_add" namespace tools { namespace sg { class render_gstos : public gstos { typedef gstos parent; public: virtual void visit(gstos_add& a_visitor,draw_type a_style) = 0; protected: //gstos virtual unsigned int create_gsto(std::ostream&,sg::render_manager& a_mgr) { std::vector gsto_data; gstos_add _add; visit(_add,draw_points); append(gsto_data,_add.m_xyzs); m_gstos_points_sz = _add.m_xyzs.size(); _add.clear(); visit(_add,draw_lines); append(gsto_data,_add.m_xyzs); m_gstos_lines_sz = _add.m_xyzs.size(); _add.clear(); visit(_add,draw_filled); append(gsto_data,_add.m_xyzs); m_gstos_tris_sz = _add.m_xyzs.size(); append(gsto_data,_add.m_nms); m_gstos_nms_sz = _add.m_nms.size(); if(gsto_data.empty()) return 0; return a_mgr.create_gsto_from_data(gsto_data); } public: //node bool gstos_render(render_action& a_action) { const state& state = a_action.state(); bool draw_edges = false; if(state.m_draw_type==draw_filled) draw_edges = state.m_GL_LIGHTING?false:true; if(state.m_use_gsto) { unsigned int _id = get_gsto_id(a_action.out(),a_action.render_manager()); if(_id) { bufpos pxyzs = 0; bufpos plines = pxyzs+m_gstos_points_sz*sizeof(float); bufpos ptris = plines+m_gstos_lines_sz*sizeof(float); bufpos pnms = ptris+m_gstos_tris_sz*sizeof(float); a_action.begin_gsto(_id); if(draw_edges) { a_action.color4f(0,0,0,1); //if lighten, then rendered grey. a_action.line_width(1); a_action.draw_gsto_v(gl::lines(),m_gstos_lines_sz/3,plines); //pushes back the filled polygons to avoid z-fighting with lines a_action.set_polygon_offset(true); a_action.color4f(state.m_color); a_action.line_width(state.m_line_width); } if(state.m_draw_type==draw_points) { a_action.draw_gsto_v(gl::points(),m_gstos_points_sz/3,pxyzs); } else if(state.m_draw_type==draw_lines) { a_action.draw_gsto_v(gl::lines(),m_gstos_lines_sz/3,plines); } else { a_action.draw_gsto_vn(gl::triangles(),m_gstos_tris_sz/3,ptris,pnms); } if(draw_edges) a_action.set_polygon_offset(state.m_GL_POLYGON_OFFSET_FILL); a_action.end_gsto(); return true; } else { //!_id // use immediate rendering. } } else { clean_gstos(&a_action.render_manager()); } return false; } bool gstos_render_no_style(render_action& a_action) { //for sg::markers. const state& state = a_action.state(); if(state.m_use_gsto) { unsigned int _id = get_gsto_id(a_action.out(),a_action.render_manager()); if(_id) { bufpos pxyzs = 0; bufpos plines = pxyzs+m_gstos_points_sz*sizeof(float); bufpos ptris = plines+m_gstos_lines_sz*sizeof(float); bufpos pnms = ptris+m_gstos_tris_sz*sizeof(float); a_action.begin_gsto(_id); a_action.draw_gsto_v(gl::points(),m_gstos_points_sz/3,pxyzs); a_action.draw_gsto_v(gl::lines(),m_gstos_lines_sz/3,plines); a_action.draw_gsto_vn(gl::triangles(),m_gstos_tris_sz/3,ptris,pnms); a_action.end_gsto(); return true; } else { //!_id // use immediate rendering. } } else { clean_gstos(&a_action.render_manager()); } return false; } public: render_gstos():parent(),m_gstos_points_sz(0),m_gstos_lines_sz(0),m_gstos_tris_sz(0),m_gstos_nms_sz(0) {} virtual ~render_gstos() {} public: render_gstos(const render_gstos& a_from):parent(a_from),m_gstos_points_sz(0),m_gstos_lines_sz(0),m_gstos_tris_sz(0),m_gstos_nms_sz(0) {} render_gstos& operator=(const render_gstos& a_from){ parent::operator=(a_from); m_gstos_points_sz = 0; m_gstos_lines_sz = 0; m_gstos_tris_sz = 0; m_gstos_nms_sz = 0; return *this; } protected: size_t m_gstos_points_sz; size_t m_gstos_lines_sz; size_t m_gstos_tris_sz; size_t m_gstos_nms_sz; }; }} #endif