Render_opengl.cpp 37.3 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
/*
** 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.
**
**
31
** ViTE developers are (for version 0.* to 1.0):
Mathieu Faverge's avatar
Mathieu Faverge committed
32 33 34 35 36 37 38 39 40 41 42
**
**        - 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 51 52 53 54 55 56
#include <sstream>
#include <cmath>
/* -- */
#include <QFile> // For loading the wait image
#include <QDate>
#include <QTimer>
/* -- */
#include "interface/resource.hpp"
#include "interface/Interface.hpp"
/* -- */
57
#include "common/common.hpp"
58
#include "common/Info.hpp"
59
#include "common/Message.hpp"
60
/* -- */
61
#include "render/Ruler.hpp"
62
#include "render/Render_opengl.hpp"
63
#include "render/Render.hpp"
64
/* -- */
65 66 67 68 69

using namespace std;


#define message *Message::get_instance() << "(" << __FILE__ << " l." << __LINE__ << "): "
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
#define NB_STEPS 20


    const double angle       = M_PI/2.0;
    const double delta_angle = 2.0*M_PI/NB_STEPS;
    const double radius = .5;


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

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

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

template <> void Render_opengl::sin_table_builder<0>(double table[]){
	table[0]=sin(angle)*(radius);
}

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


100

Olivier Lagrasse's avatar
Olivier Lagrasse committed
101
const int Render_opengl::DRAWING_TIMER_DEFAULT = 10;
102 103 104 105 106 107 108 109 110 111 112

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

Olivier Lagrasse's avatar
Olivier Lagrasse committed
113 114
Render_opengl::Render_opengl(Core* core, QWidget *parent, const QGLFormat& format)
    : Hook_event(this, core, parent, format){
115 116 117


  
118 119 120
    _arrows.clear();
    _circles.clear();
    _texts.clear();
121

Olivier Lagrasse's avatar
Olivier Lagrasse committed
122
    /* init the wait animation */
123 124 125 126 127 128
    _wait_list      = 0;
    _wait_angle     = 0.0f; /* begin with 0 rad angle */
    _wait_timer     = NULL;
    _wait_spf       = DRAWING_TIMER_DEFAULT;/* DRAWING_TIMER_DEFAULT milliseconds per frame */
    /* _minimap_widget = NULL;
       _minimap_image  = NULL;*/
129 130 131 132 133 134

#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
135
	vertical_line=0;
136
    vertical_line=0;
137
    setAutoFillBackground(false);
138 139 140 141 142
    
    
cos_table_builder<NB_STEPS>(cos_table);
sin_table_builder<NB_STEPS>(sin_table);

143 144 145
}


146
void Render_opengl::release(){
Olivier Lagrasse's avatar
Olivier Lagrasse committed
147 148 149 150 151 152 153 154 155
  /* Release the Rabbit and ruler lists */
    if (glIsList(_wait_list) == GL_TRUE)
        glDeleteLists(_wait_list, 1);

    /* Release timer (for Rabbit rotate) */
    if (_wait_timer != NULL){
        delete _wait_timer;
        _wait_timer=NULL;
    }
156 157
  
    //    release_minimap();
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
}

/***********************************
 *
 *
 *
 * 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();
178
      
179 180 181 182 183 184
}

void  Render_opengl::resizeGL(int width, int height) {
    glViewport(0, 0, width, height);
    
    /* update informations about widget size */
Olivier Lagrasse's avatar
Olivier Lagrasse committed
185 186
    Info::Screen::width  = width;
    Info::Screen::height = height;
187 188 189 190 191 192 193 194 195
    
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();


        
    if(DRAWING_STATE_WAITING == _state){// A wait is drawn
        glOrtho(-50, 50, -50, 50, 0, 1000);
    }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 200 201 202 203 204
    }
      

    glMatrixMode(GL_MODELVIEW);
}

205

