Warning, /include/Geant4/toolx/sg/GL_manager is written in an unsupported language. File is not indexed.
0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003
0004 #ifndef toolx_sg_GL_manager
0005 #define toolx_sg_GL_manager
0006
0007 #ifndef GL_VERSION_1_1
0008 #error You have to include OpenGL header(s) before including this file.
0009 #endif
0010
0011 #include <tools/sg/render_manager>
0012 #include <tools/mapmanip>
0013 #include <tools/carray>
0014 #include <tools/num2s>
0015 #ifdef TOOLS_USE_GL_VERSION_3_2
0016 #include <tools/lina/mat4f>
0017 #endif
0018
0019 #include <sstream>
0020
0021 #include <cmath> //::sqrt
0022
0023
0024 namespace toolx {
0025 namespace sg {
0026
0027 template <class GL_FUNCTIONS>
0028 class gsto_elem: protected GL_FUNCTIONS {
0029 TOOLS_T_SCLASS(GL_FUNCTIONS,toolx::sg::gsto_elem)
0030 using parent_gl_functions = GL_FUNCTIONS;
0031 public:
0032 enum kind {
0033 kind_texture,
0034 kind_buffer,
0035 kind_list,
0036 kind_memory
0037 };
0038 public:
0039 #ifdef TOOLS_USE_GL_VERSION_3_2
0040 gsto_elem(kind a_kind,unsigned int a_gl_id,size_t a_size,const float* a_data,unsigned int a_vao_id = 0)
0041 :m_gl_id(a_gl_id)
0042 ,m_vao_id(a_vao_id)
0043 #else
0044 gsto_elem(kind a_kind,unsigned int a_gl_id,size_t a_size,const float* a_data)
0045 :m_gl_id(a_gl_id)
0046 #endif
0047 ,m_kind(a_kind)
0048 ,m_size(a_size)
0049 ,m_data(0)
0050 {
0051 if(a_data) {
0052 size_t num = m_size/sizeof(float);
0053 m_data = new float[num];
0054 ::memcpy(m_data,a_data,m_size);
0055 }
0056 }
0057 virtual ~gsto_elem() {
0058 if(m_kind==kind_texture) {
0059 parent_gl_functions::gl__DeleteTextures(1,&m_gl_id);
0060 } else if(m_kind==kind_buffer) {
0061 #ifdef TOOLS_USE_GL_VERSION_3_2
0062 parent_gl_functions::gl__DeleteBuffers(1,&m_gl_id);
0063 parent_gl_functions::gl__DeleteVertexArrays(1,&m_vao_id);
0064 #endif
0065 } else if(m_kind==kind_list) {
0066 if(m_gl_id) {
0067 #ifndef TOOLS_USE_GL_VERSION_3_2
0068 parent_gl_functions::gl__DeleteLists(m_gl_id,1);
0069 #endif
0070 }
0071 }
0072
0073 if(m_data) {
0074 delete [] m_data;
0075 }
0076 }
0077 private:
0078 gsto_elem(const gsto_elem& a_from)
0079 :parent_gl_functions(a_from)
0080 ,m_gl_id(a_from.m_gl_id)
0081 #ifdef TOOLS_USE_GL_VERSION_3_2
0082 ,m_vao_id(a_from.m_vao_id)
0083 #endif
0084 ,m_kind(a_from.m_kind)
0085 ,m_size(a_from.m_size)
0086 ,m_data(0)
0087 {
0088 if(a_from.m_data) {
0089 size_t num = m_size/sizeof(float);
0090 m_data = new float[num];
0091 ::memcpy(m_data,a_from.m_data,m_size);
0092 }
0093 }
0094 gsto_elem& operator=(const gsto_elem& a_from){
0095 if(&a_from==this) return *this;
0096 m_gl_id = a_from.m_gl_id;
0097 #ifdef TOOLS_USE_GL_VERSION_3_2
0098 m_vao_id = a_from.m_vao_id;
0099 #endif
0100 m_kind = a_from.m_kind;
0101 m_size = a_from.m_size;
0102 if(m_data) {
0103 delete [] m_data;
0104 m_data = 0;
0105 }
0106 if(a_from.m_data) {
0107 size_t num = m_size/sizeof(float);
0108 m_data = new float[num];
0109 ::memcpy(m_data,a_from.m_data,m_size);
0110 }
0111 return *this;
0112 }
0113 public:
0114 bool is_valid() /*const*/ {
0115 if(!parent_gl_functions::initialize()) return false;
0116 if(m_kind==kind_texture) {
0117 return (parent_gl_functions::gl__IsTexture(m_gl_id)==GL_TRUE?true:false);
0118 } else if(m_kind==kind_buffer) {
0119 #ifdef TOOLS_USE_GL_VERSION_3_2
0120 return (parent_gl_functions::gl__IsBuffer(m_gl_id)==GL_TRUE?true:false); //If ok, then VAO is ok too.
0121 #endif
0122 } else if(m_kind==kind_list) {
0123 #ifndef TOOLS_USE_GL_VERSION_3_2
0124 return (parent_gl_functions::gl__IsList(m_gl_id)==GL_TRUE?true:false);
0125 #endif
0126 } else if(m_kind==kind_memory) {
0127 return true;
0128 }
0129 return false;
0130 }
0131 void bind() /*const*/ {
0132 parent_gl_functions::initialize();
0133 if(m_kind==kind_texture) {
0134 parent_gl_functions::gl__BindTexture(GL_TEXTURE_2D,m_gl_id);
0135 } else if(m_kind==kind_buffer) {
0136 #ifdef TOOLS_USE_GL_VERSION_3_2
0137 parent_gl_functions::gl__BindVertexArray(m_vao_id);
0138 parent_gl_functions::gl__BindBuffer(GL_ARRAY_BUFFER,m_gl_id);
0139 #endif
0140 }
0141 }
0142 public:
0143 unsigned int m_gl_id;
0144 #ifdef TOOLS_USE_GL_VERSION_3_2
0145 unsigned int m_vao_id;
0146 #endif
0147 kind m_kind;
0148 size_t m_size;
0149 float* m_data;
0150 };
0151
0152 template <class GL_FUNCTIONS>
0153 class GL_manager_T : public virtual tools::sg::render_manager, protected GL_FUNCTIONS {
0154 typedef tools::sg::render_manager parent;
0155 using parent_gl_functions = GL_FUNCTIONS;
0156 typedef gsto_elem<GL_FUNCTIONS> gsto_t;
0157 typedef typename std::map<unsigned int, gsto_t*>::const_iterator gstos_it_t;
0158 public:
0159 TOOLS_T_SCLASS(GL_FUNCTIONS,toolx::sg::GL_manager_T)
0160 virtual void* cast(const std::string& a_class) const {
0161 if(void* p = tools::cmp_cast<GL_manager_T>(this,a_class)) {return p;}
0162 else return 0;
0163 }
0164 public:
0165 virtual bool begin_render(int a_x,int a_y,unsigned int a_ww,unsigned int a_wh,
0166 float a_r,float a_g,float a_b,float a_a,bool a_clear = true) {
0167
0168 if (!parent_gl_functions::initialize()) {
0169 m_out << "toolx::sg::GL_manager_T::begin_render: parent_gl_functions::initialize() failed." << std::endl;
0170 return false;
0171 }
0172
0173 if(m_gl_version.empty()) {
0174 {m_gl_version.clear();
0175 const char* _sv = (const char*)parent_gl_functions::gl__GetString(GL_VERSION);
0176 if(_sv) m_gl_version = _sv;}
0177 #ifdef TOOLS_USE_GL_VERSION_3_2
0178 {m_gl_shading_language_version.clear();
0179 const char* _sv = (const char*)parent_gl_functions::gl__GetString(GL_SHADING_LANGUAGE_VERSION);
0180 if(_sv) m_gl_shading_language_version = _sv;}
0181 #endif
0182 {m_gl_vendor.clear();
0183 const char* _sv = (const char*)parent_gl_functions::gl__GetString(GL_VENDOR);
0184 if(_sv) m_gl_vendor = _sv;}
0185 {m_gl_renderer.clear();
0186 const char* _sv = (const char*)parent_gl_functions::gl__GetString(GL_RENDERER);
0187 if(_sv) m_gl_renderer = _sv;}
0188 {m_gl_extensions.clear();
0189 const char* _sv = (const char*)parent_gl_functions::gl__GetString(GL_EXTENSIONS);
0190 if(_sv) m_gl_extensions = _sv;}
0191 m_gl_max_texture_size = 0;
0192 parent_gl_functions::gl__GetIntegerv(GL_MAX_TEXTURE_SIZE, &m_gl_max_texture_size);
0193 }
0194
0195 clear_gl_errors();
0196
0197 #ifdef TOOLS_USE_GL_VERSION_3_2
0198
0199 // to avoid a 0x506 error message :
0200 if(parent_gl_functions::gl__CheckFramebufferStatus(GL_FRAMEBUFFER)!=GL_FRAMEBUFFER_COMPLETE) {
0201 return false;
0202 }
0203
0204 if(!create_shader_program()) {
0205 dump_if_gl_errors(m_out,"toolx::sg::GL_manager_T::create_shader_program :");
0206 m_out << "toolx::sg::GL_manager_T::begin_render : create_shader_program() failed." << std::endl;
0207 return false;
0208 }
0209 use_shader_program();
0210
0211 // WARNING : the values set here must match the default values in sg::state.
0212
0213 //WARNING : the below glEnable/glDisable corresponds
0214 // to defaults in tools::sg::state.
0215 parent_gl_functions::gl__Enable(GL_DEPTH_TEST);
0216 parent_gl_functions::gl__FrontFace(GL_CCW);
0217 parent_gl_functions::gl__Enable(GL_CULL_FACE);
0218 parent_gl_functions::gl__Disable(GL_POLYGON_OFFSET_FILL);
0219
0220 parent_gl_functions::gl__DepthFunc(GL_LESS);
0221 parent_gl_functions::gl__DepthMask(GL_TRUE);
0222
0223 parent_gl_functions::gl__Disable(GL_BLEND); //must be in sync with tools::sg::state.m_GL_BLEND and sg::blend node default.
0224 parent_gl_functions::gl__BlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
0225
0226 parent_gl_functions::gl__LineWidth(1.0f);
0227 parent_gl_functions::gl__Uniform1f(g_point_size_location(),1.0f);
0228
0229 parent_gl_functions::gl__Viewport(a_x,a_y,a_ww,a_wh);
0230
0231 if(a_clear) {
0232 parent_gl_functions::gl__ClearColor(a_r,a_g,a_b,a_a);
0233 parent_gl_functions::gl__Clear(GL_COLOR_BUFFER_BIT);
0234 parent_gl_functions::gl__Clear(GL_DEPTH_BUFFER_BIT);
0235 }
0236
0237 tools::mat4f ID4;ID4.set_identity();
0238 parent_gl_functions::gl__UniformMatrix4fv(g_model_proj_matrix_location(),1,GL_FALSE,ID4.data());
0239 parent_gl_functions::gl__UniformMatrix4fv(g_normal_matrix_location(),1,GL_FALSE,ID4.data());
0240
0241 #else //not TOOLS_USE_GL_VERSION_3_2
0242
0243 #ifdef __APPLE__
0244 #ifdef __COREFOUNDATION__ //Cocoa.h included: we build a Cocoa application.
0245 // to avoid a 0x506 error message :
0246 if(parent_gl_functions::gl__CheckFramebufferStatus(GL_FRAMEBUFFER)!=GL_FRAMEBUFFER_COMPLETE) { //It is a GL_VERSION_3_0 function.
0247 return false;
0248 }
0249 #endif
0250 #endif
0251
0252 // WARNING : the values set here must match the default values in sg::state.
0253
0254
0255 parent_gl_functions::gl__Disable(GL_POLYGON_STIPPLE); //CoinGL : reading a .wrl having Material::transparency may enable GL_POLYGON_STIPPLE.
0256
0257 parent_gl_functions::gl__Enable(GL_NORMALIZE);
0258 parent_gl_functions::gl__ShadeModel(GL_FLAT);
0259 parent_gl_functions::gl__Enable(GL_COLOR_MATERIAL);
0260
0261
0262 parent_gl_functions::gl__Disable(GL_BLEND); //must be in sync with tools::sg::state.m_GL_BLEND and sg::blend node default.
0263 parent_gl_functions::gl__BlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
0264
0265 //WARNING : the below glEnable/glDisable corresponds
0266 // to defaults in tools::sg::state.
0267 parent_gl_functions::gl__Enable(GL_DEPTH_TEST);
0268 parent_gl_functions::gl__Disable(GL_LIGHTING);
0269 parent_gl_functions::gl__FrontFace(GL_CCW);
0270 parent_gl_functions::gl__Enable(GL_CULL_FACE);
0271 parent_gl_functions::gl__Disable(GL_POLYGON_OFFSET_FILL);
0272 parent_gl_functions::gl__Disable(GL_TEXTURE_2D);
0273
0274 parent_gl_functions::gl__DepthFunc(GL_LESS);
0275 parent_gl_functions::gl__DepthMask(GL_TRUE);
0276
0277 parent_gl_functions::gl__Disable(GL_POINT_SMOOTH);
0278 parent_gl_functions::gl__PointSize(1);
0279
0280 parent_gl_functions::gl__Disable(GL_LINE_SMOOTH); //NOTE : it does not work on all platforms !
0281 parent_gl_functions::gl__LineWidth(1);
0282
0283 parent_gl_functions::gl__Viewport(a_x,a_y,a_ww,a_wh);
0284
0285 if(a_clear) {
0286 parent_gl_functions::gl__ClearColor(a_r,a_g,a_b,0);
0287 parent_gl_functions::gl__Clear(GL_COLOR_BUFFER_BIT);
0288 parent_gl_functions::gl__Clear(GL_DEPTH_BUFFER_BIT);
0289 }
0290
0291 parent_gl_functions::gl__MatrixMode(GL_PROJECTION);
0292 parent_gl_functions::gl__LoadIdentity();
0293
0294 parent_gl_functions::gl__MatrixMode(GL_MODELVIEW);
0295 parent_gl_functions::gl__LoadIdentity();
0296
0297
0298 {parent_gl_functions::gl__Color4f(a_r,a_g,a_b,::sqrt(a_a));
0299 float xyzs[12];
0300 xyzs[0] = -1;xyzs[ 1] = -1;xyzs[ 2] = 0;
0301 xyzs[3] = 1;xyzs[ 4] = -1;xyzs[ 5] = 0;
0302 xyzs[6] = 1;xyzs[ 7] = 1;xyzs[ 8] = 0;
0303 xyzs[9] = -1;xyzs[10] = 1;xyzs[11] = 0;
0304 parent_gl_functions::gl__Disable(GL_DEPTH_TEST);
0305 parent_gl_functions::gl__EnableClientState(GL_VERTEX_ARRAY);
0306 parent_gl_functions::gl__VertexPointer(3,GL_FLOAT,0,xyzs);
0307 parent_gl_functions::gl__DrawArrays(GL_TRIANGLE_FAN,0,4);
0308 parent_gl_functions::gl__DisableClientState(GL_VERTEX_ARRAY);
0309 parent_gl_functions::gl__Enable(GL_DEPTH_TEST);}
0310
0311 #endif //not TOOLS_USE_GL_VERSION_3_2
0312 return true;
0313 }
0314
0315 virtual void end_render() {
0316 #ifdef TOOLS_USE_GL_VERSION_3_2
0317 reset_shader_locations();
0318 #endif
0319 dump_if_gl_errors(m_out,"toolx::sg::GL_manager_T::end_render :");
0320 }
0321
0322 ////////////////////////////////////////////////
0323 /// texture : //////////////////////////////////
0324 ////////////////////////////////////////////////
0325 virtual unsigned int create_texture(const tools::img_byte& a_img,bool a_NEAREST) {
0326
0327 tools::img_byte* _img = 0;
0328 bool _img_delete = false;
0329
0330 if(a_img.bytes_per_pixel()==1) { //exa eiffel-tower.png
0331 _img = new tools::img_byte;
0332 _img_delete = true;
0333 if(!a_img.bw2x(3,*_img)) {
0334 m_out << "toolx::sg::GL_manager_T::create_texture :"
0335 << " a_imgr.bw2x() failed."
0336 << std::endl;
0337 delete _img;
0338 return 0;
0339 }
0340 } else if(a_img.bytes_per_pixel()==3) {
0341 _img = const_cast<tools::img_byte*>(&a_img);
0342 } else if(a_img.bytes_per_pixel()==4) { //exa windusrf.png, text_freetype/font_pixmap.
0343 _img = const_cast<tools::img_byte*>(&a_img);
0344 } else {
0345 //should not happen.
0346 m_out << "toolx::sg::GL_manager_T::create_texture :"
0347 << " image with bytes_per_pixel " << a_img.bytes_per_pixel() << " not (yet) supported."
0348 << std::endl;
0349 return 0;
0350 }
0351 if(_img->is_empty()) {
0352 m_out << "toolx::sg::GL_manager_T::create_texture : img_byte is empty." << std::endl;
0353 if(_img_delete) delete _img;
0354 return 0;
0355 }
0356
0357 {int sz;
0358 parent_gl_functions::gl__GetIntegerv(GL_MAX_TEXTURE_SIZE,&sz);
0359 if(!sz) {
0360 m_out << "toolx::sg::GL_manager_T::create_texture : warning : GL_MAX_TEXTURE_SIZE is zero." << std::endl;
0361 } else {
0362 tools::img_byte* res = new tools::img_byte;
0363 if(_img->check_gl_limit(sz,*res)) {
0364 if(res->is_empty()) { //_img does not exceed.
0365 delete res;
0366 } else {
0367 m_out << "toolx::sg::GL_manager_T::create_texture:"
0368 << " warning : img size (" << _img->size() << ") > GL_MAX_TEXTURE_SIZE (" << sz << "), we use a reduced one." << std::endl;
0369 if(_img_delete) delete _img;
0370 _img = res;
0371 _img_delete = true;
0372 }
0373 } else {
0374 m_out << "toolx::sg::GL_manager_T::create_texture :"
0375 << " warning : img size (" << _img->size() << ") > GL_MAX_TEXTURE_SIZE (" << sz << ") but can't reduce it."
0376 << std::endl;
0377 delete res;
0378 if(_img_delete) delete _img;
0379 return false;
0380 }
0381 }}
0382 if(_img->is_empty()) {
0383 m_out << "toolx::sg::GL_manager_T::create_texture : img_byte is empty." << std::endl;
0384 if(_img_delete) delete _img;
0385 return 0;
0386 }
0387
0388 unsigned int gl_id;
0389 parent_gl_functions::gl__GenTextures(1,&gl_id);
0390 if(!gl_id) {
0391 m_out << "toolx::sg::GL_manager_T::create_texture : glGenTextures failed ()." << std::endl;
0392 if(_img_delete) delete _img;
0393 return 0;
0394 }
0395
0396 unsigned int gsto_size = _img->size();
0397 if(_img->bytes_per_pixel()==3) {
0398 parent_gl_functions::gl__BindTexture(GL_TEXTURE_2D,gl_id);
0399 parent_gl_functions::gl__TexImage2D(GL_TEXTURE_2D,0,GL_RGB,_img->width(),_img->height(),0,GL_RGB,GL_UNSIGNED_BYTE,_img->buffer());
0400 if(_img_delete) delete _img;
0401 } else if(_img->bytes_per_pixel()==4) {
0402 parent_gl_functions::gl__BindTexture(GL_TEXTURE_2D,gl_id);
0403 parent_gl_functions::gl__TexImage2D(GL_TEXTURE_2D,0,GL_RGBA,_img->width(),_img->height(),0,GL_RGBA,GL_UNSIGNED_BYTE,_img->buffer());
0404 if(_img_delete) delete _img;
0405 } else {
0406 m_out << "toolx::sg::GL_manager_T::create_texture : img.bytes_per_pixel() " << _img->bytes_per_pixel() << " not handled." << std::endl;
0407 if(_img_delete) delete _img;
0408 parent_gl_functions::gl__DeleteTextures(1,&gl_id);
0409 gl_id = 0;
0410 return false;
0411 }
0412 if(a_NEAREST) {
0413 parent_gl_functions::gl__TexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); //good to see astro images pixels.
0414 parent_gl_functions::gl__TexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); //idem.
0415 } else {
0416 parent_gl_functions::gl__TexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
0417 parent_gl_functions::gl__TexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
0418 }
0419 parent_gl_functions::gl__BindTexture(GL_TEXTURE_2D,0);
0420
0421 if(dump_if_gl_errors(m_out,"toolx::sg::GL_manager_T::create_texture :")) {
0422 parent_gl_functions::gl__DeleteTextures(1,&gl_id);
0423 gl_id = 0;
0424 clear_gl_errors();
0425 return 0;
0426 }
0427
0428 unsigned int _id = m_gen_id;m_gen_id++;
0429 m_gstos[_id] = new gsto_t(gsto_t::kind_texture,gl_id,gsto_size,0);
0430 return _id;
0431 }
0432
0433 ////////////////////////////////////////////////
0434 /// gsto ///////////////////////////////////////
0435 ////////////////////////////////////////////////
0436 virtual unsigned int create_gsto_from_data(size_t a_floatn,const float* a_data) {
0437 if(!a_floatn) return 0;
0438 switch(m_gsto_mode) {
0439 case tools::sg::gsto_gl_vbo:{
0440 #ifdef TOOLS_USE_GL_VERSION_3_2
0441 GLuint vao_id = 0;
0442 parent_gl_functions::gl__GenVertexArrays(1,&vao_id);
0443 if(!vao_id) {
0444 m_out << "toolx::sg::GL_manager_T::create_gsto_from_data : glGenVertexArray failed ()." << std::endl;
0445 return 0;
0446 }
0447
0448 parent_gl_functions::gl__BindVertexArray(vao_id);
0449 ////////////////////////////////////////////////////////////////////
0450 ////////////////////////////////////////////////////////////////////
0451 GLuint gl_id = 0;
0452 parent_gl_functions::gl__GenBuffers(1,&gl_id);
0453 if(!gl_id) {
0454 parent_gl_functions::gl__DeleteVertexArrays(1,&vao_id);
0455 m_out << "toolx::sg::GL_manager_T::create_gsto_from_data : glGenBuffers failed ()." << std::endl;
0456 return 0;
0457 }
0458 parent_gl_functions::gl__BindBuffer(GL_ARRAY_BUFFER,gl_id);
0459 parent_gl_functions::gl__BufferData(GL_ARRAY_BUFFER,a_floatn*sizeof(float),a_data,GL_STATIC_DRAW);
0460 parent_gl_functions::gl__BindBuffer(GL_ARRAY_BUFFER,0);
0461 ////////////////////////////////////////////////////////////////////
0462 ////////////////////////////////////////////////////////////////////
0463 parent_gl_functions::gl__BindVertexArray(0);
0464
0465 if(dump_if_gl_errors(m_out,"toolx::sg::GL_manager_T::create_gsto_from_data :")) {
0466 m_out << "toolx::sg::GL_manager_T::create_gsto_from_data :"
0467 << " a_floatn = " << a_floatn << ", a_data = " << a_data
0468 << ", vao_id " << vao_id << ", gl_id " << gl_id
0469 << std::endl;
0470 parent_gl_functions::gl__DeleteBuffers(1,&gl_id);
0471 parent_gl_functions::gl__DeleteVertexArrays(1,&vao_id);
0472 clear_gl_errors();
0473 return 0;
0474 }
0475
0476 unsigned int _id = m_gen_id;m_gen_id++;
0477 m_gstos[_id] = new gsto_t(gsto_t::kind_buffer,gl_id,a_floatn*sizeof(float),0,vao_id);
0478 return _id;
0479
0480 #else
0481 m_out << "toolx::sg::GL_manager_T::create_gsto_from_data :"
0482 << " gsto mode is gl_vbo but class not compiled with TOOLS_USE_GL_VERSION_3_2."
0483 << std::endl;
0484 return 0;
0485 #endif
0486 }break;
0487 case tools::sg::gsto_gl_list:{
0488 unsigned int gl_id = 0;
0489 unsigned int _id = m_gen_id;m_gen_id++;
0490 m_gstos[_id] = new gsto_t(gsto_t::kind_list,gl_id,a_floatn*sizeof(float),a_data);
0491 return _id;
0492 }break;
0493 case tools::sg::gsto_memory:{
0494 unsigned int gl_id = 0;
0495 unsigned int _id = m_gen_id;m_gen_id++;
0496 m_gstos[_id] = new gsto_t(gsto_t::kind_memory,gl_id,a_floatn*sizeof(float),a_data);
0497 return _id;
0498 }break;
0499 }
0500 return 0;
0501 }
0502
0503 virtual bool is_gsto_id_valid(unsigned int a_id) const {
0504 gstos_it_t it = m_gstos.find(a_id);
0505 if(it==m_gstos.end()) return false;
0506 return (*it).second->is_valid();
0507 }
0508
0509 virtual void delete_gsto(unsigned int a_id){
0510 tools::delete_key<unsigned int,gsto_t>(m_gstos,a_id);
0511 }
0512
0513 ////////////////////////////////////////////////////////
0514 ////////////////////////////////////////////////////////
0515 ////////////////////////////////////////////////////////
0516
0517 float* gsto_data(unsigned int a_id) const {
0518 gstos_it_t it = m_gstos.find(a_id);
0519 if(it==m_gstos.end()) return 0;
0520 return (*it).second->m_data;
0521 }
0522
0523 unsigned int gsto_gl_list_id(unsigned int a_id,bool& a_created) {
0524 gstos_it_t it = m_gstos.find(a_id);
0525 if(it==m_gstos.end()) {a_created = false;return 0;}
0526 if((*it).second->m_kind!=gsto_t::kind_list) {a_created = false;return 0;}
0527 if((*it).second->m_gl_id) {
0528 a_created = false;
0529 return (*it).second->m_gl_id;
0530 } else {
0531 #ifndef TOOLS_USE_GL_VERSION_3_2
0532 unsigned int _id = parent_gl_functions::gl__GenLists(1);
0533 if(!_id) {a_created = false;return 0;}
0534 a_created = true;
0535 (*it).second->m_gl_id = _id;
0536 return _id;
0537 #else
0538 a_created = false;
0539 return 0;
0540 #endif
0541 }
0542 }
0543
0544 ////////////////////////////////////////////////////////
0545 ////////////////////////////////////////////////////////
0546 ////////////////////////////////////////////////////////
0547 virtual tools::sg::gsto_mode get_gsto_mode() const {return m_gsto_mode;}
0548
0549 virtual void set_gsto_mode(tools::sg::gsto_mode a_v) {
0550 if(a_v==m_gsto_mode) return;
0551 tools::safe_clear<unsigned int,gsto_t>(m_gstos);
0552 switch(a_v) {
0553 case tools::sg::gsto_gl_vbo:{
0554 #ifdef TOOLS_USE_GL_VERSION_3_2
0555 m_gsto_mode = a_v;
0556 #else
0557 m_gsto_mode = tools::sg::gsto_memory;
0558 #endif
0559 }break;
0560 case tools::sg::gsto_gl_list:{
0561 #ifndef TOOLS_USE_GL_VERSION_3_2
0562 m_gsto_mode = a_v;
0563 #else
0564 m_gsto_mode = tools::sg::gsto_memory;
0565 #endif
0566 }break;
0567 case tools::sg::gsto_memory:{
0568 m_gsto_mode = tools::sg::gsto_memory;
0569 }break;
0570 }
0571 }
0572
0573 virtual void available_gsto_modes(std::vector<std::string>& a_vs) {
0574 a_vs.clear();
0575 #ifdef TOOLS_USE_GL_VERSION_3_2
0576 a_vs.push_back(tools::sg::s_gsto_gl_vbo());
0577 #endif
0578 #ifndef TOOLS_USE_GL_VERSION_3_2
0579 a_vs.push_back(tools::sg::s_gsto_gl_list());
0580 #endif
0581 a_vs.push_back(tools::sg::s_gsto_memory());
0582 }
0583
0584 virtual void available_not_memory_gsto_mode(std::string& a_v) const {
0585 a_v.clear();
0586 #ifdef TOOLS_USE_GL_VERSION_3_2
0587 a_v = tools::sg::s_gsto_gl_vbo();
0588 #else
0589 a_v = tools::sg::s_gsto_gl_list();
0590 #endif
0591 }
0592
0593 virtual size_t used_texture_memory() const {
0594 size_t sz = 0;
0595 gstos_it_t it;
0596 for(it=m_gstos.begin();it!=m_gstos.end();++it) {
0597 if((*it).second->m_kind==gsto_t::kind_texture) sz += (*it).second->m_size;
0598 }
0599 return sz;
0600 }
0601
0602 virtual size_t gstos_size() const {
0603 size_t sz = 0;
0604 gstos_it_t it;
0605 for(it=m_gstos.begin();it!=m_gstos.end();++it) sz += (*it).second->m_size;
0606 return sz;
0607 }
0608
0609 public:
0610 GL_manager_T(std::ostream& a_out)
0611 :m_out(a_out)
0612 ,m_gen_id(1)
0613 ,m_gsto_mode(tools::sg::gsto_memory)
0614 #ifdef TOOLS_USE_GL_VERSION_3_2
0615 ,m_fragment_shader(0)
0616 ,m_vertex_shader(0)
0617 ,m_shader_program(0)
0618 #endif
0619 ,m_gl_max_texture_size(0)
0620 {}
0621 virtual ~GL_manager_T(){
0622 #ifdef TOOLS_USE_GL_VERSION_3_2
0623 delete_shader_program();
0624 #endif
0625 tools::safe_clear<unsigned int,gsto_t>(m_gstos);
0626 }
0627 public:
0628 GL_manager_T(const GL_manager_T& a_from)
0629 :parent(a_from)
0630 ,parent_gl_functions(a_from)
0631 ,m_out(a_from.m_out)
0632 ,m_gen_id(a_from.m_gen_id)
0633 ,m_gsto_mode(a_from.m_gsto_mode)
0634 ,m_gl_max_texture_size(0)
0635 {}
0636 GL_manager_T& operator=(const GL_manager_T& a_from){
0637 if(&a_from==this) return *this;
0638 m_gen_id = a_from.m_gen_id;
0639 m_gsto_mode = a_from.m_gsto_mode;
0640 tools::safe_clear<unsigned int,gsto_t>(m_gstos);
0641 return *this;
0642 }
0643
0644 public:
0645 void bind_gsto(unsigned int a_id) {
0646 gstos_it_t it = m_gstos.find(a_id);
0647 if(it==m_gstos.end()) return;
0648 (*it).second->bind();
0649 }
0650 void unbind_gsto() {
0651 #ifdef TOOLS_USE_GL_VERSION_3_2
0652 parent_gl_functions::gl__BindBuffer(GL_ARRAY_BUFFER,0);
0653 parent_gl_functions::gl__BindVertexArray(0);
0654 #endif
0655 }
0656
0657 void delete_gstos() {
0658 tools::safe_clear<unsigned int,gsto_t>(m_gstos);
0659 }
0660
0661 public:
0662
0663 unsigned char* get_rgbas(unsigned int a_w,unsigned int a_h) {
0664 unsigned char* rgbas = new unsigned char[4 * a_w * a_h];
0665 if(!rgbas) return 0;
0666 parent_gl_functions::gl__PixelStorei(GL_PACK_ALIGNMENT,1); //needed with Cocoa.
0667 parent_gl_functions::gl__ReadPixels(0,0,a_w,a_h,GL_RGBA,GL_UNSIGNED_BYTE,rgbas);
0668 return rgbas;
0669 }
0670
0671 unsigned char* get_rgbs(unsigned int a_w,unsigned int a_h) {
0672 unsigned char* rgbs = new unsigned char[3 * a_w * a_h];
0673 if(!rgbs) return 0;
0674 parent_gl_functions::gl__PixelStorei(GL_PACK_ALIGNMENT,1); //needed with Cocoa.
0675 parent_gl_functions::gl__ReadPixels(0,0,a_w,a_h,GL_RGB,GL_UNSIGNED_BYTE,rgbs);
0676 return rgbs;
0677 }
0678 #ifdef TOOLS_USE_GL_VERSION_3_2
0679 bool create_shader_program() {
0680 if(m_shader_program) return true; //done
0681
0682 unsigned int gl_glsl_major_version = 0;
0683 unsigned int gl_glsl_minor_version = 0;
0684 if(!get_version_numbers(m_out,m_gl_shading_language_version,gl_glsl_major_version,gl_glsl_minor_version)) {
0685 m_out << "toolx::sg::GL_manager_T::create_shader_program :"
0686 << " can't get version numnbers for GL_SHADING_LANGUAGE_VERSION."
0687 << std::endl;
0688 return false;
0689 }
0690 unsigned int glsl_shader_processor_version = gl_glsl_major_version*100+gl_glsl_minor_version;
0691 if(glsl_shader_processor_version<150) {
0692 m_out << "toolx::sg::GL_manager_T::create_shader_program :"
0693 << " glsl_shader_processor_version is " << glsl_shader_processor_version
0694 << ", but only the ones greater or equal to 150 are supported."
0695 << std::endl;
0696 return false;
0697 }
0698
0699 {unsigned int gl_major_version = 0;
0700 unsigned int gl_minor_version = 0;
0701 if(!get_version_numbers(m_out,m_gl_version,gl_major_version,gl_minor_version)) {
0702 m_out << "toolx::sg::GL_manager_T::create_shader_program :"
0703 << " can't get version numbers for GL_VERSION."
0704 << std::endl;
0705 gl_major_version = 0;
0706 gl_minor_version = 0;
0707 }
0708 m_out << "toolx::sg::GL_manager_T::create_shader_program: infos:" << std::endl
0709 << " GL_VERSION " << gl_major_version << "." << gl_minor_version << std::endl
0710 << " GL_SHADING_LANGUAGE_VERSION " << gl_glsl_major_version << "." << gl_glsl_minor_version << std::endl
0711 << " shader processor version " << glsl_shader_processor_version
0712 << std::endl;}
0713
0714 ////////////////////////////////////////////////////
0715 ////////////////////////////////////////////////////
0716 static const GLchar* str_fs_150 = "\
0717 #version 150\n\
0718 uniform sampler2D sampler;\n\
0719 in vec4 frag_color;\n\
0720 in float frag_tex_on;\n\
0721 \n\
0722 in vec2 frag_tex_coords;\n\
0723 out vec4 _gl_FragColor;\n\
0724 void main(void) {\n\
0725 if(frag_tex_on==1.0) {\n\
0726 _gl_FragColor = frag_color*texture(sampler,vec2(frag_tex_coords.s,frag_tex_coords.t));\n\
0727 } else {\n\
0728 _gl_FragColor = frag_color;\n\
0729 }\n\
0730 }\n\
0731 ";
0732
0733 m_fragment_shader = parent_gl_functions::gl__CreateShader(GL_FRAGMENT_SHADER);
0734 if(!m_fragment_shader) {
0735 m_out << "toolx::sg::GL_manager_T::create_shader_program :"
0736 << " glCreateShader(GL_FRAGMENT_SHADER) failed."
0737 << std::endl;
0738 return false;
0739 }
0740 char* str_fs = (char*)str_fs_150;
0741 parent_gl_functions::gl__ShaderSource(m_fragment_shader,1,&str_fs,NULL);
0742 parent_gl_functions::gl__CompileShader(m_fragment_shader);
0743 {GLint status;
0744 parent_gl_functions::gl__GetShaderiv(m_fragment_shader,GL_COMPILE_STATUS,&status);
0745 if(status==GL_FALSE) {
0746 m_out << "toolx::sg::GL_manager_T::create_shader_program :"
0747 << " compilation of the fragment shader failed."
0748 << std::endl;
0749
0750 {GLsizei log_size;
0751 char shader_log[4096];
0752 parent_gl_functions::gl__GetShaderInfoLog(m_fragment_shader,1024,&log_size,shader_log);
0753 m_out << "toolx::sg::GL_manager_T::create_shader_program: fragment shader_log size " << log_size << std::endl;
0754 m_out << std::string(shader_log) << std::endl;}
0755
0756 parent_gl_functions::gl__DeleteShader(m_fragment_shader);
0757 m_fragment_shader = 0;
0758 return false;
0759 }}
0760
0761 ////////////////////////////////////////////////////
0762 ////////////////////////////////////////////////////
0763 static const GLchar* str_vs_150 = "\
0764 #version 150\n\
0765 in vec3 one_pos;\n\
0766 in vec3 one_normal;\n\
0767 in vec4 one_color;\n\
0768 in vec2 one_tex;\n\
0769 uniform mat4 model_proj_matrix;\n\
0770 uniform mat4 normal_matrix;\n\
0771 uniform vec4 color;\n\
0772 uniform bool pos_color;\n\
0773 uniform vec3 normal;\n\
0774 uniform bool pos_normal;\n\
0775 uniform bool tex_on;\n\
0776 uniform bool light_on;\n\
0777 uniform vec3 light_direction;\n\
0778 uniform vec4 light_color;\n\
0779 uniform vec4 light_ambient;\n\
0780 uniform float point_size;\n\
0781 \n\
0782 out float frag_tex_on;\n\
0783 out vec4 frag_color;\n\
0784 out vec2 frag_tex_coords;\n\
0785 \n\
0786 void main(void) {\n\
0787 frag_tex_on = 0.0;\n\
0788 if(tex_on) frag_tex_on = 1.0;\n\
0789 frag_tex_coords = one_tex;\n\
0790 if(tex_on) {\n\
0791 frag_color = color;\n\
0792 } else {\n\
0793 frag_color = color;\n\
0794 if(pos_color) frag_color = one_color;\n\
0795 }\n\
0796 /*frag_color = clamp(frag_color,0,1);*/\n\
0797 \n\
0798 if(light_on) {\n\
0799 vec3 _normal = normal;\n\
0800 if(pos_normal) _normal = one_normal;\n\
0801 vec3 frag_normal = vec3(normalize(normal_matrix*vec4(_normal,0)));\n\
0802 /* at this point, light_direction should be normalized.*/\n\
0803 vec4 ambient_color = light_ambient;\n\
0804 /*ambient_color = clamp(ambient_color,0,1);*/\n\
0805 float cooking = 1.4; /*to have same intensity as GL-1.1.*/\n\
0806 float _dot = dot(frag_normal,light_direction);\n\
0807 if(_dot<0.0) {\n\
0808 _dot *= -1.0;\n\
0809 vec4 diffuse_color = light_color*_dot*cooking;\n\
0810 /*diffuse_color = clamp(diffuse_color,0,1);*/\n\
0811 vec4 _color = (ambient_color+diffuse_color)*frag_color;\n\
0812 frag_color = vec4(_color.rgb,frag_color.a);\n\
0813 } else {\n\
0814 frag_color = ambient_color*frag_color*cooking;\n\
0815 }\n\
0816 }\n\
0817 gl_PointSize = point_size;\n\
0818 gl_Position = model_proj_matrix * vec4(one_pos,1);\n\
0819 }\n\
0820 ";
0821
0822 m_vertex_shader = parent_gl_functions::gl__CreateShader(GL_VERTEX_SHADER);
0823 if(!m_vertex_shader) {
0824 m_out << "toolx::sg::GL_manager_T::create_shader_program :"
0825 << " glCreateShader(GL_VERTEX_SHADER) failed."
0826 << std::endl;
0827 parent_gl_functions::gl__DeleteShader(m_fragment_shader);
0828 m_fragment_shader = 0;
0829 return false;
0830 }
0831 char* str_vs = (char*)str_vs_150;
0832 parent_gl_functions::gl__ShaderSource(m_vertex_shader,1,&str_vs,NULL);
0833 parent_gl_functions::gl__CompileShader(m_vertex_shader);
0834 {GLint status;
0835 parent_gl_functions::gl__GetShaderiv(m_vertex_shader,GL_COMPILE_STATUS,&status);
0836 if(status==GL_FALSE) {
0837 m_out << "toolx::sg::GL_manager_T::create_shader_program :"
0838 << " compilation of the vertex shader failed."
0839 << std::endl;
0840
0841 {GLsizei log_size;
0842 char shader_log[4096];
0843 parent_gl_functions::gl__GetShaderInfoLog(m_fragment_shader,1024,&log_size,shader_log);
0844 m_out << "toolx::sg::GL_manager_T::create_shader_program: vertex shader_log size " << log_size << std::endl;
0845 m_out << std::string(shader_log) << std::endl;}
0846
0847 parent_gl_functions::gl__DeleteShader(m_vertex_shader);
0848 parent_gl_functions::gl__DeleteShader(m_fragment_shader);
0849 m_vertex_shader = 0;
0850 m_fragment_shader = 0;
0851 return false;
0852 }}
0853
0854 m_shader_program = parent_gl_functions::gl__CreateProgram();
0855 parent_gl_functions::gl__AttachShader(m_shader_program,m_fragment_shader);
0856 parent_gl_functions::gl__AttachShader(m_shader_program,m_vertex_shader);
0857 parent_gl_functions::gl__LinkProgram(m_shader_program);
0858 {GLint status;
0859 parent_gl_functions::gl__GetProgramiv(m_shader_program,GL_LINK_STATUS,&status);
0860 if(status==GL_FALSE) {
0861 m_out << "toolx::sg::GL_manager_T::create_shader_program :"
0862 << " link program failed."
0863 << std::endl;
0864 parent_gl_functions::gl__DetachShader(m_shader_program,m_fragment_shader);
0865 parent_gl_functions::gl__DetachShader(m_shader_program,m_vertex_shader);
0866 parent_gl_functions::gl__DeleteProgram(m_shader_program);
0867 parent_gl_functions::gl__DeleteShader(m_vertex_shader);
0868 parent_gl_functions::gl__DeleteShader(m_fragment_shader);
0869 m_vertex_shader = 0;
0870 m_fragment_shader = 0;
0871 m_shader_program = 0;
0872 return false;
0873 }}
0874 return true;
0875 }
0876 void delete_shader_program() {
0877 if(!m_shader_program) return;
0878 parent_gl_functions::gl__DetachShader(m_shader_program,m_fragment_shader);
0879 parent_gl_functions::gl__DetachShader(m_shader_program,m_vertex_shader);
0880 parent_gl_functions::gl__DeleteProgram(m_shader_program);
0881 parent_gl_functions::gl__DeleteShader(m_vertex_shader);
0882 parent_gl_functions::gl__DeleteShader(m_fragment_shader);
0883 m_vertex_shader = 0;
0884 m_fragment_shader = 0;
0885 m_shader_program = 0;
0886 }
0887
0888 #define GET_UNIFORM_LOCATION(a__var,a__name)\
0889 m_##a__var = parent_gl_functions::gl__GetUniformLocation(m_shader_program,a__name);\
0890 if(m_##a__var==(-1)) {\
0891 m_out << "toolx::sg::GL_manager_T::use_shader_program : glGetUniformLocation(" << a__name << ") failed." << std::endl;\
0892 }
0893
0894 #define GET_ATTRIB_LOCATION(a__var,a__name)\
0895 m_##a__var = parent_gl_functions::gl__GetAttribLocation(m_shader_program,a__name);\
0896 if(m_##a__var==(-1)) {\
0897 m_out << "toolx::sg::GL_manager_T::use_shader_program : glGetAttribLocation(" << a__name << ") failed." << std::endl;\
0898 }
0899
0900 GLint g_sampler_location() {return m_g_sampler;}
0901 GLint g_tex_on_location() {return m_g_tex_on;}
0902 GLint g_point_size_location() {return m_g_point_size;}
0903
0904 GLint g_one_pos_location() {return m_g_one_pos;}
0905 GLint g_one_normal_location() {return m_g_one_normal;}
0906 GLint g_one_color_location() {return m_g_one_color;}
0907 GLint g_one_tex_location() {return m_g_one_tex;}
0908
0909 GLint g_model_proj_matrix_location() {return m_g_model_proj_matrix;}
0910 GLint g_normal_matrix_location() {return m_g_normal_matrix;}
0911 GLint g_color_location() {return m_g_color;}
0912 GLint g_pos_color_location() {return m_g_pos_color;}
0913 GLint g_normal_location() {return m_g_normal;}
0914 GLint g_pos_normal_location() {return m_g_pos_normal;}
0915
0916 GLint g_light_on_location() {return m_g_light_on;}
0917 GLint g_light_direction_location() {return m_g_light_direction;}
0918 GLint g_light_color_location() {return m_g_light_color;}
0919 GLint g_light_ambient_location() {return m_g_light_ambient;}
0920
0921 void use_shader_program() {
0922 if(!m_shader_program) return;
0923
0924 parent_gl_functions::gl__UseProgram(m_shader_program);
0925
0926 // used by renderer :
0927 GET_UNIFORM_LOCATION(g_sampler,"sampler")
0928 GET_UNIFORM_LOCATION(g_tex_on,"tex_on")
0929 GET_UNIFORM_LOCATION(g_point_size,"point_size")
0930
0931 GET_ATTRIB_LOCATION(g_one_pos,"one_pos")
0932 GET_ATTRIB_LOCATION(g_one_normal,"one_normal")
0933 GET_ATTRIB_LOCATION(g_one_color,"one_color")
0934 GET_ATTRIB_LOCATION(g_one_tex,"one_tex")
0935
0936 GET_UNIFORM_LOCATION(g_model_proj_matrix,"model_proj_matrix")
0937 GET_UNIFORM_LOCATION(g_normal_matrix,"normal_matrix")
0938 GET_UNIFORM_LOCATION(g_color,"color")
0939 GET_UNIFORM_LOCATION(g_pos_color,"pos_color")
0940 GET_UNIFORM_LOCATION(g_normal,"normal")
0941 GET_UNIFORM_LOCATION(g_pos_normal,"pos_normal")
0942
0943 GET_UNIFORM_LOCATION(g_light_on,"light_on")
0944 GET_UNIFORM_LOCATION(g_light_direction,"light_direction")
0945 GET_UNIFORM_LOCATION(g_light_color,"light_color")
0946 GET_UNIFORM_LOCATION(g_light_ambient,"light_ambient")
0947
0948 parent_gl_functions::gl__Uniform1i(m_g_tex_on,0);
0949 parent_gl_functions::gl__Uniform1f(m_g_point_size,1);
0950
0951 parent_gl_functions::gl__Uniform4f(m_g_color,1,1,1,1);
0952 parent_gl_functions::gl__Uniform1i(m_g_pos_color,false);
0953
0954 parent_gl_functions::gl__Uniform3f(m_g_normal,0,0,1);
0955 parent_gl_functions::gl__Uniform1i(m_g_pos_normal,false);
0956
0957 parent_gl_functions::gl__Uniform1i(m_g_light_on,0);
0958 parent_gl_functions::gl__Uniform4f(m_g_light_color,1,1,1,0);
0959 parent_gl_functions::gl__Uniform3f(m_g_light_direction,0,0,-1);
0960
0961 }
0962 void reset_shader_locations() {
0963 m_g_sampler = -1;
0964 m_g_tex_on = -1;
0965 m_g_point_size = -1;
0966
0967 m_g_one_pos = -1;
0968 m_g_one_normal = -1;
0969 m_g_one_color = -1;
0970 m_g_one_tex = -1;
0971
0972 m_g_model_proj_matrix = -1;
0973 m_g_normal_matrix = -1;
0974 m_g_color = -1;
0975 m_g_pos_color = -1;
0976 m_g_normal = -1;
0977 m_g_pos_normal = -1;
0978
0979 m_g_light_on = -1;
0980 m_g_light_direction = -1;
0981 m_g_light_color = -1;
0982 m_g_light_ambient = -1;
0983 }
0984 #undef GET_ATTRIB_LOCATION
0985 #undef GET_UNIFORM_LOCATION
0986
0987 #endif //TOOLS_USE_GL_VERSION_3_2
0988
0989 protected:
0990 /*static*/ void clear_gl_errors() {
0991 GLenum glerror = parent_gl_functions::gl__GetError();
0992 while(glerror!=GL_NO_ERROR) {
0993 glerror = parent_gl_functions::gl__GetError();
0994 }
0995 }
0996
0997 /*static*/ bool dump_if_gl_errors(std::ostream& a_out,const std::string& a_head) {
0998 bool retval = false;
0999 GLenum glerror = parent_gl_functions::gl__GetError();
1000 if(glerror!=GL_NO_ERROR) {
1001 a_out << a_head
1002 << " we have gl errors :"
1003 << std::endl;
1004 retval = true;
1005 }
1006 while(glerror!=GL_NO_ERROR) {
1007 //#define GL_NO_ERROR 0
1008 //#define GL_INVALID_ENUM 0x0500
1009 //#define GL_INVALID_VALUE 0x0501
1010 //#define GL_INVALID_OPERATION 0x0502
1011 //#define GL_STACK_OVERFLOW 0x0503
1012 //#define GL_STACK_UNDERFLOW 0x0504
1013 //#define GL_OUT_OF_MEMORY 0x0505
1014
1015 //#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
1016
1017 std::ostringstream oss;
1018 oss << "0x" << std::hex << glerror;
1019 a_out << oss.str() << std::endl;
1020
1021 glerror = parent_gl_functions::gl__GetError();
1022 }
1023 return retval;
1024 }
1025
1026 static bool s2vers(const std::string& a_string,std::vector<unsigned int>& a_versions) {
1027 // a_string is of the form "<number>[.<number>.<number>] <comment>, extract <numbers>.
1028 // Examples : "1.0.2" "2.1 ATI-4.8.101"
1029 a_versions.clear();
1030 if(a_string.empty()) return false;
1031 char* pos = (char*)a_string.c_str();
1032 while((*pos!='\0')&&(*pos!=' ')) {
1033 char* s;
1034 long v = ::strtol(pos,&s,10);
1035 if(s==pos) {
1036 a_versions.clear();
1037 return false;
1038 }
1039 if(v<0) {
1040 a_versions.clear();
1041 return false;
1042 }
1043 a_versions.push_back((unsigned int)v);
1044 pos = s; //Could be at end.
1045 if(*pos=='\0') break;
1046 if(*pos==' ') break;
1047 if(*pos!='.') {
1048 a_versions.clear();
1049 return false;
1050 }
1051 // Next char is '.', skip it:
1052 pos++;
1053 }
1054 return true;
1055 }
1056
1057 /*static*/ bool get_version_numbers(std::ostream& a_out,const std::string& a_version,unsigned int& a_major,unsigned int& a_minor) {
1058 a_major = 0;
1059 a_minor = 0;
1060 std::vector<unsigned int> verss;
1061 if(!s2vers(a_version,verss)) {
1062 a_out << "toolx::sg::GL_manager_T::get_version_numbers :"
1063 << " toolx::sg::GL_manager_T::s2vers() failed on \"" << a_version << "\"."
1064 << std::endl;
1065 return false;
1066 }
1067 if(verss.size()==1) {
1068 a_major = verss[0];
1069 a_minor = 0;
1070 } else if(verss.size()>=2) {
1071 a_major = verss[0];
1072 a_minor = verss[1];
1073 } else {
1074 a_out << "toolx::sg::GL_manager_T::get_version_numbers :"
1075 << " can't extract major/minor version number from \"" << a_version << "\"."
1076 << std::endl;
1077 return false;
1078 }
1079 return true;
1080 }
1081
1082 protected:
1083 std::ostream& m_out;
1084
1085 std::map<unsigned int,gsto_t*> m_gstos;
1086
1087 unsigned int m_gen_id;
1088 tools::sg::gsto_mode m_gsto_mode;
1089
1090 #ifdef TOOLS_USE_GL_VERSION_3_2
1091 GLuint m_fragment_shader;
1092 GLuint m_vertex_shader;
1093 GLuint m_shader_program;
1094 //locations:
1095 GLint m_g_sampler;
1096 GLint m_g_tex_on;
1097 GLint m_g_point_size;
1098
1099 GLint m_g_one_pos;
1100 GLint m_g_one_normal;
1101 GLint m_g_one_color;
1102 GLint m_g_one_tex;
1103
1104 GLint m_g_model_proj_matrix;
1105 GLint m_g_normal_matrix;
1106 GLint m_g_color;
1107 GLint m_g_pos_color;
1108 GLint m_g_normal;
1109 GLint m_g_pos_normal;
1110
1111 GLint m_g_light_on;
1112 GLint m_g_light_direction;
1113 GLint m_g_light_color;
1114 GLint m_g_light_ambient;
1115 #endif //TOOLS_USE_GL_VERSION_3_2
1116
1117 std::string m_gl_version;
1118 #ifdef TOOLS_USE_GL_VERSION_3_2
1119 std::string m_gl_shading_language_version;
1120 #endif
1121 std::string m_gl_vendor;
1122 std::string m_gl_renderer;
1123 std::string m_gl_extensions;
1124 GLint m_gl_max_texture_size;
1125 };
1126
1127 }}
1128
1129 #endif