Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights reserved. 2 // See the file tools.license for terms. 3 4 #ifndef tools_sg_render_action 5 #define tools_sg_render_action 6 7 #include "matrix_action" 8 9 #include "../glprims" 10 #include "../vdata" 11 #include "../colorf" 12 13 namespace tools { 14 namespace sg { 15 class render_manager; 16 }} 17 18 19 namespace tools { 20 namespace sg { 21 22 typedef size_t bufpos; 23 24 class render_action : public matrix_action { 25 TOOLS_ACTION_NO_COPY(render_action,tools::sg::render_action,matrix_action) 26 public: 27 typedef unsigned int gstoid; 28 public: 29 virtual void load_proj_matrix(const mat4f&) = 0; 30 virtual void load_model_matrix(const mat4f&) = 0; 31 public: 32 virtual void draw_vertex_array(gl::mode_t,size_t,const float*) = 0; 33 virtual void draw_vertex_array_xy(gl::mode_t,size_t,const float*) = 0; 34 virtual void draw_vertex_color_array(gl::mode_t,size_t,const float*,const float*) = 0; 35 virtual void draw_vertex_normal_array(gl::mode_t,size_t,const float*,const float*) = 0; 36 virtual void draw_vertex_color_normal_array(gl::mode_t,size_t,const float*,const float*,const float*) = 0; 37 38 ///////////////////////////////////////////////////////////////// 39 /// texture ///////////////////////////////////////////////////// 40 ///////////////////////////////////////////////////////////////// 41 virtual void draw_vertex_array_texture(gl::mode_t,size_t,const float*,gstoid,const float*) = 0; 42 virtual void draw_vertex_normal_array_texture(gl::mode_t,size_t,const float*,const float*,gstoid,const float*) = 0; 43 44 ///////////////////////////////////////////////////////////////// 45 /// VBO ///////////////////////////////////////////////////////// 46 ///////////////////////////////////////////////////////////////// 47 virtual void begin_gsto(gstoid) = 0; 48 virtual void draw_gsto_v(gl::mode_t,size_t,bufpos) = 0; 49 virtual void draw_gsto_vc(gl::mode_t,size_t,bufpos,bufpos) = 0; 50 virtual void draw_gsto_vn(gl::mode_t,size_t,bufpos,bufpos) = 0; 51 virtual void draw_gsto_vcn(gl::mode_t,size_t,bufpos,bufpos,bufpos) = 0; 52 virtual void end_gsto() = 0; 53 ///////////////////////////////////////////////////////////////// 54 ///////////////////////////////////////////////////////////////// 55 ///////////////////////////////////////////////////////////////// 56 57 virtual void clear_color(float,float,float,float) = 0; 58 virtual void color4f(float,float,float,float) = 0; 59 virtual void line_width(float) = 0; 60 virtual void point_size(float) = 0; 61 virtual void set_polygon_offset(bool) = 0; 62 virtual void set_winding(winding_type) = 0; 63 virtual void set_shade_model(shade_type) = 0; 64 virtual void set_cull_face(bool) = 0; 65 virtual void set_point_smooth(bool) = 0; 66 virtual void set_line_smooth(bool) = 0; 67 virtual void normal(float,float,float) = 0; 68 virtual void set_depth_test(bool) = 0; 69 virtual unsigned int max_lights() = 0; 70 virtual void enable_light(unsigned int, 71 float,float,float, //directrion 72 float,float,float,float, //diffuse RGBA 73 float,float,float,float) = 0; //ambient RGBA 74 virtual void set_lighting(bool) = 0; 75 virtual void set_blend(bool) = 0; 76 virtual void restore_state(unsigned int) = 0; 77 78 virtual sg::render_manager& render_manager() = 0; //sg:: is needed. 79 public: 80 render_action(std::ostream& a_out,unsigned int a_ww,unsigned int a_wh) 81 :parent(a_out,a_ww,a_wh) 82 ,m_do_transparency(false) 83 ,m_have_to_do_transparency(false) 84 {} 85 virtual ~render_action(){} 86 public: 87 render_action(const render_action& a_from) 88 :parent(a_from) 89 ,m_do_transparency(a_from.m_do_transparency) 90 ,m_have_to_do_transparency(a_from.m_have_to_do_transparency) 91 {} 92 render_action& operator=(const render_action& a_from){ 93 parent::operator=(a_from); 94 m_do_transparency = a_from.m_do_transparency; 95 m_have_to_do_transparency = a_from.m_have_to_do_transparency; 96 return *this; 97 } 98 public: 99 void set_do_transparency(bool a_value) {m_do_transparency = a_value;} 100 bool do_transparency() const {return m_do_transparency;} 101 void set_have_to_do_transparency(bool a_value) {m_have_to_do_transparency = a_value;} 102 bool have_to_do_transparency() const {return m_have_to_do_transparency;} 103 104 bool have_to_render() { 105 bool transparent = state().m_color.a()!=1.0f?true:false; 106 if(transparent && state().m_GL_BLEND) { 107 if(m_do_transparency) return true; 108 m_have_to_do_transparency = true; 109 return false; 110 } 111 if(m_do_transparency) return false; 112 return true; 113 } 114 115 void load_matrices_to_identity() { 116 load_proj_matrix(m_identity); 117 load_model_matrix(m_identity); 118 } 119 void load_matrices_from_state() { 120 const sg::state& _state = state(); 121 load_proj_matrix(_state.m_proj); 122 load_model_matrix(_state.m_model); 123 } 124 125 void clear_color(const colorf& a_color){ 126 clear_color(a_color[0],a_color[1],a_color[2],a_color[3]); 127 } 128 void color4f(const colorf& a_color){ 129 color4f(a_color[0],a_color[1],a_color[2],a_color[3]); 130 } 131 132 void enable_light(unsigned int a_light, 133 const vec3f& a_dir, 134 const colorf& a_col,const colorf& a_ambient) { 135 enable_light(a_light, 136 a_dir[0],a_dir[1],a_dir[2], 137 a_col[0],a_col[1],a_col[2],a_col[3], 138 a_ambient[0],a_ambient[1],a_ambient[2],a_ambient[3]); 139 } 140 141 void draw_vertex_array(gl::mode_t a_mode,const std::vector<float>& a_xyzs){ 142 const float* _xyzs = vec_data<float>(a_xyzs); 143 draw_vertex_array(a_mode,a_xyzs.size(),_xyzs); 144 } 145 146 void draw_vertex_array_xy(gl::mode_t a_mode,const std::vector<float>& a_xys){ 147 const float* _xys = vec_data<float>(a_xys); 148 draw_vertex_array_xy(a_mode,a_xys.size(),_xys); 149 } 150 151 void draw_vertex_color_array(gl::mode_t a_mode, 152 const std::vector<float>& a_xyzs, 153 const std::vector<float>& a_rgbas){ 154 const float* _xyzs = vec_data<float>(a_xyzs); 155 const float* _rgbas = vec_data<float>(a_rgbas); 156 draw_vertex_color_array(a_mode,a_xyzs.size(),_xyzs,_rgbas); 157 } 158 159 void draw_vertex_normal_array(gl::mode_t a_mode, 160 const std::vector<float>& a_xyzs, 161 const std::vector<float>& a_nms){ 162 const float* _xyzs = vec_data<float>(a_xyzs); 163 const float* _nms = vec_data<float>(a_nms); 164 draw_vertex_normal_array(a_mode,a_xyzs.size(),_xyzs,_nms); 165 } 166 167 void draw_vertex_color_normal_array(gl::mode_t a_mode, 168 const std::vector<float>& a_xyzs, 169 const std::vector<float>& a_rgbas, 170 const std::vector<float>& a_nms){ 171 const float* _xyzs = vec_data<float>(a_xyzs); 172 const float* _rgbas = vec_data<float>(a_rgbas); 173 const float* _nms = vec_data<float>(a_nms); 174 draw_vertex_color_normal_array(a_mode,a_xyzs.size(),_xyzs,_rgbas,_nms); 175 } 176 177 void normal(const vec3f& a_vec) {normal(a_vec[0],a_vec[1],a_vec[2]);} 178 179 public: 180 // for sphere::visit template. 181 bool add_triangles_normal(size_t a_floatn,const float* a_xyzs,const float* a_nms) { 182 draw_vertex_normal_array(gl::triangles(),a_floatn,a_xyzs,a_nms); 183 return true; 184 } 185 bool add_triangle_fan_normal(size_t a_floatn,const float* a_xyzs,const float* a_nms) { 186 draw_vertex_normal_array(gl::triangle_fan(),a_floatn,a_xyzs,a_nms); 187 return true; 188 } 189 bool add_triangle_fan_normal_rgba(size_t a_floatn,const float* a_xyzs,float* a_nms,const float* a_rgbas) { 190 draw_vertex_color_normal_array(gl::triangle_fan(),a_floatn,a_xyzs,a_rgbas,a_nms); 191 return true; 192 } 193 bool add_triangle_strip_normal(size_t a_floatn,const float* a_xyzs,const float* a_nms) { 194 draw_vertex_normal_array(gl::triangle_strip(),a_floatn,a_xyzs,a_nms); 195 return true; 196 } 197 bool add_triangle_strip_normal_rgba(size_t a_floatn,const float* a_xyzs,const float* a_nms,const float* a_rgbas) { 198 draw_vertex_color_normal_array(gl::triangle_strip(),a_floatn,a_xyzs,a_rgbas,a_nms); 199 return true; 200 } 201 bool add_lines(size_t a_floatn,const float* a_xyzs) { 202 draw_vertex_array(gl::lines(),a_floatn,a_xyzs); 203 return true; 204 } 205 bool add_line_loop(size_t a_floatn,const float* a_xyzs) { 206 draw_vertex_array(gl::line_loop(),a_floatn,a_xyzs); 207 return true; 208 } 209 bool add_line_strip(size_t a_floatn,const float* a_xyzs) { 210 draw_vertex_array(gl::line_strip(),a_floatn,a_xyzs); 211 return true; 212 } 213 bool add_points(size_t a_floatn,const float* a_xyzs) { 214 draw_vertex_array(gl::points(),a_floatn,a_xyzs); 215 return true; 216 } 217 218 /* 219 bool add_triangles_texture(size_t a_floatn,const float* a_xyzs,gstoid a_tex,const float* a_texs){ 220 draw_vertex_array_texture(gl::triangles(),a_floatn,a_xyzs,a_tex,a_texs); 221 return true; 222 } 223 bool add_triangle_fan_texture(size_t a_floatn,const float* a_xyzs,gstoid a_tex,const float* a_texs){ 224 draw_vertex_array_texture(gl::triangle_fan(),a_floatn,a_xyzs,a_tex,a_texs); 225 return true; 226 } 227 bool add_triangle_strip_texture(size_t a_floatn,const float* a_xyzs,gstoid a_tex,const float* a_texs){ 228 draw_vertex_array_texture(gl::triangle_strip(),a_floatn,a_xyzs,a_tex,a_texs); 229 return true; 230 } 231 */ 232 bool add_triangle_fan_texture_normal(size_t a_floatn,const float* a_xyzs,const float* a_nms,gstoid a_tex,const float* a_texs){ 233 draw_vertex_normal_array_texture(gl::triangle_fan(),a_floatn,a_xyzs,a_nms,a_tex,a_texs); 234 return true; 235 } 236 bool add_triangle_strip_texture_normal(size_t a_floatn,const float* a_xyzs,const float* a_nms,gstoid a_tex,const float* a_texs){ 237 draw_vertex_normal_array_texture(gl::triangle_strip(),a_floatn,a_xyzs,a_nms,a_tex,a_texs); 238 return true; 239 } 240 241 bool add_line_loop(const std::vector<float>& a_xyzs){ 242 const float* _xyzs = vec_data<float>(a_xyzs); 243 draw_vertex_array(gl::line_loop(),a_xyzs.size(),_xyzs); 244 return true; 245 } 246 247 bool add_line_strip(const std::vector<float>& a_xyzs){ 248 const float* _xyzs = vec_data<float>(a_xyzs); 249 draw_vertex_array(gl::line_strip(),a_xyzs.size(),_xyzs); 250 return true; 251 } 252 253 /* 254 ///////////////////////////////////////////////////////// 255 /// for sg::markers and gstos : ///////////////////////// 256 ///////////////////////////////////////////////////////// 257 bool add_lines(const std::vector<float>& a_xyzs){ 258 const float* _xyzs = vec_data<float>(a_xyzs); 259 draw_vertex_array(gl::lines(),a_xyzs.size(),_xyzs); 260 return true; 261 } 262 bool add_triangles_normal(const std::vector<float>& a_xyzs,const std::vector<float>& a_nms){ 263 if(a_xyzs.size()!=a_nms.size()) return false; 264 const float* _xyzs = vec_data<float>(a_xyzs); 265 const float* _nms = vec_data<float>(a_nms); 266 draw_vertex_normal_array(gl::triangles(),a_xyzs.size(),_xyzs,_nms); 267 return true; 268 } 269 bool project_point(const mat4f& a_model_matrix,const mat4f& a_projection_matrix, 270 float& a_x,float& a_y,float& a_z,float& a_w) { 271 //return project_point(a_x,a_y,a_z,a_w); 272 a_w = 1; 273 a_model_matrix.mul_4f(a_x,a_y,a_z,a_w); 274 a_projection_matrix.mul_4f(a_x,a_y,a_z,a_w); 275 if(a_w==0.0F) return false; 276 a_x /= a_w; 277 a_y /= a_w; 278 a_z /= a_w; 279 return true; 280 } 281 ///////////////////////////////////////////////////////// 282 ///////////////////////////////////////////////////////// 283 ///////////////////////////////////////////////////////// 284 */ 285 286 bool add_triangle_strip_as_triangles(size_t a_floatn,const float* a_xyzs,const float* a_nms) { //used in sg::sphere, icosahedron_sphere. 287 // It appears that if glShadeModel is GL_FLAT, triangle strip does not look the same in "gsto mode" where it is rendered as triangles. 288 // We use this function for immediate rendering, in case we want the same rendering as "gsto mode". 289 290 size_t num = a_floatn/3; 291 if(num<3) return false; 292 size_t nxyzs = (num-2)*3*3; 293 294 std::vector<float> m_xyzs(nxyzs); 295 std::vector<float> m_nms(nxyzs); 296 297 {float* pxyzs = vec_data<float>(m_xyzs); 298 float* pnms = vec_data<float>(m_nms); 299 gl::triangle_strip_to_triangles_nms(num,a_xyzs,a_nms,pxyzs,pnms);} 300 301 return add_triangles_normal(nxyzs,vec_data<float>(m_xyzs),vec_data<float>(m_nms)); 302 } 303 304 void dump_vertex_array_xy(std::ostream& a_out,gl::mode_t /*a_mode*/,size_t a_floatn,const float* a_xys) { 305 size_t num = a_floatn/2; 306 if(!num) return; 307 a_out << "dump_vertex_array_xy : begin : " << num << std::endl; 308 for(size_t index=0;index<num;index++) { 309 a_out << "xy : " << index 310 << " " << a_xys[2*index] 311 << " " << a_xys[2*index+1] 312 << std::endl; 313 } 314 a_out << "dump_vertex_array_xy : end." << std::endl; 315 } 316 protected: 317 bool m_do_transparency; 318 bool m_have_to_do_transparency; 319 }; 320 321 }} 322 323 #endif