Olivier Lagrasse's avatar
Olivier Lagrasse committed
206
void  Render_opengl::paintGL(){
207 208
    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 */
209
    makeCurrent();
210
  //static int arrows_drawn=0;
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
    glClearDepth(1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();

   
    if(DRAWING_STATE_WAITING == _state){/* A wait is drawn */
        
        /* turn around y axis */
        _wait_angle+=0.1f;
        if (_wait_angle>=360) _wait_angle=0.0f;
      
        glPushMatrix();
      
        glScalef(15, 15, 0);
      
227
#ifdef SPINNING_LOGO
228
        glRotatef(-_wait_angle,0, 1, 0);
229
#endif // SPINNING_LOGO
230 231 232 233 234 235 236 237 238 239 240
        
        glCallList(_wait_list);

        glPopMatrix();
	
    
    }else if (DRAWING_STATE_DRAWING == _state){/* A trace is drawn */
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glPushMatrix();
	{
Olivier Lagrasse's avatar
Olivier Lagrasse committed
241
            glTranslated(0.0, Info::Render::height, 100.0);
242 243
	    glRotated(180.0, 1.0, 0.0, 0.0);
	    
244
            glPushMatrix();
245

246
            {             
247
                glTranslatef(0.0f, _ruler_y + _ruler_height -_y_state_translate,  _z_container);
248 249 250 251 252 253
                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);
254

255 256 257 258 259
            }
            glPopMatrix();

            glPushMatrix();
            {
260 261
                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);
262

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

273 274 275 276 277 278 279 280 281 282 283 284 285 286 287
        _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();
        }
                
                
Olivier Lagrasse's avatar
Olivier Lagrasse committed
288
            
289 290
            if (false == Info::Render::_no_events)/* display events */
                draw_stored_circles();
291

292 293 294 295
				
			if (Info::Render::_vertical_line){
				draw_vertical_line();
			}
296 297 298 299
            /* Untranslate ruler */
            glEnable(GL_BLEND);
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
            call_ruler();
300
            glDisable(GL_BLEND);
301 302 303
                        
        }
        glPopMatrix();
304
        
305 306 307 308 309 310 311 312 313 314 315
        glPushMatrix();
        {
            glTranslated(0.0,  0.0, 100.0);/* not accurate */
           
            if (_mouse_pressed){
               
               
                glTranslated(0.0, 0.0, _z_container_under);
               
                Element_pos old_x, old_y, new_x, new_y;
               
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 325 326 327 328

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

330 331 332 333 334 335 336
               
                glEnable(GL_BLEND);
                glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
               
                /* 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 343 344 345 346 347 348 349 350 351 352
                }
                glEnd();
              
                glDisable(GL_BLEND);
                               
            }/* end  if (true==_mouse_pressed) */
        }
        glPopMatrix();



    }else{
353
        message << tr("Undefined value for the drawing state attribute - Render area").toStdString() << Message::ende;
354
    }
Olivier Lagrasse's avatar
Olivier Lagrasse committed
355
  
356 357 358 359 360 361 362
    glFlush();


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

Olivier Lagrasse's avatar
Olivier Lagrasse committed
365

Olivier Lagrasse's avatar
Olivier Lagrasse committed
366

367 368 369 370 371

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


372
    QFont arial_font = QFont("Arial", 10);
373
    qglColor(Qt::white);
374

Olivier Lagrasse's avatar
Olivier Lagrasse committed
375

Olivier Lagrasse's avatar
Olivier Lagrasse committed
376
    /* Draw container text */
377
    const unsigned int texts_size = _texts.size();
378 379
        for (unsigned int i=0 ; i<texts_size ; i++){
            const QFontMetrics metric(arial_font);
Olivier Lagrasse's avatar
Olivier Lagrasse committed
380
            const QString text_elided = metric.elidedText(_texts[i].value.c_str(), Qt::ElideRight, _x_scale_container_state*Info::Screen::width/(Info::Trace::depth+1.));
381 382 383 384 385 386 387 388 389
            
            if (trace_to_render_y(_texts[i].y) + 0.5 < 9) continue;/* Do not display text if it is on the ruler area */
            
            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);
        }
  
390 391
  

Olivier Lagrasse's avatar
Olivier Lagrasse committed
392 393

    /* Draw ruler text */
394 395 396 397 398 399 400 401
         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);
        
        arial_font.setPointSize(14);
        
Olivier Lagrasse's avatar
Olivier Lagrasse committed
402
        buf_txt.str("");/* flush the buffer */
