Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights 2 // See the file tools.license for terms. 3 4 #ifndef toolx_sg_GL_action 5 #define toolx_sg_GL_action 6 7 #include "GL_manager" 8 9 #include <tools/sg/render_action> 10 11 //#include <tools/mathf> 12 //#include <tools/lina/matout> 13 14 namespace toolx { 15 namespace sg { 16 17 class GL_action : public tools::sg::render_act 18 TOOLS_ACTION(GL_action,toolx::sg::GL_action, 19 public: 20 virtual void draw_vertex_array(tools::gl::mo 21 size_t num = a_floatn/3; 22 if(!num) return; 23 _draw_v(a_mode,num,a_xyzs); 24 } 25 26 virtual void draw_vertex_array_xy(tools::gl: 27 size_t num = a_floatn/2; 28 if(!num) return; 29 #ifdef _WIN32 30 float* vp = new float[num*3]; 31 if(!vp) return; 32 float* pos = vp; 33 float* pda = (float*)a_xys; 34 for(size_t index=0;index<num;index++){ 35 *pos = *pda;pos++;pda++; 36 *pos = *pda;pos++;pda++; 37 *pos = 0;pos++; //Windows GL needs a z = 38 } 39 ::glEnableClientState(GL_VERTEX_ARRAY); 40 ::glVertexPointer(3,GL_FLOAT,0,vp); 41 ::glDrawArrays(a_mode,0,(GLsizei)num); 42 ::glDisableClientState(GL_VERTEX_ARRAY); 43 delete [] vp; 44 #else 45 ::glEnableClientState(GL_VERTEX_ARRAY); 46 ::glVertexPointer(2,GL_FLOAT,0,a_xys); 47 ::glDrawArrays(a_mode,0,(GLsizei)num); 48 ::glDisableClientState(GL_VERTEX_ARRAY); 49 #endif 50 } 51 52 virtual void draw_vertex_color_array(tools:: 53 // Used in atb_vertices. 54 // We expect a_rgbas of size : 4*(a_floatn 55 // (then one RGBA color per 3D point). 56 size_t num = a_floatn/3; 57 if(!num) return; 58 _draw_vc(a_mode,num,a_xyzs,a_rgbas); 59 } 60 61 virtual void draw_vertex_normal_array(tools: 62 // We expect a_nms of size : 3*(a_floatn/3 63 // (then one normal per 3D point). 64 size_t num = a_floatn/3; 65 if(!num) return; 66 _draw_vn(a_mode,num,a_xyzs,a_nms); 67 } 68 69 virtual void draw_vertex_color_normal_array( 70 size_t 71 // Used in atb_vertices. 72 // We expect a_nms of size : 3*(a_floatn/3 73 // (then one normal per 3D point). 74 // We expect a_rgbas of size : 4*(a_floatn 75 // (then one RGBA color per 3D point). 76 size_t num = a_floatn/3; 77 if(!num) return; 78 _draw_vcn(a_mode,num,a_xyzs,a_rgbas,a_nms) 79 } 80 81 //////////////////////////////////////////// 82 /// texture //////////////////////////////// 83 //////////////////////////////////////////// 84 virtual void draw_vertex_array_texture(tools 85 size_ 86 const 87 gstoi 88 const 89 size_t num = a_floatn/3; 90 if(!num) return; 91 92 //expect 2*num a_tex_coords. 93 94 ::glEnable(GL_TEXTURE_2D); 95 96 m_mgr.bind_gsto(a_tex); 97 98 ::glEnableClientState(GL_VERTEX_ARRAY); 99 ::glEnableClientState(GL_TEXTURE_COORD_ARR 100 ::glVertexPointer(3,GL_FLOAT,0,a_xyzs); 101 ::glTexCoordPointer(2,GL_FLOAT,0,a_tex_coo 102 ::glDrawArrays(a_mode,0,(GLsizei)num); 103 ::glDisableClientState(GL_VERTEX_ARRAY); 104 ::glDisableClientState(GL_TEXTURE_COORD_AR 105 106 ::glBindTexture(GL_TEXTURE_2D,0); 107 108 ::glDisable(GL_TEXTURE_2D); 109 } 110 111 virtual void draw_vertex_normal_array_textur 112 size_ 113 const 114 const 115 gstoi 116 const 117 size_t num = a_floatn/3; 118 if(!num) return; 119 120 //expect 2*num a_tex_coords. 121 122 ::glEnable(GL_TEXTURE_2D); 123 124 m_mgr.bind_gsto(a_tex); 125 126 ::glEnableClientState(GL_VERTEX_ARRAY); 127 ::glEnableClientState(GL_NORMAL_ARRAY); 128 ::glEnableClientState(GL_TEXTURE_COORD_ARR 129 ::glVertexPointer(3,GL_FLOAT,0,a_xyzs); 130 ::glNormalPointer(GL_FLOAT,0,a_nms); 131 ::glTexCoordPointer(2,GL_FLOAT,0,a_tex_coo 132 ::glDrawArrays(a_mode,0,(GLsizei)num); 133 ::glDisableClientState(GL_NORMAL_ARRAY); 134 ::glDisableClientState(GL_VERTEX_ARRAY); 135 ::glDisableClientState(GL_TEXTURE_COORD_AR 136 137 ::glBindTexture(GL_TEXTURE_2D,0); 138 139 ::glDisable(GL_TEXTURE_2D); 140 } 141 142 //////////////////////////////////////////// 143 /// VBO //////////////////////////////////// 144 //////////////////////////////////////////// 145 146 virtual void begin_gsto(gstoid a_id) { 147 switch(m_mgr.get_gsto_mode()){ 148 149 case tools::sg::gsto_gl_vbo:{ 150 #ifdef TOOLX_HAS_GL_VBO 151 m_mgr.bind_gsto(a_id); 152 #endif 153 }break; 154 155 case tools::sg::gsto_gl_list:{ 156 #ifdef TOOLX_HAS_GL_LIST 157 m_gsto = a_id; 158 m_created = false; 159 m_gl_id = m_mgr.gsto_gl_list_id(a_id,m_c 160 if(m_gl_id && m_created) { 161 ::glNewList(m_gl_id,GL_COMPILE); 162 } 163 #endif 164 }break; 165 166 case tools::sg::gsto_memory:{ 167 m_gsto = a_id; 168 }break; 169 } 170 } 171 172 virtual void end_gsto() { 173 switch(m_mgr.get_gsto_mode()){ 174 175 case tools::sg::gsto_gl_vbo:{ 176 #ifdef TOOLX_HAS_GL_VBO 177 ::glBindBuffer(GL_ARRAY_BUFFER,0); 178 #endif 179 }break; 180 181 case tools::sg::gsto_gl_list:{ 182 #ifdef TOOLX_HAS_GL_LIST 183 if(m_gl_id && m_created) { 184 ::glEndList(); 185 } 186 if(m_gl_id) ::glCallList(m_gl_id); 187 m_created = false; 188 m_gl_id = 0; 189 m_gsto = 0; 190 #endif 191 }break; 192 193 case tools::sg::gsto_memory:{ 194 m_gsto = 0; 195 }break; 196 } 197 } 198 199 typedef tools::sg::bufpos bufpos; 200 virtual void draw_gsto_v(tools::gl::mode_t a 201 202 switch(m_mgr.get_gsto_mode()){ 203 204 case tools::sg::gsto_gl_vbo:{ 205 #ifdef TOOLX_HAS_GL_VBO 206 _draw_v(a_mode,a_elems,(char*)NULL+a_pos 207 #endif 208 }break; 209 210 case tools::sg::gsto_gl_list:{ 211 #ifdef TOOLX_HAS_GL_LIST 212 float* buffer = m_mgr.gsto_data(m_gsto); 213 if(!buffer) return; 214 void* pos_xyzs = (char*)buffer+a_pos_xyz 215 if(m_gl_id && m_created) { 216 ::glBegin(a_mode); 217 float* pos = (float*)pos_xyzs; 218 for(size_t index=0;index<a_elems;index 219 ::glVertex3f(*(pos+0),*(pos+1),*(pos 220 } 221 ::glEnd(); 222 } 223 #endif 224 }break; 225 226 case tools::sg::gsto_memory:{ 227 float* buffer = m_mgr.gsto_data(m_gsto); 228 if(!buffer) return; 229 void* pos_xyzs = (char*)buffer+a_pos_xyz 230 _draw_v(a_mode,a_elems,pos_xyzs); 231 }break; 232 } 233 } 234 235 virtual void draw_gsto_vc(tools::gl::mode_t 236 237 switch(m_mgr.get_gsto_mode()){ 238 239 case tools::sg::gsto_gl_vbo:{ 240 #ifdef TOOLX_HAS_GL_VBO 241 _draw_vc(a_mode,a_elems,(char*)NULL+a_po 242 #endif 243 }break; 244 245 case tools::sg::gsto_gl_list:{ 246 #ifdef TOOLX_HAS_GL_LIST 247 float* buffer = m_mgr.gsto_data(m_gsto); 248 if(!buffer) return; 249 void* pos_xyzs = (char*)buffer+a_pos_xyz 250 void* pos_rgbas = (char*)buffer+a_pos_rg 251 if(m_gl_id && m_created) { 252 ::glBegin(a_mode); 253 float* pos = (float*)pos_xyzs; 254 float* pco = (float*)pos_rgbas; 255 for(size_t index=0;index<a_elems;index 256 ::glColor4f (*(pco+0),*(pco+1),*(pco 257 ::glVertex3f(*(pos+0),*(pos+1),*(pos 258 } 259 ::glEnd(); 260 } 261 #endif 262 }break; 263 264 case tools::sg::gsto_memory:{ 265 float* buffer = m_mgr.gsto_data(m_gsto); 266 if(!buffer) return; 267 void* pos_xyzs = (char*)buffer+a_pos_xyz 268 void* pos_rgbas = (char*)buffer+a_pos_rg 269 _draw_vc(a_mode,a_elems,pos_xyzs,pos_rgb 270 }break; 271 } 272 } 273 274 virtual void draw_gsto_vn(tools::gl::mode_t 275 276 switch(m_mgr.get_gsto_mode()){ 277 278 case tools::sg::gsto_gl_vbo:{ 279 #ifdef TOOLX_HAS_GL_VBO 280 _draw_vn(a_mode,a_elems,(char*)NULL+a_po 281 #endif 282 }break; 283 284 case tools::sg::gsto_gl_list:{ 285 #ifdef TOOLX_HAS_GL_LIST 286 float* buffer = m_mgr.gsto_data(m_gsto); 287 if(!buffer) return; 288 void* pos_xyzs = (char*)buffer+a_pos_xyz 289 //void* pos_nms = (char*)buffer+a_pos_nm 290 if(m_gl_id && m_created) { 291 ::glBegin(a_mode); 292 float* pos = (float*)pos_xyzs; 293 for(size_t index=0;index<a_elems;index 294 ::glVertex3f(*(pos+0),*(pos+1),*(pos 295 } 296 ::glEnd(); 297 } 298 #endif 299 }break; 300 301 case tools::sg::gsto_memory:{ 302 float* buffer = m_mgr.gsto_data(m_gsto); 303 if(!buffer) return; 304 void* pos_xyzs = (char*)buffer+a_pos_xyz 305 void* pos_nms = (char*)buffer+a_pos_nms; 306 _draw_vn(a_mode,a_elems,pos_xyzs,pos_nms 307 }break; 308 } 309 } 310 311 virtual void draw_gsto_vcn(tools::gl::mode_t 312 313 switch(m_mgr.get_gsto_mode()){ 314 315 case tools::sg::gsto_gl_vbo:{ 316 #ifdef TOOLX_HAS_GL_VBO 317 _draw_vcn(a_mode,a_elems,(char*)NULL+a_p 318 #endif 319 }break; 320 321 case tools::sg::gsto_gl_list:{ 322 #ifdef TOOLX_HAS_GL_LIST 323 float* buffer = m_mgr.gsto_data(m_gsto); 324 if(!buffer) return; 325 void* pos_xyzs = (char*)buffer+a_pos_xyz 326 void* pos_rgbas = (char*)buffer+a_pos_rg 327 void* pos_nms = (char*)buffer+a_pos_nms; 328 if(m_gl_id && m_created) { 329 ::glBegin(a_mode); 330 float* pos = (float*)pos_xyzs; 331 float* pco = (float*)pos_rgbas; 332 float* pnm = (float*)pos_nms; 333 for(size_t index=0;index<a_elems; 334 index++,pos+=3,pco+=4,pnm+=3) { 335 ::glVertex3f(*(pos+0),*(pos+1),*(pos 336 ::glColor4f (*(pco+0),*(pco+1),*(pco 337 ::glNormal3f(*(pnm+0),*(pnm+1),*(pnm 338 } 339 ::glEnd(); 340 } 341 #endif 342 }break; 343 344 case tools::sg::gsto_memory:{ 345 float* buffer = m_mgr.gsto_data(m_gsto); 346 if(!buffer) return; 347 void* pos_xyzs = (char*)buffer+a_pos_xyz 348 void* pos_rgbas = (char*)buffer+a_pos_rg 349 void* pos_nms = (char*)buffer+a_pos_nms; 350 _draw_vcn(a_mode,a_elems,pos_xyzs,pos_rg 351 }break; 352 } 353 } 354 355 //////////////////////////////////////////// 356 //////////////////////////////////////////// 357 //////////////////////////////////////////// 358 359 virtual void clear_color(float a_r,float a_g 360 ::glClearColor(a_r,a_g,a_b,a_a); 361 ::glClear(GL_COLOR_BUFFER_BIT); 362 } 363 virtual void color4f(float a_r,float a_g,flo 364 ::glColor4f(a_r,a_g,a_b,a_a); 365 } 366 virtual void line_width(float a_v){::glLineW 367 virtual void point_size(float a_v){::glPoint 368 virtual void set_polygon_offset(bool a_v) { 369 if(a_v) ::glEnable(GL_POLYGON_OFFSET_FILL) 370 else ::glDisable(GL_POLYGON_OFFSET_FILL 371 ::glPolygonOffset(1.,1.); 372 } 373 virtual void normal(float a_x,float a_y,floa 374 ::glNormal3f(a_x,a_y,a_z); 375 } 376 377 virtual void set_winding(tools::sg::winding_ 378 if(a_v==tools::sg::winding_ccw) 379 ::glFrontFace(GL_CCW); 380 else 381 ::glFrontFace(GL_CW); 382 } 383 384 virtual void set_shade_model(tools::sg::shad 385 if(a_v==tools::sg::shade_smooth) 386 ::glShadeModel(GL_SMOOTH); 387 else 388 ::glShadeModel(GL_FLAT); 389 } 390 391 virtual void set_cull_face(bool a_on) { 392 if(a_on) ::glEnable(GL_CULL_FACE); 393 else ::glDisable(GL_CULL_FACE); 394 } 395 396 virtual void set_point_smooth(bool a_on) { 397 if(a_on) ::glEnable(GL_POINT_SMOOTH); 398 else ::glDisable(GL_POINT_SMOOTH); 399 } 400 401 virtual void set_line_smooth(bool a_on) { 402 if(a_on) ::glEnable(GL_LINE_SMOOTH); 403 else ::glDisable(GL_LINE_SMOOTH); 404 } 405 406 virtual void set_depth_test(bool a_on) { 407 if(a_on) ::glEnable(GL_DEPTH_TEST); 408 else ::glDisable(GL_DEPTH_TEST); 409 } 410 411 virtual void load_proj_matrix(const tools::m 412 ::glMatrixMode(GL_PROJECTION); 413 ::glLoadMatrixf(a_mtx.data()); 414 } 415 416 virtual void load_model_matrix(const tools:: 417 ::glMatrixMode(GL_MODELVIEW); 418 ::glLoadMatrixf(a_mtx.data()); 419 /* 420 tools::mat4f tmp(a_mtx); 421 tmp.no_translate(); 422 tools::mat4f normal_matrix; 423 if(!tmp.invert(normal_matrix)) { 424 m_out << "toolx::sg::GL_action::render:: 425 << " can't invert model matrix." 426 << std::endl; 427 } 428 normal_matrix.transpose(); 429 430 tools::mat4f to_check(a_mtx); 431 to_check.no_translate(); 432 float fepsilon = 1e-10; 433 if(!normal_matrix.equal_prec(to_check,feps 434 mat_dump(m_out,"problem with normal_matr 435 mat_dump(m_out,"expected",to_check); 436 } 437 */ 438 } 439 440 virtual unsigned int max_lights() {return GL 441 442 virtual void enable_light(unsigned int a_lig 443 float a_dx,float a 444 float a_r,float a_ 445 float a_ar,float a 446 ::glEnable(GL_LIGHTING); 447 GLenum light = GL_LIGHT0+a_light; 448 //::printf("debug : GL_MAX_LIGHTS %d\n",GL 449 450 float params[4]; 451 params[0] = -a_dx; 452 params[1] = -a_dy; 453 params[2] = -a_dz; 454 params[3] = 0; //0 tells that it is a dire 455 ::glLightfv(light,GL_POSITION,params); 456 457 //params[0] = a_dir[0]; 458 //params[1] = a_dir[1]; 459 //params[2] = a_dir[2]; 460 //::glLightfv(light,GL_SPOT_DIRECTION,para 461 462 params[0] = a_r; 463 params[1] = a_g; 464 params[2] = a_b; 465 params[3] = a_a; 466 ::glLightfv(light,GL_DIFFUSE,params); 467 ::glLightfv(light,GL_SPECULAR,params); //c 468 469 params[0] = a_ar; 470 params[1] = a_ag; 471 params[2] = a_ab; 472 params[3] = a_aa; 473 ::glLightfv(light,GL_AMBIENT,params); //co 474 475 // coin/SoDirectionalLight does the below 476 ::glLightf(light, GL_SPOT_EXPONENT, 0.0); 477 ::glLightf(light, GL_SPOT_CUTOFF, 180.0); 478 ::glLightf(light, GL_CONSTANT_ATTENUATION, 479 ::glLightf(light, GL_LINEAR_ATTENUATION, 0 480 ::glLightf(light, GL_QUADRATIC_ATTENUATION 481 482 //::printf("debug : GL_MAX_LIGHTS %d\n",GL 483 484 ::glEnable(light); 485 } 486 487 virtual void set_lighting(bool a_on) { 488 if(a_on) ::glEnable(GL_LIGHTING); 489 else ::glDisable(GL_LIGHTING); 490 } 491 virtual void set_blend(bool a_on) { 492 if(a_on) ::glEnable(GL_BLEND); 493 else ::glDisable(GL_BLEND); 494 } 495 496 virtual void restore_state(unsigned int a_re 497 const tools::sg::state& _state = state(); 498 ::glMatrixMode(GL_PROJECTION); 499 ::glLoadMatrixf(_state.m_proj.data()); 500 501 ::glMatrixMode(GL_MODELVIEW); 502 ::glLoadMatrixf(_state.m_model.data()); 503 504 if(_state.m_GL_LIGHTING) ::glEnable(GL_LIG 505 else ::glDisable(GL_LI 506 507 if(_state.m_GL_DEPTH_TEST) ::glEnable(GL_D 508 else ::glDisable(GL_ 509 510 if(_state.m_GL_CULL_FACE) ::glEnable(GL_CU 511 else ::glDisable(GL_C 512 513 if(_state.m_GL_POINT_SMOOTH) ::glEnable(GL 514 else ::glDisable(G 515 516 if(_state.m_GL_LINE_SMOOTH) ::glEnable(GL_ 517 else ::glDisable(GL 518 519 if(_state.m_GL_POLYGON_OFFSET_FILL) ::glEn 520 else ::glDi 521 522 if(_state.m_GL_TEXTURE_2D) ::glEnable(GL_T 523 else ::glDisable(GL_ 524 525 if(_state.m_GL_BLEND) ::glEnable(GL_BLEND) 526 else ::glDisable(GL_BLEND 527 528 if(_state.m_winding==tools::sg::winding_cc 529 ::glFrontFace(GL_CCW); 530 } else { 531 ::glFrontFace(GL_CW); 532 } 533 534 if(_state.m_shade_model==tools::sg::shade_ 535 ::glShadeModel(GL_SMOOTH); 536 else 537 ::glShadeModel(GL_FLAT); 538 539 ::glColor4f(_state.m_color.r(), 540 _state.m_color.g(), 541 _state.m_color.b(), 542 _state.m_color.a()); 543 544 ::glNormal3f(_state.m_normal.x(), 545 _state.m_normal.y(), 546 _state.m_normal.z()); 547 548 // The "return of separator" state had ret 549 // The restored state has m_light. 550 // We have to glDisable lights with index 551 for(unsigned int index=_state.m_light;inde 552 ::glDisable(GL_LIGHT0+index); 553 } 554 555 ::glLineWidth(_state.m_line_width); 556 557 ::glPointSize(_state.m_point_size); 558 559 #if TARGET_OS_IPHONE 560 // GL-ES 561 #elif defined(ANDROID) 562 // GL-ES 563 #else 564 ::glDisable(GL_POLYGON_STIPPLE); //CoinGL 565 #endif 566 } 567 568 virtual tools::sg::render_manager& render_ma 569 public: 570 GL_action(GL_manager& a_mgr,std::ostream& a_ 571 :parent(a_out,a_ww,a_wh) 572 ,m_mgr(a_mgr) 573 ,m_gsto(0) 574 #ifdef TOOLX_HAS_GL_LIST 575 ,m_created(false) 576 ,m_gl_id(0) 577 #endif 578 {} 579 virtual ~GL_action(){} 580 public: 581 GL_action(const GL_action& a_from) 582 :parent(a_from) 583 ,m_mgr(a_from.m_mgr) 584 ,m_gsto(0) 585 #ifdef TOOLX_HAS_GL_LIST 586 ,m_created(false) 587 ,m_gl_id(0) 588 #endif 589 {} 590 GL_action& operator=(const GL_action& a_from 591 render_action::operator=(a_from); 592 m_gsto = 0; 593 #ifdef TOOLX_HAS_GL_LIST 594 m_created = false; 595 m_gl_id = 0; 596 #endif 597 return *this; 598 } 599 protected: 600 void _draw_v(tools::gl::mode_t a_mode,size_t 601 ::glEnableClientState(GL_VERTEX_ARRAY); 602 ::glVertexPointer(3,GL_FLOAT,0,a_pos_xyzs) 603 ::glDrawArrays(a_mode,0,(GLsizei)a_elems); 604 ::glDisableClientState(GL_VERTEX_ARRAY); 605 } 606 607 void _draw_vc(tools::gl::mode_t a_mode,size_ 608 609 ::glEnableClientState(GL_VERTEX_ARRAY); 610 ::glEnableClientState(GL_COLOR_ARRAY); 611 612 ::glVertexPointer(3,GL_FLOAT,0,a_pos_xyzs) 613 ::glColorPointer(4,GL_FLOAT,0,a_pos_rgbas) 614 615 ::glDrawArrays(a_mode,0,(GLsizei)a_elems); 616 617 ::glDisableClientState(GL_COLOR_ARRAY); 618 ::glDisableClientState(GL_VERTEX_ARRAY); 619 } 620 621 void _draw_vn(tools::gl::mode_t a_mode,size_ 622 ::glEnableClientState(GL_VERTEX_ARRAY); 623 ::glEnableClientState(GL_NORMAL_ARRAY); 624 625 ::glVertexPointer(3,GL_FLOAT,0,a_pos_xyzs) 626 ::glNormalPointer(GL_FLOAT,0,a_pos_nms); 627 628 ::glDrawArrays(a_mode,0,(GLsizei)a_elems); 629 630 ::glDisableClientState(GL_NORMAL_ARRAY); 631 ::glDisableClientState(GL_VERTEX_ARRAY); 632 } 633 634 void _draw_vcn(tools::gl::mode_t a_mode,size 635 ::glEnableClientState(GL_VERTEX_ARRAY); 636 ::glEnableClientState(GL_COLOR_ARRAY); 637 ::glEnableClientState(GL_NORMAL_ARRAY); 638 639 ::glVertexPointer(3,GL_FLOAT,0,a_pos_xyzs) 640 ::glColorPointer(4,GL_FLOAT,0,a_pos_rgbas) 641 ::glNormalPointer(GL_FLOAT,0,a_pos_nms); 642 643 ::glDrawArrays(a_mode,0,(GLsizei)a_elems); 644 645 ::glDisableClientState(GL_COLOR_ARRAY); 646 ::glDisableClientState(GL_NORMAL_ARRAY); 647 ::glDisableClientState(GL_VERTEX_ARRAY); 648 } 649 650 protected: 651 GL_manager& m_mgr; 652 gstoid m_gsto; 653 #ifdef TOOLX_HAS_GL_LIST 654 bool m_created; 655 gstoid m_gl_id; 656 #endif 657 }; 658 659 }} 660 661 662 #endif