Render_opengl.cpp 39 KB
Newer Older
Mathieu Faverge's avatar
Mathieu Faverge committed
1
/*
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
 ** This file is part of the ViTE project.
 **
 ** This software is governed by the CeCILL-A license under French law
 ** and abiding by the rules of distribution of free software. You can
 ** use, modify and/or redistribute the software under the terms of the
 ** CeCILL-A license as circulated by CEA, CNRS and INRIA at the following
 ** URL: "http://www.cecill.info".
 **
 ** As a counterpart to the access to the source code and rights to copy,
 ** modify and redistribute granted by the license, users are provided
 ** only with a limited warranty and the software's author, the holder of
 ** the economic rights, and the successive licensors have only limited
 ** liability.
 **
 ** In this respect, the user's attention is drawn to the risks associated
 ** with loading, using, modifying and/or developing or reproducing the
 ** software by the user in light of its specific status of free software,
 ** that may mean that it is complicated to manipulate, and that also
 ** therefore means that it is reserved for developers and experienced
 ** professionals having in-depth computer knowledge. Users are therefore
 ** encouraged to load and test the software's suitability as regards
 ** their requirements in conditions enabling the security of their
 ** systems and/or data to be ensured and, more generally, to use and
 ** operate it in the same conditions as regards security.
 **
 ** The fact that you are presently reading this means that you have had
 ** knowledge of the CeCILL-A license and that you accept its terms.
 **
 **
 ** ViTE developers are (for version 0.* to 1.0):
 **
 **        - COULOMB Kevin
 **        - FAVERGE Mathieu
 **        - JAZEIX Johnny
 **        - LAGRASSE Olivier
 **        - MARCOUEILLE Jule
 **        - NOISETTE Pascal
 **        - REDONDY Arthur
 **        - VUCHENER Clément
 **
 */
43 44 45
/*!
 *\file Render_opengl.cpp
 */
46

47 48 49 50
#ifdef _WIN32
	#include <Windows.h>
#endif

51 52 53
#include <sstream>
#include <cmath>
/* -- */
54 55
#include <GL/glu.h>
/* -- */
56 57 58
#include <QFile> // For loading the wait image
#include <QDate>
#include <QTimer>
59
#include <QEventLoop>
60 61 62 63
/* -- */
#include "interface/resource.hpp"
#include "interface/Interface.hpp"
/* -- */
64
#include "common/common.hpp"
65
#include "common/Info.hpp"
66
#include "common/Message.hpp"
67
/* -- */
68
#include "render/Ruler.hpp"
69
#include "render/Render_opengl.hpp"
70
#include "render/GanttDiagram.hpp"
71
/* -- */
Thomaas Herault's avatar
Thomaas Herault committed
72
#include "core/Core.hpp"
73 74 75 76 77

using namespace std;


#define message *Message::get_instance() << "(" << __FILE__ << " l." << __LINE__ << "): "
78 79 80
#define NB_STEPS 20


81 82 83
const double angle       = M_PI/2.0;
const double delta_angle = 2.0*M_PI/NB_STEPS;
const double radius = .5;
84 85 86


template <int N> void Render_opengl::cos_table_builder(double table[]){
87 88
    cos_table_builder<N-1>(table);
    table[N-1]=cos(angle+delta_angle*(N-1))*radius;
89 90 91
}

template <> void Render_opengl::cos_table_builder<0>(double table[]){
92
    table[0]=cos(angle*radius);
93 94 95
}

template <int N> void Render_opengl::sin_table_builder(double table[]){
96 97
    sin_table_builder<N-1>(table);
    table[N-1]=sin(angle+delta_angle*(N-1))*(radius);
98 99 100
}

template <> void Render_opengl::sin_table_builder<0>(double table[]){
101
    table[0]=sin(angle)*(radius);
102 103 104 105 106 107
}

static double cos_table[NB_STEPS];
static double sin_table[NB_STEPS];


108

109
const int Render_opengl::DRAWING_TIMER_DEFAULT = 10;
110 111 112 113 114 115 116 117 118 119 120

/***********************************
 *
 *
 *
 * Constructor and destructor.
 *
 *
 *
 **********************************/

Olivier Lagrasse's avatar
Olivier Lagrasse committed
121
Render_opengl::Render_opengl(Core* core, QWidget *parent, const QGLFormat& format)
122 123
    : Hook_event(this, core, parent, format)
{
124 125 126
    _arrows.clear();
    _circles.clear();
    _texts.clear();
127
    _variable_texts.clear();
128
    /* init the wait animation */
129 130
    _wait_list      = 0;
    _wait_angle     = 0.0f; /* begin with 0 rad angle */
131
    _wait_timer     = nullptr;
132 133
    _wait_spf       = DRAWING_TIMER_DEFAULT;/* DRAWING_TIMER_DEFAULT milliseconds per frame */
    /* _minimap_widget = NULL;
134
     _minimap_image  = NULL;*/
135 136 137 138 139 140

#ifdef SPINNING_LOGO
    _wait_timer = new QTimer(this);
    connect(_wait_timer, SIGNAL(timeout()), _render_instance, SLOT(updateGL()));
    _wait_timer->start(_wait_spf);
#endif // SPINNING_LOGO
141
    vertical_line=0;
142
    vertical_line=0;
143
    setAutoFillBackground(false);
Mathieu Faverge's avatar
Mathieu Faverge committed
144 145


146 147
    cos_table_builder<NB_STEPS>(cos_table);
    sin_table_builder<NB_STEPS>(sin_table);
148

149 150
}

151 152 153
void Render_opengl::release()
{
    /* Release the Rabbit and ruler lists */
154 155 156 157
    if (glIsList(_wait_list) == GL_TRUE)
        glDeleteLists(_wait_list, 1);

    /* Release timer (for Rabbit rotate) */
158
    if (_wait_timer != nullptr){
159
        delete _wait_timer;
160
        _wait_timer=nullptr;
161
    }
Mathieu Faverge's avatar
Mathieu Faverge committed
162

163
    //release_minimap();
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
}

/***********************************
 *
 * Default QGLWidget functions.
 *
 **********************************/