403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425
        buf_txt << "min: " << (double)Info::Render::_x_min_visible;
        
        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);
        
        buf_txt.str("");/* flush the buffer */
        buf_txt << "max: " << (double)Info::Render::_x_max_visible;
        
        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);
        
        buf_txt.str("");
        buf_txt << Ruler::get_common_part_string(Info::Render::_x_min_visible, coeff_prefix) << "--";
        
        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),
426 427
                    buf_txt.str().c_str(),
                    arial_font);
428 429 430 431 432 433 434 435 436 437 438 439 440 441
        
        arial_font.setPointSize(10);
        
        for (Element_pos i = Info::Render::_x_min_visible ; 
             i < Info::Render::_x_max_visible ; 
             i+=graduation_diff){
            
            buf_txt.str("");/* flush the buffer */
            buf_txt << Ruler::get_variable_part(i, coeff_prefix, 2);
            
            renderText (render_to_screen_x(trace_to_render_x(i)+1),
                        render_to_screen_y(8),
                        buf_txt.str().c_str(),
                        arial_font);
442

443 444 445 446 447 448 449 450
        }      
       
         //  update_minimap();


                         


451 452 453 454
       //initialize the minimap if it hasn't been done yet                 
       if(!_minimap.is_initialized()){
           QImage buf = grabFrameBuffer(true);
           _minimap.init(buf);
455 456
       }
     
Olivier Lagrasse's avatar
Olivier Lagrasse committed
457
}
458 459 460



Olivier Lagrasse's avatar
Olivier Lagrasse committed
461 462


463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483
/***********************************
 *
 *
 *
 * Building functions.
 *
 *
 *
 **********************************/



bool Render_opengl::build(){
    
    _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 */
484
    init_geometry();/* Initialize geometry */
485

486 487
#ifdef SPINNING_LOGO
    if (_wait_timer != NULL){
488 489 490
        _wait_timer->stop();
        delete(_wait_timer);
        _wait_timer = NULL;
491 492
    }
#endif // SPINNING_LOGO
493

494 495 496 497
 
    if (NULL == _render_instance)
        return true;

498

499
   // updateGL();
500 501 502 503
 //   QImage buf = grabFrameBuffer(true);
   // _minimap.init(buf);
    //updateGL();

504

505 506 507 508
   // QImage buf = grabFrameBuffer(true);
   // _minimap.init(buf);
   // updateGL();
	
509
    return true;//_render_instance->display_build();
510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530
}



bool Render_opengl::unbuild(){
     
    /**********************
     *
     * 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);
   
    glEnable(GL_TEXTURE_2D);

    glEnable(GL_BLEND);/* enable blending for the alpha color */ 
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

531
    glColor3f(1.0, 1.0, 1.0);/* init color to white */
532 533 534 535 536 537 538 539 540 541 542


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

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

    _wait_angle=0.0f;/* begin with 0 rad angle */
543
    
544

Olivier Lagrasse's avatar
Olivier Lagrasse committed
545 546 547 548
    /* clear lists to store container texts */
    _text_pos.clear();
    _text_value.clear();

549 550 551
    _arrows.clear();
    _circles.clear();
    _texts.clear();
552 553
    
    /* empty the selection stack */
554 555
   // while(false == _previous_selection.empty())
     //   _previous_selection.pop();
556 557 558 559

    if (NULL == _render_instance)
        return true;

560
    /* Now, timer is set */
561
#ifdef SPINNING_LOGO
562 563 564
    if (_wait_timer == NULL){
        _wait_angle = 0.0f;
        
565
        _wait_timer = new QTimer(this);
566
        connect(_wait_timer, SIGNAL(timeout()), _render_instance, SLOT(updateGL()));
567
        _wait_timer->start(_wait_spf);
568
    }
569
#endif // SPINNING_LOGO
570
    _minimap.release();
571

572 573
    init_geometry();/* Initialize geometry */

574
    return true;//_render_instance->display_unbuild();
575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641
}





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



