From 0b750bf4e444a8810c46399217a370d9705eb038 Mon Sep 17 00:00:00 2001
From: Thibault Soucarre <thibault.soucarre@inria.fr>
Date: Thu, 7 Aug 2014 12:11:10 +0000
Subject: [PATCH] detection of the available glsl version and creation of
 adapted shaders

---
 src/render/Render_alternate.cpp | 42 ++++++++++++++++++-----------
 src/render/Render_alternate.hpp |  3 ++-
 src/render/Shader.cpp           | 48 +++++++++++++++++++++++----------
 src/render/Shader.hpp           |  3 ++-
 4 files changed, 64 insertions(+), 32 deletions(-)

diff --git a/src/render/Render_alternate.cpp b/src/render/Render_alternate.cpp
index 2b29cddf..20830402 100644
--- a/src/render/Render_alternate.cpp
+++ b/src/render/Render_alternate.cpp
@@ -99,13 +99,11 @@ static bool _draw_counter;
 
 Render_alternate::Render_alternate(Core* core, QWidget *parent, const QGLFormat& format)
     : Hook_event(this, core, parent, format), _containers(GL_QUADS), /*_states(GL_QUADS),*/ _events(GL_POINTS), _events2(GL_LINES), _arrows(GL_LINE), _arrows2(GL_TRIANGLES), _counters(GL_LINE), _ruler(GL_QUADS), /*_shader("vertexshader.vertexshader", "fragmentshader.fragmentshader"),*/ _modelview(glm::mat4(1.0)), _projection(glm::mat4(1.0)), _container_height(_DRAWING_CONTAINER_HEIGHT_DEFAULT){
-
-    setAutoFillBackground(false);
-
 }
 
 
 Render_alternate::~Render_alternate(){
+    delete _shader;
 }
 
 /***********************************
@@ -124,11 +122,23 @@ void  Render_alternate::initializeGL() {
     if(err!=GLEW_OK){
         std::cout << "ERROR : GlewInit failed" << std::endl;
     }
-    _shader.charger();
+    //_shader.charger();
     glClearColor(0.5f, 0.5f, 0.55f, 0.0f);
     glEnable(GL_DEPTH_TEST);
     glClearStencil(0);
     std::cout << "init" << std::endl;
+    const GLubyte * version = glGetString(GL_SHADING_LANGUAGE_VERSION);
+    if (version==NULL)
+        std::cout << "ERROR : could not detect your GLSL version" << std::endl;
+    else
+        std::cout << "Version GLSL : " << version << std::endl;
+    _glsl = (version[0]-'0')*100 + (version[2]-'0')*10 + version[3]-'0';
+    std::cout << _glsl << std::endl;
+    _shader = new Shader(_glsl);
+    _shader->charger();
+    //std::cout << version[2] << std::endl;
+    //std::cout << version[3] << std::endl;
+    setAutoFillBackground(false);
     if(_core == NULL)
         std::cout << "_core = NULL" << std::endl;
     _core->waitGUIInit->quit();
@@ -162,7 +172,7 @@ void  Render_alternate::paintGL(){
     resizeGL(Render_alternate::QGLWidget::width(), Render_alternate::QGLWidget::height());
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     //select shader program
-    glUseProgram(_shader.getProgramID());
+    glUseProgram(_shader->getProgramID());
     std::cout << "paintGL" << std::endl;
     glm::mat4 tmp = _modelview;
     glm::mat4 tmp2 = _modelview;
@@ -176,12 +186,12 @@ void  Render_alternate::paintGL(){
     mvp = _projection * _modelview;
     //glUniformMatrix4fv(glGetUniformLocation(_shader.getProgramID(), "modelview"), 1, GL_FALSE, glm::value_ptr(_modelview));
     //glUniformMatrix4fv(glGetUniformLocation(_shader.getProgramID(), "projection"), 1, GL_FALSE, glm::value_ptr(_projection));
-    glUniformMatrix4fv(glGetUniformLocation(_shader.getProgramID(), "MVP"), 1, GL_FALSE, glm::value_ptr(mvp));
+    glUniformMatrix4fv(glGetUniformLocation(_shader->getProgramID(), "MVP"), 1, GL_FALSE, glm::value_ptr(mvp));
     glDrawArrays(GL_QUADS, 0, 8);
     _modelview = tmp;
     _modelview = glm::translate(_modelview, glm::vec3(0.0, 0.0, _z_ruler_over));
     mvp = _projection * _modelview;
-    glUniformMatrix4fv(glGetUniformLocation(_shader.getProgramID(), "MVP"), 1, GL_FALSE, glm::value_ptr(mvp));
+    glUniformMatrix4fv(glGetUniformLocation(_shader->getProgramID(), "MVP"), 1, GL_FALSE, glm::value_ptr(mvp));
     //glUniformMatrix4fv(glGetUniformLocation(_shader.getProgramID(), "modelview"), 1, GL_FALSE, glm::value_ptr(_modelview));
     glDrawArrays(GL_LINES, 8, _ruler.getNbVertex());
     _ruler.unlock();
@@ -192,7 +202,7 @@ void  Render_alternate::paintGL(){
     _modelview = glm::translate(_modelview, glm::vec3(0.0, _ruler_y + _ruler_height - _y_state_translate, _z_container));
     _modelview = glm::scale(_modelview, glm::vec3(_x_scale_container_state/0.20, _y_state_scale, 1.0));
     mvp = _projection * _modelview;
-    glUniformMatrix4fv(glGetUniformLocation(_shader.getProgramID(), "MVP"), 1, GL_FALSE, glm::value_ptr(mvp));
+    glUniformMatrix4fv(glGetUniformLocation(_shader->getProgramID(), "MVP"), 1, GL_FALSE, glm::value_ptr(mvp));
     //glUniformMatrix4fv(glGetUniformLocation(_shader.getProgramID(), "modelview"), 1, GL_FALSE, glm::value_ptr(_modelview));
     //glUniformMatrix4fv(glGetUniformLocation(_shader.getProgramID(), "projection"), 1, GL_FALSE, glm::value_ptr(_projection));
     glDrawArrays(GL_QUADS, 0, _containers.getNbVertex());
@@ -221,8 +231,8 @@ void  Render_alternate::paintGL(){
         it_state++;
         //_modelview = tmp;
     }
-    glUseProgram(_shader.getProgramID());
-    glUniformMatrix4fv(glGetUniformLocation(_shader.getProgramID(), "MVP"), 1, GL_FALSE, glm::value_ptr(mvp));
+    glUseProgram(_shader->getProgramID());
+    glUniformMatrix4fv(glGetUniformLocation(_shader->getProgramID(), "MVP"), 1, GL_FALSE, glm::value_ptr(mvp));
     /*drawing counters*/
     _counters.lock();
     glDrawArrays(GL_LINES, 0, _counters.getNbVertex());