void  Render_opengl::initializeGL() {
    glClearColor(0.5f, 0.5f, 0.55f, 1.0f);

    glEnable(GL_DEPTH_TEST);

    glClearStencil(0);

    _wait_list = draw_wait();
Thomaas Herault's avatar
Thomaas Herault committed
180
    _core->waitGUIInit->quit();
181 182 183 184
}

void  Render_opengl::resizeGL(int width, int height) {
    glViewport(0, 0, width, height);
Mathieu Faverge's avatar
Mathieu Faverge committed
185

186
    /* update informations about widget size */
Olivier Lagrasse's avatar
Olivier Lagrasse committed
187 188
    Info::Screen::width  = width;
    Info::Screen::height = height;
Mathieu Faverge's avatar
Mathieu Faverge committed
189

190 191 192 193 194
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    if(DRAWING_STATE_WAITING == _state){// A wait is drawn
        glOrtho(-50, 50, -50, 50, 0, 1000);
Mathieu Faverge's avatar
Mathieu Faverge committed
195
    }else if (DRAWING_STATE_DRAWING == _state){// A trace is drawn
Olivier Lagrasse's avatar
Olivier Lagrasse committed
196
        glOrtho(0, Info::Render::width, 0, Info::Render::height, 0, -1000);
197
    }else{
198
        message << tr("Undefined value for the drawing state attribute - Render area").toStdString() << Message::ende;
199
    }
Mathieu Faverge's avatar
Mathieu Faverge committed
200

201 202 203
    glMatrixMode(GL_MODELVIEW);
}

204