GLuint Render_opengl::draw_wait() {
    GLuint object;
    GLuint texture;
   
    object = glGenLists(1);/* create the list */

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


    glGenTextures(1, &texture);/* create the texture and link it with the list previously created */   
    
    QFile texture_file(QString(":/img/img/logo") +  QDate::currentDate().toString("MMdd") + QString(".png"));
  
    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 */
     
        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();
        
     
    }    
    glEndList();/* close the list */
    
    /* 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);
   
    glEnable(GL_TEXTURE_2D);

    glEnable(GL_BLEND);/* enable blending for the alpha color */ 
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

  
    /* Now, timer is set */
    if (_wait_timer == NULL){
        _wait_angle = 0.0f;
642 643 644 645
        /*
        _wait_timer = new QTimer(this);
        connect(_wait_timer, SIGNAL(timeout()), _render_instance, SLOT(updateGL()));
        _wait_timer->start(_wait_spf);*/
646 647 648 649 650 651 652
    }

    return object;
}


void Render_opengl::call_ruler(){
Olivier Lagrasse's avatar
Olivier Lagrasse committed
653 654 655
    Element_pos graduation_diff;
    Element_pos coeff_prefix;
    const Element_pos offset_x = _default_entity_x_translate;
656
    const Element_pos offset_y = _ruler_y + _ruler_height+3.5;
Olivier Lagrasse's avatar
Olivier Lagrasse committed
657

658
    update_visible_interval_value();
Olivier Lagrasse's avatar
Olivier Lagrasse committed
659 660 661 662
    
    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);
    
663
    set_color(1.0, 1.0, 1.0);
Olivier Lagrasse's avatar
Olivier Lagrasse committed
664
    
665 666 667 668
    for (Element_pos i = Info::Render::_x_min_visible ;
         i < Info::Render::_x_max_visible ;
         i+=graduation_diff){

Olivier Lagrasse's avatar
Olivier Lagrasse committed
669 670
        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){
671 672 673 674

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

Olivier Lagrasse's avatar
Olivier Lagrasse committed
675 676
            draw_line( trace_to_render_x(j) + offset_x, offset_y  ,
                       trace_to_render_x(j) + offset_x, 2+offset_y, _z_ruler);
Olivier Lagrasse's avatar
Olivier Lagrasse committed
677
        }
Olivier Lagrasse's avatar
Olivier Lagrasse committed
678

679 680 681
        if (i>=Info::Render::_x_max_visible)
            break;
   
682
        draw_line( trace_to_render_x(i) + offset_x, offset_y-1  ,
Olivier Lagrasse's avatar
Olivier Lagrasse committed
683 684
                   trace_to_render_x(i) + offset_x, 4+offset_y, _z_ruler);
    }
Olivier Lagrasse's avatar
Olivier Lagrasse committed
685 686 687
    
    glBegin(GL_QUADS);
    {
688
        glColor4f(0.0f, 0.0f, 1.0f, 0.8f);
689
        glVertex3d(trace_to_render_x(Info::Render::_x_min_visible) , 3, _z_ruler_under );
Olivier Lagrasse's avatar
Olivier Lagrasse committed
690 691
        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 );
692
        glVertex3d(trace_to_render_x(Info::Render::_x_max_visible) , 3, _z_ruler_under );
Olivier Lagrasse's avatar
Olivier Lagrasse committed
693 694 695 696 697
    }
    glEnd();
    
    glBegin(GL_QUADS);
    {
698
        glColor4f(0.0, 0.0, 0.0, 1.0);
Olivier Lagrasse's avatar
Olivier Lagrasse committed
699 700 701 702 703 704 705
        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 );
    }
    glEnd();
         
Olivier Lagrasse's avatar
Olivier Lagrasse committed
706
    return;
707 708
}    

709 710 711 712 713 714 715 716


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

Olivier Lagrasse's avatar
Olivier Lagrasse committed
717 718
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 */
719
    if (_draw_state) message << "Fatal error! Cannot put text in state lists!" << Message::ende;
Olivier Lagrasse's avatar
Olivier Lagrasse committed
720

721
        Container_text_ buf;
722
        
723
        buf.x     = x;
Olivier Lagrasse's avatar
Olivier Lagrasse committed
724
        buf.y     = render_to_trace_y(y);/* Cancel previous transformation. */
725 726 727 728 729 730
        buf.value = s;

        _texts.push_back(buf);
}


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