@@ -247,7 +257,7 @@ void  Render_alternate::paintGL(){
          _modelview = glm::scale(_modelview, glm::vec3(_links[4*i+1], _links[4*i+1/10], 1));*/
             //draw the arrow
         mvp = _projection * _modelview;
-        glUniformMatrix4fv(glGetUniformLocation(_shader.getProgramID(), "MVP"), 1, GL_FALSE, glm::value_ptr(mvp));
+        glUniformMatrix4fv(glGetUniformLocation(_shader->getProgramID(), "MVP"), 1, GL_FALSE, glm::value_ptr(mvp));
             //glUniformMatrix4fv(glGetUniformLocation(_shader.getProgramID(), "modelview"), 1, GL_FALSE, glm::value_ptr(_modelview));
             //glUniformMatrix4fv(glGetUniformLocation(_shader.getProgramID(), "projection"), 1, GL_FALSE, glm::value_ptr(_projection));
         glDrawArrays(GL_LINES, 0, _arrows.getNbVertex());
@@ -264,7 +274,7 @@ void  Render_alternate::paintGL(){
                 _modelview = glm::translate(_modelview, glm::vec3(_x_state_scale*_links[4*i+2], _y_state_scale*_links[4*i+3], 0));
                 _modelview = glm::rotate(_modelview, (float) _links[4*i], glm::vec3(0,0,1));
                 mvp = _projection * _modelview;
-                glUniformMatrix4fv(glGetUniformLocation(_shader.getProgramID(), "MVP"), 1, GL_FALSE, glm::value_ptr(mvp));
+                glUniformMatrix4fv(glGetUniformLocation(_shader->getProgramID(), "MVP"), 1, GL_FALSE, glm::value_ptr(mvp));
                 glDrawArrays(GL_TRIANGLES, 0, _arrows3.getNbVertex());
                 _modelview = tmp2;
         }
@@ -311,7 +321,7 @@ void  Render_alternate::paintGL(){
         _modelview = glm::scale(_modelview, glm::vec3(_x_state_scale, _y_state_scale, 1.0));
         _events.lock();
         mvp = _projection * _modelview;
-        glUniformMatrix4fv(glGetUniformLocation(_shader.getProgramID(), "MVP"), 1, GL_FALSE, glm::value_ptr(mvp));
+        glUniformMatrix4fv(glGetUniformLocation(_shader->getProgramID(), "MVP"), 1, GL_FALSE, glm::value_ptr(mvp));
         //glUniformMatrix4fv(glGetUniformLocation(_shader.getProgramID(), "modelview"), 1, GL_FALSE, glm::value_ptr(_modelview));
         //glUniformMatrix4fv(glGetUniformLocation(_shader.getProgramID(), "projection"), 1, GL_FALSE, glm::value_ptr(_projection));
         glEnable(GL_PROGRAM_POINT_SIZE);
@@ -341,7 +351,7 @@ void  Render_alternate::paintGL(){
         float selection[12] = {x0, y0, x0, y1, x1, y1, x1, y0};
         float selection_colors[16] = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0};
         mvp = _projection * _modelview;
-        glUniformMatrix4fv(glGetUniformLocation(_shader.getProgramID(), "MVP"), 1, GL_FALSE, glm::value_ptr(mvp));
+        glUniformMatrix4fv(glGetUniformLocation(_shader->getProgramID(), "MVP"), 1, GL_FALSE, glm::value_ptr(mvp));
         //glUniformMatrix4fv(glGetUniformLocation(_shader.getProgramID(), "modelview"), 1, GL_FALSE, glm::value_ptr(_modelview));
         //glUniformMatrix4fv(glGetUniformLocation(_shader.getProgramID(), "projection"), 1, GL_FALSE, glm::value_ptr(_projection));
         glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, selection);
@@ -789,7 +799,7 @@ void Render_alternate::start_draw_states(){
 
 void Render_alternate::draw_state(const Element_pos x, const Element_pos y, const Element_pos z, const Element_pos w, const Element_pos h, const EntityValue* value){
     if(_states.count(value)==0){
-        Shader *s = new Shader(_r, _g, _b);
+        Shader *s = new Shader(_glsl, _r, _g, _b);
         //Shader *s = new Shader();
         s->charger();
         std::pair<const EntityValue*, Shader*> p(value, s);
@@ -1011,7 +1021,7 @@ void Render_alternate::draw_vertical_line(){
     //glUniformMatrix4fv(glGetUniformLocation(_shader.getProgramID(), "modelview"), 1, GL_FALSE, glm::value_ptr(_modelview));
     //glUniformMatrix4fv(glGetUniformLocation(_shader.getProgramID(), "projection"), 1, GL_FALSE, glm::value_ptr(_projection));
     mvp = _projection * _modelview;
-    glUniformMatrix4fv(glGetUniformLocation(_shader.getProgramID(), "MVP"), 1, GL_FALSE, glm::value_ptr(mvp));
+    glUniformMatrix4fv(glGetUniformLocation(_shader->getProgramID(), "MVP"), 1, GL_FALSE, glm::value_ptr(mvp));
     glVertexAttribPointer(0, 2, GL_DOUBLE, GL_FALSE, 0, vertex);
     glEnableVertexAttribArray(0);
     glVertexAttribPointer(1, 3, GL_DOUBLE, GL_FALSE, 0, colors);
diff --git a/src/render/Render_alternate.hpp b/src/render/Render_alternate.hpp
index 64ad6d4a..b0208404 100644
--- a/src/render/Render_alternate.hpp
+++ b/src/render/Render_alternate.hpp
@@ -99,7 +99,8 @@ class Render_alternate :  /*public QGLWidget,*/ public Hook_event, public Render
 {
     Q_OBJECT
 private:
-    Shader _shader;
+    int _glsl; //version of OpenGL Shading Language
+    Shader* _shader;
     Element_pos _container_height;
     Element_col _r;
     Element_col _g;
diff --git a/src/render/Shader.cpp b/src/render/Shader.cpp
index e4481b6f..a1506325 100644
--- a/src/render/Shader.cpp
+++ b/src/render/Shader.cpp
@@ -28,16 +28,35 @@ Shader::Shader() : m_vertexID(0), m_fragmentID(0), m_programID(0),
                    m_vertex_code("#version 330 core \n in vec2 in_Vertex; \n in vec3 in_Color; \n uniform mat4 MVP; \n out vec3 color; \n void main(){ \n gl_Position = MVP * vec4(in_Vertex, 0.0, 1.0); \n color = in_Color; \n }"), m_fragment_code("#version 330 core \n in vec3 color; \n out vec4 out_Color; \n void main(){ \n out_Color = vec4(color, 0.5); \n }")
 {
 }
-
-Shader::Shader(Element_col r, Element_col g, Element_col b):m_vertexID(0), m_fragmentID(0), m_programID(0), m_vertex_code("#version 330 core \n in vec2 in_Vertex; \n in int c; \n uniform mat4 MVP; \n out float shade; \n void main(){ \n gl_Position = MVP * vec4(in_Vertex, 0.0, 1.0); \n shade=intBitsToFloat(c); \n }"){
-    std::ostringstream os;
+Shader::Shader(int glsl){
+    std::ostringstream os1, os2;
+    os1 << "#version ";
+    os1 << glsl;
+    os1 << " core \n in vec2 in_Vertex; \n in vec3 in_Color; \n uniform mat4 MVP; \n out vec3 color; \n void main(){ \n gl_Position = MVP * vec4(in_Vertex, 0.0, 1.0); \n color = in_Color; \n }";
+    os2 << "#version ";
+    os2 << glsl;
+    os2 << " core \n in vec3 color; \n out vec4 out_Color; \n void main(){ \n out_Color = vec4(color, 0.5); \n }";
+    std::cout << os1 << std::endl;
+    std::cout << os2 << std::endl;
+    m_vertex_code   = os1.str();
+    m_fragment_code = os2.str();
+    std::cout << m_vertex_code << std::endl;
+    std::cout << m_fragment_code << std::endl;
+}
+Shader::Shader(int glsl, Element_col r, Element_col g, Element_col b):m_vertexID(0), m_fragmentID(0), m_programID(0){
+    std::ostringstream os1, os2;
     //std::cout << "rgb" << r << " " << g << " " << b << std::endl;
-    os << "#version 330 core \n  in float shade; \n out vec4 outColor; \n void main(){ \n outColor = vec4(";
-    os << r/2;
-    os << "*shade, ";
-    os << g/2;
-    os << "*shade, ";
-    os << b/2;
+    os1 << "#version ";
+    os1 << glsl;
+    os1 << " core \n in vec2 in_Vertex; \n in int c; \n uniform mat4 MVP; \n out float shade; \n void main(){ \n gl_Position = MVP * vec4(in_Vertex, 0.0, 1.0); \n shade=intBitsToFloat(c); \n }";
+    os2 << "#version ";
+    os2 << glsl;
+    os2 << " core \n  in float shade; \n out vec4 outColor; \n void main(){ \n outColor = vec4(";
+    os2 << r/2;
+    os2 << "*shade, ";
+    os2 << g/2;
+    os2 << "*shade, ";
+    os2 << b/2;
     /*os << ", 0.5); \n";
     os << "else \n outColor = vec4(";
     os << r/2;
@@ -45,11 +64,12 @@ Shader::Shader(Element_col r, Element_col g, Element_col b):m_vertexID(0), m_fra
     os << g/2;
     os << ", ";
     os << b/2;*/
-    os << "*shade, 0.5); \n }";
-    m_fragment_code=os.str();
-    std::cout << "code shaders" << std::endl;
-    std::cout << m_vertex_code << std::endl;
-    std::cout << m_fragment_code << std::endl;
+    os2 << "*shade, 0.5); \n }";
+    m_vertex_code   = os1.str();
+    m_fragment_code = os2.str();
+    //std::cout << "code shaders" << std::endl;
+    //std::cout << m_vertex_code << std::endl;
+    //std::cout << m_fragment_code << std::endl;
 
 }
 
diff --git a/src/render/Shader.hpp b/src/render/Shader.hpp
index d7d87b42..dc244eef 100644
--- a/src/render/Shader.hpp
+++ b/src/render/Shader.hpp
@@ -16,7 +16,8 @@ class Shader
     public:
 
     Shader();
-    Shader(Element_col, Element_col, Element_col);
+    Shader(int glsl);
+    Shader(int glsl, Element_col, Element_col, Element_col);
     //Shader(Shader const &shaderACopier);
     //Shader();
     ~Shader();
-- 
GitLab