Geant4 Cross Reference

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

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 ]

Diff markup

Differences between /externals/g4tools/include/toolx/sg/GL_manager (Version 11.3.0) and /externals/g4tools/include/toolx/sg/GL_manager (Version 11.1.1)


  1 // Copyright (C) 2010, Guy Barrand. All rights      1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
  2 // See the file tools.license for terms.            2 // See the file tools.license for terms.
  3                                                     3 
  4 #ifndef toolx_sg_GL_manager                         4 #ifndef toolx_sg_GL_manager
  5 #define toolx_sg_GL_manager                         5 #define toolx_sg_GL_manager
  6                                                     6 
  7 #include "gl"                                       7 #include "gl"
  8 #include "../glbuf"                                 8 #include "../glbuf"
  9                                                     9 
 10 #include <tools/sg/render_manager>                 10 #include <tools/sg/render_manager>
 11 #include <tools/mapmanip>                          11 #include <tools/mapmanip>
 12 #include <tools/carray>                            12 #include <tools/carray>
 13                                                    13 
 14 #include <cmath> //::sqrt                          14 #include <cmath> //::sqrt
 15                                                    15 
 16 #ifdef TOOLS_MEM                                   16 #ifdef TOOLS_MEM
 17 #include <tools/mem>                               17 #include <tools/mem>
 18 #endif                                             18 #endif
 19                                                    19 
 20 namespace toolx {                                  20 namespace toolx {
 21 namespace sg {                                     21 namespace sg {
 22                                                    22 
 23 class GL_manager : public virtual tools::sg::r     23 class GL_manager : public virtual tools::sg::render_manager {
 24   typedef tools::sg::render_manager parent;        24   typedef tools::sg::render_manager parent;
 25 public:                                            25 public:
 26   TOOLS_SCLASS(toolx::sg::GL_manager)              26   TOOLS_SCLASS(toolx::sg::GL_manager)
 27   virtual void* cast(const std::string& a_clas     27   virtual void* cast(const std::string& a_class) const {
 28     if(void* p = tools::cmp_cast<GL_manager>(t     28     if(void* p = tools::cmp_cast<GL_manager>(this,a_class)) {return p;}
 29     else return 0;                                 29     else return 0;
 30   }                                                30   }
 31 public:                                            31 public:
 32   virtual bool begin_render(int a_x,int a_y,un     32   virtual bool begin_render(int a_x,int a_y,unsigned int a_ww,unsigned int a_wh,
 33                             float a_r,float a_     33                             float a_r,float a_g,float a_b,float a_a,bool a_clear = true) {
 34     gl_clear_errors();                             34     gl_clear_errors();
 35                                                    35 
 36 #if TARGET_OS_IPHONE                               36 #if TARGET_OS_IPHONE
 37 #elif defined(ANDROID)                             37 #elif defined(ANDROID)
 38 #elif _WIN32                                       38 #elif _WIN32
 39 #elif __APPLE__ // Cocoa                           39 #elif __APPLE__ // Cocoa
 40     // to avoid a 0x506 error message :            40     // to avoid a 0x506 error message :
 41 #ifdef TOOLX_HAS_GL_VBO                            41 #ifdef TOOLX_HAS_GL_VBO
 42 #if GL_ARB_framebuffer_object                      42 #if GL_ARB_framebuffer_object
 43     if(::glCheckFramebufferStatus(GL_FRAMEBUFF     43     if(::glCheckFramebufferStatus(GL_FRAMEBUFFER)!=GL_FRAMEBUFFER_COMPLETE) {
 44       //m_out << "toolx::sg::GL_manager::begin     44       //m_out << "toolx::sg::GL_manager::begin_render :"
 45       //      << " frame buffer not complete."     45       //      << " frame buffer not complete."
 46       //      << std::endl;                        46       //      << std::endl;
 47       return false;                                47       return false;
 48     }                                              48     }
 49 #endif //GL_ARB_framebuffer_object                 49 #endif //GL_ARB_framebuffer_object
 50 #endif //TOOLX_HAS_GL_VBO                          50 #endif //TOOLX_HAS_GL_VBO
 51 #else                                              51 #else
 52 #endif                                             52 #endif
 53                                                    53 
 54     // WARNING : the values set here must matc     54     // WARNING : the values set here must match the default values in sg::state.
 55                                                    55 
 56     // Antialiasing :                              56     // Antialiasing :
 57 #if TARGET_OS_IPHONE                               57 #if TARGET_OS_IPHONE
 58 #elif defined(ANDROID)                             58 #elif defined(ANDROID)
 59     ::glEnable(GL_MULTISAMPLE);                    59     ::glEnable(GL_MULTISAMPLE);
 60 #elif _WIN32                                       60 #elif _WIN32
 61 #elif __APPLE__                                    61 #elif __APPLE__
 62     ::glEnable(GL_MULTISAMPLE); //Cocoa            62     ::glEnable(GL_MULTISAMPLE); //Cocoa
 63 #else                                              63 #else
 64 #endif                                             64 #endif
 65                                                    65 
 66     /* NOTE : not GL-ES :                          66     /* NOTE : not GL-ES :
 67     //   ::glPolygonMode(GL_FRONT_AND_BACK,GL_     67     //   ::glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
 68     // The upper is cruely lacking with povama     68     // The upper is cruely lacking with povama solid+light.
 69     //   ::glEnable(GL_LINE_STIPPLE);              69     //   ::glEnable(GL_LINE_STIPPLE);
 70                                                    70 
 71     ::glDisable(GL_POLYGON_SMOOTH);                71     ::glDisable(GL_POLYGON_SMOOTH);
 72     ::glAccum(GL_LOAD,1.0f);                       72     ::glAccum(GL_LOAD,1.0f);
 73     ::glAccum(GL_RETURN,1.0f);                     73     ::glAccum(GL_RETURN,1.0f);
 74     ::glReadBuffer(GL_FRONT);                      74     ::glReadBuffer(GL_FRONT);
 75                                                    75 
 76     NOTE : GL_POLYGON_SMOOTH is here on Cocoa/     76     NOTE : GL_POLYGON_SMOOTH is here on Cocoa/AGL, Windows/WGL but it
 77            does nothing.                           77            does nothing.
 78     */                                             78     */
 79                                                    79 
 80 #if TARGET_OS_IPHONE                               80 #if TARGET_OS_IPHONE
 81 // GL-ES                                           81 // GL-ES
 82 #elif defined(ANDROID)                             82 #elif defined(ANDROID)
 83 // GL-ES                                           83 // GL-ES
 84 #else                                              84 #else
 85     ::glDisable(GL_POLYGON_STIPPLE); //CoinGL      85     ::glDisable(GL_POLYGON_STIPPLE); //CoinGL : reading a .wrl having Material::transparency may enable GL_POLYGON_STIPPLE.
 86 #endif                                             86 #endif
 87                                                    87 
 88 /*                                                 88 /*
 89     ::printf("debug : is enabled %d\n",::glIsE     89     ::printf("debug : is enabled %d\n",::glIsEnabled(GL_COLOR_MATERIAL));
 90    {GLfloat v[4];                                  90    {GLfloat v[4];
 91     ::glGetMaterialfv(GL_FRONT,GL_AMBIENT,v);      91     ::glGetMaterialfv(GL_FRONT,GL_AMBIENT,v);
 92     ::printf("debug : ambient : %g %g %g %g\n"     92     ::printf("debug : ambient : %g %g %g %g\n",v[0],v[1],v[2],v[3]);}
 93    {GLfloat v[4];                                  93    {GLfloat v[4];
 94     ::glGetMaterialfv(GL_FRONT,GL_DIFFUSE,v);      94     ::glGetMaterialfv(GL_FRONT,GL_DIFFUSE,v);
 95     ::printf("debug : diffuse : %g %g %g %g\n"     95     ::printf("debug : diffuse : %g %g %g %g\n",v[0],v[1],v[2],v[3]);}
 96    {GLfloat v[4];                                  96    {GLfloat v[4];
 97     ::glGetMaterialfv(GL_FRONT,GL_SPECULAR,v);     97     ::glGetMaterialfv(GL_FRONT,GL_SPECULAR,v);
 98     ::printf("debug : specular : %g %g %g %g\n     98     ::printf("debug : specular : %g %g %g %g\n",v[0],v[1],v[2],v[3]);}
 99    {GLfloat v[4];                                  99    {GLfloat v[4];
100     ::glGetMaterialfv(GL_FRONT,GL_EMISSION,v);    100     ::glGetMaterialfv(GL_FRONT,GL_EMISSION,v);
101     ::printf("debug : emission : %g %g %g %g\n    101     ::printf("debug : emission : %g %g %g %g\n",v[0],v[1],v[2],v[3]);}
102    {GLfloat shine;                                102    {GLfloat shine;
103     ::glGetMaterialfv(GL_FRONT,GL_SHININESS,&s    103     ::glGetMaterialfv(GL_FRONT,GL_SHININESS,&shine);
104     ::printf("debug : shine : %g\n",shine);}      104     ::printf("debug : shine : %g\n",shine);}
105 debug : is enabled 0                              105 debug : is enabled 0
106 debug : ambient : 0.2 0.2 0.2 1                   106 debug : ambient : 0.2 0.2 0.2 1
107 debug : diffuse : 0.8 0.8 0.8 1                   107 debug : diffuse : 0.8 0.8 0.8 1
108 debug : specular : 0 0 0 1                        108 debug : specular : 0 0 0 1
109 debug : emission : 0 0 0 1                        109 debug : emission : 0 0 0 1
110 debug : shine : 0                                 110 debug : shine : 0
111 */                                                111 */
112                                                   112 
113     ::glEnable(GL_NORMALIZE);                     113     ::glEnable(GL_NORMALIZE);
114     ::glShadeModel(GL_FLAT);                      114     ::glShadeModel(GL_FLAT);
115     //::glShadeModel(GL_SMOOTH);                  115     //::glShadeModel(GL_SMOOTH);
116     // GL-ES : ::glMaterialfv does not work. W    116     // GL-ES : ::glMaterialfv does not work. We then use :
117     //         ::glEnable(GL_COLOR_MATERIAL) a    117     //         ::glEnable(GL_COLOR_MATERIAL) and ::glColor.
118     //::glColorMaterial(GL_FRONT, GL_DIFFUSE);    118     //::glColorMaterial(GL_FRONT, GL_DIFFUSE);  //?
119     ::glEnable(GL_COLOR_MATERIAL);                119     ::glEnable(GL_COLOR_MATERIAL);
120                                                   120 
121 /*                                                121 /*
122 debug : is enabled 1                              122 debug : is enabled 1
123 debug : ambient : 1 1 1 1                         123 debug : ambient : 1 1 1 1
124 debug : diffuse : 1 1 1 1                         124 debug : diffuse : 1 1 1 1
125 debug : specular : 0 0 0 1                        125 debug : specular : 0 0 0 1
126 debug : emission : 0 0 0 1                        126 debug : emission : 0 0 0 1
127 debug : shine : 0                                 127 debug : shine : 0
128 */                                                128 */
129                                                   129 
130     // to handle transparency (same as SoGLRen    130     // to handle transparency (same as SoGLRenderAction::SCREEN_DOOR ?) :
131     //::glEnable(GL_BLEND);                       131     //::glEnable(GL_BLEND);
132     // NOTE : with Cocoa+AppleGL on macOS-10.1    132     // NOTE : with Cocoa+AppleGL on macOS-10.14 (Mojave), it appears that points are blended ! (Even if alpha color is 1).
133     //        Seen with some simulated catalog    133     //        Seen with some simulated catalog of galaxies done for LSST/DC2.
134     //        To master this, we disable GL_BL    134     //        To master this, we disable GL_BLEND by default. Then people wanting some transparency have to
135     //        use the tools::sg::blend node in    135     //        use the tools::sg::blend node in their scene graph.
136     ::glDisable(GL_BLEND); //must be in sync w    136     ::glDisable(GL_BLEND); //must be in sync with tools::sg::state.m_GL_BLEND and sg::blend node default.
137     ::glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SR    137     ::glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
138                                                   138 
139     //WARNING : the below glEnable/glDisable c    139     //WARNING : the below glEnable/glDisable corresponds
140     //          to defaults in tools::sg::stat    140     //          to defaults in tools::sg::state.
141     ::glEnable(GL_DEPTH_TEST);                    141     ::glEnable(GL_DEPTH_TEST);
142     ::glDisable(GL_LIGHTING);                     142     ::glDisable(GL_LIGHTING);
143     ::glFrontFace(GL_CCW);                        143     ::glFrontFace(GL_CCW);
144     ::glEnable(GL_CULL_FACE);                     144     ::glEnable(GL_CULL_FACE);
145     ::glDisable(GL_POLYGON_OFFSET_FILL);          145     ::glDisable(GL_POLYGON_OFFSET_FILL);
146     ::glDisable(GL_TEXTURE_2D);                   146     ::glDisable(GL_TEXTURE_2D);
147                                                   147 
148     ::glDisable(GL_POINT_SMOOTH);                 148     ::glDisable(GL_POINT_SMOOTH);
149     ::glPointSize(1);                             149     ::glPointSize(1);
150     ::glDisable(GL_LINE_SMOOTH); //NOTE : it d    150     ::glDisable(GL_LINE_SMOOTH); //NOTE : it does not work on all platforms !
151     ::glLineWidth(1);                             151     ::glLineWidth(1);
152                                                   152 
153     ::glViewport(a_x,a_y,a_ww,a_wh);              153     ::glViewport(a_x,a_y,a_ww,a_wh);
154                                                   154 
155    // NOTE : iOS : glScissor logic does not wo    155    // NOTE : iOS : glScissor logic does not work properly with Apple multisampling.
156    //        But it appears that it is not nee    156    //        But it appears that it is not needed for VR split views.
157    //        Here a combination glViewport+[co    157    //        Here a combination glViewport+[correct camera lrbt] does the clipping job (???).
158    //        (But the clear color should be th    158    //        (But the clear color should be the same for both views).
159    //::glEnable(GL_SCISSOR_TEST);                 159    //::glEnable(GL_SCISSOR_TEST);
160    //::glScissor(a_x,a_y,a_ww,a_wh);              160    //::glScissor(a_x,a_y,a_ww,a_wh);
161                                                   161 
162     //NOTE : a=0 coworks with the below logic     162     //NOTE : a=0 coworks with the below logic to handle transparent background.
163     if(a_clear) {                                 163     if(a_clear) {
164       ::glClearColor(a_r,a_g,a_b,0);              164       ::glClearColor(a_r,a_g,a_b,0);
165       ::glClear(GL_COLOR_BUFFER_BIT);             165       ::glClear(GL_COLOR_BUFFER_BIT);
166       ::glClear(GL_DEPTH_BUFFER_BIT);             166       ::glClear(GL_DEPTH_BUFFER_BIT);
167     }                                             167     }
168                                                   168 
169     //WARNING : Android, iPhone : only one glP    169     //WARNING : Android, iPhone : only one glPushMatrix ok !
170     ::glMatrixMode(GL_PROJECTION);                170     ::glMatrixMode(GL_PROJECTION);
171     ::glLoadIdentity();                           171     ::glLoadIdentity();
172                                                   172 
173     //WARNING : we take the convention that th    173     //WARNING : we take the convention that the current mode is MODELVIEW
174     ::glMatrixMode(GL_MODELVIEW);                 174     ::glMatrixMode(GL_MODELVIEW);
175     ::glLoadIdentity();                           175     ::glLoadIdentity();
176                                                   176 
177     //m_clear_color.set_a(0.2);                   177     //m_clear_color.set_a(0.2);
178                                                   178 
179     // to handle a transparent background :       179     // to handle a transparent background :
180     //NOTE : not tested on Android and iOS.       180     //NOTE : not tested on Android and iOS.
181     // dst color :                                181     // dst color :
182     //    cr * alpha + cr * (1-alpha) = cr        182     //    cr * alpha + cr * (1-alpha) = cr
183     //    cg * alpha + cg * (1-alpha) = cg        183     //    cg * alpha + cg * (1-alpha) = cg
184     //    cb * alpha + cb * (1-alpha) = cb        184     //    cb * alpha + cb * (1-alpha) = cb
185     //    alpha*alpha + 0 * (1-alpha) = ca =>     185     //    alpha*alpha + 0 * (1-alpha) = ca => alpha = sqrt(ca)
186                                                   186 
187    {::glColor4f(a_r,a_g,a_b,::sqrt(a_a));         187    {::glColor4f(a_r,a_g,a_b,::sqrt(a_a));
188     float xyzs[12];                               188     float xyzs[12];
189     xyzs[0] = -1;xyzs[ 1] = -1;xyzs[ 2] = 0;      189     xyzs[0] = -1;xyzs[ 1] = -1;xyzs[ 2] = 0;
190     xyzs[3] =  1;xyzs[ 4] = -1;xyzs[ 5] = 0;      190     xyzs[3] =  1;xyzs[ 4] = -1;xyzs[ 5] = 0;
191     xyzs[6] =  1;xyzs[ 7] =  1;xyzs[ 8] = 0;      191     xyzs[6] =  1;xyzs[ 7] =  1;xyzs[ 8] = 0;
192     xyzs[9] = -1;xyzs[10] =  1;xyzs[11] = 0;      192     xyzs[9] = -1;xyzs[10] =  1;xyzs[11] = 0;
193     ::glDisable(GL_DEPTH_TEST);                   193     ::glDisable(GL_DEPTH_TEST);
194     ::glEnableClientState(GL_VERTEX_ARRAY);       194     ::glEnableClientState(GL_VERTEX_ARRAY);
195     ::glVertexPointer(3,GL_FLOAT,0,xyzs);         195     ::glVertexPointer(3,GL_FLOAT,0,xyzs);
196     ::glDrawArrays(GL_TRIANGLE_FAN,0,4);          196     ::glDrawArrays(GL_TRIANGLE_FAN,0,4);
197     ::glDisableClientState(GL_VERTEX_ARRAY);      197     ::glDisableClientState(GL_VERTEX_ARRAY);
198     ::glEnable(GL_DEPTH_TEST);}                   198     ::glEnable(GL_DEPTH_TEST);}
199                                                   199 
200     return true;                                  200     return true;
201   }                                               201   }
202                                                   202 
203   virtual void end_render() {                     203   virtual void end_render() {
204     ::glFinish();                                 204     ::glFinish();
205     gl_dump_if_errors(m_out,"toolx::sg::GL_man    205     gl_dump_if_errors(m_out,"toolx::sg::GL_manager::end_render :");
206   }                                               206   }
207                                                   207 
208   ////////////////////////////////////////////    208   ////////////////////////////////////////////////
209   /// texture : //////////////////////////////    209   /// texture : //////////////////////////////////
210   ////////////////////////////////////////////    210   ////////////////////////////////////////////////
211   virtual unsigned int create_texture(const to    211   virtual unsigned int create_texture(const tools::img_byte& a_img,bool a_NEAREST) {
212                                                   212 
213     unsigned int gl_id;                           213     unsigned int gl_id;
214     ::glGenTextures(1,&gl_id);                    214     ::glGenTextures(1,&gl_id);
215     if(!gl_id) return 0;                          215     if(!gl_id) return 0;
216                                                   216 
217 #ifdef TOOLS_MEM                                  217 #ifdef TOOLS_MEM
218     tools::mem::increment(tools::s_tex().c_str    218     tools::mem::increment(tools::s_tex().c_str());
219 #endif                                            219 #endif
220     unsigned int gsto_size = a_img.size();        220     unsigned int gsto_size = a_img.size();
221     ::glBindTexture(GL_TEXTURE_2D,gl_id);         221     ::glBindTexture(GL_TEXTURE_2D,gl_id);
222     bool status = true;                           222     bool status = true;
223    {int sz;                                       223    {int sz;
224     ::glGetIntegerv(GL_MAX_TEXTURE_SIZE,&sz);     224     ::glGetIntegerv(GL_MAX_TEXTURE_SIZE,&sz);
225   // MacBookPro : it returns 8192.                225   // MacBookPro : it returns 8192.
226   // Android : it returns 2048.                   226   // Android : it returns 2048.
227   // iPad1 : it returns 2048.                     227   // iPad1 : it returns 2048.
228   // iPod : it returns ?                          228   // iPod : it returns ?
229   //::printf("debug : GL_MAX_TEXTURE_SIZE : %d    229   //::printf("debug : GL_MAX_TEXTURE_SIZE : %d\n",sz);
230     tools::img_byte res;                          230     tools::img_byte res;
231     if(!sz) {                                     231     if(!sz) {
232       m_out << "toolx::sg::gl::tex_img : warni    232       m_out << "toolx::sg::gl::tex_img : warning : GL_MAX_TEXTURE_SIZE is zero." << std::endl;
233       status = gl_tex_img(m_out,a_img);           233       status = gl_tex_img(m_out,a_img);
234     } else {                                      234     } else {
235     if(a_img.check_gl_limit(sz,res)) {            235     if(a_img.check_gl_limit(sz,res)) {
236       if(res.is_empty()) { //a_img does not ex    236       if(res.is_empty()) { //a_img does not exceed.
237         status = gl_tex_img(m_out,a_img);         237         status = gl_tex_img(m_out,a_img);
238       } else {                                    238       } else {
239         m_out << "toolx::sg::gl::tex_img : war    239         m_out << "toolx::sg::gl::tex_img : warning : img size > GL_MAX_TEXTURE_SIZE (" << sz << ")." << std::endl;
240         status = gl_tex_img(m_out,res);           240         status = gl_tex_img(m_out,res);
241         gsto_size = res.size();                   241         gsto_size = res.size();
242       }                                           242       }
243     } else {                                      243     } else {
244       m_out << "toolx::sg::gl::tex_img :"         244       m_out << "toolx::sg::gl::tex_img :"
245             << " warning : img size > GL_MAX_T    245             << " warning : img size > GL_MAX_TEXTURE_SIZE (" << sz << ") but can't reduce."
246             << std::endl;                         246             << std::endl;
247       status = false;                             247       status = false;
248     }}}                                           248     }}}
249                                                   249 
250     if(a_NEAREST) {                               250     if(a_NEAREST) {
251       ::glTexParameteri(GL_TEXTURE_2D,GL_TEXTU    251       ::glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); //good to see astro images pixels.
252       ::glTexParameteri(GL_TEXTURE_2D,GL_TEXTU    252       ::glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); //idem.
253     } else {                                      253     } else {
254       ::glTexParameteri(GL_TEXTURE_2D,GL_TEXTU    254       ::glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
255       ::glTexParameteri(GL_TEXTURE_2D,GL_TEXTU    255       ::glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
256     }                                             256     }
257     ::glBindTexture(GL_TEXTURE_2D,0);             257     ::glBindTexture(GL_TEXTURE_2D,0);
258                                                   258 
259     if(!status) {                                 259     if(!status) {
260       gl_dump_if_errors(m_out,"toolx::sg::GL_m    260       gl_dump_if_errors(m_out,"toolx::sg::GL_manager::create_texture (1) :");
261       ::glDeleteTextures(1,&gl_id);               261       ::glDeleteTextures(1,&gl_id);
262 #ifdef TOOLS_MEM                                  262 #ifdef TOOLS_MEM
263       tools::mem::decrement(tools::s_tex().c_s    263       tools::mem::decrement(tools::s_tex().c_str());
264 #endif                                            264 #endif
265       gl_id = 0;                                  265       gl_id = 0;
266       gl_clear_errors();                          266       gl_clear_errors();
267       return 0;                                   267       return 0;
268     }                                             268     }
269                                                   269 
270     if(gl_dump_if_errors(m_out,"toolx::sg::GL_    270     if(gl_dump_if_errors(m_out,"toolx::sg::GL_manager::create_texture (2) :")) {
271       ::glDeleteTextures(1,&gl_id);               271       ::glDeleteTextures(1,&gl_id);
272 #ifdef TOOLS_MEM                                  272 #ifdef TOOLS_MEM
273       tools::mem::decrement(tools::s_tex().c_s    273       tools::mem::decrement(tools::s_tex().c_str());
274 #endif                                            274 #endif
275       gl_id = 0;                                  275       gl_id = 0;
276       gl_clear_errors();                          276       gl_clear_errors();
277       return 0;                                   277       return 0;
278     }                                             278     }
279                                                   279 
280     unsigned int _id = m_gen_id;m_gen_id++;       280     unsigned int _id = m_gen_id;m_gen_id++;
281     m_gstos[_id] = new gsto_t(gsto_t::kind_tex    281     m_gstos[_id] = new gsto_t(gsto_t::kind_texture,gl_id,gsto_size,0);
282     return _id;                                   282     return _id;
283   }                                               283   }
284                                                   284 
285   ////////////////////////////////////////////    285   ////////////////////////////////////////////////
286   /// VBO ////////////////////////////////////    286   /// VBO ////////////////////////////////////////
287   ////////////////////////////////////////////    287   ////////////////////////////////////////////////
288   virtual unsigned int create_gsto_from_data(s    288   virtual unsigned int create_gsto_from_data(size_t a_floatn,const float* a_data) {
289     if(!a_floatn) return 0;                       289     if(!a_floatn) return 0;
290     switch(m_gsto_mode) {                         290     switch(m_gsto_mode) {
291     case tools::sg::gsto_gl_vbo:{                 291     case tools::sg::gsto_gl_vbo:{
292 #ifdef TOOLX_HAS_GL_VBO                           292 #ifdef TOOLX_HAS_GL_VBO
293       unsigned int gl_id = 0;                     293       unsigned int gl_id = 0;
294       ::glGenBuffers(1,&gl_id);                   294       ::glGenBuffers(1,&gl_id);
295       if(!gl_id) {                                295       if(!gl_id) {
296         if(!m_warned) {                           296         if(!m_warned) {
297           m_warned = true;                        297           m_warned = true;
298           m_out << "toolx::sg::GL_manager::cre    298           m_out << "toolx::sg::GL_manager::create_gsto_from_data : glGenBuffers failed ()." << std::endl;
299         }                                         299         }
300         return 0;                                 300         return 0;
301       }                                           301       }
302 #ifdef TOOLS_MEM                                  302 #ifdef TOOLS_MEM
303       tools::mem::increment(tools::s_gsto().c_    303       tools::mem::increment(tools::s_gsto().c_str());
304 #endif                                            304 #endif
305                                                   305 
306       ::glBindBuffer(GL_ARRAY_BUFFER,gl_id);      306       ::glBindBuffer(GL_ARRAY_BUFFER,gl_id);
307       ::glBufferData(GL_ARRAY_BUFFER,             307       ::glBufferData(GL_ARRAY_BUFFER,
308                      a_floatn*sizeof(float),a_    308                      a_floatn*sizeof(float),a_data,
309                      GL_STATIC_DRAW);             309                      GL_STATIC_DRAW);
310       ::glBindBuffer(GL_ARRAY_BUFFER,0);          310       ::glBindBuffer(GL_ARRAY_BUFFER,0);
311                                                   311 
312       if(gl_dump_if_errors(m_out,"toolx::sg::G    312       if(gl_dump_if_errors(m_out,"toolx::sg::GL_manager::create_gsto_from_data :")) {
313         ::glDeleteBuffers(1,&gl_id);              313         ::glDeleteBuffers(1,&gl_id);
314 #ifdef TOOLS_MEM                                  314 #ifdef TOOLS_MEM
315         tools::mem::decrement(tools::s_gsto().    315         tools::mem::decrement(tools::s_gsto().c_str());
316 #endif                                            316 #endif
317         gl_id = 0;                                317         gl_id = 0;
318         gl_clear_errors();                        318         gl_clear_errors();
319         return 0;                                 319         return 0;
320       }                                           320       }
321                                                   321 
322       unsigned int _id = m_gen_id;m_gen_id++;     322       unsigned int _id = m_gen_id;m_gen_id++;
323       m_gstos[_id] = new gsto_t(gsto_t::kind_b    323       m_gstos[_id] = new gsto_t(gsto_t::kind_buffer,gl_id,a_floatn*sizeof(float),0);
324       return _id;                                 324       return _id;
325 #else //!TOOLX_HAS_GL_VBO                         325 #else //!TOOLX_HAS_GL_VBO
326       m_out << "toolx::sg::GL_manager::create_    326       m_out << "toolx::sg::GL_manager::create_gsto_from_data :"
327             << " gsto mode is gl_vbo but class    327             << " gsto mode is gl_vbo but class not compiled with TOOLX_HAS_GL_VBO."
328             << std::endl;                         328             << std::endl;
329       return 0;                                   329       return 0;
330 #endif //TOOLX_HAS_GL_VBO                         330 #endif //TOOLX_HAS_GL_VBO
331       }break;                                     331       }break;
332     case tools::sg::gsto_gl_list:{                332     case tools::sg::gsto_gl_list:{
333       unsigned int gl_id = 0;                     333       unsigned int gl_id = 0;
334       unsigned int _id = m_gen_id;m_gen_id++;     334       unsigned int _id = m_gen_id;m_gen_id++;
335       m_gstos[_id] = new gsto_t(gsto_t::kind_l    335       m_gstos[_id] = new gsto_t(gsto_t::kind_list,gl_id,a_floatn*sizeof(float),a_data);
336       return _id;                                 336       return _id;
337       }break;                                     337       }break;
338     case tools::sg::gsto_memory:{                 338     case tools::sg::gsto_memory:{
339       unsigned int gl_id = 0;                     339       unsigned int gl_id = 0;
340       unsigned int _id = m_gen_id;m_gen_id++;     340       unsigned int _id = m_gen_id;m_gen_id++;
341       m_gstos[_id] = new gsto_t(gsto_t::kind_m    341       m_gstos[_id] = new gsto_t(gsto_t::kind_memory,gl_id,a_floatn*sizeof(float),a_data);
342       return _id;                                 342       return _id;
343       }break;                                     343       }break;
344     }                                             344     }
345     return 0;                                     345     return 0;
346   }                                               346   }
347                                                   347 
348   virtual bool is_gsto_id_valid(unsigned int a    348   virtual bool is_gsto_id_valid(unsigned int a_id) const {
349     std::map<unsigned int,gsto_t*>::const_iter    349     std::map<unsigned int,gsto_t*>::const_iterator it = m_gstos.find(a_id);
350     if(it==m_gstos.end()) return false;           350     if(it==m_gstos.end()) return false;
351     return (*it).second->is_valid();              351     return (*it).second->is_valid();
352   }                                               352   }
353                                                   353 
354   virtual void delete_gsto(unsigned int a_id){    354   virtual void delete_gsto(unsigned int a_id){
355     tools::delete_key<unsigned int,gsto_t>(m_g    355     tools::delete_key<unsigned int,gsto_t>(m_gstos,a_id);
356   }                                               356   }
357                                                   357 
358   ////////////////////////////////////////////    358   ////////////////////////////////////////////////////////
359   ////////////////////////////////////////////    359   ////////////////////////////////////////////////////////
360   ////////////////////////////////////////////    360   ////////////////////////////////////////////////////////
361                                                   361 
362   float* gsto_data(unsigned int a_id) const {     362   float* gsto_data(unsigned int a_id) const {
363     std::map<unsigned int,gsto_t*>::const_iter    363     std::map<unsigned int,gsto_t*>::const_iterator it = m_gstos.find(a_id);
364     if(it==m_gstos.end()) return 0;               364     if(it==m_gstos.end()) return 0;
365     return (*it).second->m_data;                  365     return (*it).second->m_data;
366   }                                               366   }
367                                                   367 
368   unsigned int gsto_gl_list_id(unsigned int a_    368   unsigned int gsto_gl_list_id(unsigned int a_id,bool& a_created) const {
369     std::map<unsigned int,gsto_t*>::const_iter    369     std::map<unsigned int,gsto_t*>::const_iterator it = m_gstos.find(a_id);
370     if(it==m_gstos.end()) {a_created = false;r    370     if(it==m_gstos.end()) {a_created = false;return 0;}
371     if((*it).second->m_kind!=gsto_t::kind_list    371     if((*it).second->m_kind!=gsto_t::kind_list) {a_created = false;return 0;}
372     if((*it).second->m_gl_id) {                   372     if((*it).second->m_gl_id) {
373       a_created = false;                          373       a_created = false;
374       return (*it).second->m_gl_id;               374       return (*it).second->m_gl_id;
375     } else {                                      375     } else {
376 #ifdef TOOLX_HAS_GL_LIST                          376 #ifdef TOOLX_HAS_GL_LIST
377       unsigned int _id = ::glGenLists(1);         377       unsigned int _id = ::glGenLists(1);
378       if(!_id) {a_created = false;return 0;}      378       if(!_id) {a_created = false;return 0;}
379 #ifdef TOOLS_MEM                                  379 #ifdef TOOLS_MEM
380       tools::mem::increment(tools::s_gsto().c_    380       tools::mem::increment(tools::s_gsto().c_str());
381 #endif                                            381 #endif
382       a_created = true;                           382       a_created = true;
383       (*it).second->m_gl_id = _id;                383       (*it).second->m_gl_id = _id;
384       return _id;                                 384       return _id;
385 #else                                             385 #else
386       a_created = false;                          386       a_created = false;
387       return 0;                                   387       return 0;
388 #endif                                            388 #endif
389     }                                             389     }
390   }                                               390   }
391                                                   391 
392   ////////////////////////////////////////////    392   ////////////////////////////////////////////////////////
393   ////////////////////////////////////////////    393   ////////////////////////////////////////////////////////
394   ////////////////////////////////////////////    394   ////////////////////////////////////////////////////////
395   virtual tools::sg::gsto_mode get_gsto_mode()    395   virtual tools::sg::gsto_mode get_gsto_mode() const {return m_gsto_mode;}
396                                                   396 
397   virtual void set_gsto_mode(tools::sg::gsto_m    397   virtual void set_gsto_mode(tools::sg::gsto_mode a_v) {
398     if(a_v==m_gsto_mode) return;                  398     if(a_v==m_gsto_mode) return;
399     tools::safe_clear<unsigned int,gsto_t>(m_g    399     tools::safe_clear<unsigned int,gsto_t>(m_gstos);
400     switch(a_v) {                                 400     switch(a_v) {
401     case tools::sg::gsto_gl_vbo:{                 401     case tools::sg::gsto_gl_vbo:{
402 #ifdef TOOLX_HAS_GL_VBO                           402 #ifdef TOOLX_HAS_GL_VBO
403       m_gsto_mode = a_v;                          403       m_gsto_mode = a_v;
404 #else                                             404 #else
405       m_gsto_mode = tools::sg::gsto_memory;       405       m_gsto_mode = tools::sg::gsto_memory;
406 #endif                                            406 #endif
407       }break;                                     407       }break;
408     case tools::sg::gsto_gl_list:{                408     case tools::sg::gsto_gl_list:{
409 #ifdef TOOLX_HAS_GL_LIST                          409 #ifdef TOOLX_HAS_GL_LIST
410       m_gsto_mode = a_v;                          410       m_gsto_mode = a_v;
411 #else                                             411 #else
412       m_gsto_mode = tools::sg::gsto_memory;       412       m_gsto_mode = tools::sg::gsto_memory;
413 #endif                                            413 #endif
414       }break;                                     414       }break;
415     case tools::sg::gsto_memory:{                 415     case tools::sg::gsto_memory:{
416       m_gsto_mode = tools::sg::gsto_memory;       416       m_gsto_mode = tools::sg::gsto_memory;
417       }break;                                     417       }break;
418     }                                             418     }
419   }                                               419   }
420                                                   420 
421   virtual void available_gsto_modes(std::vecto    421   virtual void available_gsto_modes(std::vector<std::string>& a_vs) {
422     a_vs.clear();                                 422     a_vs.clear();
423 #ifdef TOOLX_HAS_GL_VBO                           423 #ifdef TOOLX_HAS_GL_VBO
424     a_vs.push_back(tools::sg::s_gsto_gl_vbo())    424     a_vs.push_back(tools::sg::s_gsto_gl_vbo());
425 #endif                                            425 #endif
426 #ifdef TOOLX_HAS_GL_LIST                          426 #ifdef TOOLX_HAS_GL_LIST
427     a_vs.push_back(tools::sg::s_gsto_gl_list()    427     a_vs.push_back(tools::sg::s_gsto_gl_list());
428 #endif                                            428 #endif
429     a_vs.push_back(tools::sg::s_gsto_memory())    429     a_vs.push_back(tools::sg::s_gsto_memory());
430   }                                               430   }
431                                                   431 
432   virtual void available_not_memory_gsto_mode(    432   virtual void available_not_memory_gsto_mode(std::string& a_v) const {
433     a_v.clear();                                  433     a_v.clear();
434 #ifdef TOOLX_HAS_GL_VBO                           434 #ifdef TOOLX_HAS_GL_VBO
435     a_v = tools::sg::s_gsto_gl_vbo();             435     a_v = tools::sg::s_gsto_gl_vbo();
436 #endif                                            436 #endif
437 #ifdef TOOLX_HAS_GL_LIST                          437 #ifdef TOOLX_HAS_GL_LIST
438     if(a_v.empty()) a_v = tools::sg::s_gsto_gl    438     if(a_v.empty()) a_v = tools::sg::s_gsto_gl_list();
439 #endif                                            439 #endif
440   }                                               440   }
441                                                   441 
442   virtual size_t used_texture_memory() const {    442   virtual size_t used_texture_memory() const {
443     size_t sz = 0;                                443     size_t sz = 0;
444     std::map<unsigned int,gsto_t*>::const_iter    444     std::map<unsigned int,gsto_t*>::const_iterator it;
445     for(it=m_gstos.begin();it!=m_gstos.end();+    445     for(it=m_gstos.begin();it!=m_gstos.end();++it) {
446       if((*it).second->m_kind==gsto_t::kind_te    446       if((*it).second->m_kind==gsto_t::kind_texture) sz += (*it).second->m_size;
447     }                                             447     }
448     return sz;                                    448     return sz;
449   }                                               449   }
450                                                   450 
451   virtual size_t gstos_size() const {             451   virtual size_t gstos_size() const {
452     size_t sz = 0;                                452     size_t sz = 0;
453     std::map<unsigned int,gsto_t*>::const_iter    453     std::map<unsigned int,gsto_t*>::const_iterator it;
454     for(it=m_gstos.begin();it!=m_gstos.end();+    454     for(it=m_gstos.begin();it!=m_gstos.end();++it) sz += (*it).second->m_size;
455     return sz;                                    455     return sz;
456   }                                               456   }
457                                                   457 
458 public:                                           458 public:
459   GL_manager(std::ostream& a_out)                 459   GL_manager(std::ostream& a_out)
460   :m_out(a_out)                                   460   :m_out(a_out)
461   ,m_gen_id(1)                                    461   ,m_gen_id(1)
462 #ifdef TOOLX_HAS_GL_VBO                           462 #ifdef TOOLX_HAS_GL_VBO
463   ,m_gsto_mode(tools::sg::gsto_gl_vbo) //prior    463   ,m_gsto_mode(tools::sg::gsto_gl_vbo) //priority to GL VBOs.
464 #elif TOOLX_HAS_GL_LIST                           464 #elif TOOLX_HAS_GL_LIST
465   ,m_gsto_mode(tools::sg::gsto_gl_list)           465   ,m_gsto_mode(tools::sg::gsto_gl_list)
466 #else                                             466 #else
467   ,m_gsto_mode(tools::sg::gsto_memory)            467   ,m_gsto_mode(tools::sg::gsto_memory)
468 #endif                                            468 #endif
469   ,m_warned(false)                                469   ,m_warned(false)
470   {}                                              470   {}
471   virtual ~GL_manager(){                          471   virtual ~GL_manager(){
472     tools::safe_clear<unsigned int,gsto_t>(m_g    472     tools::safe_clear<unsigned int,gsto_t>(m_gstos);
473   }                                               473   }
474 public:                                           474 public:
475   GL_manager(const GL_manager& a_from)            475   GL_manager(const GL_manager& a_from)
476   :parent(a_from)                                 476   :parent(a_from)
477   ,m_out(a_from.m_out)                            477   ,m_out(a_from.m_out)
478   ,m_gen_id(a_from.m_gen_id)                      478   ,m_gen_id(a_from.m_gen_id)
479   ,m_gsto_mode(a_from.m_gsto_mode)                479   ,m_gsto_mode(a_from.m_gsto_mode)
480   ,m_warned(false)                                480   ,m_warned(false)
481   {}                                              481   {}
482   GL_manager& operator=(const GL_manager& a_fr    482   GL_manager& operator=(const GL_manager& a_from){
483     if(&a_from==this) return *this;               483     if(&a_from==this) return *this;
484     m_gen_id = a_from.m_gen_id;                   484     m_gen_id = a_from.m_gen_id;
485     m_gsto_mode = a_from.m_gsto_mode;             485     m_gsto_mode = a_from.m_gsto_mode;
486     tools::safe_clear<unsigned int,gsto_t>(m_g    486     tools::safe_clear<unsigned int,gsto_t>(m_gstos);
487     m_warned = false;                             487     m_warned = false;
488     return *this;                                 488     return *this;
489   }                                               489   }
490                                                   490 
491 public:                                           491 public:
492   void bind_gsto(unsigned int a_id) {             492   void bind_gsto(unsigned int a_id) {
493     std::map<unsigned int,gsto_t*>::const_iter    493     std::map<unsigned int,gsto_t*>::const_iterator it = m_gstos.find(a_id);
494     if(it==m_gstos.end()) return;                 494     if(it==m_gstos.end()) return;
495     (*it).second->bind();                         495     (*it).second->bind();
496   }                                               496   }
497                                                   497 
498   void delete_gstos() {                           498   void delete_gstos() {
499     tools::safe_clear<unsigned int,gsto_t>(m_g    499     tools::safe_clear<unsigned int,gsto_t>(m_gstos);
500   }                                               500   }
501                                                   501 
502 public:                                           502 public:
503                                                   503 
504   static unsigned char* get_rgbas(unsigned int    504   static unsigned char* get_rgbas(unsigned int a_w,unsigned int a_h) {
505     //WARNING : it does OpenGL. Under Android     505     //WARNING : it does OpenGL. Under Android it should be executed
506     //          in the OpenGL thread.             506     //          in the OpenGL thread.
507     //NOTE : Android, iOS : RGB produces a bla    507     //NOTE : Android, iOS : RGB produces a black image.
508     unsigned char* rgbas = new unsigned char[4    508     unsigned char* rgbas = new unsigned char[4 * a_w * a_h];
509     if(!rgbas) return 0;                          509     if(!rgbas) return 0;
510     ::glPixelStorei(GL_PACK_ALIGNMENT,1); //ne    510     ::glPixelStorei(GL_PACK_ALIGNMENT,1); //needed with Cocoa.
511     ::glReadPixels(0,0,a_w,a_h,GL_RGBA,GL_UNSI    511     ::glReadPixels(0,0,a_w,a_h,GL_RGBA,GL_UNSIGNED_BYTE,rgbas);
512  /*{size_t number = 4 * a_w * a_h;                512  /*{size_t number = 4 * a_w * a_h;
513     size_t count_not_255 = 0;                     513     size_t count_not_255 = 0;
514     for(size_t item=3;item<number;item+=4) {      514     for(size_t item=3;item<number;item+=4) {
515       unsigned char a = rgbas[item];              515       unsigned char a = rgbas[item];
516       if(a!=255) {                                516       if(a!=255) {
517         ::printf("%lu : %d\n",item,a);            517         ::printf("%lu : %d\n",item,a);
518         count_not_255++;                          518         count_not_255++;
519   rgbas[item] = 255;                              519   rgbas[item] = 255;
520       }                                           520       }
521     }                                             521     }
522     ::printf("not_255 : %lu\n",count_not_255);    522     ::printf("not_255 : %lu\n",count_not_255);}*/
523     return rgbas;                                 523     return rgbas;
524   }                                               524   }
525                                                   525 
526 #if defined(TARGET_OS_IPHONE) || defined(ANDRO    526 #if defined(TARGET_OS_IPHONE) || defined(ANDROID)
527   static unsigned char* get_rgbs(unsigned int     527   static unsigned char* get_rgbs(unsigned int a_w,unsigned int a_h) {
528     unsigned char* rgbas = get_rgbas(a_w,a_h);    528     unsigned char* rgbas = get_rgbas(a_w,a_h);
529     if(!rgbas) return 0;                          529     if(!rgbas) return 0;
530     unsigned char* rgbs = tools::_4s_to_3s<uns    530     unsigned char* rgbs = tools::_4s_to_3s<unsigned char,unsigned int>(rgbas,a_w,a_h);
531     delete [] rgbas;                              531     delete [] rgbas;
532     return rgbs;                                  532     return rgbs;
533   }                                               533   }
534 #else                                             534 #else
535   static unsigned char* get_rgbs(unsigned int     535   static unsigned char* get_rgbs(unsigned int a_w,unsigned int a_h) {
536     //WARNING : it does OpenGL. Under Android     536     //WARNING : it does OpenGL. Under Android it should be executed
537     //          in the OpenGL thread.             537     //          in the OpenGL thread.
538     //NOTE : Android, iOS : RGB produces a bla    538     //NOTE : Android, iOS : RGB produces a black image.
539     unsigned char* rgbs = new unsigned char[3     539     unsigned char* rgbs = new unsigned char[3 * a_w * a_h];
540     if(!rgbs) return 0;                           540     if(!rgbs) return 0;
541     ::glPixelStorei(GL_PACK_ALIGNMENT,1); //ne    541     ::glPixelStorei(GL_PACK_ALIGNMENT,1); //needed with Cocoa.
542     ::glReadPixels(0,0,a_w,a_h,GL_RGB,GL_UNSIG    542     ::glReadPixels(0,0,a_w,a_h,GL_RGB,GL_UNSIGNED_BYTE,rgbs);
543     return rgbs;                                  543     return rgbs;
544   }                                               544   }
545 #endif                                            545 #endif
546                                                   546 
547 protected:                                        547 protected:
548   std::ostream& m_out;                            548   std::ostream& m_out;
549                                                   549 
550   class gsto_t {                                  550   class gsto_t {
551     TOOLS_SCLASS(GL_manager::gsto_t)              551     TOOLS_SCLASS(GL_manager::gsto_t)
552   public:                                         552   public:
553     enum kind {                                   553     enum kind {
554       kind_texture,                               554       kind_texture,
555       kind_buffer,                                555       kind_buffer,
556       kind_list,                                  556       kind_list,
557       kind_memory                                 557       kind_memory
558     };                                            558     };
559   public:                                         559   public:
560     gsto_t(kind a_kind,int a_gl_id,size_t a_si    560     gsto_t(kind a_kind,int a_gl_id,size_t a_size,const float* a_data)
561     :m_gl_id(a_gl_id)                             561     :m_gl_id(a_gl_id)
562     ,m_kind(a_kind)                               562     ,m_kind(a_kind)
563     ,m_size(a_size)                               563     ,m_size(a_size)
564     ,m_data(0)                                    564     ,m_data(0)
565     {                                             565     {
566 #ifdef TOOLS_MEM                                  566 #ifdef TOOLS_MEM
567       tools::mem::increment(s_class().c_str())    567       tools::mem::increment(s_class().c_str());
568 #endif                                            568 #endif
569       if(a_data) {                                569       if(a_data) {
570         size_t num = m_size/sizeof(float);        570         size_t num = m_size/sizeof(float);
571         m_data = new float[num];                  571         m_data = new float[num];
572 #ifdef TOOLS_MEM                                  572 #ifdef TOOLS_MEM
573         tools::mem::increment(tools::s_new().c    573         tools::mem::increment(tools::s_new().c_str());
574 #endif                                            574 #endif
575         ::memcpy(m_data,a_data,m_size);           575         ::memcpy(m_data,a_data,m_size);
576       }                                           576       }
577     }                                             577     }
578     virtual ~gsto_t() {                           578     virtual ~gsto_t() {
579       if(m_kind==kind_texture) {                  579       if(m_kind==kind_texture) {
580         ::glDeleteTextures(1,&m_gl_id);           580         ::glDeleteTextures(1,&m_gl_id);
581 #ifdef TOOLS_MEM                                  581 #ifdef TOOLS_MEM
582         tools::mem::decrement(tools::s_tex().c    582         tools::mem::decrement(tools::s_tex().c_str());
583 #endif                                            583 #endif
584       } else if(m_kind==kind_buffer) {            584       } else if(m_kind==kind_buffer) {
585 #ifdef TOOLX_HAS_GL_VBO                           585 #ifdef TOOLX_HAS_GL_VBO
586         ::glDeleteBuffers(1,&m_gl_id);            586         ::glDeleteBuffers(1,&m_gl_id);
587 #ifdef TOOLS_MEM                                  587 #ifdef TOOLS_MEM
588         tools::mem::decrement(tools::s_gsto().    588         tools::mem::decrement(tools::s_gsto().c_str());
589 #endif                                            589 #endif
590 #endif                                            590 #endif
591       } else if(m_kind==kind_list) {              591       } else if(m_kind==kind_list) {
592         if(m_gl_id) {                             592         if(m_gl_id) {
593 #ifdef TOOLX_HAS_GL_LIST                          593 #ifdef TOOLX_HAS_GL_LIST
594           ::glDeleteLists(m_gl_id,1);             594           ::glDeleteLists(m_gl_id,1);
595 #ifdef TOOLS_MEM                                  595 #ifdef TOOLS_MEM
596           tools::mem::decrement(tools::s_gsto(    596           tools::mem::decrement(tools::s_gsto().c_str());
597 #endif                                            597 #endif
598 #endif                                            598 #endif
599         }                                         599         }
600       }                                           600       }
601                                                   601 
602       if(m_data) {                                602       if(m_data) {
603         delete [] m_data;                         603         delete [] m_data;
604 #ifdef TOOLS_MEM                                  604 #ifdef TOOLS_MEM
605         tools::mem::decrement(tools::s_new().c    605         tools::mem::decrement(tools::s_new().c_str());
606 #endif                                            606 #endif
607       }                                           607       }
608 #ifdef TOOLS_MEM                                  608 #ifdef TOOLS_MEM
609       tools::mem::decrement(s_class().c_str())    609       tools::mem::decrement(s_class().c_str());
610 #endif                                            610 #endif
611     }                                             611     }
612   private:                                        612   private:
613     gsto_t(const gsto_t& a_from)                  613     gsto_t(const gsto_t& a_from)
614     :m_gl_id(a_from.m_gl_id)                      614     :m_gl_id(a_from.m_gl_id)
615     ,m_kind(a_from.m_kind)                        615     ,m_kind(a_from.m_kind)
616     ,m_size(a_from.m_size)                        616     ,m_size(a_from.m_size)
617     ,m_data(0)                                    617     ,m_data(0)
618     {                                             618     {
619 #ifdef TOOLS_MEM                                  619 #ifdef TOOLS_MEM
620       tools::mem::increment(s_class().c_str())    620       tools::mem::increment(s_class().c_str());
621 #endif                                            621 #endif
622       if(a_from.m_data) {                         622       if(a_from.m_data) {
623         size_t num = m_size/sizeof(float);        623         size_t num = m_size/sizeof(float);
624         m_data = new float[num];                  624         m_data = new float[num];
625 #ifdef TOOLS_MEM                                  625 #ifdef TOOLS_MEM
626         tools::mem::increment(tools::s_new().c    626         tools::mem::increment(tools::s_new().c_str());
627 #endif                                            627 #endif
628         ::memcpy(m_data,a_from.m_data,m_size);    628         ::memcpy(m_data,a_from.m_data,m_size);
629       }                                           629       }
630     }                                             630     }
631     gsto_t& operator=(const gsto_t& a_from){      631     gsto_t& operator=(const gsto_t& a_from){
632       if(&a_from==this) return *this;             632       if(&a_from==this) return *this;
633       m_gl_id = a_from.m_gl_id;                   633       m_gl_id = a_from.m_gl_id;
634       m_kind = a_from.m_kind;                     634       m_kind = a_from.m_kind;
635       m_size = a_from.m_size;                     635       m_size = a_from.m_size;
636       if(m_data) {                                636       if(m_data) {
637         delete [] m_data;                         637         delete [] m_data;
638 #ifdef TOOLS_MEM                                  638 #ifdef TOOLS_MEM
639         tools::mem::decrement(tools::s_new().c    639         tools::mem::decrement(tools::s_new().c_str());
640 #endif                                            640 #endif
641         m_data = 0;                               641         m_data = 0;
642       }                                           642       }
643       if(a_from.m_data) {                         643       if(a_from.m_data) {
644         size_t num = m_size/sizeof(float);        644         size_t num = m_size/sizeof(float);
645         m_data = new float[num];                  645         m_data = new float[num];
646 #ifdef TOOLS_MEM                                  646 #ifdef TOOLS_MEM
647         tools::mem::increment(tools::s_new().c    647         tools::mem::increment(tools::s_new().c_str());
648 #endif                                            648 #endif
649         ::memcpy(m_data,a_from.m_data,m_size);    649         ::memcpy(m_data,a_from.m_data,m_size);
650       }                                           650       }
651       return *this;                               651       return *this;
652     }                                             652     }
653   public:                                         653   public:
654     bool is_valid() const {                       654     bool is_valid() const {
655       if(m_kind==kind_texture) {                  655       if(m_kind==kind_texture) {
656         return (::glIsTexture(m_gl_id)==GL_TRU    656         return (::glIsTexture(m_gl_id)==GL_TRUE?true:false);
657       } else if(m_kind==kind_buffer) {            657       } else if(m_kind==kind_buffer) {
658 #ifdef TOOLX_HAS_GL_VBO                           658 #ifdef TOOLX_HAS_GL_VBO
659         return (::glIsBuffer(m_gl_id)==GL_TRUE    659         return (::glIsBuffer(m_gl_id)==GL_TRUE?true:false);
660 #endif                                            660 #endif
661       } else if(m_kind==kind_list) {              661       } else if(m_kind==kind_list) {
662 #ifdef TOOLX_HAS_GL_LIST                          662 #ifdef TOOLX_HAS_GL_LIST
663         return (::glIsList(m_gl_id)==GL_TRUE?t    663         return (::glIsList(m_gl_id)==GL_TRUE?true:false);
664 #endif                                            664 #endif
665       } else if(m_kind==kind_memory) {            665       } else if(m_kind==kind_memory) {
666         return true;                              666         return true;
667       }                                           667       }
668       return false;                               668       return false;
669     }                                             669     }
670     void bind() const {                           670     void bind() const {
671       if(m_kind==kind_texture) {                  671       if(m_kind==kind_texture) {
672         ::glBindTexture(GL_TEXTURE_2D,m_gl_id)    672         ::glBindTexture(GL_TEXTURE_2D,m_gl_id);
673       } else if(m_kind==kind_buffer) {            673       } else if(m_kind==kind_buffer) {
674 #ifdef TOOLX_HAS_GL_VBO                           674 #ifdef TOOLX_HAS_GL_VBO
675         ::glBindBuffer(GL_ARRAY_BUFFER,m_gl_id    675         ::glBindBuffer(GL_ARRAY_BUFFER,m_gl_id);
676 #endif                                            676 #endif
677       }                                           677       }
678     }                                             678     }
679   public:                                         679   public:
680     unsigned int m_gl_id;                         680     unsigned int m_gl_id;
681     kind m_kind;                                  681     kind m_kind;
682     size_t m_size;                                682     size_t m_size;
683     float* m_data;                                683     float* m_data;
684   };                                              684   };
685                                                   685 
686   std::map<unsigned int,gsto_t*> m_gstos;         686   std::map<unsigned int,gsto_t*> m_gstos;
687                                                   687 
                                                   >> 688   bool m_gsto_on_card;
688   unsigned int m_gen_id;                          689   unsigned int m_gen_id;
689   tools::sg::gsto_mode m_gsto_mode;               690   tools::sg::gsto_mode m_gsto_mode;
690   bool m_warned;                                  691   bool m_warned;
691 };                                                692 };
692                                                   693 
693 }}                                                694 }}
694                                                   695 
695 #endif                                            696 #endif