Olivier Lagrasse's avatar
Olivier Lagrasse committed
733
    Element_pos offset_x;
734 735 736
    const Element_pos offset_y = -_ruler_y - _ruler_height;

    if (_draw_ruler) return;/* do not draw quad for ruler */
Olivier Lagrasse's avatar
Olivier Lagrasse committed
737 738 739 740 741

    offset_x = 0;

    if (!_draw_container)
        offset_x = -_default_entity_x_translate;
742 743 744
   

    glBegin(GL_QUADS);
745
    {
746
        glColor3f(_red, _green, _blue);
747
      
748 749
        glVertex2d(x + offset_x    , y + offset_y);
        glVertex2d(x + offset_x    , y + h + offset_y);
750

751 752

	if (Info::Render::_shaded_states){/* State color is shaded */
753
	        glColor3f(_red*0.6, _green*0.6, _blue*0.6);
754 755 756 757
	
        	glVertex2d(x + w + offset_x, y + h + offset_y);
	        glVertex2d(x + w + offset_x, y + offset_y);
	}else{/* State color must be uniform */
758
	        glColor3f(_red, _green, _blue);
759 760 761 762 763 764 765
	
		/* 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);
	}
766 767 768 769
    }
    glEnd();
}

Olivier Lagrasse's avatar
Olivier Lagrasse committed
770 771
void Render_opengl::draw_triangle(Element_pos , Element_pos ,
                                  Element_pos , Element_pos ){
772 773 774
}

void Render_opengl::draw_line(Element_pos x1, Element_pos y1, Element_pos x2, Element_pos y2, Element_pos z){
Olivier Lagrasse's avatar
Olivier Lagrasse committed
775 776 777 778

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

779 780
    if (_draw_ruler || _draw_arrow || _draw_event) return;/* do not draw line for ruler or for arrow or for event */

781 782
    if (_draw_state) message << "Fatal error! Cannot put line in state lists!" << Message::ende;
   
783
   
784 785
    glBegin(GL_LINES);
    {
786
        glColor3f(_red, _green, _blue);
Olivier Lagrasse's avatar
Olivier Lagrasse committed
787 788
        glVertex3d(x1 + offset_x, y1 + offset_y, z);
        glVertex3d(x2 + offset_x, y2 + offset_y, z);
789 790 791 792
    }
    glEnd();
}

Olivier Lagrasse's avatar
Olivier Lagrasse committed
793
void Render_opengl::draw_circle(Element_pos /*x*/, Element_pos /*y*/, Element_pos /*z*/, Element_pos /*r*/){
794 795 796 797
}


void Render_opengl::start_draw(){
Olivier Lagrasse's avatar
Olivier Lagrasse committed
798 799

    _draw_container = false;
800 801 802 803
    _draw_state     = false;
    _draw_ruler     = false;
    _draw_arrow     = false;
    _draw_event     = false;
804 805 806
 
    init_geometry();/* Initialize geometry */
  
807 808 809 810 811
}

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

    _draw_container = true;    
816 817 818
    glNewList(_list_containers, GL_COMPILE);/* open the list */
}

Olivier Lagrasse's avatar
Olivier Lagrasse committed
819
void Render_opengl::draw_container(const Element_pos , const Element_pos , const Element_pos , const Element_pos ){
820 821 822
    
}

Olivier Lagrasse's avatar
Olivier Lagrasse committed
823
void Render_opengl::draw_container_text(const Element_pos , const Element_pos , const std::string ){
824 825 826
}

void Render_opengl::end_draw_containers(){
Olivier Lagrasse's avatar
Olivier Lagrasse committed
827
    _draw_container = false;
828 829 830 831 832 833
    glEndList();/* close the list */
}

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

    _draw_state = true;    
838 839 840
    glNewList(_list_states, GL_COMPILE);/* open the list */
}

Olivier Lagrasse's avatar
Olivier Lagrasse committed
841
void Render_opengl::draw_state(const Element_pos , const Element_pos , const Element_pos , const Element_pos , const Element_col , const Element_col , const Element_col ){
842 843 844
}

void Render_opengl::end_draw_states(){
845 846
    glEndList();/* close the states list */
    _draw_state = false;
847 848 849
}

