c++ - OpenGL redraw scene when receive an input -


i have implement thread in visual c++ app draw in opengl window series of cubes related vector of cubes, of have center, side , level. it's vector of class object, tree, various levels , stratification. during main elaboration, cubes in object change: added, removed...at every step of elaboration...

i need redraw (refresh) content of opengl window when every step it's completed, obtain dynamic representation of evolve of list of cubes.

i mean:

  • first step done, pass array opengl thread, draw.
  • second step run, content of opengl window mantain first cube.
  • secondo step done, content of opengl updated new cubes.
  • and on...

the opengl thread it's in background mode thread...i need see evolution of cubes when elaboration...now, problem it's statement glutmainloop() situation it's continuos...and it's heavy or crash, system nvidia quadro 4000....opengl windows showed, blocked, unmovable , grey or don't show anything.

here piece of code (all related opengl):

#include <iostream> #include <opencv\cv.h> #include <opencv\highgui.h> #include <opencv2\highgui\highgui.hpp> #include <windows.h> #include <process.h> #include <queue> #include <array> #include <vector> #include <gl/glut.h> #include <gl/freeglut.h>  using namespace std; using namespace cv;    //premessa delle funzioni di posizionamento con mouse    void mousecb(int button, int stat, int x, int y);   void mousemotioncb(int x, int y);    //funzioni di inizializzazione e pulizia   bool initsharedmem();  void clearsharedmem();  void initlights();  void setcamera(float posx, float posy, float posz, float targetx, float targety, float    targetz);   void toortho();  void toperspective();   //variabili e costanti  const int   screen_width    = 640;  const int   screen_height   = 480; const float camera_distance = 10.0f;  int screenwidth; int screenheight; bool mouseleftdown;  bool mouserightdown;  bool mousemiddledown;  float mousex, mousey; float cameraanglex;  float cameraangley; float cameradistance; int drawmode;   ///////////////////////////////////////////////////////////////////////////////  // funzione inizializzazione opengl standard  /////////////////////////////////////////////////////////////////////////////// void init() { glshademodel(gl_smooth); glpixelstorei(gl_unpack_alignment, 4); glhint(gl_perspective_correction_hint,gl_nicest); glenable(gl_depth_test); glenable(gl_lighting);  glenable(gl_texture_2d); glenable(gl_cull_face); glenable(gl_color_material); initlights();  }   ///////////////////////////////////////////////////////////////////////////////  // funzione di inizializzazione globale delle variabili  /////////////////////////////////////////////////////////////////////////////// bool initsharedmem() { screenwidth = screen_width; screenheight = screen_height;  mouseleftdown = mouserightdown = mousemiddledown = false; mousex = mousey = 0;  cameraanglex = cameraangley = 0.0f; //cameradistance = camera_distance; cameradistance = 0.3f; drawmode = 0; // 0:pieno, 1: solo contorni, 2:punti  return true; }   ///////////////////////////////////////////////////////////////////////////////  // funzione di pulitura variabili globali  /////////////////////////////////////////////////////////////////////////////// void clearsharedmem() {  }   ///////////////////////////////////////////////////////////////////////////////  // inizializzazione luci  /////////////////////////////////////////////////////////////////////////////// void initlights() { glfloat lightka[] = {.2f, .2f, .2f, 1.0f};  // luce ambientale glfloat lightkd[] = {.7f, .7f, .7f, 1.0f};  // luce diffusa glfloat lightks[] = {1, 1, 1, 1};           // luce speculare  gllightfv(gl_light0, gl_ambient, lightka); gllightfv(gl_light0, gl_diffuse, lightkd); gllightfv(gl_light0, gl_specular, lightks);  // posizione delle luci float lightpos[4] = {0, 0, 20, 1};  gllightfv(gl_light0, gl_position, lightpos);  //attiva tutti settaggi delle luci glenable(gl_light0);                        }   ///////////////////////////////////////////////////////////////////////////////  //  posizione della telecamera e direzioni  ///////////////////////////////////////////////////////////////////////////////  void setcamera(float posx, float posy, float posz, float targetx, float targety, float   targetz) { glmatrixmode(gl_modelview); glloadidentity(); glulookat(posx, posy, posz, targetx, targety, targetz, 0, 1, 0); // eye(x,y,z),  focal(x,y,z), up(x,y,z)  }  /////////////////////////////////////////////////////////////////////////////// // impostazione proiezione ortogonale ///////////////////////////////////////////////////////////////////////////////  void toortho() { // imposta il viewport di tutta la finestra glviewport(0, 0, (glsizei)screenwidth, (glsizei)screenheight);  // imposta il frustum di visione glmatrixmode(gl_projection); glloadidentity(); glortho(0, screenwidth, 0, screenheight, -1, 1);  // passaggio modelview per interattività glmatrixmode(gl_modelview); glloadidentity(); }     ///////////////////////////////////////////////////////////////////////////////  // impostazione come perspective /////////////////////////////////////////////////////////////////////////////// void toperspective() {  // imposta il viewport di tutta la finestra glviewport(0, 0, (glsizei)screenwidth, (glsizei)screenheight);  //frustum perspective glmatrixmode(gl_projection); glloadidentity();  //gluperspective(60.0f, (float)(screenwidth)/screenheight, 1.0f, 1000.0f);  gluperspective(60.0f, (float)(screenwidth)/screenheight, 10.0f, 0.0f); // fov,   aspectratio, nearclip, farclip  // switch modelview matrix in order set scene glmatrixmode(gl_modelview); glloadidentity(); }     ///////////////////////////////////////////////////////////////////////////////   //  funzione ricorsiva di disegno   ///////////////////////////////////////////////////////////////////////////////   void addraw(cubo temp)  { //se non ci sono sottocubi    if (temp.lista_sottocubi.size() == 0)    {                 if (temp.livello == lmaxi) {              double centro[3]={(temp.v[6].x)/2, (temp.v[6].y)/2,         (temp.v[6].z)/2};              glpushmatrix();              gltranslatef(centro[0],centro[1],centro[2]);              glcolor3ub(0,0,255);              glutsolidcube(temp.lato);              glpopmatrix();         } } //se sottocubi ci sono else {     (int i=0;i<(int)temp.lista_sottocubi.size();i++){             addraw(temp.lista_sottocubi[i]);         }  } }   ///////////////////////////////////////////////////////////////////////////////  // funzione disegno principale  ///////////////////////////////////////////////////////////////////////////////  void draw() {  // clear buffer glclear(gl_color_buffer_bit | gl_depth_buffer_bit | gl_stencil_buffer_bit); glpushmatrix();  //spostamento del disegno gltranslatef(0, 0, -cameradistance); glrotatef(cameraanglex, 1, 0, 0);   // pitch glrotatef(cameraangley, 0, 1, 0);   // heading  //lancio funzione di disegno vera e propria addraw(prova);  //reset glpopmatrix(); glutswapbuffers();  }  //////////////////////////////////////////////////////////////////////////////  //  funzione di reshape  /////////////////////////////////////////////////////////////////////////////// void reshape(int w, int h) {  screenwidth = w;   screenheight = h;  toperspective();  }     ///////////////////////////////////////////////////////////////////////////////     //  funzione di refresh temporizzato della finestra     ///////////////////////////////////////////////////////////////////////////////      void timercb(int millisec){ gluttimerfunc(millisec, timercb, millisec); glutpostredisplay();   }   /////////////////////////////////////////////////////////////////////////////// // funzione rilevamento movimenti del mouse /////////////////////////////////////////////////////////////////////////////// void motion(int x,int y) { if(mouseleftdown) {     cameraangley += (x - mousex);     cameraanglex += (y - mousey);     mousex = x;     mousey = y; } if(mouserightdown) {     cameradistance -= (y - mousey) * 0.2f;     mousey = y;     }  }    ///////////////////////////////////////////////////////////////////////////////  // funzione per rilevamento bottoni mouse  /////////////////////////////////////////////////////////////////////////////// void mouse(int button, int state, int x, int y) { mousex = x; mousey = y;  if(button == glut_left_button) {     if(state == glut_down)     {         mouseleftdown = true;     }     else if(state == glut_up)         mouseleftdown = false; }   else if(button == glut_right_button)  {     if(state == glut_down)     {         mouserightdown = true;     }     else if(state == glut_up)         mouserightdown = false;  }   else if(button == glut_middle_button)  {     if(state == glut_down)     {         mousemiddledown = true;     }     else if(state == glut_up)         mousemiddledown = false;    }   }     ///////////////////////////////////////////////////////////////////////////////   // inizializzazione di glut   ///////////////////////////////////////////////////////////////////////////////   void initglut(){  //parametri fake per il lancio di initglut char *myargv[1]; int myargc = 1; myargv[0]=strdup("myopengl");  //inizializzazione glut basso livello glutinit(&myargc,myargv);  //lancio funzioni di settaggio finestra,visualizzazione ed altro glutinitdisplaymode( glut_rgba| glut_double | glut_depth |glut_stencil);     glutinitwindowsize(screenwidth, screenheight); glutinitwindowposition(850,100); glutcreatewindow("ricostruzione attuale");      //callback delle funzioni richiamate     glutdisplayfunc(draw);     gluttimerfunc(33,timercb,33);     glutreshapefunc(reshape);     glutmousefunc(mouse);     glutmotionfunc(motion);  }    ///////////////////////////////////////////////////////////////////////////////  //  thread richiamato per lanciare opengl  ///////////////////////////////////////////////////////////////////////////////  void draw3d (void *param){  //abbassa priorità del thread backgroud if(!setthreadpriority(getcurrentthread(), thread_mode_background_begin))     {         dwerror = getlasterror();         if (error_thread_mode_already_background == dwerror)         _tprintf(text("gia' in background\n"));         else _tprintf(text("errore nell'entrare in modalita' background (%d)\n"), dwerror);     }      // lancia funzione di inizializzazione variabili globali     initsharedmem();      //initiglut     initglut();     init();      //ciclo opengl     glutmainloop();      _endthread(); 

}