205
void  Render_opengl::paintGL(){
206 207
    resizeGL(Render_opengl::QGLWidget::width(), Render_opengl::QGLWidget::height());
    Render_opengl::QGLWidget::setFocus(Qt::ActiveWindowFocusReason);/* give the focus to the render area for mouse and keyboard events */
208
    makeCurrent();
209
    //static int arrows_drawn=0;
210 211 212 213 214 215
    glClearDepth(1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();

    if(DRAWING_STATE_WAITING == _state){/* A wait is drawn */
Mathieu Faverge's avatar
Mathieu Faverge committed
216

217 218 219
        /* turn around y axis */
        _wait_angle+=0.1f;
        if (_wait_angle>=360) _wait_angle=0.0f;
Mathieu Faverge's avatar
Mathieu Faverge committed
220

221
        glPushMatrix();
Mathieu Faverge's avatar
Mathieu Faverge committed
222

223
        glScalef(15, 15, 0);
Mathieu Faverge's avatar
Mathieu Faverge committed
224

225
#ifdef SPINNING_LOGO
226
        glRotatef(-_wait_angle,0, 1, 0);
227
#endif // SPINNING_LOGO
Mathieu Faverge's avatar
Mathieu Faverge committed
228

229 230 231
        glCallList(_wait_list);

        glPopMatrix();
Mathieu Faverge's avatar
Mathieu Faverge committed
232 233


234 235 236 237
    }else if (DRAWING_STATE_DRAWING == _state){/* A trace is drawn */
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glPushMatrix();
Mathieu Faverge's avatar
Mathieu Faverge committed
238
        {
Olivier Lagrasse's avatar
Olivier Lagrasse committed
239
            glTranslated(0.0, Info::Render::height, 100.0);
Mathieu Faverge's avatar
Mathieu Faverge committed
240 241
            glRotated(180.0, 1.0, 0.0, 0.0);

242
            glPushMatrix();
243

Mathieu Faverge's avatar
Mathieu Faverge committed
244
            {
245
                glTranslatef(0.0f, _ruler_y + _ruler_height -_y_state_translate,  _z_container);
246 247 248 249 250 251
                glScalef(_x_scale_container_state/0.20, _y_state_scale, 1.0);

                if (glIsList(_list_containers) == GL_FALSE)
                    *Message::get_instance() << tr("ERROR LIST not exist for containers.").toStdString() << Message::ende;
                else
                    glCallList(_list_containers);
252

253 254 255 256 257
            }
            glPopMatrix();

            glPushMatrix();
            {
258 259
                glTranslated(_default_entity_x_translate - _x_state_translate, _ruler_y + _ruler_height - _y_state_translate,  _z_state);
                glScalef(_x_state_scale, _y_state_scale, 1);
260

261
                if (glIsList(_list_states) == GL_FALSE)
262
                    *Message::get_instance() << tr("ERROR LIST not exist for states.").toStdString() << Message::ende;
263
                else{
264
                    glCallList(_list_states);
265
                    glCallList(_list_counters);
266
                    // if( (false == Info::Render::_no_arrows) && arrows_drawn!=0 ) glCallList(_list_arrows);
267
                }
268 269 270
            }
            glPopMatrix();

271 272 273 274 275 276 277 278 279 280 281 282 283
            _minimap.update( ( ( (_x_state_translate - _default_entity_x_translate)/ (Info::Render::width*_x_state_scale) ) +  (_default_entity_x_translate/Info::Render::width) )*_minimap.width(),
                             ( (_y_state_translate - _ruler_height) / (Info::Render::height*_y_state_scale) + (_ruler_height/Info::Render::height) )*_minimap.height(),
                             _minimap.width()/_x_state_scale,
                             _minimap.height()/_y_state_scale
                             );
            //initialize the minimap if it hasn't been done yet
            if(!_minimap.is_initialized()){
                QImage buf = grabFrameBuffer(true);
                _minimap.init(buf);
            }
            if(false == Info::Render::_no_arrows){
                draw_stored_arrows();
            }
Mathieu Faverge's avatar
Mathieu Faverge committed
284 285 286



287 288
            if (false == Info::Render::_no_events)/* display events */
                draw_stored_circles();
289

Mathieu Faverge's avatar
Mathieu Faverge committed
290

291

292 293
            /* Untranslate ruler */
            glEnable(GL_BLEND);
Mathieu Faverge's avatar
Mathieu Faverge committed
294
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
295
            call_ruler();
296
            glDisable(GL_BLEND);
Mathieu Faverge's avatar
Mathieu Faverge committed
297

298
            if (Info::Render::_vertical_line){
299 300
                draw_vertical_line();
            }
Mathieu Faverge's avatar
Mathieu Faverge committed
301

302 303
        }
        glPopMatrix();
Mathieu Faverge's avatar
Mathieu Faverge committed
304

305 306 307
        glPushMatrix();
        {
            glTranslated(0.0,  0.0, 100.0);/* not accurate */
Mathieu Faverge's avatar
Mathieu Faverge committed
308

309
            if (_mouse_pressed && (Info::Render::_key_ctrl == false) && !_mouse_pressed_inside_container){
Mathieu Faverge's avatar
Mathieu Faverge committed
310 311


312
                glTranslated(0.0, 0.0, _z_container_under);
Mathieu Faverge's avatar
Mathieu Faverge committed
313

314
                Element_pos old_x, old_y, new_x, new_y;
Mathieu Faverge's avatar
Mathieu Faverge committed
315 316


317

318 319 320 321 322
                old_x = screen_to_render_x(_mouse_x);
                old_y = Info::Render::height - screen_to_render_y(_mouse_y);

                new_x = screen_to_render_x(_new_mouse_x);
                new_y = Info::Render::height -  screen_to_render_y(_new_mouse_y);
323 324

#ifdef DEBUG_MODE_RENDER_OPENGL
Mathieu Faverge's avatar
Mathieu Faverge committed
325 326 327

                cerr << __FILE__ << " l." << __LINE__ << ":" << endl;
                cerr << "Selection rectangle position: (" << old_x << ", " << old_y << ") - (" << new_x << ", " << new_y << ")" << endl;
328
#endif
329

Mathieu Faverge's avatar
Mathieu Faverge committed
330

331
                glEnable(GL_BLEND);
Mathieu Faverge's avatar
Mathieu Faverge committed
332 333
                glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

334 335 336
                /* Square for selection */
                glBegin(GL_QUADS);
                {
337 338 339 340
                    glColor4f(0.9f, 1.0f, 0.9f, _selection_rectangle_alpha);glVertex2d(old_x, old_y);
                    glColor4f(0.9f, 0.9f, 0.9f, _selection_rectangle_alpha);glVertex2d(old_x, new_y);
                    glColor4f(0.9f, 0.9f, 0.9f, _selection_rectangle_alpha);glVertex2d(new_x, new_y);
                    glColor4f(0.9f, 0.9f, 0.9f, _selection_rectangle_alpha);glVertex2d(new_x, old_y);
341 342
                }
                glEnd();
Mathieu Faverge's avatar
Mathieu Faverge committed
343

344
                glDisable(GL_BLEND);
Mathieu Faverge's avatar
Mathieu Faverge committed
345

346 347 348 349 350 351 352
            }/* end  if (true==_mouse_pressed) */
        }
        glPopMatrix();



    }else{
353
        message << tr("Undefined value for the drawing state attribute - Render area").toStdString() << Message::ende;
354
    }
Mathieu Faverge's avatar
Mathieu Faverge committed
355

356 357 358 359 360 361
    glFlush();

    /* Check the errors */
    GLenum glerror;
    glerror = glGetError();
    if(glerror != GL_NO_ERROR)
362
        message << tr("Render area : the following OpengGL error occured: ").toStdString() << (char *)gluErrorString(glerror) << Message::endw;
363

364 365 366
    if(DRAWING_STATE_WAITING == _state)/* A wait is drawn, do not take car about the ruler drawing */
        return;

367
    QFont arial_font = QFont("Arial", 10);
368
    qglColor(Qt::white);
369

370
    const QFontMetrics metric(arial_font);
Mathieu Faverge's avatar
Mathieu Faverge committed
371

372 373
    //we calculate the height of the interline we want : max height of the font + 1 pixel to avoid overlapping (metric.height() returns a bigger value, a bit too much)
    int height = metric.tightBoundingRect("fg").height()+1;
Mathieu Faverge's avatar
Mathieu Faverge committed
374

375
    /* Draw container text */
376
    const unsigned int texts_size = _texts.size();
377
    std::map<Element_pos,Element_pos> previous_by_column;
Mathieu Faverge's avatar
Mathieu Faverge committed
378

379

380
    //int skipped,displayed=0;
381
    for (unsigned int i=0 ; i<texts_size ; i++){
382 383


Mathieu Faverge's avatar
Mathieu Faverge committed
384

385
        if (trace_to_render_y(_texts[i].y) + 0.5 < 9) continue;/* Do not display text if it is on the ruler area */
Mathieu Faverge's avatar
Mathieu Faverge committed
386

387 388 389
        //check if ye are not too close to another container to properly display the text
        std::map<Element_pos,Element_pos>::const_iterator it = previous_by_column.find(_texts[i].x);
        const std::map<Element_pos,Element_pos>::const_iterator it_end = previous_by_column.end();
390

391 392 393 394 395 396
        if (it==it_end || render_to_screen_y(trace_to_render_y(_texts[i].y)) - render_to_screen_y(trace_to_render_y((*it).second))> height ){
            const QString text_elided = metric.elidedText(_texts[i].value.c_str(), Qt::ElideRight, _x_scale_container_state*Info::Screen::width/(Info::Trace::depth+1.));
            renderText ( render_to_screen_x(_texts[i].x * _x_scale_container_state/0.20),
                         render_to_screen_y( trace_to_render_y(_texts[i].y) + 0.5),
                         text_elided,
                         arial_font);
397 398

            //push only displayed values in the map
399 400 401 402
            previous_by_column[_texts[i].x]=_texts[i].y;
            //displayed++;
        }//else{skipped++;}
    }
Mathieu Faverge's avatar
Mathieu Faverge committed
403

404
    // printf("skipped %d displayed %d\n", skipped, displayed);
405

406 407

    /* Draw ruler text */
408 409 410 411 412
    std::ostringstream buf_txt;
    Element_pos graduation_diff;
    Element_pos coeff_prefix;
    graduation_diff = Ruler::get_graduation_diff(Info::Render::_x_min_visible, Info::Render::_x_max_visible);
    coeff_prefix    = Ruler::get_coeff_for_common_prefix(Info::Render::_x_min_visible, Info::Render::_x_max_visible);
Mathieu Faverge's avatar
Mathieu Faverge committed
413

414
    arial_font.setPointSize(14);
Mathieu Faverge's avatar
Mathieu Faverge committed
415

416 417
    buf_txt.str("");/* flush the buffer */
    buf_txt << "min: " << (double)Info::Render::_x_min_visible;
Mathieu Faverge's avatar
Mathieu Faverge committed
418

419 420 421 422
    renderText (render_to_screen_x(trace_to_render_x(Info::Render::_x_min_visible)),
                render_to_screen_y(3),
                buf_txt.str().c_str(),
                arial_font);
Mathieu Faverge's avatar
Mathieu Faverge committed
423

424 425
    buf_txt.str("");/* flush the buffer */
    buf_txt << "max: " << (double)Info::Render::_x_max_visible;
Mathieu Faverge's avatar
Mathieu Faverge committed
426

427 428 429 430
    renderText (render_to_screen_x(trace_to_render_x(Info::Render::_x_max_visible))-130,
                render_to_screen_y(3),
                buf_txt.str().c_str(),
                arial_font);
Mathieu Faverge's avatar
Mathieu Faverge committed
431

432 433
    buf_txt.str("");
    buf_txt << Ruler::get_common_part_string(Info::Render::_x_min_visible, coeff_prefix) << "--";
Mathieu Faverge's avatar
Mathieu Faverge committed
434

435 436 437 438 439 440 441
    renderText (render_to_screen_x(
                    trace_to_render_x(
                        (Info::Render::_x_min_visible +
                         Info::Render::_x_max_visible) / 2)),
                render_to_screen_y(3),
                buf_txt.str().c_str(),
                arial_font);
Mathieu Faverge's avatar
Mathieu Faverge committed
442

443
    arial_font.setPointSize(10);
Mathieu Faverge's avatar
Mathieu Faverge committed
444

445 446 447
    for (Element_pos i = Info::Render::_x_min_visible ;
         i < Info::Render::_x_max_visible ;
         i+=graduation_diff){
Mathieu Faverge's avatar
Mathieu Faverge committed
448

449 450
        buf_txt.str("");/* flush the buffer */
        buf_txt << Ruler::get_variable_part(i, coeff_prefix, 2);
Mathieu Faverge's avatar
Mathieu Faverge committed
451

452 453 454 455
        renderText (render_to_screen_x(trace_to_render_x(i)+1),
                    render_to_screen_y(8),
                    buf_txt.str().c_str(),
                    arial_font);
456

457
    }
Mathieu Faverge's avatar
Mathieu Faverge committed
458

459
    //  update_minimap();
460 461 462 463




Mathieu Faverge's avatar
Mathieu Faverge committed
464

465 466 467 468 469
    //initialize the minimap if it hasn't been done yet
    if(!_minimap.is_initialized()){
        QImage buf = grabFrameBuffer(true);
        _minimap.init(buf);
    }
Mathieu Faverge's avatar
Mathieu Faverge committed
470

471
}
472 473 474



Olivier Lagrasse's avatar
Olivier Lagrasse committed
475 476


477 478 479 480 481 482 483 484 485 486 487 488 489
/***********************************
 *
 *
 *
 * Building functions.
 *
 *
 *
 **********************************/



bool Render_opengl::build(){
Mathieu Faverge's avatar
Mathieu Faverge committed
490

491 492 493 494 495 496 497
    _state = DRAWING_STATE_DRAWING;/* change the drawing state */

    /* disable some OpenGL features to enhance the rendering */
    glDisable(GL_TEXTURE_2D);
    glDisable(GL_BLEND);

    replace_scale(1);/* for states scaling */
498
    init_geometry();/* Initialize geometry */
499

500 501
#ifdef SPINNING_LOGO
    if (_wait_timer != NULL){
502 503 504
        _wait_timer->stop();
        delete(_wait_timer);
        _wait_timer = NULL;
505 506
    }
#endif // SPINNING_LOGO
507

Mathieu Faverge's avatar
Mathieu Faverge committed
508

509
    if (nullptr == _render_instance)
510 511
        return true;

512

513 514 515
    // updateGL();
    //   QImage buf = grabFrameBuffer(true);
    // _minimap.init(buf);
516 517
    //updateGL();

518

519 520 521
    // QImage buf = grabFrameBuffer(true);
    // _minimap.init(buf);
    // updateGL();
Mathieu Faverge's avatar
Mathieu Faverge committed
522

523
    return true;//_render_instance->display_build();
524 525 526 527 528
}



bool Render_opengl::unbuild(){
Mathieu Faverge's avatar
Mathieu Faverge committed
529

530 531 532 533 534 535 536 537 538
    /**********************
     *
     * Init OpenGL features
     *
     **********************/

    /* enable some OpenGL features*/
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
Mathieu Faverge's avatar
Mathieu Faverge committed
539

540 541
    glEnable(GL_TEXTURE_2D);

Mathieu Faverge's avatar
Mathieu Faverge committed
542
    glEnable(GL_BLEND);/* enable blending for the alpha color */
543 544
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

545
    glColor3f(1.0, 1.0, 1.0);/* init color to white */
546 547 548 549 550 551 552 553 554 555 556


    /*****************************
     *
     * Init render area attributes
     *
     *****************************/

    _state = DRAWING_STATE_WAITING;/* change the drawing state */

    _wait_angle=0.0f;/* begin with 0 rad angle */
Mathieu Faverge's avatar
Mathieu Faverge committed
557

558

559 560 561 562
    /* clear lists to store container texts */
    _text_pos.clear();
    _text_value.clear();

563 564 565
    _arrows.clear();
    _circles.clear();
    _texts.clear();
Mathieu Faverge's avatar
Mathieu Faverge committed
566

567
    /* empty the selection stack */
568 569
    // while(false == _previous_selection.empty())
    //   _previous_selection.pop();
570

571
    if (nullptr == _render_instance)
572 573
        return true;

574
    /* Now, timer is set */
575
#ifdef SPINNING_LOGO
576 577
    if (_wait_timer == NULL){
        _wait_angle = 0.0f;
Mathieu Faverge's avatar
Mathieu Faverge committed
578

579
        _wait_timer = new QTimer(this);
580
        connect(_wait_timer, SIGNAL(timeout()), _render_instance, SLOT(updateGL()));
581
        _wait_timer->start(_wait_spf);
582
    }
583
#endif // SPINNING_LOGO
584
    _minimap.release();
585

586 587
    init_geometry();/* Initialize geometry */

588
    return true;//_render_instance->display_unbuild();
589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609
}





/***********************************
 *
 *
 *
 * Drawing function for the wait screen.
 *
 *
 *
 **********************************/



GLuint Render_opengl::draw_wait() {
    GLuint object;
    GLuint texture;
Mathieu Faverge's avatar
Mathieu Faverge committed
610

611 612 613 614 615 616
    object = glGenLists(1);/* create the list */

    if (object == 0)
        message << tr("Error when creating list").toStdString() << Message::endw;


Mathieu Faverge's avatar
Mathieu Faverge committed
617 618
    glGenTextures(1, &texture);/* create the texture and link it with the list previously created */

619
    QFile texture_file(QString(":/img/img/logo") +  QDate::currentDate().toString("MMdd") + QString(".png"));
Mathieu Faverge's avatar
Mathieu Faverge committed
620

621 622 623 624 625 626 627 628
    if (true == texture_file.exists())/* The texture exists */
        texture = bindTexture(QPixmap(texture_file.fileName()), GL_TEXTURE_2D);
    else/* use the default picture */
        texture = bindTexture(QPixmap(":/img/img/logo.png"), GL_TEXTURE_2D);

    glNewList(object, GL_COMPILE);/* open the list */
    {
        glBindTexture(GL_TEXTURE_2D, texture);/* load texture for drawing */
Mathieu Faverge's avatar
Mathieu Faverge committed
629

630 631 632 633 634 635 636 637
        glBegin(GL_QUADS);/* draw a square */
        {
            glTexCoord2d(0,0); glVertex2f(-1, -1);
            glTexCoord2d(1,0); glVertex2f(1, -1);
            glTexCoord2d(1,1); glVertex2f(1, 1);
            glTexCoord2d(0,1); glVertex2f(-1, 1);
        }
        glEnd();
Mathieu Faverge's avatar
Mathieu Faverge committed
638 639 640


    }
641
    glEndList();/* close the list */
Mathieu Faverge's avatar
Mathieu Faverge committed
642

643 644 645
    /* apply some parameters on the texture */
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
Mathieu Faverge's avatar
Mathieu Faverge committed
646

647 648
    glEnable(GL_TEXTURE_2D);

Mathieu Faverge's avatar
Mathieu Faverge committed
649
    glEnable(GL_BLEND);/* enable blending for the alpha color */
650 651
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

Mathieu Faverge's avatar
Mathieu Faverge committed
652

653
    /* Now, timer is set */
654
    if (_wait_timer == nullptr){
655
        _wait_angle = 0.0f;
656
        /*
657 658 659
         _wait_timer = new QTimer(this);
         connect(_wait_timer, SIGNAL(timeout()), _render_instance, SLOT(updateGL()));
         _wait_timer->start(_wait_spf);*/
660 661 662 663 664 665 666
    }

    return object;
}


void Render_opengl::call_ruler(){
667
    Element_pos graduation_diff;
668
    //Element_pos coeff_prefix;
669
    const Element_pos offset_x = _default_entity_x_translate;
670
    const Element_pos offset_y = _ruler_y + _ruler_height+3.5;
Olivier Lagrasse's avatar
Olivier Lagrasse committed
671

672
    update_visible_interval_value();
Mathieu Faverge's avatar
Mathieu Faverge committed
673

674
    graduation_diff = Ruler::get_graduation_diff(Info::Render::_x_min_visible, Info::Render::_x_max_visible);
675
    // coeff_prefix    = Ruler::get_coeff_for_common_prefix(Info::Render::_x_min_visible, Info::Render::_x_max_visible);
Mathieu Faverge's avatar
Mathieu Faverge committed
676

677
    set_color(1.0, 1.0, 1.0);
Mathieu Faverge's avatar
Mathieu Faverge committed
678

679 680 681 682
    for (Element_pos i = Info::Render::_x_min_visible ;
         i < Info::Render::_x_max_visible ;
         i+=graduation_diff){

683 684
        const Element_pos grad_div_by_5 = graduation_diff/5;
        for (Element_pos j = (i+grad_div_by_5) ; j<(i+graduation_diff) ; j+= grad_div_by_5){
685 686 687 688

            if (j>=Info::Render::_x_max_visible)
                break;

689
            draw_line( trace_to_render_x(j) + offset_x, offset_y ,
690
                       trace_to_render_x(j) + offset_x, 2+offset_y, _z_ruler);
691
        }
Olivier Lagrasse's avatar
Olivier Lagrasse committed
692

693 694
        if (i>=Info::Render::_x_max_visible)
            break;
Mathieu Faverge's avatar
Mathieu Faverge committed
695

696
        draw_line( trace_to_render_x(i) + offset_x, offset_y-1 ,
697 698
                   trace_to_render_x(i) + offset_x, 4+offset_y, _z_ruler);
    }
Mathieu Faverge's avatar
Mathieu Faverge committed
699

Olivier Lagrasse's avatar
Olivier Lagrasse committed
700 701
    glBegin(GL_QUADS);
    {
702
        glColor4f(0.0f, 0.0f, 1.0f, 0.8f);
703 704 705 706
        glVertex3d(trace_to_render_x(Info::Render::_x_min_visible), 3, _z_ruler_under );
        glVertex3d(trace_to_render_x(Info::Render::_x_min_visible), 8, _z_ruler_under );
        glVertex3d(trace_to_render_x(Info::Render::_x_max_visible), 8, _z_ruler_under );
        glVertex3d(trace_to_render_x(Info::Render::_x_max_visible), 3, _z_ruler_under );
Olivier Lagrasse's avatar
Olivier Lagrasse committed
707 708
    }
    glEnd();
Mathieu Faverge's avatar
Mathieu Faverge committed
709

Olivier Lagrasse's avatar
Olivier Lagrasse committed
710 711
    glBegin(GL_QUADS);
    {
712
        glColor4f(0.0, 0.0, 0.0, 1.0);
713 714 715 716
        glVertex3d(trace_to_render_x(Info::Render::_x_min_visible), 0, _z_ruler_over );
        glVertex3d(trace_to_render_x(Info::Render::_x_min_visible), 3, _z_ruler_over );
        glVertex3d(trace_to_render_x(Info::Render::_x_max_visible), 3, _z_ruler_over );
        glVertex3d(trace_to_render_x(Info::Render::_x_max_visible), 0, _z_ruler_over );
Olivier Lagrasse's avatar
Olivier Lagrasse committed
717
    }
718
    glEnd();
Mathieu Faverge's avatar
Mathieu Faverge committed
719

720
    return;
Mathieu Faverge's avatar
Mathieu Faverge committed
721
}
722

723 724 725 726 727 728 729 730


void Render_opengl::set_color(float r, float g, float b){
    _red = r;
    _green = g;
    _blue = b;
}

731 732 733 734 735
void Render_opengl::draw_text_value(long int id,double text, double y){
    if(y!=-1){
        Variable_text_ buf;
        buf.y=y;
        buf.value=text;
736
        // printf("adding %f at %f for %p\n", text, y, (void*)id);
737 738 739 740 741 742 743 744 745 746
        _variable_texts[id]=buf;
    }else{
        //it's an update
        Variable_text_ buf=_variable_texts[id];
        buf.value=text;
        //printf("updating %f at %f for %p\n", text, y, (void*)id);
        _variable_texts[id]=buf;
    }
}

747 748
void Render_opengl::draw_text(const Element_pos x, const Element_pos y, const Element_pos, const std::string s){
    if (_draw_ruler) return;/* do not draw text for ruler */
749
    if (_draw_state) message << "Fatal error! Cannot put text in state lists!" << Message::ende;
750

751
    Container_text_ buf;
Mathieu Faverge's avatar
Mathieu Faverge committed
752

753 754 755
    buf.x     = x;
    buf.y     = render_to_trace_y(y);/* Cancel previous transformation. */
    buf.value = s;
756

757
    _texts.push_back(buf);
758 759 760
}


761
void Render_opengl::draw_quad(Element_pos x, Element_pos y, Element_pos /*z*/, Element_pos w, Element_pos h){
762

763
    Element_pos offset_x;
764 765
    const Element_pos offset_y = -_ruler_y - _ruler_height;

766 767 768 769
    offset_x = 0;

    if (!_draw_container)
        offset_x = -_default_entity_x_translate;
Mathieu Faverge's avatar
Mathieu Faverge committed
770

771 772

    glBegin(GL_QUADS);
773
    {
774
        glColor3f(_red, _green, _blue);
Mathieu Faverge's avatar
Mathieu Faverge committed
775

776 777
        glVertex2d(x + offset_x   , y + offset_y);
        glVertex2d(x + offset_x   , y + h + offset_y);
778

779

Mathieu Faverge's avatar
Mathieu Faverge committed
780
        if (Info::Render::_shaded_states){/* State color is shaded */
781
            glColor3f(_red*0.6, _green*0.6, _blue*0.6);
Mathieu Faverge's avatar
Mathieu Faverge committed
782

783 784
            glVertex2d(x + w + offset_x, y + h + offset_y);
            glVertex2d(x + w + offset_x, y + offset_y);
Mathieu Faverge's avatar
Mathieu Faverge committed
785
        }else{/* State color must be uniform */
786
            glColor3f(_red, _green, _blue);
Mathieu Faverge's avatar
Mathieu Faverge committed
787

788 789 790 791 792
            /* Multiply by 0.98 to allow distinction between two States with the same color. Temporary solution
             before using a border.
             */
            glVertex2d(x + w*0.98 + offset_x, y + h + offset_y);
            glVertex2d(x + w*0.98 + offset_x, y + offset_y);
Mathieu Faverge's avatar
Mathieu Faverge committed
793
        }
794 795 796 797
    }
    glEnd();
}

798 799
void Render_opengl::draw_triangle(Element_pos, Element_pos,
                                  Element_pos, Element_pos ){
800 801 802
}

void Render_opengl::draw_line(Element_pos x1, Element_pos y1, Element_pos x2, Element_pos y2, Element_pos z){
803 804 805 806

    const Element_pos offset_x = -_default_entity_x_translate;
    const Element_pos offset_y = -_ruler_y - _ruler_height;

807
    if (_draw_state) message << "Fatal error! Cannot put line in state lists!" << Message::ende;
Mathieu Faverge's avatar
Mathieu Faverge committed
808 809


810 811
    glBegin(GL_LINES);
    {
812
        glColor3f(_red, _green, _blue);
813 814
        glVertex3d(x1 + offset_x, y1 + offset_y, z);
        glVertex3d(x2 + offset_x, y2 + offset_y, z);
815 816 817 818
    }
    glEnd();
}

Olivier Lagrasse's avatar
Olivier Lagrasse committed
819
void Render_opengl::draw_circle(Element_pos /*x*/, Element_pos /*y*/, Element_pos /*z*/, Element_pos /*r*/){
820 821 822 823
}


void Render_opengl::start_draw(){
824 825

    _draw_container = false;
826 827 828 829
    _draw_state     = false;
    _draw_ruler     = false;
    _draw_arrow     = false;
    _draw_event     = false;
Mathieu Faverge's avatar
Mathieu Faverge committed
830

831
    init_geometry();/* Initialize geometry */
Mathieu Faverge's avatar
Mathieu Faverge committed
832

833 834 835 836 837
}

void Render_opengl::start_draw_containers(){
    _list_containers = glGenLists(1);/* create the list */
    if (_list_containers == 0) {
838
        *Message::get_instance() << tr("Error when creating containers list.").toStdString() << Message::endw;
839
    }
840

Mathieu Faverge's avatar
Mathieu Faverge committed
841
    _draw_container = true;
842 843 844
    glNewList(_list_containers, GL_COMPILE);/* open the list */
}

845
void Render_opengl::draw_container(const Element_pos, const Element_pos, const Element_pos, const Element_pos ){
Mathieu Faverge's avatar
Mathieu Faverge committed
846

847 848
}

849
void Render_opengl::draw_container_text(const Element_pos, const Element_pos, const std::string &){
850 851 852
}

void Render_opengl::end_draw_containers(){
853
    _draw_container = false;
854 855 856 857 858 859
    glEndList();/* close the list */
}

void Render_opengl::start_draw_states(){
    _list_states = glGenLists(1);/* create the list */
    if (_list_states == 0) {
860
        *Message::get_instance() << tr("Error when creating states list.").toStdString() << Message::endw;
861
    }
862

Mathieu Faverge's avatar
Mathieu Faverge committed
863
    _draw_state = true;
864 865 866
    glNewList(_list_states, GL_COMPILE);/* open the list */
}

867 868 869 870 871 872 873
void Render_opengl::draw_state( const Element_pos x,
                                const Element_pos y,
                                const Element_pos z,
                                const Element_pos w,
                                const Element_pos h,
                                EntityValue *value )
{
874
    if ((value == nullptr) || (value->get_visible() == true) ) {
875 876
        draw_quad( x, y, z, w, h );
    }
877 878 879
}

void Render_opengl::end_draw_states(){
880 881
    glEndList();/* close the states list */
    _draw_state = false;
882 883 884
}

void Render_opengl::start_draw_arrows(){
885
    _draw_arrow = true;
886 887
}

888 889 890 891 892 893 894
void Render_opengl::draw_arrow(const Element_pos start_time,
                               const Element_pos end_time,
                               const Element_pos start_height,
                               const Element_pos end_height,
                               const Element_col red,
                               const Element_col green,
                               const Element_col blue,
895
                               EntityValue *value)
896
{
897
    Arrow_ buf;
898 899
    const Element_pos offset_x = -_default_entity_x_translate;
    const Element_pos offset_y = -_ruler_y - _ruler_height;
900

901
    if ((value == nullptr) || (value->get_visible() == true) ) {
902 903 904 905 906 907 908
        buf.start_time   = start_time   + offset_x;
        buf.end_time     = end_time     + offset_x;
        buf.start_height = start_height + offset_y;
        buf.end_height   = end_height   + offset_y;
        buf.red          = red;
        buf.green        = green;
        buf.blue         = blue;
909

910 911
        _arrows.push_back(buf);
    }
912 913 914
}

void Render_opengl::end_draw_arrows(){
915
    _draw_arrow = false;
916 917
}

918 919 920 921
void Render_opengl::start_draw_events(){
    _draw_event = true;
}

922 923 924
void Render_opengl::draw_event(const Element_pos time,
                               const Element_pos height,
                               const Element_pos container_height,
925
                               EntityValue *value)
926
{
927
    Event_ buf;
928 929 930
    const Element_pos offset_x = -_default_entity_x_translate;
    const Element_pos offset_y = -_ruler_y - _ruler_height;

931
    if ((value == nullptr) || (value->get_visible() == true) ) {
932 933 934 935 936 937
        buf.time             = time   + offset_x;
        buf.height           = height + offset_y;
        buf.container_height = -container_height/2   ;
        buf.red              = _red;
        buf.green            = _green;
        buf.blue             = _blue;
938

939 940
        _circles.push_back(buf);
    }
941 942
}

943 944 945 946 947

void Render_opengl::end_draw_events(){
    _draw_event = false;
}

948
void Render_opengl::start_draw_counter(){
949 950
    _list_counters = glGenLists(1);/* create the list */
    if (_list_counters == 0) {
951
        *Message::get_instance() << tr("Error when creating counters list").toStdString() << Message::ende;
952
    }
Mathieu Faverge's avatar
Mathieu Faverge committed
953

954
    glNewList(_list_counters, GL_COMPILE);/* open the list */
955 956
}

957
void Render_opengl::draw_counter(const Element_pos, const Element_pos ){
958 959 960
}

void Render_opengl::end_draw_counter(){
961
    glEndList();/* close the list */
962 963
}

964 965 966 967 968 969 970 971
void Render_opengl::start_ruler(){
    _draw_ruler = true;
}

void Render_opengl::end_ruler(){
    _draw_ruler = false;
}

972
void Render_opengl::end_draw(){
973
    //printf("sizeof eventlist : %d %d %d %d %d %d\n",_circles.size(), _circles.size()*sizeof(Event_),_arrows.size(),_arrows.size()*sizeof(Arrow_), _texts.size(), _texts.size()*sizeof(Container_text_));
974 975 976 977 978 979 980 981 982
}


void Render_opengl::draw_stored_texts(){
}

void Render_opengl::draw_stored_arrows(){

    /* Only draw triangle. Lines are already in a display list */
983
    const Element_pos coeff = 180.0/M_PI;
984 985
    Element_pos angle;
    Element_pos start_time, end_time, start_height, end_height;
986
    Element_pos scaled_start_time, scaled_end_time, scaled_start_height, scaled_end_height;
987

Olivier Lagrasse's avatar
Olivier Lagrasse committed
988

989

990 991
    const unsigned int arrow_size = _arrows.size();
    for (unsigned int i=0 ; i<arrow_size ; i++){
Mathieu Faverge's avatar
Mathieu Faverge committed
992

993 994
        start_time   = _arrows[i].start_time;// + _x_state_scale*_x_state_translate;
        end_time     = _arrows[i].end_time;// + _x_state_scale*_x_state_translate;
995 996
        start_height = _arrows[i].start_height;
        end_height   = _arrows[i].end_height;
Olivier Lagrasse's avatar
Olivier Lagrasse committed
997

998
        glColor3f(_arrows[i].red, _arrows[i].green, _arrows[i].blue);
Mathieu Faverge's avatar
Mathieu Faverge committed
999

1000 1001 1002 1003 1004
        scaled_start_time   = start_time   * _x_state_scale;
        scaled_end_time     = end_time     * _x_state_scale;
        scaled_start_height = start_height * _y_state_scale;
        scaled_end_height   = end_height   * _y_state_scale;

1005 1006
        glPushMatrix();
        {
Mathieu Faverge's avatar
Mathieu Faverge committed
1007 1008

            glTranslated(_default_entity_x_translate + _x_state_scale*end_time - _x_state_translate,
1009
                         _ruler_y + _ruler_height + _y_state_scale*end_height - _y_state_translate,
1010
                         _z_arrow);/*
Mathieu Faverge's avatar
Mathieu Faverge committed
1011

1012 1013 1014
                                    glTranslated( _x_state_scale*end_time,
                                    _y_state_scale*end_height,
                                    0);*/
1015 1016

            if (start_time != end_time){
1017
                angle = atan2((scaled_end_height - scaled_start_height), (scaled_end_time - scaled_start_time))*coeff;/* arc tangent */
1018
                glRotated(angle, 0, 0, 1);
1019 1020
            }
            else
1021
                glRotated(90, 0, 0, 1);/* vertical alignment */
Mathieu Faverge's avatar
Mathieu Faverge committed
1022

1023 1024
            glBegin(GL_TRIANGLES);
            {
1025
                // glColor3d(_red, _green, _blue);
1026 1027 1028 1029 1030
                glVertex2d(0.0, 0.0);
                glVertex2d(-1.2, -0.4);
                glVertex2d(-1.2, 0.4);
            }
            glEnd();
Mathieu Faverge's avatar
Mathieu Faverge committed
1031

1032 1033
        }
        glPopMatrix();
1034
    }
1035 1036

    for (unsigned int i=0 ; i<arrow_size ; i++){
Mathieu Faverge's avatar
Mathieu Faverge committed
1037

1038 1039 1040 1041
        start_time   = _arrows[i].start_time;// + _x_state_scale*_x_state_translate;
        end_time     = _arrows[i].end_time;// + _x_state_scale*_x_state_translate;
        start_height = _arrows[i].start_height;
        end_height   = _arrows[i].end_height;
1042

1043
        glColor3f(_arrows[i].red, _arrows[i].green, _arrows[i].blue);
Mathieu Faverge's avatar
Mathieu Faverge committed
1044

1045 1046
        glPushMatrix();
        {
Mathieu Faverge's avatar
Mathieu Faverge committed
1047

1048
            glTranslated(_default_entity_x_translate - _x_state_translate,
1049 1050
                         _ruler_y + _ruler_height - _y_state_translate,
                         _z_arrow);
1051
            glScaled(_x_state_scale, _y_state_scale, 1.0);
Mathieu Faverge's avatar
Mathieu Faverge committed
1052

1053 1054 1055
            glBegin(GL_LINES);
            {
                glVertex2d(start_time, start_height);
1056
                glVertex2d(end_time , end_height  );
1057 1058
            }
            glEnd();
1059 1060 1061 1062 1063
        }
        glPopMatrix();
    }
}

1064

1065
void Render_opengl::draw_stored_circles(){
1066

1067

1068 1069 1070
    //tables to store values used for circles drawings, with run-time data (zoom, size of the window), using pre-generated tables
    double cos_table2[NB_STEPS];
    double sin_table2[NB_STEPS];
1071 1072

    for(int j = 0 ; j < NB_STEPS ; j ++){
1073 1074
        cos_table2[j]=  cos_table[j]/_x_state_scale;
        sin_table2[j]= (sin_table[j]*Info::Screen::width)/(_y_state_scale*Info::Screen::height);
1075
    }
Mathieu Faverge's avatar
Mathieu Faverge committed
1076

1077
    const unsigned int size = _circles.size();
1078

1079
    for (unsigned int i=0 ; i<size ; i++){
Mathieu Faverge's avatar
Mathieu Faverge committed
1080

1081
        glPushMatrix();
1082
        {
1083

Mathieu Faverge's avatar
Mathieu Faverge committed
1084 1085
            glColor3f(1.0 - _circles[i].red, 1.0 - _circles[i].green, 1.0 - _circles[i].blue);

1086 1087 1088
            glTranslated(_default_entity_x_translate - _x_state_translate,
                         _ruler_y + _ruler_height - _y_state_translate,
                         _z_arrow);
Mathieu Faverge's avatar
Mathieu Faverge committed
1089 1090 1091 1092
            glScalef(_x_state_scale, _y_state_scale, 1.0);



1093
            // Draw the outer circle
1094

1095 1096 1097 1098 1099 1100 1101 1102 1103
            glBegin(GL_POLYGON);
            {
                for(int j = 0 ; j < NB_STEPS ; j ++){
                    glVertex2d(_circles[i].time + cos_table2[j],
                               _circles[i].height + sin_table2[j]);
                }
            }
            glEnd();
        }
1104
        glPopMatrix();
Mathieu Faverge's avatar
Mathieu Faverge committed
1105
    }
1106

1107
    for (unsigned int i=0 ; i<size ; i++){
Mathieu Faverge's avatar
Mathieu Faverge committed
1108

1109 1110
        glPushMatrix();
        {
Mathieu Faverge's avatar
Mathieu Faverge committed
1111 1112


1113 1114
            glColor3f(_circles[i].red, _circles[i].green, _circles[i].blue);
            glTranslated(_default_entity_x_translate - _x_state_translate,
1115 1116
                         _ruler_y + _ruler_height - _y_state_translate,
                         _z_arrow);
1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129
            glScalef(_x_state_scale, _y_state_scale, 1.0);

            // Draw the sub-circle
            glBegin(GL_POLYGON);
            {
                for(int j = 0 ; j < NB_STEPS ; j ++){
                    glVertex3d(_circles[i].time + cos_table2[j]/1.2,
                               _circles[i].height + sin_table2[j]/1.2,
                               0.1);
                }
            }
            glEnd();
        }
1130 1131
        glPopMatrix();
    }
Mathieu Faverge's avatar
Mathieu Faverge committed
1132

1133 1134
    //draw the line in another loop for better performance
    for (unsigned int i=0 ; i<size ; i++){
Mathieu Faverge's avatar
Mathieu Faverge committed
1135

1136 1137 1138
        glPushMatrix();
        {

Mathieu Faverge's avatar
Mathieu Faverge committed
1139
            glColor3f(_circles[i].red, _circles[i].green, _circles[i].blue);
1140
            glTranslated(_default_entity_x_translate - _x_state_translate,
1141 1142
                         _ruler_y + _ruler_height - _y_state_translate,
                         _z_arrow);
Mathieu Faverge's avatar
Mathieu Faverge committed
1143 1144
            glScalef(_x_state_scale, _y_state_scale, 1.0);

1145
            glLineWidth( 3.0 );
Mathieu Faverge's avatar
Mathieu Faverge committed
1146
            //Draw the line
1147
            glBegin(GL_LINES);
1148
            {
1149
                glVertex2d(_circles[i].time, _circles[i].height-_circles[i].container_height);
1150
                glVertex2d(_circles[i].time, _circles[i].height);
1151

1152
            }
1153
            glEnd();
1154
        }
1155
        glPopMatrix();
1156
    }
Mathieu Faverge's avatar
Mathieu Faverge committed
1157

1158
    glLineWidth( 1.0 );
1159
}
1160 1161

void Render_opengl::update_vertical_line(){
1162

Mathieu Faverge's avatar
Mathieu Faverge committed
1163