void Render_opengl::start_draw_arrows(){
Olivier Lagrasse's avatar
Olivier Lagrasse committed
850
    _draw_arrow = true;
851 852
}

Olivier Lagrasse's avatar
Olivier Lagrasse committed
853
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){
854 855

    Arrow_ buf;
Olivier Lagrasse's avatar
Olivier Lagrasse committed
856 857
    const Element_pos offset_x = -_default_entity_x_translate;
    const Element_pos offset_y = -_ruler_y - _ruler_height;
858

Olivier Lagrasse's avatar
Olivier Lagrasse committed
859 860 861 862
    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;
Olivier Lagrasse's avatar
Olivier Lagrasse committed
863 864 865
    buf.red          = red;
    buf.green        = green;
    buf.blue         = blue;
866 867

    _arrows.push_back(buf);
868
	//printf("sizeof eventlist : %d %d %d %d\n",_circles.size(), _circles.size()*sizeof(Event_),_arrows.size(),_arrows.size()*sizeof(Arrow_));
869 870 871
}

void Render_opengl::end_draw_arrows(){
Olivier Lagrasse's avatar
Olivier Lagrasse committed
872
    _draw_arrow = false;
873 874
}

875 876 877 878
void Render_opengl::start_draw_events(){
    _draw_event = true;
}

879
void Render_opengl::draw_event(const Element_pos time, const Element_pos height,  const Element_pos container_height){
880
    Event_ buf;
881 882 883 884 885 886
    const Element_pos offset_x = -_default_entity_x_translate;
    const Element_pos offset_y = -_ruler_y - _ruler_height;

    buf.time             = time   + offset_x;
    buf.height           = height + offset_y;
    buf.container_height = container_height   + offset_y;
887 888 889
    buf.red              = _red;
    buf.green            = _green;
    buf.blue             = _blue;
890 891

    _circles.push_back(buf);
892
	//printf("sizeof eventlist : %d %d\n", _circles.size()*sizeof(Event_),_arrows.size()*sizeof(Arrow_));
893 894
}

895 896 897

void Render_opengl::end_draw_events(){
    _draw_event = false;
898
   // printf("sizeof eventlist : %d %d %d %d\n",_circles.size(), _circles.size()*sizeof(Event_),_arrows.size(),_arrows.size()*sizeof(Arrow_));
899 900
}

901
void Render_opengl::start_draw_counter(){
902 903
    _list_counters = glGenLists(1);/* create the list */
    if (_list_counters == 0) {
904
        *Message::get_instance() << tr("Error when creating counters list").toStdString() << Message::ende;
905 906 907
    }
    
    glNewList(_list_counters, GL_COMPILE);/* open the list */
908 909
}

Olivier Lagrasse's avatar
Olivier Lagrasse committed
910
void Render_opengl::draw_counter(const Element_pos , const Element_pos ){
911 912 913
}

void Render_opengl::end_draw_counter(){
914
    glEndList();/* close the list */
915 916
}

Olivier Lagrasse's avatar
Olivier Lagrasse committed
917 918 919 920 921 922 923 924
void Render_opengl::start_ruler(){
    _draw_ruler = true;
}

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

925
void Render_opengl::end_draw(){
926
//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_));
927 928 929 930 931 932 933 934 935
}


void Render_opengl::draw_stored_texts(){
}

