Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/toolx/sg/GL_action

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
  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_action {
 18   TOOLS_ACTION(GL_action,toolx::sg::GL_action,tools::sg::render_action)
 19 public:
 20   virtual void draw_vertex_array(tools::gl::mode_t a_mode,size_t a_floatn,const float* a_xyzs){
 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::mode_t a_mode,size_t a_floatn,const float* a_xys){
 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 = 0.
 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::gl::mode_t a_mode,size_t a_floatn,const float* a_xyzs,const float* a_rgbas){
 53     // Used in atb_vertices.
 54     // We expect a_rgbas of size : 4*(a_floatn/3)
 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::gl::mode_t a_mode,size_t a_floatn,const float* a_xyzs,const float* a_nms){
 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(tools::gl::mode_t a_mode,
 70                                        size_t a_floatn,const float* a_xyzs,const float* a_rgbas,const float* a_nms){
 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/3)
 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::gl::mode_t a_mode,
 85                                          size_t a_floatn,
 86                                          const float* a_xyzs,
 87                                          gstoid a_tex,
 88                                          const float* a_tex_coords) {
 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_ARRAY);
100     ::glVertexPointer(3,GL_FLOAT,0,a_xyzs);
101     ::glTexCoordPointer(2,GL_FLOAT,0,a_tex_coords);
102     ::glDrawArrays(a_mode,0,(GLsizei)num);
103     ::glDisableClientState(GL_VERTEX_ARRAY);
104     ::glDisableClientState(GL_TEXTURE_COORD_ARRAY);
105 
106     ::glBindTexture(GL_TEXTURE_2D,0);
107 
108     ::glDisable(GL_TEXTURE_2D);
109   }
110 
111   virtual void draw_vertex_normal_array_texture(tools::gl::mode_t a_mode,
112                                          size_t a_floatn,
113                                          const float* a_xyzs,
114                                          const float* a_nms,
115                                          gstoid a_tex,
116                                          const float* a_tex_coords) {
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_ARRAY);
129     ::glVertexPointer(3,GL_FLOAT,0,a_xyzs);
130     ::glNormalPointer(GL_FLOAT,0,a_nms);
131     ::glTexCoordPointer(2,GL_FLOAT,0,a_tex_coords);
132     ::glDrawArrays(a_mode,0,(GLsizei)num);
133     ::glDisableClientState(GL_NORMAL_ARRAY);
134     ::glDisableClientState(GL_VERTEX_ARRAY);
135     ::glDisableClientState(GL_TEXTURE_COORD_ARRAY);
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_created);
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_mode,size_t a_elems,bufpos a_pos_xyzs){
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_xyzs);
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_xyzs;
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++,pos+=3) {
219           ::glVertex3f(*(pos+0),*(pos+1),*(pos+2));
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_xyzs;
230       _draw_v(a_mode,a_elems,pos_xyzs);
231       }break;
232     }
233   }
234 
235   virtual void draw_gsto_vc(tools::gl::mode_t a_mode,size_t a_elems,bufpos a_pos_xyzs,bufpos a_pos_rgbas){
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_pos_xyzs,(char*)NULL+a_pos_rgbas);
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_xyzs;
250       void* pos_rgbas = (char*)buffer+a_pos_rgbas;
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++,pos+=3,pco+=4) {
256           ::glColor4f (*(pco+0),*(pco+1),*(pco+2),*(pco+3));
257           ::glVertex3f(*(pos+0),*(pos+1),*(pos+2));
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_xyzs;
268       void* pos_rgbas = (char*)buffer+a_pos_rgbas;
269       _draw_vc(a_mode,a_elems,pos_xyzs,pos_rgbas);
270       }break;
271     }
272   }
273 
274   virtual void draw_gsto_vn(tools::gl::mode_t a_mode,size_t a_elems,bufpos a_pos_xyzs,bufpos a_pos_nms){
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_pos_xyzs,(char*)NULL+a_pos_nms);
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_xyzs;
289       //void* pos_nms = (char*)buffer+a_pos_nms;
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++,pos+=3) {
294           ::glVertex3f(*(pos+0),*(pos+1),*(pos+2));
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_xyzs;
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 a_mode,size_t a_elems,bufpos a_pos_xyzs,bufpos a_pos_rgbas,bufpos a_pos_nms){
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_pos_xyzs,(char*)NULL+a_pos_rgbas,(char*)NULL+a_pos_nms);
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_xyzs;
326       void* pos_rgbas = (char*)buffer+a_pos_rgbas;
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+2));
336           ::glColor4f (*(pco+0),*(pco+1),*(pco+2),*(pco+3));
337           ::glNormal3f(*(pnm+0),*(pnm+1),*(pnm+2));
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_xyzs;
348       void* pos_rgbas = (char*)buffer+a_pos_rgbas;
349       void* pos_nms = (char*)buffer+a_pos_nms;
350       _draw_vcn(a_mode,a_elems,pos_xyzs,pos_rgbas,pos_nms);
351       }break;
352     }
353   }
354 
355   /////////////////////////////////////////////////////////////////
356   /////////////////////////////////////////////////////////////////
357   /////////////////////////////////////////////////////////////////
358 
359   virtual void clear_color(float a_r,float a_g,float a_b,float a_a){
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,float a_b,float a_a){
364     ::glColor4f(a_r,a_g,a_b,a_a);
365   }
366   virtual void line_width(float a_v){::glLineWidth(a_v);}
367   virtual void point_size(float a_v){::glPointSize(a_v);}
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,float a_z) {
374     ::glNormal3f(a_x,a_y,a_z);
375   }
376 
377   virtual void set_winding(tools::sg::winding_type a_v) {
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::shade_type a_v) {
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::mat4f& a_mtx) {
412     ::glMatrixMode(GL_PROJECTION);
413     ::glLoadMatrixf(a_mtx.data());
414   }
415 
416   virtual void load_model_matrix(const tools::mat4f& a_mtx) {
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::load_model_matrix :"
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,fepsilon,tools::ffabs)) {
434       mat_dump(m_out,"problem with normal_matrix ",normal_matrix);
435       mat_dump(m_out,"expected",to_check);
436     }
437 */
438   }
439 
440   virtual unsigned int max_lights() {return GL_MAX_LIGHTS;}
441 
442   virtual void enable_light(unsigned int a_light,
443                             float a_dx,float a_dy,float a_dz,
444                             float a_r,float a_g,float a_b,float a_a,
445                             float a_ar,float a_ag,float a_ab,float a_aa){
446     ::glEnable(GL_LIGHTING);
447     GLenum light = GL_LIGHT0+a_light;
448     //::printf("debug : GL_MAX_LIGHTS %d\n",GL_MAX_LIGHTS);
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 directional light.
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,params);
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); //coin/SoDirectionalLight does that.
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); //coin/SoDirectionalLight does that.
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, 1);
479     ::glLightf(light, GL_LINEAR_ATTENUATION, 0);
480     ::glLightf(light, GL_QUADRATIC_ATTENUATION, 0);
481 
482     //::printf("debug : GL_MAX_LIGHTS %d\n",GL_MAX_LIGHTS);
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_ret_num_light) {
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_LIGHTING);
505     else                     ::glDisable(GL_LIGHTING);
506 
507     if(_state.m_GL_DEPTH_TEST) ::glEnable(GL_DEPTH_TEST);
508     else                       ::glDisable(GL_DEPTH_TEST);
509 
510     if(_state.m_GL_CULL_FACE) ::glEnable(GL_CULL_FACE);
511     else                      ::glDisable(GL_CULL_FACE);
512 
513     if(_state.m_GL_POINT_SMOOTH) ::glEnable(GL_POINT_SMOOTH);
514     else                         ::glDisable(GL_POINT_SMOOTH);
515 
516     if(_state.m_GL_LINE_SMOOTH) ::glEnable(GL_LINE_SMOOTH);
517     else                        ::glDisable(GL_LINE_SMOOTH);
518 
519     if(_state.m_GL_POLYGON_OFFSET_FILL) ::glEnable(GL_POLYGON_OFFSET_FILL);
520     else                                ::glDisable(GL_POLYGON_OFFSET_FILL);
521 
522     if(_state.m_GL_TEXTURE_2D) ::glEnable(GL_TEXTURE_2D);
523     else                       ::glDisable(GL_TEXTURE_2D);
524 
525     if(_state.m_GL_BLEND) ::glEnable(GL_BLEND);
526     else                  ::glDisable(GL_BLEND);
527 
528     if(_state.m_winding==tools::sg::winding_ccw) {
529       ::glFrontFace(GL_CCW);
530     } else {
531       ::glFrontFace(GL_CW);
532     }
533 
534     if(_state.m_shade_model==tools::sg::shade_smooth)
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_num_light.
549     // The restored state has m_light.
550     // We have to glDisable lights with index in [m_light,ret_num_light-1]
551     for(unsigned int index=_state.m_light;index<a_ret_num_light;index++) {
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 : reading a .wrl having Material::transparency may enable GL_POLYGON_STIPPLE.
565 #endif
566   }
567 
568   virtual tools::sg::render_manager& render_manager() {return m_mgr;}
569 public:
570   GL_action(GL_manager& a_mgr,std::ostream& a_out,unsigned int a_ww,unsigned int a_wh)
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 a_elems,const void* a_pos_xyzs){
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_t a_elems,const void* a_pos_xyzs,const void* a_pos_rgbas){
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_t a_elems,const void* a_pos_xyzs,const void* a_pos_nms){
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_t a_elems,const void* a_pos_xyzs,const void* a_pos_rgbas,const void* a_pos_nms){
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