where prova it's vector container of cubes object instanced class defines cube 6 vertex , size of side (lato) , level.

removing recursive function "addraw" simple first level "read , draw" function (without recursivity) resolve problem (windows show correct 1° level cubes, rotable, zoomable...no crash or blocked window) need draw cubes of maximum level in every ramification...so need recursive scan of vector...

so, don't know how this...someone can me?

1) how can refresh opengl draw when need? 2) how draw opengl thread series of cube contained in multilevel vector?

i'm on visual c++ 2010 under windows 7 64 bit, freeglut 2.8.1

the absolute easiest thing create display callback , use glutpostredisplay (...) means of signaling thread's main loop invoke display callback. in glut, function increments counter reset @ end of every iteration of main loop , tells glut window dirty (needs redrawn) if has value > 0.

semaphores overkill here, useful when need prevent simultaneous access resource. not @ need. complicated approach problem put drawing thread sleep until receives signal redraw. acceptable approach non-interactive rendering, interactive rendering simple busy-wait loop checks "dirty" flag described above job done (in fact, believe how implementations of glut's main loop work).

the reason suggest avoiding glut here implementations (e.g. version ships os x) have known issues running main loop in secondary thread.


Comments

Popular posts from this blog

apache - Remove .php and add trailing slash in url using htaccess not loading css -

javascript - jQuery show full size image on click -