void Render_opengl::draw_stored_arrows(){

    /* Only draw triangle. Lines are already in a display list */
936
    const Element_pos coeff = 180.0/M_PI;
937 938
    Element_pos angle;
    Element_pos start_time, end_time, start_height, end_height;
Olivier Lagrasse's avatar
Olivier Lagrasse committed
939
    Element_pos scaled_start_time, scaled_end_time, scaled_start_height, scaled_end_height;
940

Olivier Lagrasse's avatar
Olivier Lagrasse committed
941

942

943 944
    const unsigned int arrow_size = _arrows.size();
    for (unsigned int i=0 ; i<arrow_size ; i++){
945
        
Olivier Lagrasse's avatar
Olivier Lagrasse committed
946 947
        start_time   = _arrows[i].start_time;// + _x_state_scale*_x_state_translate;
        end_time     = _arrows[i].end_time;// + _x_state_scale*_x_state_translate;
948 949
        start_height = _arrows[i].start_height;
        end_height   = _arrows[i].end_height;
Olivier Lagrasse's avatar
Olivier Lagrasse committed
950

951
        glColor3f(_arrows[i].red, _arrows[i].green, _arrows[i].blue);
952
        
Olivier Lagrasse's avatar
Olivier Lagrasse committed
953 954 955 956 957
        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;

958 959 960
        glPushMatrix();
        {
            
Olivier Lagrasse's avatar
Olivier Lagrasse committed
961 962
            glTranslated(_default_entity_x_translate + _x_state_scale*end_time - _x_state_translate, 
                         _ruler_y + _ruler_height + _y_state_scale*end_height - _y_state_translate,
963 964 965 966 967
                         _z_arrow);/*
                         
                         glTranslated( _x_state_scale*end_time, 
                        _y_state_scale*end_height ,
                         0);*/
968 969

            if (start_time != end_time){
Olivier Lagrasse's avatar
Olivier Lagrasse committed
970
                angle = atan2((scaled_end_height - scaled_start_height), (scaled_end_time - scaled_start_time))*coeff;/* arc tangent */
971
                glRotated(angle, 0, 0, 1);
972 973
            }
            else
974
                glRotated(90, 0, 0, 1);/* vertical alignment */
975 976 977
       
            glBegin(GL_TRIANGLES);
            {
978
                // glColor3d(_red, _green, _blue);
979 980 981 982 983
                glVertex2d(0.0, 0.0);
                glVertex2d(-1.2, -0.4);
                glVertex2d(-1.2, 0.4);
            }
            glEnd();
Olivier Lagrasse's avatar
Olivier Lagrasse committed
984 985 986
        
        }
        glPopMatrix();
987 988 989 990 991 992 993 994
}

    for (unsigned int i=0 ; i<arrow_size ; i++){
        
        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;
Olivier Lagrasse's avatar
Olivier Lagrasse committed
995

996 997
        glColor3f(_arrows[i].red, _arrows[i].green, _arrows[i].blue);
        
Olivier Lagrasse's avatar
Olivier Lagrasse committed
998 999 1000
        glPushMatrix();
        {
            
1001
           glTranslated(_default_entity_x_translate - _x_state_translate,
Olivier Lagrasse's avatar
Olivier Lagrasse committed
1002 1003
                         _ruler_y + _ruler_height - _y_state_translate,
                         _z_arrow);
1004
            glScaled(_x_state_scale, _y_state_scale, 1.0);
Olivier Lagrasse's avatar
Olivier Lagrasse committed
1005 1006 1007 1008 1009 1010 1011
     
            glBegin(GL_LINES);
            {
                glVertex2d(start_time, start_height);
                glVertex2d(end_time  , end_height  );
            }
            glEnd();
1012 1013 1014 1015 1016
        }
        glPopMatrix();
    }
}

1017

1018
void Render_opengl::draw_stored_circles(){
Olivier Lagrasse's avatar
Olivier Lagrasse committed
1019

1020 1021 1022 1023 1024 1025 1026 1027 1028 1029

   //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];

    for(int j = 0 ; j < NB_STEPS ; j ++){
                     cos_table2[j]=  cos_table[j]/_x_state_scale;
                     sin_table2[j]= (sin_table[j]*Info::Screen::width)/(_y_state_scale*Info::Screen::height);
    }
    
1030
    const unsigned int size = _circles.size();
1031

1032
    for (unsigned int i=0 ; i<size ; i++){
Olivier Lagrasse's avatar
Olivier Lagrasse committed
1033
 
1034
        glPushMatrix();
1035
        {
1036

1037
            glColor3f(1.0 - _circles[i].red, 1.0 - _circles[i].green, 1.0 - _circles[i].blue); 
1038 1039 1040 1041
                      
            glTranslated(_default_entity_x_translate - _x_state_translate,
                         _ruler_y + _ruler_height - _y_state_translate,
                         _z_arrow);
1042
            glScalef(_x_state_scale, _y_state_scale, 1.0); 
1043
          
1044

Olivier Lagrasse's avatar